#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define SCANPORT P1 //定义键盘扫描的端口P1口
#define NOP _nop_()
sbit SDA = P3^1;
sbit SHIFT_CP = P3^0;
sbit ST_CP = P3^2;
uchar i=0;
uchar uca_LineScan[4]={0xEF,0xDF,0xBF,0x7F}; //列线扫描电压,分为第1,2,3,4根列线(实验中接p1.4-p1.7)为低电平0,其他为高电平1。
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; //共阴极接法,0~9,a~f
void delay(uint k)
{
uint j;
for (; k > 0; k--)
for (j = 0; j < 50; j++);
}
void SerialSendData(uchar dat)
{
uchar ii;
uchar sdata=dat;
for(ii=0;ii<8;ii++)
{
if(sdata&0x80)SDA=1;
else SDA = 0;
sdata<<=1;
SHIFT_CP =0;
NOP;
NOP;
SHIFT_CP = 1;
NOP;
NOP;
}
ST_CP = 1;
NOP;
NOP;
ST_CP = 0;
}
uchar ucKeyScan()
{
uchar Temp=0;
uchar ucRow=0,ucLine=0;
for(ucLine=0;ucLine<4;ucLine++) //列线扫描电压 (逐行进行)
{
SCANPORT=uca_LineScan[ucLine];
Temp=SCANPORT & 0x0F; //屏蔽低4位(低4位是行线,高4位是列线)
if(Temp!=0x0F) //判断该列是否有按键(低4位不全为1,则键被按下)。若按下,return (uckeycode)。
{ //返回按键坐标(ucline是行数)
if(Temp==0x0E)return ucLine*4+0; //返回值【0,4,8,12】 : 代表键值分别为【0,4,8,c】
if(Temp==0x0D)return ucLine*4+1; //返回值【1,5,9,13】 :代表键值分别为【1,5,9,d】
if(Temp==0x0B)return ucLine*4+2; //返回值【2,6,10,14】:代表键值分别为【2,6,a,e】
if(Temp==0x07)return ucLine*4+3; //返回值【3,7,11,15】:代表键值分别为【3,7,b,f】
}
}
return 16;
}
void vKeyProcess(unsigned char ucKeyCode)
{
switch(ucKeyCode)//16种情况
{
case 0:SerialSendData(table[0]);break;
case 1:SerialSendData(table[1]);break;
case 2:SerialSendData(table[2]);break;
case 3:SerialSendData(table[3]);break;
case 4:SerialSendData(table[4]);break;
case 5:SerialSendData(table[5]);break;
case 6:SerialSendData(table[6]);break;
case 7:SerialSendData(table[7]);break;
case 8:SerialSendData(table[8]);break;
case 9:SerialSendData(table[9]);break;
case 10:SerialSendData(table[10]);break;
case 11:SerialSendData(table[11]);break;
case 12:SerialSendData(table[12]);break;
case 13:SerialSendData(table[13]);break;
case 14:SerialSendData(table[14]);break;
case 15:SerialSendData(table[15]);break;
default:break;
}
}
void InitSerialPort(void)
{
SDA = 0;
SHIFT_CP = 0;
ST_CP = 0;
}
void main()
{
InitSerialPort();
while(1)
{
vKeyProcess(ucKeyScan());
delay(500);
i=(i+1)%8;
}
}
基于8051的扫描式键盘驱动和串并转换式显示编程实现人机I/O(键盘输入,数码管输出)
最新推荐文章于 2024-04-29 14:06:08 发布