这是我的C语言程序:
#include <reg51.h>
#include <string.h>
#define uchar unsigned char
#define uint unsigned int
#define delayNOP() {_nop_();_nop_();_nop_();_nop_();}
sbit RS = P2^0;
sbit RW = P2^1;
sbit EN = P2^2;
sbit SPK = P3^7;
//12个键盘按键字符总表
//注意串空间应设为6字节,因为最长串为5,设为5时会使部分长串无法附带串结束标志'\0'
uchar code KeyPad_Chars[12][6] =
{"1 ","2ABC","3DEF","4GHI","5JKL","6MNO","7PQRS","8TUV","9WXYZ","*","0+","#"};
uchar code Line1[] = " Mobile KeyPad "; //固定显示字符串
uchar code Line2[] = "KEY_CHAR: ";
uchar KeyNo = -1; //键位0~11
uchar Inner_Idx = 0; //同键位的内部索引
uchar tSpan = 0; //同键位连续按键的时间间隔
// 延时
//-----------------------------------------------------------------
void DelayMS(uint ms)
{
uchar i;
while(ms--) for(i = 0; i < 50; i++);
}
//-----------------------------------------------------------------
// 限于篇幅,这里省略了部分LCD显示控制函数,读者可自行补充完整.
// uchar Get_LCD_Status()
// void Busy_Waiting()
// void Write_LCD_DATA(uchar dat)
// void Write_LCD_Command(uchar cmd)
// void Init_LCD()
// void Set_LCD_POS(uchar position)
//-----------------------------------------------------------------
//-----------------------------------------------------------------
// 键盘矩阵扫描
//-----------------------------------------------------------------
void Keys_Scan()
{
//高四位置0,放入四行
P1 = 0x0F; DelayMS(1);
//按键后00001111将变成0000XXXX,X中1个为0,3个仍为1
//判断按键发生于0~3列中的哪一列
switch (P1)
{
case 0x0E: KeyNo = 0; break;
case 0x0D: KeyNo = 1; break;
case 0x0B: KeyNo = 2; break;
}
//低四位置0,放入四列
P1 = 0xF0; DelayMS(1);
//按键后11110000将变成XXXX0000,X中1个为0,3个仍为1
//对0~3行分别附加起始值0,4,8,12
switch (P1)
{
case 0xE0: KeyNo += 0; break; //此行可省,这里为了对称而保留
case 0xD0: KeyNo += 3; break;
case 0xB0: KeyNo += 6; break;
case 0x70: KeyNo += 9;
}
}
//-----------------------------------------------------------------
// 蜂鸣器
//-----------------------------------------------------------------
void Beep()
{
uchar i;
for(i = 0; i < 60; i++)
{
SPK = !SPK; DelayMS(1);
}
SPK = 1;
DelayMS(100);
}
//-----------------------------------------------------------------
// 定时器0跟踪同位按键的时间间隔
//-----------------------------------------------------------------
void T0_INT() interrupt 1
{
TH0 = -50000 / 256;
TL0 = -50000 % 256;
//tSpan最大值限制在41及即以上即可
//不加限制时会使某次较长的延时累加超过255后,累加又从0开始
//而程序判断时它可能刚好还在40以内,
//从而导致较长的延时却被误断为较短的延时
if (tSpan < 50 ) tSpan++; else TR0 = 0;
}
//-----------------------------------------------------------------
// 主程序
//-----------------------------------------------------------------
void main()
{
uchar i,Pre_KeyNo = -1;
IE = 0x82;
TMOD = 0x01;
TH0 = -50000 / 256;
TL0 = -50000 % 256;
P0 = P2 = 0xFF;
DelayMS(10);
Init_LCD(); //初始化
Set_LCD_POS(0); //显示第一行
for(i = 0; i < 16; i++)
Write_LCD_DATA(Line1[ i]);
Set_LCD_POS(0x40); //显示第二行
for(i = 0; i < 16; i++)
Write_LCD_DATA(Line1);
Set_LCD_POS(0x40); //显示第二行
for(i = 0; i < 16; i++)
Write_LCD_DATA(Line2);
while(1)
{
P1 = 0xF0;
//有键按下则扫描,否则不作任何处理
if(P1 != 0xF0) Keys_Scan(); else continue;
if (Pre_KeyNo != KeyNo) //按下新按键
{
Pre_KeyNo = KeyNo;
tSpan = 0; //时间间隔归0
Inner_Idx = 0; //按键内部索引归0
TR0 = 1; //按下新按键时启动计时
}
else //否则按下的是相同位置按键
{
//同位按键时间间隔在50ms×40=2s以内则认为是连续按键
//否则按键内字符索引归0
if (tSpan <= 40)
Inner_Idx = (Inner_Idx + 1) % strlen(KeyPad_Chars[KeyNo]);
else
Inner_Idx = 0;
tSpan = 0;
}
Set_LCD_POS(0x4B);
Write_LCD_DATA(KeyPad_Chars[KeyNo][Inner_Idx]); //显示按键字符
Beep();
DelayMS(400);
}
}
当中出现的遗漏:
编译之后出现的错误:
这是我的部分电路图:
求大神帮我解决!!!!!!!!!
|