這是我的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);
}
}
當中出現的遺漏:
Z6%)87BM%Y_JQ2K9]U(1]UJ.png (56.28 KB, 下載次數: 11)
下載附件
2019-12-12 16:35 上傳
編譯之后出現的錯誤:
Q_H6G$R0L5QYUH)SVSI)WIK.png (49.81 KB, 下載次數: 11)
下載附件
2019-12-12 16:35 上傳
這是我的部分電路圖:
2RVO3BOAHFPH(`JTDA9M(]4.png (96.54 KB, 下載次數: 11)
下載附件
2019-12-12 16:40 上傳
求大神幫我解決!!!!!!!!!
|