基于8051的扫描式键盘驱动和串并转换式显示编程实现人机I/O(键盘输入,数码管输出)

#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;
	}
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值