这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » MCU » 一个4*4矩阵键盘输入的数据(最多四位数)送LCD1602显示,盼大神指教 ~

共8条 1/1 1 跳转至

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

菜鸟
2014-06-01 17:50:23     打赏

小僧闲来无事,尝试着写了一个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);  
}




关键词: 4*4矩阵键盘     LCD    

菜鸟
2014-06-01 18:04:34     打赏
2楼

大神们谈谈看法吧 ~ 我估摸着问题肯定出在键盘扫描的程序部分,我从网上有复制过几个矩阵键盘扫描程序,最后可以显示 ~ 

只是我想按照自己的扫描思路尝试一下,就出现问题了 ~ 一直未能发现问题是神马 ~


院士
2014-06-02 09:58:53     打赏
3楼
别急,别急,大家还在休息的状态中,估计马上调整状态了

高工
2014-06-02 10:33:02     打赏
4楼

“运行时,无论主函数写的如何简单,也没有输出”

你的液晶显示没问题吧·?

你随便显示一个数试试


菜鸟
2014-06-02 20:39:51     打赏
5楼
我用这个程序里的LCD子程序再另外编一个新的现实一个字符数组的程序,是可以显示出来的 ~ 所以,LCD部分应该是没有错误的,但是程序得不到想要的结果 ~ 真是头疼 ~

菜鸟
2014-06-02 20:41:22     打赏
6楼
对于LCD子函数部分,我对NOP的宏定义部分省去了~

高工
2014-06-02 23:30:44     打赏
7楼
楼主,你这样吧。;检测到某个按键,你就点亮一个灯,用P1=0X(按键数)来点亮,如果连led都不能点亮,那就是扫描按键出错了

菜鸟
2014-06-04 19:23:18     打赏
8楼
恩,只能这样先试一试了 ~

共8条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]