×
嵌入式 > 嵌入式开发 > 详情

3个普通IO识别22个按键试验

发布时间:2022-07-13 发布时间:
|

吸取各位前辈的经验,将之前二极管用量多的问题优化一下,目前不用二极管能接6键,2只二极管能接12键,6只二极管能接18键,9只二极管能接21键,第22键要单独占用3只二极管最不化算。

实验用89S51作试验,电路接线就是P1.2,P1.3,P1.4接键盘,P1.0接显示器。

(原文件名:GIF.gif)

(原文件名SC00015.JPG)

/*==================================================================*

*3个IO接识别22键测试程序*

*------------------------------------------------*

*MCU:AT89C2051*

*OSC:12Mcysytel*

*程序设计:Cowboy*

*程序版本:V1.0*

*==================================================================*/

#include

//==================IO口线连接==================

sbitBus=P1^0;

sbitIO_a=P1^4;

sbitIO_b=P1^3;

sbitIO_c=P1^2;

//==================变量声明====================

unsignedcharDisp_buf[3];

unsignedcharDig;

unsignedcharKey_count;

unsignedcharbdataKey_state;

sbitKB0=Key_state^0;

sbitKB1=Key_state^1;

sbitKB2=Key_state^2;

sbitKB3=Key_state^3;

sbitKB4=Key_state^4;

sbitKB5=Key_state^5;

//==================表格数据====================

codeunsignedcharLED_font[24]=

{

0x84,0x9f,0xa2,0x8a,0x99,0xc8,0xc0,0x9e,0x80,//012345678

0x88,0x90,0xc1,0xe4,0x83,0xe0,0xf0,0xff,0xfb,//9abcdef-

};

codeunsignedcharKey_tab[64]=//键码映射表

{//0123456789

22,0,2,0,0,0,0,0,4,0,//0

0,0,0,0,0,18,0,0,0,0,//1X

0,0,0,0,0,0,3,14,0,0,//2X

20,10,6,0,0,0,0,0,1,19,//3X

0,5,0,0,0,15,0,11,0,0,//4X

0,17,0,0,13,8,0,21,0,9,//5X

16,12,7,0//6X

};

//===============检测按键=================

voidKey_scan()

{

unsignedchari;

Key_count--;//扫描次序

Key_count&=3;

switch(Key_count)//按次序处理

{

case2://第一轮扫描

KB0=IO_b;

KB1=IO_c;

IO_a=1;

IO_b=0;

break;

case1://每二轮扫描

KB2=IO_c;

KB3=IO_a;

IO_b=1;

IO_c=0;

break;

case0://每三轮扫描

KB4=IO_a;

KB5=IO_b;

IO_c=1;

break;

default://每四轮扫描

if(!IO_a)KB0=0;

if(!IO_b)KB2=0;

if(!IO_c)KB4=0;

IO_a=0;

//======更新显示缓冲区=======

i=Key_tab[Key_state];

if(i==0)

{

Disp_buf[2]=0x11;//显示三横

Disp_buf[1]=0x11;

Disp_buf[0]=0x11;

}

else

{

Disp_buf[2]=0x0c;//字符"C"

Disp_buf[1]=i/10;//键码十位

Disp_buf[0]=B;于//键码个位

}

Key_state=0;

}

}

/*===================================================================

ONEWIRE显示总线驱动程序

===================================================================*/

//===============发送一位=================

voidSend_bit(bitDat)

{

unsignedchari=3;

if(!Dat)Bus=0;

else

{

Bus=0;

Bus=1;

}

while(--i);//延时8us

Bus=1;

}

//===============总线驱动=================

voidBus_drive()

{

unsignedchari=0;

unsignedcharSdat;

Send_bit(1);//Bit6消隐

doBus=1;while(--i);//延时768us

doBus=0;while(--i);//延时768us

Bus=1;

Sdat=LED_font[Disp_buf[Dig++]];//获取显示数据

Send_bit(Sdat&0x01);//发送位0

Send_bit(Sdat&0x02);//发送位1

Send_bit(Sdat&0x04);//发送位2

Send_bit(Sdat&0x08);//发送位3

Send_bit(Sdat&0x10);//发送位4

Send_bit(Sdat&0x20);//发送位5

Send_bit(Dig&0x01);//发送位选1

Send_bit(Dig&0x02);//发送位选2

while(--i);//延时512us

Send_bit(Sdat&0x40);//发送位6

for(i=7;i>0;i--)Send_bit(1);//位6移至Dout

if(Dig==3)Dig=0;

}

/*===================================================================

延时5ms程序

===================================================================*/

voidDelay_5ms()

{

while(!TF1);

TF1=0;

TH1=(-5000)/256;

TL1=(-5000)%256;

}

/*===================================================================

主程序

===================================================================*/

voidmain()

{

TMOD=0x10;//定时器1,16位模式

TCON=0xc0;//TR1=1;TF1=1;

while(1)//主循环

{

Bus_drive();//显示总线驱动

Key_scan();//检测按键

Delay_5ms();//延时5MS

}



『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
一个简单的SOCKET程序的数据包结构和封解包函数