功能概述:
实现一个4x4按键矩阵,通过按键扫描,当有按键按下时,识别按键值,并通过UART串口发送,同时在lcd1602显示。
功能实现:
1. 按键扫描
void keyboardScan(){
P1OUT = 0xef;//P1.4 = 0
if((P1IN & 0x0f) != 0x0f){
delay_ms8M(5);//消抖
if((P1IN & 0x0f) != 0x0f){
if((P1IN & 0x01) == 0){ keyValue = '3';while((P1IN & 0x01) == 0);};
if((P1IN & 0x02) == 0){ keyValue = '7';while((P1IN & 0x02) == 0);};
if((P1IN & 0x04) == 0){ keyValue = 'B';while((P1IN & 0x04) == 0);};
if((P1IN & 0x08) == 0){ keyValue = 'F';while((P1IN & 0x08) == 0);};
keyboard_envent = ~keyboard_envent;
}
}
P1OUT = 0xdf;//P1.5 = 0
if((P1IN & 0x0f) != 0x0f){
delay_ms8M(5);//消抖
if((P1IN & 0x0f) != 0x0f){
if((P1IN & 0x01) == 0){ keyValue = '2';while((P1IN & 0x01) == 0);};
if((P1IN & 0x02) == 0){ keyValue = '6';while((P1IN & 0x02) == 0);};
if((P1IN & 0x04) == 0){ keyValue = 'A';while((P1IN & 0x04) == 0);};
if((P1IN & 0x08) == 0){ keyValue = 'E';while((P1IN & 0x08) == 0);};
keyboard_envent = ~keyboard_envent;
}
}
P1OUT = 0xbf;//P1.6 = 0
if((P1IN & 0x0f) != 0x0f){
delay_ms8M(5);//消抖
if((P1IN & 0x0f) != 0x0f){
if((P1IN & 0x01) == 0){ keyValue = '1';while((P1IN & 0x01) == 0);};
if((P1IN & 0x02) == 0){ keyValue = '5';while((P1IN & 0x02) == 0);};
if((P1IN & 0x04) == 0){ keyValue = '9';while((P1IN & 0x04) == 0);};
if((P1IN & 0x08) == 0){ keyValue = 'D';while((P1IN & 0x08) == 0);};
keyboard_envent = ~keyboard_envent;
}
}
P1OUT = 0x7f;//P1.7 = 0
if((P1IN & 0x0f) != 0x0f){
delay_ms8M(5);//消抖
if((P1IN & 0x0f) != 0x0f){
if((P1IN & 0x01) == 0){ keyValue = '0';while((P1IN & 0x01) == 0);};
if((P1IN & 0x02) == 0){ keyValue = '4';while((P1IN & 0x02) == 0);};
if((P1IN & 0x04) == 0){ keyValue = '8';while((P1IN & 0x04) == 0);};
if((P1IN & 0x08) == 0){ keyValue = 'C';while((P1IN & 0x08) == 0);};
keyboard_envent = ~keyboard_envent;
}
<div> }</div><div>}</div>
复制代码
2. UART初始化
void uartInit(){
DCOCTL = 0;
BCSCTL1 = CALBC1_1MHZ; // 选择1MHZ作为波特率发生器输入时钟频率
DCOCTL = CALDCO_1MHZ;
P3SEL = 0X30; // P3.4 TX P3.5 RX
UCA0CTL1 |= UCSSEL_2;//clk = SMCLK 辅助时钟 select clock source
UCA0BR0 = 104; // 1MHZ / 9600 = 104.17
UCA0BR1 = 0; // baud rate 9600
UCA0MCTL = UCBRS0;//波特率调整 0.17 * 8 = 1.36 取整 1
UCA0CTL1 &= ~UCSWRST; // 初始化USCI,复位释放,结束初始化
}
复制代码
3. LCD1602初始化
void lcd1602Init(){
P3DIR |= BIT0 + BIT1 + BIT2;
dataout;
rst_en;
P1DIR = 0X70;
write_com(0x38);//8 bit data, doule line, 5x7 point matrix
write_com(0x0c);//open display, close cusor,close blink
write_com(0x06);//auto move to next char after write or read
write_com(0x01);//clear screen
}
实现过程中遇到的问题:
1. 按键按下后会连续不断的发送,就算以很快的速度按下还是会发送两次。
解决办法:等待按键放开。
2. Proteus虚拟终端关闭后再也打不开。
解决办法:感觉这是一个bug,只能重新建一个项目。