打印
[国产单片机]

基于状态机的键盘扫描程序求助!!!!

[复制链接]
2280|9
手机看帖
扫描二维码
随时随地手机跟帖
楼主
lc7745166|  楼主 | 2011-3-8 21:13 | 只看该作者 |只看大图 回帖奖励 |倒序浏览

键盘扫描,1602显示求助!!!

#include<reg52.h>
#include<stdio.h>
#include<string.h>
#include"diy.h"

bit time_flag=0;
uint8 const dofly[]="0123456789abcdef";
unsigned char const dofly1[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,
                                           0x77,0x7c,0x39,0x5e,0x79,0x71};//0-F
uint8 Read_busy();
void delay(unsigned int z);
uint8 Key_Scan();
uint8 key_Dis();
sbit jp=P2^1;
sbit RS=P2^4;
sbit RW=P2^5;
sbit E=P2^6;

void Write_Com(unsigned char Com)
{
        E=0;
        RS=0;
        RW=0;
        delay(4);
        E=1;
        PORT0=Com;       
        E=0;
}
void Write_Dat(unsigned char Dat)
{
        E=0;
        RS=1;
        RW=0;
        delay(4);
        E=1;
        PORT0=Dat;               
        E=0;

}

uint8 Read_busy()
{        unsigned char dat;
        E=0;
        RS=0;
        RW=1;
        //E=0;
        delay(3);
        E=1;       
        dat=PORT0;
        E=0;
        return dat;
               
}
void delay(unsigned int z)
{
unsigned int x,y;
        for(x=z;x>0;x--)
                for(y=110;y>0;y--);

}


void Init()
{                       
                delay(3);
                Write_Com(0x38);//设置1602显示
                delay(3);       
                Write_Com(0x0e);//开显示显示光标、光标闪烁       
                Write_Com(0x06);//当读一个字符后。地址指针加一,且光标加一
                Write_Com(0x0c);//不显示光标
                Write_Com(0x01);//清屏

                TMOD=0X01;
                TH0=(65535-1000)/256;
                TL0=(65535-1000)%256;
                EA=1;
                ET0=1;
                TR0=1;
                                               
}

uint8 Key_Scan()
{
        uint8 key_value,value_l,value_r;
        PORT3=0XF0;
        value_l=PORT3&0XF0;
        if((value_l)!=0xf0)
        {       
                delay(100);
                if((value_l)!=0XF0)
                {       
                        value_l=PORT3&0XF0;
                        PORT3=value_l|0X0F;
                        value_r=0x0f&PORT3;                                 
                        key_value=value_l|value_r;
               
                        return key_value;               
                }
       
        }
         return 0xff;
}

uint8 key_Dis(uint8 key)
{
        uint8 key_number;
        key=Key_Scan;
        switch(key)
        {
                case 0x7e: key_number=dofly[0];P0=dofly1[0];break;
                case 0x7d: key_number=dofly[1];P0=dofly1[1];break;
                case 0x7b: key_number=dofly[2];P0=dofly1[2];break;
                case 0x77: key_number=dofly[3];P0=dofly1[3];break;

                case 0xbe: key_number=dofly[4];P0=dofly1[4];break;
                case 0xbd: key_number=dofly[5];P0=dofly1[5];break;
                case 0xbb: key_number=dofly[6];P0=dofly1[6];break;
                case 0xb7: key_number=dofly[7];P0=dofly1[7];break;

                case 0xde: key_number=dofly[8];P0=dofly1[8];break;
                case 0xdd: key_number=dofly[9];P0=dofly1[9];break;
                case 0xdb: key_number=dofly[10];P0=dofly1[10];break;
                case 0xd7: key_number=dofly[11];P0=dofly1[11];break;

                case 0xee: key_number=dofly[12];P0=dofly1[12];break;
                case 0xed: key_number=dofly[13];P0=dofly1[13];break;
                case 0xeb: key_number=dofly[14];P0=dofly1[14];break;
                case 0xe7: key_number=dofly[15];P0=dofly1[15];break;
                       
                default :key_number=' ';break;
        }
        return        key_number;

}

void main()
{       

        uint8 key,key_number,busy,com;
                com=0x80+1;
                if(time_flag==1)
                {
                        time_flag=0;
                        key=Key_Scan();
                        jp=0;
                        key_number=key_Dis(key);
                        Init();
                        delay(1);
                        busy=Read_busy();
                        busy=busy&0x80;
                       
                        if(busy!=0x80)
                        {
                                delay(1);
                                Write_Com(com++);
                                delay(1);
                                Write_Dat(key_number);
                                if(com>0x90)
                                {
                                        com=0x80+1;
                                        Write_Com(0x01);//清屏
                                 }
                                                       
                        }
                        else
                        {
                                delay(1);
                                busy=Read_busy();                                       
                        }
                }

}


void time0() interrupt        1
{
        TH0=(65535-1000)/256;
        TL0=(65535-1000)%256;
        time_flag=1;
               
}
这是我写的键盘扫描程序,想通过1602来显示,程序调试没有错误,但是功能实现不了!我用的是STC89C54的单片机,12M晶振,希望路过的各位帮帮忙,看看吧!我是在没有办法了!!!!

4.jpg (58.95 KB )

4.jpg

12.jpg (48.55 KB )

12.jpg

123.jpg (68.61 KB )

123.jpg

使用特权

评论回复
沙发
lc7745166|  楼主 | 2011-3-8 21:18 | 只看该作者 |阅读模式
#include<reg52.h>
#include"diy.h"
#define key_state1 1
#define key_state2 2
#define key_state3 3

unsigned char const dofly[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,
                                           0x77,0x7c,0x39,0x5e,0x79,0x71};//0-F


void Key_Scan()
{
uint8 value_l,value_r,key_value,table;
        static uint8 key_state=1;
        switch(key_state)
        {
                case key_state1:
       
                        PORT3=0XF0;
                        value_l=PORT3&0XF0;
                        if(value_l!=0XF0)
                        {       
                                key_state=key_state2;
                                value_l=PORT3&0Xf0;                         
                                PORT3=0X0F;       
                                value_r=PORT3&0x0f;                               
                                key_value=(value_l|value_r);               
                       
                        }
                        else
                        {key_state=key_state1;}
                break;

                case key_state2:

                        {
                                switch(key_value)
                                {
                                        case 0x7e: table=dofly[0];key_state=2;break;
                                        case 0x7d: table=dofly[1];key_state=2;break;
                                        case 0x7b: table=dofly[2];key_state=2;break;
                                        case 0x77: table=dofly[3];key_state=2;break;
                       
                                        case 0xbe: table=dofly[4];key_state=2;break;
                                        case 0xbd: table=dofly[5];key_state=2;break;
                                        case 0xbb: table=dofly[6];key_state=2;break;
                                        case 0xb7: table=dofly[7];key_state=2;break;
                       
                                        case 0xde: table=dofly[8];key_state=2;break;
                                        case 0xdd: table=dofly[9];key_state=2;break;
                                        case 0xdb: table=dofly[10];key_state=2;break;
                                        case 0xd7: table=dofly[11];key_state=2;break;
                       
                                        case 0xee: table=dofly[12];key_state=2;break;
                                        case 0xed: table=dofly[13];key_state=2;break;
                                        case 0xeb: table=dofly[14];key_state=2;break;
                                        case 0xe7: table=dofly[15];key_state=2;break;
                                       
                                        default :key_state=key_state1;break;       
                       
                                }       
                 
                               
                        }

                       
                break;

                case key_state3:
                        if(value_l!=0XF0)                                       
                        //while(value_l!=0XF0)
                        {       
                                        PORT2=0x00;
                                        PORT0=dofly[table];         
                                                               
                        }
                        else
                        {
                                key_state=key_state1;
       
                        }
                break;

        }          
}

void main()
{       
       
        while(1)
        {
                Key_Scan();       
       

        }

}
这是我根据状态机的思想写的单片机矩阵键盘扫描程序,用的是STC的单片机89c54系列,12M的晶振程序没有错误,但是功能实现不了,还请各位指点,我是在束手无策了!!!谢谢!

123.jpg (68.61 KB )

123.jpg

4.jpg (58.95 KB )

4.jpg

相关帖子

板凳
谈的元| | 2011-3-8 21:28 | 只看该作者
搜: 手把手设计1602

//////////////////////////////////////
同时测试输出口是否正常,

引脚是否接错

使用特权

评论回复
地板
McuPlayer| | 2011-3-9 09:15 | 只看该作者
提问题,不要重复发帖,这样不利于讨论!

0、没人能替你解决问题,只能提供思路,根本还是要靠自己
1、键盘扫描和LCM显示是2个问题,要独立解决
2、键盘扫描有问题,首先确认硬件设计有问题否,焊接有问题否,负责输出的IO能否正常输出,负责输入的IO输入是否正确
3、LCM的显示,参考键盘问题的解决思路

使用特权

评论回复
5
McuPlayer| | 2011-3-9 09:19 | 只看该作者
先不要用状态机,用简单的扫描看能否实现。

先易后难

使用特权

评论回复
6
lc7745166|  楼主 | 2011-3-9 16:39 | 只看该作者
其实,我先前把键盘扫描的程序写好了,1602的也写好了,单独运行都能通过,和在一起就出问题。

使用特权

评论回复
7
lc7745166|  楼主 | 2011-3-9 16:41 | 只看该作者
我想问个问题,键盘扫描不是得一直运行么,但是这样的话1602就没有办法显示了呀!还有,我自今很疑惑,每次按键按下,1602都显示在一个位置,要怎么处理呢?

使用特权

评论回复
8
McuPlayer| | 2011-3-9 17:29 | 只看该作者
键盘扫描不是一直在运行,而是间歇式的运行,比如用定时中断的方式

使用特权

评论回复
9
谈的元| | 2011-3-9 23:00 | 只看该作者
键盘10-100MS查询一次

使用特权

评论回复
10
ABCDELF| | 2013-1-28 23:24 | 只看该作者
帖子太长了,看的头晕

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

0

主题

8

帖子

1

粉丝