51单片机键盘驱动程序
51单片机的I2C底层驱动程序(IO口模拟)
51单片机的I2C底层驱动程序(IO口模拟)/*Title:I2C for 80C51Author:yuyouliang51单片机(本人使用STC89C52单片机,12T模式)的I2C驱动程序,使用逻辑分析仪对该协议进行分析,发现波形比较美观,SCL 的频率在70KHz左右(11.0592M晶振),低于标准的100K,可以适应大多数的I2C器件。
如果感觉速度过快或过慢,可以自行修改延时。
希望可以给读者一个参考,给读者一些帮助!*//*i2c.h文件 */#ifndef __I2C_H_#define __I2C_H_sbit SCL = P2^1;sbit SDA = P2^0;void start_i2c(); //启动I2C总线:SCL高电平期间,SDA由高变低void stop_i2c(); //停止I2C总线:SCL高电平期间,SDA由低变高void send_i2c(unsigned char c); //主机发送一个字节,先发送最高位unsigned char receive_i2c(); //主机接收一个字节,先接收最高位void master_ack(bit ack); //主机非应答信号(填参数0)或应答信号(填参数1)void slave_ack(); //等待从机应答信号#endif/* i2c.c文件 */#include#include#include#define nop() _nop_()void start_i2c() //启动I2C总线:SCL高电平期间,SDA由高变低{SDA=1;SCL=1;nop();nop();nop();nop();SDA=0;SCL=0;}void stop_i2c() //停止I2C总线,SCL高电平期间,SDA由低变高{SDA=0;SCL=1;nop();nop();nop();nop();SDA=1;}void slave_ack() //等待从机应答信号,如果从机迟迟没有应答,则结束总线。
C51单片机模块驱动程序参考
0x38,0x39,0x41,0x42,0x43,0x44,0x45,0x46
};定义在函数外部
unsigned char Key_ASC2(unsigned char key)
{
unsigned char key_asc2;
{
StartI2C();
Write8Bit(0xA2);
ChackAck();
Write8Bit(RomAddress);
ChackAck();
StartI2C();
Write8Bit(0xA3);
ChackAck();
for(;bytes!=1;bytes--)
{
*RamAddress=Read8Bit();
i=*ptr;
i &=பைடு நூலகம்0x80;
if(i==0)
break;
}
}
函数功能描述:向1602指令寄存器写指令;
void WriteW(uint a)
{
ptr=0xAFF0;//RS=0,R/W=0
*ptr=a;
}
函数功能描述:LCD初始化;
void LCD_Init(void)
{
CheckBF();
WriteW(0x38);
函数功能描述:键盘初始化,将标志位置1;
void Key_Init(void)
{
bKeyUp_Flag=1;//标志(全局变量)位置1
}
函数功能描述:键盘扫描函数,得到键的行列位置;
unsigned char GetScanKey(void)
{
unsigned char key, i, temp;
51单片机驱动LCD1602程序设计(C语言)
字符液晶绝大多数是基于 HD44780 液晶芯片的,控制原理是完全相同的,因此 HD44780 写 的控制程序可以很方便地应用于市面上大部分的字符型液晶。字符型 LCD 通常有 14 条引脚线或 16 条引脚线的 LCD,多出来的 2 条线是背光电源线 VCC(15 脚)和地线 GND(16 脚),其控制原理 与 14 脚的 LCD 完全一样,定义如下表所示:
for(i=0;i<count;i++) {
if (0 == y) x |= 0x80; //当要显示第一行时地址码+0x80; else x |= 0xC0; //在第二行显示是地址码+0xC0; Write_com(x); //发送地址码 Write_dat(*p); //发送要显示的字符编码 x++; p++; }
01110
○■■■○
10001
■○○○■
10001
■○○○■
10001
■○○○■
11111
■■■■■
10001
■○○○■
10001
■○○○■
上图左边的数据就是字模数据,右边就是将左边数据用“○”代表 0,用“■”代表 1。看出是个“A”
字了吗?在文本文件中“A”字的代码是 41H,PC 收到 41H 的代码后就去字模文件中将代表 A 字的
字符型 LCD 的引脚定义
HD44780 内置了 DDRAM、CGROM 和 CGRAM。DDRAM 就是显示数据 RAM,用来寄存 待显示的字符代码。共 80 个字节,其地址和屏幕的对应关系如下表:
也就是说想要在 LCD1602 屏幕的第一行第一列显示一个"A"字,就要向 DDRAM 的 00H 地址写 入“A”字的代码就行了。但具体的写入是要按 LCD 模块的指令格式来进行的。在 1602 中我们用前 16 个就行了。第二行也一样用前 16 个地址。对应如下:
基于51单片机的数码管及键盘程序
/*本程序功能:4*4按键,其中四个按键组成独立键盘,有加一减一和定时功能;另外十二个按键组成矩阵键盘,显示相应的编号。
*/#include<reg52.h>#define uchar unsigned char#define uint unsigned intuchar code duan[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; uchar code wei[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};/*sbit key7=P3^7;sbit key6=P3^6;sbit key5=P3^5;sbit key4=P3^4;sbit key3=P3^3;sbit key2=P3^2;sbit key1=P3^1;sbit key0=P3^0;*/uchar temp,num,shi,ge;void delay(uint tms){uint i,j;for(i=tms;i>0;i--)for(j=110;j>0;j--);}void display(){shi=num/10;ge=num%10;P2=wei[2];P0=~duan[shi];P2=wei[3];P0=~duan[ge];delay(2);}/*void keyscan() //法①{key0=0;if(key4==0)P0=~duan[0];else if(key5==0)P0=~duan[4];else if(key6==0)P0=~duan[8];else if(key7==0)P0=~duan[12];delay(2);key0=1;key1=0;if(key4==0)P0=~duan[1];else if(key5==0)P0=~duan[5];else if(key6==0)P0=~duan[9];else if(key7==0)P0=~duan[13];delay(2);key1=1;if(key4==0)P0=~duan[2];else if(key5==0)P0=~duan[6];else if(key6==0)P0=~duan[10];else if(key7==0)P0=~duan[14];delay(2);key2=1;key3=0;if(key4==0)P0=~duan[3];else if(key5==0)P0=~duan[7];else if(key6==0)P0=~duan[11];else if(key7==0)P0=~duan[15];delay(2);key3=1;//这一句很重要,不要漏写}*/void init_t0()//法二{TMOD=0x01;TH0=(65536-46083)/256;TL0=(65536-46083)%256;EA=1;ET0=1;//TR0=1;}void timer0() interrupt 1{uchar count;TH0=(65536-46083)/256;TL0=(65536-46083)%256;count++;if(count==20){count=0;num++;if(num==60)num=0;}}void keyscan(){P1=0xfe;temp=P1;temp=temp&0xf0;if(temp!=0xf0){temp=P1;temp=temp&0xf0;delay(10);if(temp!=0xf0){temp=P1;switch(temp){case 0xee:num++;/* while(temp==0xee){temp=P1;}*/ //这几条语句也可用于检测按键是否释放;若没有temp=P1,则不正确break;case 0xde:if(num==0)num=60;num--;// while(temp!=0xde);break;case 0xbe:num=0;// while(temp!=0xbe);break;case 0x7e:TR0=~TR0;// while(temp==0x7e);break;}while(temp!=0xf0){temp=P1;temp=temp&0xf0;}}}P1=0xfd;temp=P1;temp=temp&0xf0;if(temp!=0xf0){temp=P1;switch(temp){case 0xed:num=1;break;case 0xdd:num=5;break;case 0xbd:num=9;break;case 0x7d:num=13;break;}}P1=0xfb;temp=P1;temp=temp&0xf0;if(temp!=0xf0){temp=P1;switch(temp){case 0xeb:num=2;break;case 0xdb:num=6;break;case 0xbb:num=10;break;case 0x7b:num=14;break; }}P1=0xf7;temp=P1;temp=temp&0xf0;if(temp!=0xf0){temp=P1;switch(temp){case 0xe7:num=3;break;case 0xd7:num=7;break;case 0xb7:num=11;break;case 0x77:num=15;break; }}}void main(){init_t0();while(1){keyscan();display();}}。
4×4矩阵键盘51单片机识别实验及程序
4×4矩阵键盘51单片机识别实验与程序1.实验任务如图4.14.2所示,用AT89S51的并行口P1接4×4矩阵键盘,以P1.0-P1.3作输入线,以P1.4-P1.7作输出线;在数码管上显示每个按键的“0-F〞序号。
对应的按键的序号排列如图4.14.1所示图4.14.12.硬件电路原理图图4.14.23.系统板上硬件连线〔1.把“单片机系统“区域中的P3.0-P3.7端口用8芯排线连接到“4*4行列式键盘〞区域中的C1-C4 R1-R4端口上;〔2.把“单片机系统〞区域中的P0.0/AD0-P0.7/AD7端口用8芯排线连接到“四路静态数码显示模块〞区域中的任一个a-h端口上;要求:P0.0/AD0对应着a,P0.1/AD1对应着b,……,P0.7/AD7对应着h。
4.程序设计容〔1.4×4矩阵键盘识别处理(2.每个按键有它的行值和列值,行值和列值的组合就是识别这个按键的编码。
矩阵的行线和列线分别通过两并行接口和CPU通信。
每个按键的状态同样需变成数字量“0〞和“1〞,开关的一端〔列线〕通过电阻接VCC,而接地是通过程序输出数字“0〞实现的。
键盘处理程序的任务是:确定有无键按下,判断哪一个键按下,键的功能是什么;还要消除按键在闭合或断开时的抖动。
两个并行口中,一个输出扫描码,使按键逐行动态接地,另一个并行口输入按键状态,由行扫描值和回馈信号共同形成键编码而识别按键,通过软件查表,查出该键的功能。
5.程序框图图4.14.3C语言源程序*include <AT89*51.H>unsigned char code table[]={0*3f,0*06,0*5b,0*4f,0*66,0*6d,0*7d,0*07,0*7f,0*6f,0*77,0*7c,0*39,0*5e,0*79,0*71};unsigned char temp;unsigned char key;unsigned char i,j;void main(void) {while(1){P3=0*ff;P3_4=0;temp=P3;temp=temp & 0*0f; if (temp!=0*0f) {for(i=50;i>0;i--) for(j=200;j>0;j--); temp=P3;temp=temp & 0*0f; if (temp!=0*0f) {temp=P3;temp=temp & 0*0f; switch(temp){case 0*0e:key=7;break;case 0*0d:key=8;break;case 0*0b:key=9;break;case 0*07:key=10;break;}temp=P3;P1_0=~P1_0;P0=table[key]; temp=temp & 0*0f; while(temp!=0*0f) {temp=P3;temp=temp & 0*0f; }}}P3=0*ff;P3_5=0;temp=P3;temp=temp & 0*0f; if (temp!=0*0f) {for(i=50;i>0;i--) for(j=200;j>0;j--); temp=P3;temp=temp & 0*0f; if (temp!=0*0f) {temp=P3;temp=temp & 0*0f; switch(temp){case 0*0e:key=4;break;case 0*0d:break;case 0*0b:key=6;break;case 0*07:key=11;break;}temp=P3;P1_0=~P1_0;P0=table[key]; temp=temp & 0*0f; while(temp!=0*0f) {temp=P3;temp=temp & 0*0f; }}}P3=0*ff;temp=P3;temp=temp & 0*0f; if (temp!=0*0f) {for(i=50;i>0;i--) for(j=200;j>0;j--); temp=P3;temp=temp & 0*0f; if (temp!=0*0f) {temp=P3;temp=temp & 0*0f; switch(temp){case 0*0e:key=1;break;case 0*0d:key=2;break;case 0*0b:break;case 0*07:key=12;break;}temp=P3;P1_0=~P1_0;P0=table[key]; temp=temp & 0*0f; while(temp!=0*0f) {temp=P3;temp=temp & 0*0f; }}}P3=0*ff;P3_7=0;temp=P3;temp=temp & 0*0f;if (temp!=0*0f) {for(i=50;i>0;i--) for(j=200;j>0;j--); temp=P3;temp=temp & 0*0f; if (temp!=0*0f) {temp=P3;temp=temp & 0*0f; switch(temp){case 0*0e:key=0;break;case 0*0d:key=13;break;case 0*0b:key=14;break;case 0*07:key=15;break;}temp=P3;P1_0=~P1_0;P0=table[key]; temp=temp & 0*0f; while(temp!=0*0f) {temp=P3;temp=temp & 0*0f; }}}}}。
51单片机控制PS2键盘头文件
51单片机控制PS2键盘头文件51单片机控制PS2键盘是DM51的一个有用接口,光盘中程序给出了调试过的,如果有用户丢失了头文件,请将下面文件存为ps2.h转载请注明出处。
//===========================ps2.h头文件=============================// #ifndef PS2_H#define PS2_Hsbit keydata=P1^7;sbit clk=P3^2;unsigned char times=0;unsigned char i=0;unsigned char keycode=0,ps2_key; //ps2_key用于存放接收到的键码static unsigned char BF=0; //标识是否有字符被收到unsigned char code noshift[80][2]={1 , 8,// { f9 }3 , 4,// { f5 }4 , 2,// { f3 }5 , 0,// { f1 }6 , 1,// { f2 }7 ,11,// { f12 }9 , 9,// { f10 }13 ,25,// { tab }20 ,27,// { ctrl }41 ,29,// { space } 31 ,30,// { win } 12 , 3,// { f4 }11 , 5,// { f6 }10 , 7,// { f8 }14 ,96,// { ` }22 ,49,// { 1 }28 ,97,// { a }30 ,50,// { 2 }33 ,99,// { c }38 ,51,// { 3 }37 ,52,// { 4 }46 ,53,// { 5 }47 ,31,// { winright} 54 ,54,// { 6 }61 ,55,// { 7 }62 ,56,// { 8 }50 ,98,// { b }35 ,100,// { d }36 ,101,// { e }43 ,102,// { f }52 ,103,// { g }51 ,104,// { h }59 ,106,// { j }58 ,109,// { m }49 ,110,// { n }21 ,113,// { q }45 ,114,// { r }27 ,115,// { s }60 ,117,// { u } 42 ,118,// { v }29 ,119,// { w } 34 ,120,// { x }53 ,121,// { y }26 ,122,// { z }65 ,44,// { , }66 ,107,// { k }67 ,105,// { i }68 ,111,// { o }69 ,48,// { 0 }70 ,57,// { 9 }73 ,46,// { . }74 ,47,// { / }75 ,108,// { l }76 ,59,// { ; }77 ,112,// { p }78 ,45,// { - }82 ,39,// { ' }85 ,61,// { = }84 ,91,// { [ }91 ,93,// { ] }88 ,26,// { caps } 93 ,92,// { \ }90 ,32,// { enter } 120,10,// { f11 } 102,12,// { back } 224,13,// { home } 105,14,// { end }125,15,// { pageup }122,16,// { pagedown }117,17,// { up }114,18,// { down }107,19,// { left }116,20,// { right }113,21,// { del }112,22,// { insert }225,23,// { pause }118,24,// { esc }131, 6,// { f7 }};unsigned char code addshift[47][2]= {14,126, // { ~ }22, 33, // { ! }30, 64, // { @ }38, 35, // { # }37, 36, // { $ }46, 37, // { % }54, 94, // { ^ }61, 38, // { & }62, 42, // { * }70, 40, // { ( }69, 41, // { ) }78, 95, // { _ }85, 43, // { + }93,124, // { | }84,123, // { { }76, 58, // { : } 82, 34, // { " } 65, 60, // { < } 73, 62, // { > } 74, 63, // { ? } 28 ,65,// { a } 50 ,66,// { b } 33 ,67,// { c }35 ,68,// { d }36 ,69,// { e } 43 ,70,// { f } 52 ,71,// { g } 51 ,72,// { h } 67 ,73,// { i } 59 ,74,// { j } 66 ,75,// { k } 75 ,76,// { l } 58 ,77,// { m } 49 ,78,// { n } 68 ,79,// { o } 77 ,80,// { p } 21 ,81,// { q } 45 ,82,// { r } 27 ,83,// { s } 44 ,84,// { t } 60 ,85,// { u } 42 ,86,// { v } 29 ,87,// { w } 34 ,88,// { x }26 ,90,// { z }};unsigned char getchar(unsigned char k) //转换键码为ASCII码{unsigned char j;if(!i)for(j=0;j<80;j++){if(noshift[j][0]==k){ps2_key=noshift[j][1];return 1;}}elsefor(j=0;j<47;j++){if(addshift[j][0]==k){ps2_key=addshift[j][1];return 1;}}return 0;}void Keyboard_out(void) interrupt 0{if(times<9){keycode=keycode>>1; //因键盘数据是低>>高,结合上一句所以右移一位if(keydata) keycode=keycode | 0x80; //当键盘数据线为1时为1到最高位 }times++;if(times>10){times=0;if(keycode==0xe0 || keycode==0xf0){}//return;}else if((keycode==18 || keycode==89) && i==0){i=1;}else if((keycode==18 || keycode==89) && i==1){i=0;}else {EX0=0;BF=1;} //关中断等显示完后再开中断//当中断11次后表示一帧数据收完,清变量准备下一次接收//(注:如这里不用BF和关中断直接调Decode()//则所Decode中所调用的所有函数要声明为再入函数)}// while(!clk); //等待PS/2CLK拉高}#endif。
SLE4442卡_IC的51单片机驱动程序
SLE4442卡_IC的51单片机驱动程序整理了最初的实验草稿版,将端口宏定义,函数声明以及常用的函数声明建立头文件,感觉清楚多了,在不断地修改中凝练,在不停的实践中提高,满眼的思绪,在小小的Readme中划过一笔~~~~~~~~char data_RST[4], ErrorCount[4];void IC_RST(void){uchar value,i,count;DATA_IN; //IC输入RST_LOW; //复位时序CLK_LOW;DATA_HIGH;DelayUs(5);RST_HIGH;DelayUs(5);CLK_HIGH;DelayUs(5);CLK_LOW;DelayUs(5);RST_LOW;for(i=0;i;>; 1;DelayUs(2);CLK_LOW;DelayUs(2);CLK_HIGH;DelayUs(2);if(RD5 == 1){value |= 0x80; //判断IO脚是否为1,是则位置1 }else{value &= 0x7f; //否则位置0}DelayUs(2);}data_RST[i] = value;DelayUs(2);}DelayUs(2);CLK_LOW;DATA_HIGH;}void IC_Init(void) //初始化{TRISD1 = 0;RD1 = 0; //上电TRISD4 = 0; //时钟输出TRISD3 = 0; //RST输出DelayMs(5); //上电的必要延时,否则程序出错}void Start(void){DATA_OUT; //开始时序CLK_LOW;DATA_HIGH;DelayUs(2);CLK_HIGH;DelayUs(2);DATA_LOW;DelayUs(2);CLK_LOW;}void Stop(void) //结束时序{DATA_OUT;CLK_LOW;NOP();NOP();DATA_LOW;DelayUs(2);CLK_HIGH;DelayUs(2);DATA_HIGH;DelayUs(2);}uchar Byte_Read(void) //读字节{uchar count;uchar value;DATA_IN;DelayUs(2);value = 0xff;for(count=0;count;>; 1; //循环右移,从最低位开始读 DelayUs(2);CLK_LOW;DelayUs(2);CLK_HIGH;DelayUs(2);if(RD5 == 1){value |= 0x80;//判断IO脚是否为1}else{value &= 0x7f;}DelayUs(2);}return (value);}void Byte_WRT(uchar Xdata)//写字节{uchar count;DATA_OUT;DelayUs(2);for(count=8;count!=0;count--){CLK_LOW;DelayUs(2);if((Xdata)&0x01){DATA_HIGH;}else{DATA_LOW;}DelayUs(2);CLK_HIGH;DelayUs(2);Xdata = Xdata >;>; 1; //循环右移,从最低位开始写}}void Command(uchar command,uchar address,uchar IC_data){Start();Byte_WRT(command);//发送命令Byte_WRT(address);//发送地址Byte_WRT(IC_data);//发送数据Stop();//操作命令结束}void Process(void){uint j; //写指令后的处理过程DATA_OUT;DelayUs(2);CLK_LOW;DATA_LOW;DelayUs(2);for(j = 0;j < 255;j++)CLK_HIGH;DelayUs(2);CLK_LOW;DelayUs(2);}DATA_HIGH;}void Process2(void){uint j; //写指令后的短处理过程DATA_OUT;DelayUs(2);CLK_LOW;DATA_LOW;DelayUs(2);for(j = 0;j < 2;j++){CLK_HIGH;DelayUs(2);CLK_LOW;DelayUs(2);DATA_HIGH;}uchar Code_Check(uchar Code1,uchar Code2,uchar Code3) //密码校验函数{uchar i;Command(0x31,0x00,0x00);for(i = 0;i < 4;i++){ErrorCount[i] = Byte_Read();}if(ErrorCount[0] == 0){return 0;}else{if((ErrorCount[0]&0x01) == 1){ErrorCount[0] &= 0x06;//bit0=0;}else if((ErrorCount[0]&0x02) == 1) {ErrorCount[0] &= 0x05;//bit1=0;}else{ErrorCount[0] &= 0x03;//bit2=0}}Command(0x39,0x00,ErrorCount[0]); Process();Command(0x33,0x01,Code1); Process2();Command(0x33,0x02,Code2); Process2();Command(0x33,0x03,Code3);Process2();Command(0x39,0x00,0xff);Process();Command(0x31,0x00,0x00);for(i = 0;i < 4;i ++){ErrorCount[i] = Byte_Read();}if(ErrorCount[0] == 0x07){return 1;}else{return 0;}}void ReadMainROM(uchar addr,uchar *p,uchar N) //读主存区{Command(0x30,addr,0xff);while(N--){*p=Byte_Read();p++;}}void WriteMainROM(uchar addr,uchar *t,uchar N) //写主存区{while(N--){Command(0x38,addr,*t);Process();addr++;t++;}}void ReadProROM(uchar addr,uchar *p,uchar N) //读保护区{Command(0x34,addr,0xff);while(N--){*p=Byte_Read();p++;}}void WriteProROM(uchar addr,uchar *t,uchar N) //写保护区{while(N--){Command(0x3c,addr,*t);Process();addr++;t++;}}void ReadCode(uchar addr,uchar *p,uchar N) //读密码Command(0x31,addr,0xff);while(N--){*p=Byte_Read();p++;}}void WriteCode(uchar addr,uchar *t,uchar N) //写密码{while(N--){Command(0x39,addr,*t);Process();addr++;t++;}}}。
51单片机矩阵键盘控制数码管显示过程中出现的问题及解决方法
51单片机矩阵键盘控制数码管显示过程中出现的问题及解决方法在使用51单片机控制矩阵键盘同时驱动数码管显示的过程中,可能会遇到一些常见的问题。
以下是一些可能的问题及相应的解决方法:按键无法正常响应:* 问题可能原因:接线错误、按键损坏、软件扫描不到按键信号。
* 解决方法:检查按键连接是否正确,确保按键没有损坏。
在软件中进行适当的按键扫描,确保能够正确检测到按键的状态。
数码管显示异常或不亮:* 问题可能原因:数码管接线问题、数码管损坏、数码管驱动程序错误。
* 解决方法:仔细检查数码管的接线是否正确,确保数码管没有损坏。
检查数码管的驱动程序,确保它按照正确的顺序和时序进行驱动。
按键重复响应或漏按现象:* 问题可能原因:按键抖动、软件扫描速度过快。
* 解决方法:在软件中增加适当的按键抖动延时,确保在按键按下或抬起时只响应一次。
调整软件扫描速度,避免扫描间隔过短导致的重复响应。
矩阵键盘的多个按键同时按下导致混乱:* 问题可能原因:矩阵键盘硬件连接错误、软件扫描算法问题。
* 解决方法:检查矩阵键盘的硬件连接,确保矩阵行和列没有短路或断路。
调整软件扫描算法,确保同时按下多个按键时能够正确识别。
数码管显示不正常的数字或乱码:* 问题可能原因:程序错误、数码管接线错误。
* 解决方法:仔细检查程序,确保数码管段选和位选的控制逻辑正确。
检查数码管的接线,确保每个数码管的连接都正确。
在解决问题时,建议逐步排除可能的原因,通过调试工具、逻辑分析仪或输出调试信息的方式来定位问题。
另外,仔细查阅51单片机的数据手册和相关文档,以确保硬件连接和软件设计都符合标准。
51单片机keil下键盘驱动程序设计
K2: CJNE A,#2,K3 MOV P1,#11111100B LJMP LOOP
K3: CJNE A,#3,K4 MOV P1,#11111000B LJMP LOOP
K4: CJNE A,#4,K5 MOV P1,#11110000B
Y
KEY3按下? N
延时10ms KEY3按下? N
(A)=3 KEY3抬起? N
Y
KEY4按下? 延时10ms KEY4按下?
(A)=3 KEY4抬起? N
Y
独立式键盘驱动程序参考
;在A中返回键码:01234,0表示没有按键按 下
KEY1 EQU P3.2 KEY2 EQU P3.3 KEY3 EQU P3.4 KEY4 EQU P3.5 ;---------------------------RDKEY: MOV A,#0 RDKEY1: JB KEY1,RDKEY2
;是key1? ;显示键码
练习3:用动态显示数码管显示键码
;用6位数码管的最右面一位显示键码,按KEY1显示1,按KEY2显示2, 按KEY3显示3,按KEY4显示4。
键盘接口方式
独立式键盘接口
每个按键占用一个端口 优点:接口简单,编程简单 缺点:占用端口多,适应与按键少的场合
矩阵式键盘接口
按键排列成行列矩阵形式 优点:占用端口少,适应与按键多的场合 缺点:编程复杂
独立式键盘接口电路
AT89S51 P3.2 P3.3 P3.4 P3.5
DJNZ R7,DELAY2 DJNZ R6,DELAY1 RET
练习2:用P1口的发光管显示键码
51单片机矩阵按键程序
51单片机矩阵按键程序下述为程序:#include <reg51.h>#define Keyvalue P1 //按下的键的代号#define Digvalue P0 //用宏定义来定义一下数码管的发送屈始数据端口typedef unsigned int ut;typedef unsigned char uc;ut k;sbit LSA=P2^2; //定义三八译码器泪亲的三个输入端口sbit LSB=P2^3;sbit LSC=P2^4;utsmgduan[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71}; //从0~15的十六进制编码void delay(ut i) //延时函数{ while(i) i--;}void anjian( //检测按键是否按下,若按键按下则给k附上按下的键的序号{ uta; Keyvalue=0x0f; if(Keyvalue!=0x0f) { delay(1000); if(Keyvalue!=0x0f) { Key value=0x0f; switch(Keyvalue) { case(0x07):k=0;break; case(0x0b):k=1;break ; case(0x0d):k=2;break; case(0x0e):k=3;break; } Keyvalue=0xf0; switch(Keyv alue) { case(0x70):k=k;break; case(0xb0):k=k+4;break; case(0xd0):k=k+8;br eak; case(0xe0):k=k+12;break; } } 劣蚊各} while((a<50)&&(Keyvalue!=0x0f)) { delay(1000); a++; }}voidmain({ LSA=0; //让第一个数码管显示数字 LSB=0; LSC=0; while(1) { anjian(; Digvalue=smgduan[k]; //显示数字 }}。
在51单片机上使用PC机ps2键盘
在51单片机上使用PC机ps/2键盘(附源码)本人弄了几天,终于在今天晚上,也就是刚才实验成功,心情特佳,特写出来以享大家。
单片机上应用非编码键盘,各书上均有介绍。
作为实验用,我想到了用PC机的ps/2键盘。
PC机键盘内部有单片机电路来完成编码和去抖动,它按照ps/2协议来发送扫描码。
因此在应用中,我们需要做的只是将扫描码与字符对应起来,大部分事情都由键盘自己完成了。
首先介绍一下键盘的接口,典型的几种接口如下图:其中第一种用于老式键盘(我原来的键盘就是),第二种便是现在的PS/2键盘,第三个不用去管它。
我的实验是按照最常用的PS/2(即第二种)来做的。
再略微介绍一下PS/2协议的相关内容。
PS/2的一个数据帧为11位,时序如下:PS/2帧的第一位是起始位,为0,然后是8位数据位,发送键盘扫描码的一个字节(扫描码为1-4个字节),然后是奇偶校验位,最后是停止位,为1。
这些是在数据线(即1号引脚线)上发送的。
无键按下时,数据线和始终线都保持为1。
当有键按下时,时钟线CLOCK 送出脉冲,同时数据线送出数据。
主机(此处是89c51 MCU)在始终脉冲的下降沿对数据线采样获得数据。
键盘扫描码包括通码和断码,当键按下时发送通码,抬起时发送断码。
更详细的内容可参考所附的《PS/2技术参考》。
根据上述原理,我这样设计了实验:将键盘的脉冲线接至89c51的外部中断输入口(INT0或INT1),当键按下和抬起时有脉冲产生,此脉冲引发MCU中断。
将键盘的DATA线连至89c51的输入口(如P1.0)。
在中断处理程序中,从输入口读入数据,然后通过循环移位对读进的数据位进行处理,1(起始位)、10(奇偶校验)、11(停止位)可抛弃,如不嫌麻烦也可将奇偶校验位加以应用。
当一个数据帧收完后,将处理后剩下的2-9位(即扫描码)通过串口发至PC机,通过PC机的串口监视软件(如“串口调试助手”)来查看。
硬件连线和源码如下:源码:ORG 0000HAJMP MAIN;转入主程序ORG 0003H ;外部中断P3.2脚INT0入口地址AJMP INT ;转入外部中断服务子程序;以下为主程序进行CPU中断方式设置MAIN:MOV SCON,#50H;设置成串口1方式MOV TMOD,#20H;波特率发生器T1工作在模式2上MOV PCON,#80H;波特率翻倍为2400x2=4800BPSMOV TH1,#0F3H;预置初值(按照波特率2400BPS预置初值)MOV TL1,#0F3H;预置初值(按照波特率2400BPS预置初值)SETB EA ;打开CPU总中断请求SETB IT0 ;设定INT0的触发方式为脉冲负边沿触发SETB EX0 ;打开INT0中断请求SJMP $INT: CLR EA ;暂时关闭CPU的所有中断请求CJNE R0,#0,L1L3: INC R0SJMP L5L1: CJNE R0,#9,L2SJMP L3L2: CJNE R0,#10,L4SETB TR1;启动定时器T1MOV SBUF,AMOV R0,#0L5: SETB EA ;允许中断RETI ;退出子程序L4: MOV C,P1.0RRC ASJMP L3END搞定后,当按下和释放键时,会在PC机上显示其扫描码。
51单片机控制ps2键盘设计说明
51接PS2键盘2008-09-20 16:02在这个周末,终于有时间做做试验了。
昨晚用AVR和MC9S12DG128驱动1602成功,今天突然想到PS2键盘的驱动,当时觉得PS2键盘与MCU接口很神秘,做了之后才觉得其实不然哈。
再传张键盘的扫描码的波形。
(协议规定:数据低位在前,采用奇校验数据格式(PS->MCU):1起始位为0,8数据位,1奇校验位,1停止位为1)'A'键(0x1C)的make code:代码:PS_2_KB.H//************write by zhouyong********* //************qq:510559254************** //************2008-9-20*****************#ifndef _PS_2_KB_H#define _PS_2_KB_H#include <AT89X51.H>#define KB_CLK P3_3#define KB_DATA P3_4uchar Get_Key(void);uchar Key_Scan(void);uchar Key_Scan(void){uchar i,key_temp;KB_CLK=1; //输入KB_DATA=1;key_temp=0;while(KB_CLK); //第一次为0for(i=0;i<8;i++){key_temp>>=1;while(!KB_CLK); //下沿,第一位while(KB_CLK);_nop_();if(KB_DATA){key_temp|=0x80; //低位在前}}while(!KB_CLK); //校验位while(KB_CLK);while(!KB_CLK); //停止位while(KB_CLK);while(!KB_CLK);return key_temp;}//由于make_code和第二个break_code一样,就取break_code第二个作为键码uchar Get_Key(void){uchar Key_Code;Key_Code=Key_Scan(); //make_codeKey_Code=Key_Scan(); //break_code 1Key_Code=Key_Scan(); //break_code 2switch(Key_Code){case 0x1c: return 'A';break;case 0x32: return 'B';break;case 0x21: return 'C';break;case 0x23: return 'D';break;case 0x24: return 'E';break;case 0x2b: return 'F';break;case 0x34: return 'G';break;case 0x33: return 'H';break;case 0x43: return 'I';break;case 0x3b: return 'J';break;case 0x42: return 'K';break;case 0x4b: return 'L';break;case 0x3a: return 'M';break;case 0x31: return 'N';break;case 0x44: return 'O';break;case 0x4d: return 'P';break;case 0x15: return 'Q';break;case 0x2d: return 'R';break;case 0x1b: return 'S';break;case 0x2c: return 'T';break;case 0x3c: return 'U';break;case 0x2a: return 'V';break;case 0x1d: return 'W';break;case 0x22: return 'X';break;case 0x35: return 'Y';break;case 0x1a: return 'Z';break;case 0x45: return '0';break;case 0x16: return '1';break;case 0x1e: return '2';break;case 0x26: return '3';break;case 0x25: return '4';break;case 0x2e: return '5';break;case 0x36: return '6';break;case 0x3d: return '7';break;case 0x3e: return '8';break;case 0x46: return '9';break;default: return 0xff; break;}}#endifLCD1602.H://************write by zhouyong*********//************qq:510559254**************//************2008-9-14*****************#ifndef _LCD1602_#define _LCD1602_#include <AT89X51.H>#include <string.h>#include <intrins.h>//--------------------------------------------------------------------#define E_1602 P3_7 //on falling edge enable data or command #define RW_1602 P3_6 //read or write control#define RS_1602 P3_5 //cmd or data register select#define DATA_1602 P2 //data port#define DATA 1 //select DATA register#define CMD 0 //select CMD register#define READ 1#define WRITE 0//--------------------------------------------------------------- void Delay_us(uchar t);void Delay_ms(uchar t);void Init_1602(void);void Write_Char_1602(uchar Data,bit CMD_DATA,bit Check);void Check_Busy_1602(void);void Write_String_1602(uchar *P);void Set_R_C(uchar R,uchar C);//void Clear_LCD_1602(void);//---------------------------------------------------------------- /*void Clear_LCD_1602(void){Write_Char_1602(0x01,CMD,1);//clear screen}*/void Delay_us_1602(uchar t){while(--t);}void Delay_ms_1602(uchar t){while(t--){Delay_us_1602(225);Delay_us_1602(227);}}void Init_1602(void){Delay_ms_1602(15);Write_Char_1602(0x38,CMD,0); //don't check busyDelay_ms_1602(5);Write_Char_1602(0x38,CMD,0);Delay_ms_1602(5);Write_Char_1602(0x38,CMD,0);Write_Char_1602(0x38,CMD,1);//8 wire,2 line display,5x10 charWrite_Char_1602(0x08,CMD,1);//close display,no cursor,don't blink Write_Char_1602(0x01,CMD,1);//clear screenWrite_Char_1602(0x06,CMD,1);//the cursor move from left to right,the text don't moveWrite_Char_1602(0x0c,CMD,1);//open display}void Write_Char_1602(uchar Data,bit CMD_DATA,bit Check){if(Check)Check_Busy_1602();RS_1602=CMD_DATA;RW_1602=WRITE;DATA_1602=Data;E_1602=1;_nop_();E_1602=0;}void Write_String_1602(uchar *P) //only can write from start to end {uchar i,len;len=strlen(P);Set_R_C(0,0);if(len>16){for(i=0;i<16;i++){Write_Char_1602(P[i],DATA,1);}Set_R_C(1,0);for(i=16;i<len;i++){Write_Char_1602(P[i],DATA,1);}}else{for(i=0;i<len;i++){Write_Char_1602(P[i],DATA,1);}}}void Set_R_C(uchar R,uchar C) //set row and column R=0/1;C=0~F {R&=0x01;C&=0x0f;if(R)Write_Char_1602(0x80+0x40+C,CMD,1);elseWrite_Char_1602(0x80+C,CMD,1);}void Check_Busy_1602(void){DATA_1602=0xff; //set as input portRS_1602=CMD;RW_1602=READ;E_1602=1;while(DATA_1602 & 0x80){E_1602=0; //这两句protues仿真必须加E_1602=1; //}E_1602=0;}#endifmain.c:#include <AT89X51.H>#include <intrins.h>#define uchar unsigned char#define uint unsigned int#include "PS_2_KB.h"#include "LCD1602.h"void main(void){ucharBuffer[]="";uchar Key_Code,Key_Count,i;Init_1602();Set_R_C(0,0);for(;;){Key_Code=Get_Key();if(Key_Code!=0xff) // 为0xff时视为无效键{Buffer[Key_Count]=Key_Code;Write_String_1602(Buffer);Key_Code=0;Key_Count++; //第n次按键,显示在第n位if(Key_Count==32){for(i=0;i<32;i++){Buffer[i]=' ';}Key_Count=0;}P1=~P1; //P1口接有LED,用于指示按键 }}}。
基于Small RTOS51的PS/2键盘驱动程序开发
/ 接 收 数 据 , 一 高 / 低
1 驱 动 的 设 计
驱 动 的实 现 一 般 可 用 以下 几 种 方 法 : 使 用 任 务 编 ① 写 ; 使用消息编写 ; 使用信 号量 编写 。P / ② ③ S 2键 盘 既 不 需 要 CP 周 期 服务 , 不 具 有 自 己的 中断 设 备 , 为 了 U 又 但
维普资讯
技 术 纵 横
基 于 S R OS 1的 ma T 5 l l P/ S 2键 盘 驱动 程序 开发
■ 武 汉 军 械 士 官 学 校
■ 中 国 地 质 大 学
王 志 国
王 晓 威
…
根据 P / S 2键 盘扫 描 码 的 特 点 , 于 S l R 基 mal TOS 1嵌 入 式 操 作 系统 , 写 一 种 响 应 快 , 植 性 强 , 5 编 移 占用 资
引 言
随着 嵌 入 式 系统 的 发 展 , 入 式 软 件设 计 向软 件 平 台 嵌 靠 近 , 片机 软 件 设 计 不 再 是 单 一 线 程 结 构 方 式 , 是 逐 单 而
E0 F H 和 标 识 码 。c H、 O .组 合 键 , G。得 到 G 的 按键 顺 如 序是 : s i , g, 按 hf 按 t 释放 g 最后 释 放 s i 。所 以 扫 描 码 应 , hf t
维普资讯
技 术 纵 横
程 序 首 先 按 照 S lR O 5 ma T S 1的 中 断 编 写 规 范 调 用 l 宏 0 n_ N R( 。如 果 用 户 禁 止 中断 嵌 套 管 理 ( N S ItE TE ) E 一
0s ILE - n NTER一 0 , 么 不 必 调 用 宏 。接 着 , 收 扫 描 )那 接
实例制作一个51单片机连接PS2键盘
实例制作的是用一个AT89C51单片机连接PS/2键盘接口和一个16x2的液晶显示屏,当敲击键盘时,字母可以显示在液晶显示屏上。
这个实例能启发你如何利用单片机来实现对PS/2接口的控制。
实例中提供的源代码修改后可以用到其他PS/2键盘制作项目中。
实例中提供的16x2字符型的液晶显示屏的驱动函数也可以其他项目。
电路原理主电路板中的AT89C51单片机(可以用AT89C52/S51/S52直接替换,如用AT89C2051/4051则需要改程序)组成了51最小化系统。
液晶显示屏于嗯了SMC1602A. 键盘通过PS/2六孔插座和主电路板。
PS/2设备的连接器使用mini-DIN连接器,正有6个引线,其中2个保留为用。
DATA和CLK是可双向通信的I/O线,也就是说通过这两根线,既可以把主机的数据发送到PS/2设备,有可以把设备的数据发向主机。
在无键按下是,DATA 和CLK一直处于高电平状态。
但有键按下时,键盘先检查CLK,看它是否处于高电平,如果是处在低电平,说明主机无空闲接收数据,这是键盘将会把数据放在自己的缓冲区(16Bytes).直到CLK重新被拉高。
键盘获得总线权,这是键盘产生始终信号在CLK上输出。
同时每一个时钟周期在DATA 线上输出一位数据。
第1位是起始位为0,第2-9位为一个八位二进制数据由地位到高位依次输出,第10位为奇偶校验位下面是电路原理图PS/2设备接口用于许多现代的鼠标和键盘,PS/2连接器上有四个管脚:电源地、+5V、数据和时钟。
Host(计算机)提供+5V并且键盘/鼠标的地连接到host的电源地上,数据和时钟都是集电极开路的这就意味着它们通常保持高电平而且很容易下拉到地(逻辑0)。
任何你连接到PS/2鼠标、键盘或host 的设备,在时钟和数据线上要有一个大的上拉电阻。
置“0”就把线拉低,置“1”就让线上浮成高。
从键盘/鼠标发送到主机的数据在时钟信号的下降沿(当时钟从高变到低的时候)被读取;从主机发送到键盘/鼠标的数据在上升沿(当时钟从低变到高的时候)被读取。
51单片机独立按键控制八路LED亮灭程序代码
//51单片机独立按键控制八路LED灯亮灭程序代码//#include <reg51.h> //调用头文件unsigned int count,count1; //定义两个int类型的变量sbit key=P3^5; //定义按键接入串口sbit key1=P3^4; //定义按键接入串口//以下是一个延时函数,便于后面程序按键的消抖,除了这个用途外,延时函数还有很多用途......//void delay(unsigned int ms){while(ms--);}//以下是一个声明的按键检测函数,在这个函数中通过count及count1两个变量的值来确定按键按下LED的亮灭,我这用了两个按键,不同按键控制LED从不同方向一次点亮,函数中采用了if语句与switch语句相结合,这是关键所在。
//void keysan(){if(key==0){delay(10);if(key==0){count++;switch(count){case 0:P1=0xff;break;case 1:P1=0xfe;break;case 2:P1=0xfd;break;case 3:P1=0xfb;break;case 4:P1=0xf7;break;case 5:P1=0xef;break;case 6:P1=0xdf;break;case 7:P1=0xbf;break;case 8:P1=0x7f;break;case 9:P1=0xff;break;}if(count>=9){count=0;}while(!key);}}delay(10);if(key1==0){delay(10);if(key1==0){count1++;switch(count1){case 0:P1=0xff;break; case 1:P1=0x7f;break; case 2:P1=0xbf;break; case 3:P1=0xdf;break; case 4:P1=0xef;break; case 5:P1=0xf7;break; case 6:P1=0xfb;break; case 7:P1=0xfd;break; case 8:P1=0xfe;break; case 9:P1=0xff;break; }if(count1>=9){count1=0;}while(!key1);}}}void main(){while(1){keysan();}}。
单片机驱动74HC595的c51程序
单片机驱动74HC595的c51程序//该子程序为74HC595 发送字符的程序,该程序是先发送的是最低位!//芯片74HC595 的时钟引脚为第11 脚//芯片74HC595 的数据引脚为第14 脚//芯片74HC595 的锁存引脚为第12 脚//当有多片74HC595 串联时,只有当所有数据都发送完成后,再锁存信号!//同样74hc164 与51 单片机连接也可以由这个程序来驱动#include#define uchar unsigned char#define uint unsigned int sbit clk=P3 ;sbit dat=P3;sb it shuo_cun=P3;uchar volatile e,f;uchar code tab[]={0x03,/*0*/0x9F,/*1*/0x25,/*2*/0x0D,/*3*/0x99,/*4*/0x49,/*5*/0x41,/*6*/0x1F,/*7*/0x01,/*8*/0x09,/*9*/};void fa_shon(uchar k) //{uchar i; //定义循环变量for(i=0;i8;i++) //因为是1 字节是8 位,所以循环8 次{dat=k0x01; //将要发送的数据与上0X01 送到数据引脚clk=0; //时钟引脚加低电平clk=1; //时钟引脚加高电平k=1; //将发送的数据右移1 位} }void main() {TMOD=0x01;TH0=15535/256;TL0=15535%256;EA=1;ET0=1;TR0=1;while(1){ uchara;for(a=0;a3;a++){fa_shon(tab[e%10]);fa_shon(tab[e%100/10]);fa_shon(tab[e/100]);}s huo_cun=0; //锁存为低电平shuo_cun=1; //锁存为高电平}}void tt()interrupt1{TH0=15535/256;TL0=15535%256;f++;if(f10){f=0;e++;if(e250)e=0;}}tips:感谢大家的阅读,本文由我司收集整编。
MzT35C1的MCS51基础驱动演示说明
5.1 端口定义 ···········································································································································16 5.2 底层驱动函数····································································································································18 5.3 MzT35C1 驱动程序说明···················································································································21
关键字
MzT35C1 LCD 彩色 TFT 铭正同创 MCS51
北京铭正同创科技有限公司
mzdesign@
4
MzT35C1 的 MCS51 基础驱动演示说明
1 技术概述
MzT35C1 彩色 TFT 液晶模块为北京铭正同创科技有限公司为广大用户提供的可由普通单片机控制 显示的彩色 TFT 液晶模块,并为用户提供了完整的驱动程序;而驱动程序当中包括了基本的绘图功能函 数、中西文显示功能函数,并且该模块可通过寄存器的设置来完成对背光亮度的控制。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
{
dula=1;
P0=table[ge];
dula=0;
P0=0xff;
wela=1;
P0=0xfe;
wela=0;
delay(1);
}
//*************************************************
//*************函数声明*************
uchar keyscan();
//***********初始化函数*************
void init()
{
num=17;
wela=1;
P0=0xfe;
wela=0;
}
//**********************************
case 0xed:num=5;
break;
case 0xdd:num=6;
break;
case 0xbd:num=7;
}
}
}
P3=0xfd;//第二行
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0)
{
delay(5);
{
temp=P3;
temp=temp&0xf0;
}
}
}
P3=0xfb;//第三行
temp=P3;
//函数名称:延时函数
//函数功能:实现1MS延时
//**********************************
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
init();
while(1)
{
display(keyscan());
}
}
//*************按键代码返回函数*************
uchar keyscan()
{
P3=0xfe;//第一行
//按下最后一个显示F。
//***********************************************
//**********包含头文件************
#include<reg52.h>
//************宏定义**************
#define uint unsigned int
void main()
{
P3=0xff;
while(1)
{
if(key1==0)
{
delay(10);
if(key1==0)
{
D1=0;
case 0xdb:num=10;
break;
case 0xbb:num=11;
break;
case 0x7b:num=12;
#include<reg52.h>
//************宏定义**************
#define uint unsigned int
#define uchar unsigned char
//************位声明**************
sbit D1=P1^0;
//*************变量声明*************
uchar ge;
//**********************************
//函数名称:延时函数
//函数功能:实现1MS延时
//**********************************
void delay(uint z)
//函数名称:主函数
//函数功能:判断按键是否按下。按下,L1亮,松开L1灭!
// 松开的同时,数码管的第一位加一计数。
// 从0-9循环。(延时去抖动)
//*************************************************
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0)
{
delay(5);
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0)
}
}
#define uchar unsigned char
//************位声明**************
sbit dula=P2^6;
sbit wela=P2^7;
//*****************数字编码表********************
uchar code table[]={
{
temp=P3;
switch(temp)
{
case 0xeb:num=9;
break;
sbit key1=P3^4;
sbit dula=P2^6;
sbit wela=P2^7;
//************数字编码表***********
uchar code table[]={
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
brexf0)
{
temp=P3;
temp=temp&0xf0;
case 0xde:num=2;
break;
case 0xbe:num=3;
break;
case 0x7e:num=4;
//*******************************************
//函数名称:显示函数
//函数功能:第一位数码管显示按键键值
//******************************************
void display(uchar shu)
{
dula=1;
{
temp=P3;
switch(temp)
{
case 0xee:num=1;
break;
}
else
{
D1=1;
}
display(ge);
}
}
C语言2:
//***********************************************
//现象:按下按键,显示其键值。按下第一个,显示0。
break;
case 0x7d:num=8;
break;
}
while(temp!=0xf0)
break;
}
while(temp!=0xf0)
{
temp=P3;
temp=temp&0xf0;
P0=table[shu-1];
dula=0;
}
//**************************************
//函数名称:主函数
//函数功能:
//**************************************
void main()
{
ge++;
if(ge==10)
ge=0;
}
while(!key1);
delay(10);
while(!key1);
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0)
{
temp=P3;
switch(temp)
{
temp=temp&0xf0;
while(temp!=0xf0)
{
delay(5);
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0)
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};
//******************变量声明*********************
uchar temp,num,shu;
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
//************************************
//函数名称:显示函数
//函数功能:第一位数码管显示按键次数
//************************************