找回密码
 注册会员
更新自动建库工具PCB Footprint Expert 2024.04 Pro / Library Expert 破解版

一个4*4矩阵键盘输入的数据(最多四位数)送LCD1602显示,盼大神指教 ~ ~

[复制链接]
永登一男. 发表于 2014-6-1 18:07:36 | 显示全部楼层 |阅读模式

本文包含原理图、PCB、源代码、封装库、中英文PDF等资源

您需要 登录 才可以下载或查看,没有账号?注册会员

×
小僧闲来无事,尝试着写了一个51的单片机程序。想实现的功能是通过一个4*4的一个矩阵键盘最多输入一个4位数,显示这个四位数,并将其转化成10进制的数参与运算。

编译之后,Keil显示无错误,无警告,但就是没有输出 ~

主函数省去 ~ 其中定义一个含4个元素的数组是想将最多输入4位的数据存起来并方便转化为十进制数 ~ 因为我运行时,无论主函数写的如何简单,也没有输出 ~ 可能各个函数有不当之处,盼大神施以援手 ~
不废话,直接上程序 ~

#define KEYPAD P2   //P2端口用来进行键盘的扫描和输入数据的接收端
#define uchar unsigned char
#define uint unsigned int
uchar key_No[]={'0','1','2','3','4','5','6','7','8','9'};   // ASCII码送LCD显示
uint digits[]={0,0,0,0};                                    // 输入数据最多位4位,用数组保存
static uchar Enter=0,KeyCount=0;   //定义全局静态变量并初始化,用来保存按数字键和确认键的次数
uchar FlagClear=0;  //定义键盘上特殊键的标志位
uint Lower_Value=0;
uint Upper_value=0;

/* 1ms延时子程序 */
void delay(uchar u)
{
    uchar i,j;
    for(i=0;i<u;i++)
        for(j=0;j<120;j++);
}
/* 3x4键盘扫描子程序*/
/*键盘的排布如下:*/
/*   7   8   9   Clear   */
/*   4   5   6   Enter   */
/*   1   2   3   0       */
void KeyPad()
{
    uchar i,KeyNumber;                      //定义循环控制变量和键盘上的数值指示变量
    uchar scan[3]={0x10,0x20,0x40};         //定义扫描数组
    delay(10);  
    for(i=0;i<3;i++)
    {
         KEYPAD=scan[i];                    //将扫描变量送入P2端口
         delay1ms(10);
         if(KEYPAD!=scan[i])
         {
         delay1ms(10);                      //消抖
         KEYPAD|=scan[i];                   //取端口采集到的数据
         delay1ms(200);
         switch(KEYPAD)                     //判断是否有键按下
         {
             case 0x11:                     
                       KeyCount++;          //记录键按下一次
                       KeyNumber=0;         //采集到的数值为0
                       lcd_pos(KeyNumber);              //定位显示的位置
                       lcd_wdat(key_No[KeyNumber]);     //显示数字
                       break;      
             case 0x18:                     
                       KeyCount++;          //记录键按下一次
                       KeyNumber=1;         //采集到的数值为1
                       lcd_pos(KeyNumber);              //定位显示的位置
                       lcd_wdat(key_No[KeyNumber]);     //显示数字
                       break;
             case 0x14:                     
                       KeyCount++;          //记录键按下一次
                       KeyNumber=2;         //采集到的数值为2
                       lcd_pos(KeyNumber);              //定位显示的位置
                       lcd_wdat(key_No[KeyNumber]);     //显示数字
                       break;
             case 0x12:                     
                       KeyCount++;          //记录键按下一次
                       KeyNumber=3;         //采集到的数值为3
                       lcd_pos(KeyNumber);              //定位显示的位置
                       lcd_wdat(key_No[KeyNumber]);     //显示数字
                       break;
             case 0x57:                     
                       KeyCount++;          //记录键按下一次
                       KeyNumber=4;         //采集到的数值为4
                       lcd_pos(KeyNumber);              //定位显示的位置
                       lcd_wdat(key_No[KeyNumber]);     //显示数字
                       break;
             case 0x5b:                     
                       KeyCount++;          //记录键按下一次
                       KeyNumber=5;         //采集到的数值为5
                       lcd_pos(KeyNumber);              //定位显示的位置
                       lcd_wdat(key_No[KeyNumber]);     //显示数字
                       break;
             case 0x5d:                     
                       KeyCount++;          //记录键按下一次
                       KeyNumber=6;         //采集到的数值为6
                       lcd_pos(KeyNumber);              //定位显示的位置
                       lcd_wdat(key_No[KeyNumber]);     //显示数字
                       break;
             case 0x37:                     
                       KeyCount++;          //记录键按下一次
                       KeyNumber=7;         //采集到的数值为7
                       lcd_pos(KeyNumber);              //定位显示的位置
                       lcd_wdat(key_No[KeyNumber]);     //显示数字
                       break;
             case 0x3b:                     
                       KeyCount++;          //记录键按下一次
                       KeyNumber=8;         //采集到的数值为8
                       lcd_pos(KeyNumber);              //定位显示的位置
                       lcd_wdat(key_No[KeyNumber]);     //显示数字
                       break;        
             case 0x3d:                     
                       KeyCount++;          //记录键按下一次
                       KeyNumber=9;         //采集到的数值为9
                       lcd_pos(KeyNumber);              //定位显示的位置
                       lcd_wdat(key_No[KeyNumber]);     //显示数字
                       break;
             case 0x41:                     
                       FlagClear=1;         //液晶显示器清屏Clear按下
                       clear();             //调用清屏子程序
                       break;
             case 0x21:                     
                       Enter++;             //记录输入确认键Enter按下的次数  
                       break;
             default:
                     break;
         }  // switch语句结束
         }  // if语句结束
    }       // for循环语句结束
   
    if(KeyCount==1)                         // 将输出的键值存入数组中
    {   
         digits[3]=KeyNumber;            
     }
    if(KeyCount==2)
    {
         digits[2]=digits[3];
         digits[3]=KeyNumber;
     }
    if(KeyCount==3)
    {
         digits[1]=digits[2];
         digits[2]=digits[3];
         digits[3]=KeyNumber;
     }
    if(KeyCount==4)
    {
         digits[0]=digits[1];
         digits[1]=digits[2];
         digits[2]=digits[3];
         digits[3]=KeyNumber;
     }
}           // 键盘扫描子程序结束

/*清屏子程序 */
void clear()                        
{   
    uchar i;      
    for(i=0;i<16;i++)                       //对液晶写入空格      
    {   
        write_com(0x80+i);        
        write_data(' ');         
     }      
    for(i=0;i<16;i++)      
    {           
        write_com(0x80+0x40+i);         
        write_data(' ');      
     }      
    digits[]={0,0,0,0};      
    KeyCount=0;
    Enter=0;
    FlagClear=1;                            //将标志位清零
    Lower_Value=0;
    Upper_value=0;
}


/* 判断LCD的忙标志位 */
bit lcd_busy()
{                          
    bit result;
    LCD_RS = 0;
    LCD_RW = 1;
    LCD_EN = 1;
    DelayNOP();
    result = (bit)(P0&0x80);
    LCD_EN = 0;
    return(result);
}

void lcd_wcmd(uchar cmd)
{                          
   while(lcd_busy());
    LCD_RS = 0;
    LCD_RW = 0;
    LCD_EN = 0;
    _nop_();
    _nop_();
    P0 = cmd;
    DelayNOP();
    LCD_EN = 1;
    DelayNOP();
    LCD_EN = 0;  
}

void lcd_wdat(uchar dat)
{                          
   while(lcd_busy());
    LCD_RS = 1;
    LCD_RW = 0;
    LCD_EN = 0;
    P0 = dat;
    DelayNOP();
    LCD_EN = 1;
    DelayNOP();
    LCD_EN = 0;
}


void lcd_init()
{
    Delay(15);                  
    lcd_wcmd(0x38);     
    Delay(5);
    lcd_wcmd(0x38);         
    Delay(5);
    lcd_wcmd(0x38);         
    Delay(5);


    lcd_wcmd(0x0c);      
    Delay(5);
    lcd_wcmd(0x06);     
    Delay(5);
    lcd_wcmd(0x01);     
    Delay(5);
}

void lcd_pos(uchar pos)
{                          
  lcd_wcmd(pos|0x80);  
}
晶犀电阻 发表于 2014-6-16 17:39:27 | 显示全部楼层
因为我运行时,无论主函数写的如何简单
*滑块验证:
您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

QQ|手机版|MCU资讯论坛 ( 京ICP备18035221号-2 )|网站地图

GMT+8, 2024-11-23 11:46 , Processed in 0.056977 second(s), 9 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表