本帖最后由 芯圣电子官方QQ 于 2023-7-19 16:31 编辑
今天搞了一下矩阵键盘。
四根行线P1.0-P1.4,四根列线P1.4-P1.7
键值用串口1打印
代码:
#define ALLOCATE_EXTERN
#include "HC89S105AC8.h"
#define uint8_t unsigned char
#define uint16_t unsigned int
#define Hang_00_L P1_0=0
#define Hang_00_H P1_0=1
#define Hang_01_L P1_1=0
#define Hang_01_H P1_1=1
#define Hang_02_L P1_2=0
#define Hang_02_H P1_2=1
#define Hang_03_L P1_3=0
#define Hang_03_H P1_3=1
#define Lie_00_V P1_4
#define Lie_01_V P1_5
#define Lie_02_V P1_6
#define Lie_03_V P1_7
#define Lie_04_V ((P1&0xF0)>>4)
#define Hang_10_L P1_4=0
#define Hang_10_H P1_4=1
#define Hang_11_L P1_5=0
#define Hang_11_H P1_5=1
#define Hang_12_L P1_6=0
#define Hang_12_H P1_6=1
#define Hang_13_L P1_7=0
#define Hang_13_H P1_7=1
#define Lie_10_V P1_0
#define Lie_11_V P1_1
#define Lie_12_V P1_2
#define Lie_13_V P1_3
#define Lie_14_V ((P1&0x0f)<<4)
#define jpys 20 //??????jpys==20?????????
uint8_t cord_h,cord_l;//???????
uint8_t temp;
unsigned char guc_Uartflag = 0; //UART判断标志位
unsigned char guc_Uartcnt = 0; //UART计数使用
unsigned char guc_Uartbuf_a[5] = {0}; //用于存放接和收收据
unsigned char guc_i;
uint8_t txBuf[] = "Key Value = : \r\n";
//发送数据计数
void DelayMs(uint16_t nms)
{
uint16_t i,j;
for(i=0;i<nms;i++)
for(j=0;j<200;j++);
}
void PORT_Initialize1(void)
{
P1M0=0xcc;
P1M1=0xcc;
P1M2=0x22;
P1M3=0x22;
}
void PORT_Initialize2(void)
{
P1M0=0x22;
P1M1=0x22;
P1M2=0xcc;
P1M3=0xcc;
}
unsigned char KeyScan(void) //????????????????
{
uint16_t i,j;
PORT_Initialize1();
for(i=0;i<1250;i++);
Hang_00_L;
Hang_01_L;
Hang_02_L;
Hang_03_L;
for(i=0;i<1250;i++);
//cord_h=(Lie_04_V&0x0f);
cord_h=(uint8_t)(Lie_04_V);
//cord_h=Lie_01_V|Lie_02_V|Lie_03_V|Lie_04_V;
if(cord_h != 0xf0) //?????????
{
DelayMs(10); //??
cord_h=(uint8_t)(Lie_04_V);
if(cord_h!=0xf0)
{
cord_h=(uint8_t)(Lie_04_V); //?????
for(i=0;i<1250;i++);
PORT_Initialize2();
for(i=0;i<1250;i++);
if((cord_h&0x01)==0x01)
Hang_10_H;
else
Hang_10_L;
if((cord_h&0x02)==0x02)
Hang_11_H;
else
Hang_11_L;
if((cord_h&0x04)==0x04)
Hang_12_H;
else
Hang_12_L;
if((cord_h&0x08)==0x08)
Hang_13_H;
else
Hang_13_L;
for(i=0;i<1250;i++);
cord_l=(uint8_t)(Lie_14_V); //?????
while(1) //???????
{
j=(uint8_t)(Lie_14_V);
if(j==0xF0)
break;
for(i=0;i<1250;i++);
}
return(cord_h+cord_l);//????????
}
}
return(0xff); //????*/
}
unsigned char KeyPro(void)
{
switch(KeyScan())
{
case 0x7e:return 0;break;//0 ??????????????
case 0x7d:return 1;break;//1
case 0x7b:return 2;break;//2
case 0x77:return 3;break;//3
case 0xbe:return 4;break;//4
case 0xbd:return 5;break;//5
case 0xbb:return 6;break;//6
case 0xb7:return 7;break;//7
case 0xde:return 8;break;//8
case 0xdd:return 9;break;//9
case 0xdb:return 10;break;//a
case 0xd7:return 11;break;//b
case 0xee:return 12;break;//c
case 0xed:return 13;break;//d
case 0xeb:return 14;break;//e
case 0xe7:return 15;break;//f
default:return 0xff;break;
}
}
/***************************************************************************************
* @实现效果 UART1接收到上位机发送的数据后,把接收的数据再次发送给上位机
* @注意 波特率1200,8位数据,无校验位
***************************************************************************************/
void main(void)
{
uint8_t i;
/********************************系统初始化*******************************************/
WDTCCR = 0x00; //关闭看门狗
//本例程为方便测试关闭看门狗,实际使用中,建议客户打开看门狗,详见WDT复位例程
CLKCON = 0x02; //选择内部高频RC为系统时钟,Fosc=32MHz
CLKDIV = 0x02; //Fosc 2分频得到Fper,Fper=16MHz
/**********************************IO配置初始化**************************************/
P0M0 = P0M0&0xF0|0x02; //P00设置为上拉输入
P0M0 = P0M0&0x0F|0x80; //P01设置为推挽输出
/**********************************UART配置初始化**************************************/
TXD_MAP = 0x01; //TXD映射P01
RXD_MAP = 0x00; //RXD映射P00
//8位数据发送,波特率1200
//波特率计算
//波特率 = 1/16 * 时钟源频率 / (65536 - 0xFCBE)
// = 1/16 * 16000000 / 834)
// = 1199.04(误差0.05%)
//波特率1200
//反推初值
//初值 = (65536 - (Fper / 波特率) * (1 / 16))
// = (65536 - (16000000 / 1200) * (1 / 16))
// = (65536 - 833.33)
// = FCBE
SBRTH = 0xFCBE/256;
SBRTL = 0xFCBE%256;
SCON2 = 0x12; //8位UART 独立波特率,波特率可变
SCON = 0x10; //开串口接收
//IE = 0x10; //使能串口中断
//EA = 1; //使能总中断
while(1)
{
// if(guc_Uartflag)
// {
// IE &=~ 0x10; //失能UART1中断
// for(guc_i= 0;guc_i<guc_Uartcnt;guc_i++)
// {
// SBUF = guc_Uartbuf_a[guc_i]; //发送数据
// while(!(SCON&0x02));
// SCON &=~ 0x02; //发送中断请求中断标志位清0
// }
// guc_Uartflag = 0; //标志位置0
// guc_Uartcnt = 0;
// SCON |= 0x10; //使能串口中断
// IE |= 0x10; //UART1中断使能
// }
temp=KeyPro();
if(temp!=0xff)
{
if((temp>=0)&&(temp<=9))
txBuf[14]=temp+0x30;
else if((temp>=10)&&(temp<=15))
txBuf[14]=temp+55;
for(i = 0; i < sizeof(txBuf); i++)
{
SBUF = txBuf[i]; //发送数据
while(!(SCON&0x02));
SCON &=~ 0x02; //发送中断请求中断标志位?
}
}
}
}
效果图:
|