#include "reg51.h"
#include "intrins.h"
typedef unsigned char uint8; // 無符號(hào)8位整型變量
typedef signed char int8; // 有符號(hào)8位整型變量
typedef unsigned short uint16; // 無符號(hào)16位整型變量
typedef signed short int16; // 有符號(hào)16位整型變量
typedef unsigned int uint32; // 無符號(hào)32位整型變量
typedef signed int int32; // 有符號(hào)32位整型變量
typedef float fp32; // 單精度浮點(diǎn)數(shù)(32位長度)
typedef double fp64; // 雙精度浮點(diǎn)數(shù)(64位長度)
//串口有關(guān)的定義
//#define FOSC 18432000L //系統(tǒng)頻率
#define FOSC 11059200L
#define BAUD 9600 //串口波特率
#define NONE_PARITY 0 //無校驗(yàn)
#define ODD_PARITY 1 //奇校驗(yàn)
#define EVEN_PARITY 2 //偶校驗(yàn)
#define MARK_PARITY 3 //標(biāo)記校驗(yàn)
#define SPACE_PARITY 4 //空白校驗(yàn)
#define PARITYBIT NONE_PARITY //定義校驗(yàn)位
sfr AUXR = 0x8e; //輔助寄存器
sfr P_SW1 = 0xA2; //外設(shè)功能切換寄存器1
#define S1_S0 0x40 //P_SW1.6
#define S1_S1 0x80 //P_SW1.7
sbit P22 = P2^2;
bit busy;
sbit row0 = P1 ^ 1;
sbit row1 = P1 ^ 2;
sbit row2 = P1 ^ 3;
sbit row3 = P1 ^ 4;
sbit row4 = P1 ^ 5;
sbit col0 = P3 ^ 2;
sbit col1 = P3 ^ 3;
sbit col2 = P3 ^ 6;
void Delay(uint16 count)
{
uint8 i;
while(--count != 0)
{
for(i = 0; i < 125; i++); // ";" 表示空語句,CPU空轉(zhuǎn)。
} // i 從0加到125,在12M晶體下CPU大概耗時(shí)1毫秒
}
uint8 KeyDown(void)
{
col0=0; col1=0; col2=0; // 列線全部置低
if((row0==0) || (row1==0) || (row2==0) || (row3==0) || (row4 == 0)) // 若有任一行線讀回狀態(tài)為低
{
Delay(80); // 延時(shí)消抖
if((row0==0) || (row1==0) || (row2==0) || (row3==0) || (row4 ==0)) // 再次讀行線狀態(tài),若有任一行線讀回狀態(tài)為低
return 1; // 返回1,表明有鍵盤按下
else
return 0; // 返回0,表明無鍵盤按下
}
else
return 0;
}
uint8 KeyUp(void)
{
col0=0; col1=0; col2=0; // 列線全部置低
if((row0==1) && (row1==1) && (row2==1) && (row3==1) && (row4 == 1)) // 若全部行線讀回狀態(tài)都為高
{
Delay(80); // 延時(shí)消抖
if((row0==1) && (row1==1) && (row2==1) && (row3==1) && (row4 == 1)) // 再次讀行線狀態(tài),若全部行線讀回狀態(tài)都為高
return 1; // 返回1,表明所有鍵盤都處于彈起狀態(tài)
else
return 0; // 返回0,表明有鍵盤處于按下狀態(tài)
}
else
return 0;
}
uint8 KeyNum(void)
{
uint8 KeyTemp;
KeyTemp=0;
if(KeyDown()==1) // 若鍵盤被按下
{
col1=0; col2=1; col2=1; // 將列線1置低,其他列線置高
if (row0==0) KeyTemp=1; // 若行線0讀回狀態(tài)為低,則表明按鍵1被按下
if (row1==0) KeyTemp=4; // 若行線1讀回狀態(tài)為低,則表明按鍵4被按下
if (row2==0) KeyTemp=7; // 若行線2讀回狀態(tài)為低,則表明按鍵7被按下
if (row3==0) KeyTemp=11; // 若行線3讀回狀態(tài)為低,則表明按鍵"."被按下 11表示 .
if (row4==0) KeyTemp=13; // 若行線4讀回狀態(tài)為低,則表明按鍵"取消"被按下 13表示
col0=1; col1=0; col2=1; // 將列線1置低,其他列線置高
if (row0==0) KeyTemp=2; // 若行線0讀回狀態(tài)為低,則表明按鍵2被按下
if (row1==0) KeyTemp=5; // 若行線1讀回狀態(tài)為低,則表明按鍵5被按下
if (row2==0) KeyTemp=8; // 若行線2讀回狀態(tài)為低,則表明按鍵8被按下
if (row3==0) KeyTemp=10; // 若行線3讀回狀態(tài)為低,則表明按鍵0被按下 10表示0
if (row4==0) KeyTemp=14; // 若行線4讀回狀態(tài)為低,則表明按鍵"功能"被按下 14表示
col0=1; col1=1; col2=0; // 將列線2置低,其他列線置高
if (row0==0) KeyTemp=3; //若行線0讀回狀態(tài)為低,則表明按鍵3被按下
if (row1==0) KeyTemp=6; //若行線1讀回狀態(tài)為低,則表明按鍵6被按下
if (row2==0) KeyTemp=9; //若行線2讀回狀態(tài)為低,則表明按鍵9被按下
if (row3==0) KeyTemp=12; //若行線3讀回狀態(tài)為低,則表明按鍵"退格"鍵被按下 退格 12 表示
if (row4==0) KeyTemp=15; //若行線4讀回狀態(tài)為低,則表明按鍵"確認(rèn)"鍵被按下 確認(rèn) 15 表示
while ( KeyUp()!=1); // 等待按下的鍵盤被釋放
return KeyTemp; // 返回被按下并被釋放的鍵盤的編號(hào)
}
else
return 0; //表示無按鍵按下
}
void Uart() interrupt 4 using 1
{
if (RI)
{
RI = 0; //清除RI位
//P0 = SBUF; //P0顯示串口數(shù)據(jù)
// P22 = RB8; //P2.2顯示校驗(yàn)位
}
if (TI)
{
TI = 0; //清除TI位
busy = 0; //清忙標(biāo)志
}
}
void SendData(uint8 dat)
{
while (busy); //等待前面的數(shù)據(jù)發(fā)送完成 賦值累加器
ACC = dat; //獲取校驗(yàn)位P (PSW.0)
if (P) //根據(jù)P來設(shè)置校驗(yàn)位 1奇校驗(yàn) 0偶數(shù)校驗(yàn)
{
#if (PARITYBIT == ODD_PARITY)
TB8 = 0; //設(shè)置校驗(yàn)位為0
#elif (PARITYBIT == EVEN_PARITY)
TB8 = 1; //設(shè)置校驗(yàn)位為1
#endif
}
else
{
#if (PARITYBIT == ODD_PARITY)
TB8 = 1; //設(shè)置校驗(yàn)位為1
#elif (PARITYBIT == EVEN_PARITY)
TB8 = 0; //設(shè)置校驗(yàn)位為0
#endif
}
busy = 1;
SBUF = ACC; //寫數(shù)據(jù)到UART數(shù)據(jù)寄存器
}
void SendString(char *s)
{
while (*s) //檢測字符串結(jié)束標(biāo)志
{
SendData(*s++); //發(fā)送當(dāng)前字符
}
}
void init_ser()
{
//切換串口位置 STC代碼
ACC = P_SW1;
ACC &= ~(S1_S0 | S1_S1); //S1_S0=0 S1_S1=0
P_SW1 = ACC; //(P3.0/RxD, P3.1/TxD)
//確定數(shù)據(jù)與校驗(yàn)位 STC代碼
#if (PARITYBIT == NONE_PARITY)
SCON = 0x50; //8位可變波特率
#elif (PARITYBIT == ODD_PARITY) || (PARITYBIT == EVEN_PARITY) || (PARITYBIT == MARK_PARITY)
SCON = 0xda; //9位可變波特率,校驗(yàn)位初始為1
#elif (PARITYBIT == SPACE_PARITY)
SCON = 0xd2; //9位可變波特率,校驗(yàn)位初始為0
#endif
AUXR = 0x40; //定時(shí)器1為1T模式
TMOD = 0x20; //定時(shí)器1為模式2(8位自動(dòng)重載)
TL1 = (256 - (FOSC/32/BAUD)); //設(shè)置波特率重裝值
TH1 = (256 - (FOSC/32/BAUD));
TR1 = 1; //定時(shí)器1開始工作
ES = 1; //使能串口中斷
EA = 1;
}
void main()
{
init_ser();
while(1)
{
SendData(KeyNum());
}
}