基于tx-1c的51单片机矩阵键盘检测
矩阵键盘检测
C51矩阵键盘的检测要求:扫描矩阵键盘,并将对应按键的值显示在LED上方法一(传统检测):#include<reg52.h>#define uint unsigned int#define uchar unsigned charsbit dula=P2^6;sbit wela=P2^7;//sbit key1=P3^4;uchar code table[]={//共阳极LED数码管显示数字0~F0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};uchar num,temp,num1;void delay(uint z){uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}uchar keyscan();void display(uchar aa);void main(){while(1){display(keyscan());}}void display(uchar aa){/*先送数,后选通,延时以后,将所有端口都不选通,这样,拖影就消失了*/ dula=1;P0=table[aa-1];dula=0;wela=1;P0=0x01;wela=0;delay(5);wela=1;P0=0x00;wela=0;}uchar keyscan(){P3=0xfe;temp=P3;temp=temp&0xf0;while(temp!=0xf0){delay(5);temp=P3;temp=temp&0xf0;while(temp!=0xf0){temp=P3;switch(temp){case0xee:num=1;break;case0xde:num=2;break;case0xbe:num=3;break;case0x7e:num=4;break;}while(temp!=0xf0){temp=P3;temp=temp&0xf0;}}}P3=0xfd;temp=P3;temp=temp&0xf0;while(temp!=0xf0){delay(5);temp=P3;temp=temp&0xf0;while(temp!=0xf0){temp=P3;switch(temp){case0xed:num=5;break;case0xdd:num=6;break;case0xbd:num=7;break;case0x7d:num=8;break;}while(temp!=0xf0){temp=P3;temp=temp&0xf0;}}}P3=0xfb;temp=P3;temp=temp&0xf0;while(temp!=0xf0){delay(5);temp=P3;temp=temp&0xf0;while(temp!=0xf0){temp=P3;switch(temp){case0xeb:num=9;break;case0xdb:num=10;break;case0xbb:num=11;break;case0x7b:num=12;break;}while(temp!=0xf0){temp=P3;temp=temp&0xf0;}}}P3=0xf7;temp=P3;temp=temp&0xf0;while(temp!=0xf0){delay(5);temp=P3;temp=temp&0xf0;while(temp!=0xf0){temp=P3;switch(temp){case0xe7:num=13;break;case0xd7:num=14;break;case0xb7:num=15;break;case0x77:num=16;break;}while(temp!=0xf0){temp=P3;temp=temp&0xf0;}}}return num;}方法二(技巧检测):#include<reg51.h>#include<intrins.h>sbit dula=P2^6;sbit wela=P2^7;#define uint unsigned int#define uchar unsigned char//uchar code table[10]={0x03,0x9f,0x25,0x0d,0x99,0x49,0x41,0x1f,0x01, 0x09};uchar code table[]={//共阳极LED数码管显示数字0~F0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};uchar Key_Value;void Delay_1ms(uint x){uchar i,j;for(i=0;i<x;i++)for(j=0;j<=148;j++);}void Getkey(){uchar i,j,temp,num,Key_Temp1,Key_Temp2,Buffer[4]={0xfe,0xfd,0xfb, 0xf7};for(j=0;j<4;j++)//循环四次{P3=Buffer[j];_nop_();_nop_();temp=0x10;for(i=0;i<4;i++)//循环四次{if(!(P3&temp)){num=i+j*4;//返回取得的按键值}temp<<=1;//换左边一位}}P3=0xff;Key_Temp1=num;//读入按键if(Key_Temp1<16)//有键按下{Delay_1ms(5);//延时消抖Key_Temp2=num;//再读一次if(Key_Temp1==Key_Temp2)//两次相等Key_Value=Key_Temp1;//就确认下来}}void Display(uchar k){dula=1;P0=table[k];dula=0;wela=1;P0=0x01;wela=0;Delay_1ms(5);wela=1;P0=0x00;wela=0;}void Main(void){while(1){Getkey();Display(Key_Value);//显示键值}}。
51键盘矩阵扫描程序
51键盘矩阵扫描程序假设按下的是S1键进行如下检测(4*4键盘)先在P3口输出p3 00001111低四位行会有变化cord_h =00001111&00001110 =00001110if !=00001111延时0.1uscord_h=00001110&00001111=00001110if !=00001111P3再输出11111110P3 =00001110|11110000=11111110输出高四位cord_l=P3&0xf0 //此时P3口就是(实际值)输入值01111110 而不是上面的11111110cord_l=01111110&11110000=01110000cord_h+cord_l=00001110+01110000=01111110=0x7e //此编码即为S1的编码#include <reg52.h>//包含头文件#define uchar unsigned char#define uint unsigned intunsigned char consttable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//0-Fuchar keyscan(void);void delay(uint i);void main(){uchar key;P2=0x00;//1数码管亮按相应的按键,会显示按键上的字符while(1){key=keyscan();//调用键盘扫描,switch(key){case 0x7e:P0=table[0];break;//0 按下相应的键显示相对应的码值case 0x7d:P0=table[1];break;//1case 0x7b:P0=table[2];break;//2case 0x77:P0=table[3];break;//3case 0xbe:P0=table[4];break;//4case 0xbd:P0=table[5];break;//5case 0xbb:P0=table[6];break;//6case 0xb7:P0=table[7];break;//7case 0xde:P0=table[8];break;//8case 0xdd:P0=table[9];break;//9case 0xdb:P0=table[10];break;//acase 0xd7:P0=table[11];break;//bcase 0xee:P0=table[12];break;//ccase 0xed:P0=table[13];break;//dcase 0xeb:P0=table[14];break;//ecase 0xe7:P0=table[15];break;//f}}}uchar keyscan(void)//键盘扫描函数,使用行列反转扫描法{uchar cord_h,cord_l;//行列值P3=0x0f; //行线输出全为0cord_h=P3&0x0f; //读入列线值if(cord_h!=0x0f) //先检测有无按键按下{delay(100); //去抖cord_h=P3&0x0f; //读入列线值if(cord_h!=0x0f){P3=cord_h|0xf0; //输出当前列线值cord_l=P3&0xf0; //读入行线值return(cord_h+cord_l);//键盘最后组合码值}}return(0xff); //返回该值}void delay(uint i)//延时函数{while(i--);}。
TX-1C 单片机开发板实验
关于按键去抖动的解释,我们在手动按键的时候,由于机械抖动或是其它一些非人为 的因素很有可能会造成误识别,一般手动按下一次键然后接着释放,按键两片金属膜接触的 时间大约为 50ms 左右,在按下瞬间到稳定的时间为 5-10ms,在松开的瞬间到稳定的时间也 为 5-10ms,如果我们在首次检测到键被按下后延时 10ms 左右再去检测,这时如果是干扰 信号将不会被检测到,如果确实是有键被按下,则可确认,以上为按键识别去抖动的原理。
【硬件电路】
25
【程序代码】
#include<reg51.h>
#define uchar unsigned char
uchar j,k,i,a,A1,A2,second; sbit dula=P2^6;
//锁存器控制端定义
sbit wela=P2^7;
uchar code table[]= {
//数字编码
参考程序:
程序一:
ORG 0000H AJMP START
ORG 000BH AJMP TIME0
;定时器 0 的中断向量地址 ;跳转到真正的定时器程序处
ORG 0030H
START:
MOV P1,#0FFH ;关所有灯
MOV TMOD,#00000001B ;定时/计数器 0 工作于方式 1
MOV TH0,#15H
【实验说明】
本开发板上数码管为共阴极。静态数码管显示原理(视频中有详细介绍):这里就共阴极数 码管显示原理进行讲解,一位数码管内一共有 8 个发光二极管,对共阴极来说其 8 个发光二极 管的阴极在数码管内部全部接在一起,也就是“共阴”说法的来源,阳极是独立的,设计电路时 一般把阴极接地,当我们从外部给任一个阳极加一个高电平时这个发光二极管就亮了,如果想要 出一个 8 字,并且把右下角的小数点也点亮的话,那可以给 8 个阳极全送高电平,想让数码管 显示几就给相对应的发光二极管送高电平,因此我们在显示数字的时候首先做的就是给 0-9 十个 数字编好码,在要它亮什么数字的时候直接把这个编码送到它的阳极就行了。另外说一下,一般 的数码管每一段亮至少需要 10 个毫安的电流,而单片机的 IO 口送不出如此大的电流,所以我 们需要加数码管的驱动电路,可以用上拉电阻的方法,也可以使用专门的驱动芯片,本开发板使 用的 74HC573,其输出电流较大,足够点亮数码管。本开发板上的六位数码管中每个相同段号 (段指 a,b,c,d,e,f,g,h)全部是接在一起的,其中每一个位(阴极)是独立的,所以在做静态显 示的时候所有的数码管只能显示相同的数字,当然可以控制哪几位显示,如果让它们显示不同的 数字那就得给每一个数码管加一套驱动电路了。但这样做是没有必要的,后面我们会讲到关于数 码管动态显示原理。
51单片机矩阵键盘行扫描
51单⽚机矩阵键盘⾏扫描————————————————————————————————————————————分类:按结构原理分:触点式开关按键⽆触点开关按键接⼊⽅式独⽴式按键矩阵式键盘————————————————————————————————————————————矩阵式键盘识别⽅法(⾏扫描法)检测列线的状态:列线Y4~Y7置⾼电平,⾏线Y0~Y3置低电平。
只要有⼀列的电平为低,则表⽰键盘该列有⼀个或多个按键被按下。
若所有列线全为⾼电平,则键盘中⽆按键按下。
判断闭合按键所在的位置:⾏线置⾼电平,列线置低电平。
检测⾏线的状态。
举例:当按下第⼀⾏第⼀列的按键时⾏扫描,⾏线为低电平,列线为⾼电平,得到 1110 0000列扫描,⾏线为⾼电平,列线为低电平,得到 0000 1110将得到的结果进⾏或运算,得到 1110 1110,对应第⼀⾏第⼀列,⼗六进制为0xEE按键表⾏列bin hex111110 11100xEE121101 11100xDE131011 11100xBE140111 11100x7E211110 11010xED221101 11010xDD231011 11010xBD240111 11010x7D311110 10110xEB321101 10110xDB331011 10110xBB340111 10110x7B411110 01110xE7421101 01110xD7431011 01110xB7440111 01110x77————————————————————————————————————————————矩阵式键盘应⽤实例实现结果:通过4*4矩阵键盘对应数码管显⽰0~F设计思路:当检测到按键被按下时,将此时⾏扫描的结果存⼊临时变量,再进⾏列扫描,得到的结果和临时变量进⾏或运算。
通过数组存放按键和数码管编码,⾏列扫描得到结果后遍历数组,找到对应的编码位置并显⽰数码管编码实现代码:1 #include <reg52.h>2 typedef unsigned char uchar;3 typedef unsigned int uint;4 uchar code KEY_TABLE[] =5 {60xEE, 0xDE, 0xBE, 0x7E,70xED, 0xDD, 0xBD, 0x7D,80xEB, 0xDB, 0xBB, 0x7B,90xE7, 0xD7, 0xB7, 0x7710 };11 uchar code TABLE[] =12 {130x3F, 0x06, 0x5B, 0x4F,140x66, 0x6D, 0x7D, 0x07,150x7F, 0x6F, 0x77, 0x7C,160x39, 0x5E, 0x79, 0x71,17 };18void Delay(uchar m)19 {20 --m;21 }22void main()23 {24 uchar temp, key, i;25while(1)26 {27 P3 = 0xF0;28if (P3 != 0xF0)29 {30 Delay(2000);31if (P3 != 0xF0)32 {33 temp = P3;34 P3 = 0x0F;35 key = temp | P3;36for (i = 0; i < 16; ++i)37if (key == KEY_TABLE[i])38break;39 P2 = TABLE[i];40 }41 }42 }43 }。
TX-1C单片机实验板使用手册V2.0
基于51单片机的六层电梯c语言矩阵键盘控制系统
#include〈reg51.h〉#define MAXFLOOR 6unsigned char code LEDCODES[]={0x3f,0x06, 0x5b, 0x4f,0x66,0x6d,0x7d}; sbit LEDUP=P3^6;sbit LEDDOWN=P3^7;bit DIRECTION=1,STOP=0;unsigned char CURFLOOR=1;unsigned char DESTFLOOR=1;unsigned char RUN=1;unsigned int timer1=0, timer2=0;unsigned char CALLFLOORUP[7]={0, 0,0, 0, 0, 0, 0};unsigned char CALLFLOORDOWN[7]={0, 0, 0, 0, 0,0,0};unsigned char CALLFLOOR[7]={0, 0,0, 0, 0, 0,0};unsigned char keyscan(void);unsigned char key;void readarray(void);void SELECTNEXT();void step(bit DIRECTION);void DELAY(unsigned int Z);void DELAY2(unsigned int S);void JUDGESIT();void main(void){P0=LEDCODES[1];TH0=0x3C;TL0=0xB0;TMOD=0x01;ET0=1;EA=1;EX0=1;IT0=1;while(1){if(! RUN&&! STOP){SELECTNEXT();step(DIRECTION);}else if(STOP){timer2=0;TR0=1;while(timer2<100&&STOP);TR0=0;timer2=0;STOP=0;}return;}}void SELECTNEXT(){ char n;if(CURFLOOR==MAXFLOOR){DIRECTION=0;}else if(CURFLOOR==1){DIRECTION=1;}if(DIRECTION==0){if(CALLFLOORDOWN[CURFLOOR]){CALLFLOORDOWN[CURFLOOR]=0;STOP=1;return;}for(n=CURFLOOR-1;n〉=1;n——)if(CALLFLOORDOWN[n]){DESTFLOOR=n;return;}for(n=0;n<CURFLOOR;n++)if(CALLFLOORUP[n]){DESTFLOOR=n;return;}DIRECTION=1;for(n=CURFLOOR+1;n<=MAXFLOOR;n++)if(CALLFLOORUP[n]){DESTFLOOR=n;return;}for(n=MAXFLOOR;n>CURFLOOR;n——)if(CALLFLOORDOWN[n]){DESTFLOOR=n;return;}}else{if(CALLFLOORUP[CURFLOOR]){CALLFLOORUP[CURFLOOR]=0;STOP=1;return;}for(n=CURFLOOR+1;n<=MAXFLOOR;n++)if(CALLFLOORUP[n]){DESTFLOOR=n;return;}for(n=MAXFLOOR;n〉CURFLOOR;n——)if(CALLFLOORDOWN[n]){DESTFLOOR=n;return;}DIRECTION=0;for(n=CURFLOOR-1;n〉=1;n——)if(CALLFLOORDOWN[n]){DESTFLOOR=n;return;}for(n=1;n〈=CURFLOOR;n++)if(CALLFLOORDOWN[n]){DESTFLOOR=n;return;}}}void step(bit DIRECTION){if(DESTFLOOR==CURFLOOR)return;else if(! RUN){RUN=1;DELAY(50);if(DIRECTION==1){LEDUP=0;LEDDOWN=1;}else{LEDUP=1;LEDDOWN=0;}timer1=0;TR0=1;}}void DELAY(unsigned int Z){unsigned int X, Y;for(X=Z;X〉0;X-—)for(Y=125;Y>0;Y—-);}void timer0_int() interrupt 1{TH0=0x3C;TL0=0xB0;timer1++;timer2++;if(RUN){if(timer1==20){timer1=0;if(DIRECTION){CURFLOOR++;CALLFLOORUP[CURFLOOR]=0;}else{CURFLOOR—-;CALLFLOORDOWN[CURFLOOR]=0;}RUN=0;TR0=0;P0=LEDCODES[CURFLOOR];if(DESTFLOOR==CURFLOOR){TR0=0;LEDUP=1;LEDDOWN=1;STOP=1;return;}}}}void readarray(void){unsigned char key;while(1){key=keyscan();switch(key){case 0xee:CALLFLOORDOWN[6]=1;break;case 0xed: CALLFLOORUP[5]=1;break;case 0xeb: CALLFLOORDOWN[5]=1;break;case 0xe7: CALLFLOORUP[4]=1;break;case 0xde: CALLFLOORDOWN[4]=1;break;case 0xdd:CALLFLOORUP[3]=1;break;case 0xdb: CALLFLOORDOWN[3]=1;break;case 0xd7: CALLFLOORUP[2]=1;break;case 0xbe: CALLFLOORDOWN[2]=1;break;case 0xbd:CALLFLOORUP[1]=1;break;case 0xbb:CALLFLOORDOWN[6]=1;JUDGESIT();break;case 0xb7:CALLFLOORDOWN[5]=1;JUDGESIT();break;case 0x7e:CALLFLOORDOWN[4]=1;JUDGESIT();break;case 0x7d: CALLFLOORDOWN[3]=1;JUDGESIT();break;case 0x7b:CALLFLOORDOWN[2]=1;JUDGESIT();break;case 0x77: CALLFLOORDOWN[1]=1;JUDGESIT();break;}}}unsigned char keyscan(void) //键盘扫描函数, 使用行列反转扫描法{unsigned char cord_h,cord_l;//行列值中间变量P1=0x0f; //行线输出全为0cord_h=P1&0x0f; //读入列线值if(cord_h!=0x0f) //先检测有无按键按下{DELAY2(100); //去抖if(cord_h! =0x0f){cord_h=P1&0x0f; //读入列线值P1=cord_h|0xf0; //输出当前列线值cord_l=P1&0xf0; //读入行线值return(cord_h+cord_l);//键盘最后组合码值}}return(0xff); //返回该值}void DELAY2(unsigned int S){while(S——);}void JUDGESIT(){char m;for(m=1;m<=MAXFLOOR;m++){if (CALLFLOOR[m]){if (CURFLOOR<=m){CALLFLOORUP[m]=1;CALLFLOOR[m]=0;return;}else{CALLFLOORDOWN[m]=1;CALLFLOOR[m]=0;return;}}}}。
51单片机数码管显示及矩阵键盘扫描程序
51单片机数码管显示及矩阵键盘扫描程序硬件实验十一八段数码管实验一、实验任务1、在静态数码管上轮流显示数字0-9。
2、在两个4位数码管上动态显示数字0-9二、流程图及程序静态显示:流程图:程序代码:#include#define uchar unsigned chucharcodevalue[10]={0xC0,0xF9,0xA4,0xB0,0X99,0x92,0x82,0xF8,0 x80,0x90};//0 -9数码管显示段码void delay(char x) //延时子程序{uchar i;for(i=0;i<200;i++);}main() //主函数{int i;while(1){for(i=0;i<10;i++) //显示0-9{P0=codevalue[i];delay(500); //延时1秒}}}动态显示:#include#includetab1[]={0x3f,0x06,0x5b,0x4f,0x66,0x6D,0x7D,0x07,0x7f,0x6f}; //数码管显示数字字段unsigned char tab2[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//片选字段unsigned char i,k,j,x;void delay(x); //声明延时子函数void main() //主函数{while(1){for(i=0;i<8;i++) //显示0-7{ P1=tab1[i];P0=tab2[i];delay(5); //延时}P1=tab1[8]; P0=tab2[0]; delay(5); //显示8-9P1=tab1[9]; P0=tab2[1]; delay(5);}}void delay(x) //延时函数定义{do{for(j=0;j<250;j++)for(k=0;k<250;k++);}}硬件实验十二矩阵键盘扫描显示一、实验任务1、把矩阵键盘上的按键输入的键码在静态数码管上显示出来。
51单片机矩阵键盘线反转法体会
51 单片机矩阵键盘线反转法体会独立式键盘扫描只需读取10 口状态,而矩阵式键盘描通常有两种实现方法: 逐行扫描法和线反转法。
(1) 逐行扫描法依次从第一至最末行线上发出低电平信号,如果该行线所连接的键没有按下的话,则列线所接的端口得到的是全“1信”号,如果有键按下的话,则得到非全“1信” 号。
(2) 线反转法线反转法比行扫描速度快,原理是先将行线作为输出线,列线作为输入线,行线输出全“0信”号,读入列线的值,那么在闭合键所在的列线上的值必为0;然后从列线输出全“0信”号,再读取行线的输入值,闭合键所在的行线值必为0。
这样,当一个键被按下时,必定可读到一对唯一的行列值。
再由这一对行列值可以求出闭合键所在的位置。
/*在TX-1C实验板上实现如下描述:实验板上电时,数码管不显示,顺序按下矩阵键盘后,在数码管上依次显示0~F, 6个数码管同时显示。
这里用线反转”的方法写,可以代替郭天祥书上例【4.2.1 】该书上使用逐行扫描的方式。
*/#include<reg52.h>#define uchar unsigned char#define uintunsigned intsbit dua n=P2八6;//打开位选和段选sbit wei=P2八7;uchar code table[]={// 数码管显示数值表0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71};void delay(uint x){uint i,j;for(i=x;i>0;i--)for(j=110;j>0;j--);}void xianshi(uchar num){P0=table[num]; duan=1; duan=0;}uchar keyscan(void){uchar h,l;P3=0x0f;h=P3&0x0f;if(h!=0x0f){delay(10);if(h!=0x0f){h=P3&0x0f;P3=0xf0;l=P3&0xf0;return (h+l);}}return 0xff;}void main(){uchar key;P0=0示duan=1;duan=0;// 毫秒级延时函数// 段选显示函数// 矩阵键盘扫描函数// 定义行、列值中间变量// 列线输出全为0// 读入行线// 检测有无按键按下// 延时去抖// 如果确实按下// 再次读入行线// 输出当前列线值,行线反转// 读入列线值// 键盘最后组合编码值,也就是键值// 其余情况返回该值// 关闭所有数码管段选,实验板上电数码管不显PO=OxcO;〃选中6位数码管wei=1;wei=0;while(1){key二keyscan();〃用key 读取keyscan(的值switch(key){case 0xee: key=0;while(keyscan()!=0xff); xianshi(key); break;//while(keyscan()!=0xff) 是松手检测语句,松手时检测case0xde:key=1;while(keysca n()!=Oxff);xia nshi(key);//keysca n(函数会得到返回值0xff,!=oxff 时表示按下去了case 0xbe: key=2;while(keyscan()!=0xff); xianshi(key); break;case 0x7e: key=3;while(keyscan()!=0xff); xianshi(key); break;case 0xed: key=4;while(keyscan()!=0xff); xianshi(key); break;case 0xdd: key=5;while(keyscan()!=0xff); xianshi(key); break;case 0xbd: key=6;while(keyscan()!=0xff); xianshi(key); break;case 0x7d: key=7;while(keyscan()!=0xff); xianshi(key); break;case 0xeb: key=8;while(keyscan()!=0xff); xianshi(key); break;case 0xdb: key=9;while(keyscan()!=0xff); xianshi(key); break;case 0xbb:key=10; while(keyscan()!=0xff); xianshi(key); break; case 0x7b:key=11; while(keyscan()!=0xff); xianshi(key); break;case 0xe7: key=12; while(keyscan()!=0xff); xianshi(key); break;case 0xd7: key=13; while(keyscan()!=0xff); xianshi(key); break;case 0xb7: key=14; while(keyscan()!=0xff); xianshi(key); break;case 0x77: key=15; while(keyscan()!=0xff); xianshi(key); break; default: break;}}}/* 后记*//*刚开始写这个程序时我把主函数里面的switch —case语句这样写的, while(1){key二keyscan();〃用key 读取keyscan()的值switch(key){case 0xee: key=0;break;case 0xde:key=1;break;case 0xbe:key=2;break;break;}case 0x7e: key=3;break;case 0xed:key=4;break;case 0xdd:key=5;break;case 0xbd: key=6;break;case 0x7d: key=7;break;case 0xeb: key=8;break;case 0xdb: key=9;break;case 0xbb: key=10; break;case 0x7b:key=11; break;case 0xe7: key=12; break; case 0xd7: key=13; break; case 0xb7: key=14; break;case 0x77: key=15; break; default:break;}xianshi(key);运行程序后发现当手按下按键时会有数码的显示,但是一旦放开按键数码管就什么都不显示了。
51单片机的矩阵按键扫描的设计C语言程序
#include <reg51.h>#define KEY P1// ----------------------- 变量声明-------------------------------------------------------------------- void program_SCANkey(); // 程序扫描键盘 ,供主程序调用void delay(unsigned int N) ;// 延时子程序,实现 (16*N+24)us 的延时bitjudge_hitkey();// 判断是否有键按下,有返回 1,没 有返回 0void key_manage(unsigned char keycode); //键盘散转////函数名称:program_SCANkey//函数声明,变量定义unsigned char scan_key();表行,低四位代表列 )// 扫描键盘,返回键值 (高四位代void manage_key1(void);// 按键 1 处理程序 void manage_key2(void);// 按键 2 处理程序 void manage_key3(void);// 按键 3 处理程序 void manage_key4(void);// 按键 4 处理程序 //每个按键对应一个处理程序,这里// 函数功能:程序扫描键盘,// 有键按下完成按键处理,无键按下直接返回// -------------------------------------------------------------------------------------------------- void program_SCANkey(){unsigned char key_code;----------------------------------------------------------------- //函数名称: delay //入口参数:N//函数功能:延时子程序,实现(16*N+24)us 的延时// 系统采用11.0592MHz 的时钟时,延时满足要求,其它情况需要改动// --------------------------------------------------------------------------------------------------void delay(unsigned int N){int i;for(i=0;i<N;i++);}// --------------------// 函数名称:system_init()if(judge_hitkey())(1000);if(judge_hitkey())while(judge_hitkey());key_manage(key_code);// ------------------------------// 判断是否有键按下 {delay //延时20ms 左右,消除抖动干扰 //判断是否有效按键 {key_code=scan_key (;) // 等待按键释放 // 键盘扫描、键盘散转、按键处理 }}}// 函数功能:初始化设置// 设定INT0、INT1 及T0、T1的工作方式// --------------------------------------------------------------------------------------------------/* void system」nit(void ){TMOD=0x55;〃定时器1和定时器0工作在方式1,的计数模式TR0=1; //定时器 1 和定时器0开始计数TR1=1;ET0=1; //定时器1 和定时器0中断允许ET1=1;IT1=0; //选择INTO和INT1为电平触发方式IT0=0;EX0=1; //外部中断允许EX1=0;EA=1; // 系统中断允许}// --------------------------------------------------------------// 函数名称:INT0_intrupt// 函数功能:外部中断0 处理程序//void INT0_intrupt() interrupt 0 using 1{EA=0; // 系统中断禁止delay(1000); // 键盘消抖动if(INT_0==0) // 判断是否干扰{ // 的确有健按下while(INT_O==O);〃等待键盘释放delay(1000); //键盘消抖动manage_key1();}EA=1;}*/// -------------------------------------------------------------------------------------------------- // 函数名称:judge_hitkey// 函数功能:// 判断是否有键按下,有返回1,没有返回0// --------------------------------------------------------------------------------------------------bitjudge_hitkey() // 判断是否有键按下,有返回1,没有返回0{unsigned char scancode,keycode;scancode=0xff; //P1.4~P1.7 输出全 1 则无键闭合 KEY=scancode;// 函数名称:scan_key// 函数功能:// 扫描键盘,返回键值 (高四位代表行,低四位代表列 )// ----------------------------- unsignedcharscan_key() // 扫描键盘,返回键值 (高四位代表 行,低四位代表列 ){unsigned char scancode,keycode;scancode=0xef; // 键盘扫描码,采用逐行扫描的方法 while(scancode!=0xff){KEY=scancode; // 输入扫描 码,扫描 P1.4 对应的行keycode=KEY;1.0~P1.3 的状态if(keycode==0xff)return(0);elsereturn(1);// 读 P // 全 1 则无键闭合 //否则有键闭合 }//if((keycode&0x0f)!=0x0f)keycode=~keycode;return(keycode);}// --------------------------------------------------------------------------- // 函数名称:key_manage// 入口参数:keycode 扫描键盘返回的键值 (高四位代表行,低四位代表列 )// 函数功能: 键盘散转// -------------------------------------------------------------------------------------------------- void key_manage(unsigned char keycode){switch(keycode){case 0x11:manage_key1();break;case 0x12: manage_key2();break;case 0x14: manage_key3();break;case 0x18: manage_key4();break;case 0x21:manage_key5();break;case 0x22: manage_key6();break;case 0x24: manage_key7();break;case 0x28: manage_key8();break;keycode=KEY;列键盘被按下// 读出数据,看是否在此行上的某 break; scancode=(keycode<<1)|0x0f;// 扫描到按下的键,则退出// 否则,更新扫描码继续扫描 }case 0x41:manage_key9();break;case 0x42: manage_key10();break;case 0x44: manage_key11();break;case 0x48: manage_key12();break;case 0x81:manage_key13();break;case 0x82: manage_key14();break;case 0x84: manage_key15();break;case 0x88: manage_key16();break;// default:}}// -------------------------------------------------------------------------------------------------- // 函数名称:manage_key1// 函数功能:按键 1 处理程序// -------------------------------------------------------------------------------------------------- void manage_key1(void){}程序扫描键盘,有键按下完成按键处理,无键按下直接返回。
TX-1C扩展版单片机开发系统介绍
TX-1C扩展版单片机开发系统介绍一.C51系列单片机实验板(直接USB口和串口两种方式直接下载程序和在线仿真调试) 本实验板使用的是STC公司生产的STC89C52RC单片机,它是一款性价比非常高的单片机,普通用户可完全将其当作一般的51单片机使用,高级用户可使用其扩展功能,STC公司的单片机内部资源比起ATMEL公司的单片机来要丰富的多,它内部有1280字节的SRAM、8-64K字节的内部程序存储器、2-8K字节的ISP引导码、除P0-P3口外还多P4口(PLCC封装)、片内自带8路8位AD(AD系列),片内自带EEPROM、片机自带看门狗、双数据指针等。
目前STC公司的单片机在国内市场上的占有率与日俱增。
TX系列单片机学习板可完全作为各种51单片机的实验板,用汇编语言或C语言对其进行编程。
通过板上USB程序下载接口可直接通过计算机的USB口下载程序给单片机,同时也支持USB口在线仿真调试功能。
二.TX-1C扩展版实验板基本配置及功能介绍1、6位数码管(做数码管动态扫描及静态显示实验)。
2、4*4矩阵键盘及四个独立键盘(键盘检测试验)。
3、8位LED发光二极管(做流水灯实验)。
4、串口RS232通讯接口(可以作为与计算机通讯的接口同时也可作为该实验板下载程序及仿真调试的接口).5、USB供电系统,可以使用外接电源扩展口供电。
6、蜂鸣器(做单片机发声实验)7、一路继电器输出,有了它我们就可以知道怎么来做一个以弱控强的系统。
8、ADC0804芯片(做模数转换实验)。
9、DAC0832芯片(做数模转换实验) 。
10、一体化 高灵敏度红外接收头,可以做红外线解码实验,红外线遥控器等等,酷!!!配合遥控器完成遥控解码及红外遥控实验。
如:按遥控器的数字键1——8,即可点亮实验板上的第一个发光管至第八个发光管。
当然,你也可以通过改动程序来达到红外遥控其它资源的目的。
11、DS18B20数字温度传感器(亲自编写程序获知当前温度)12、AT24C02 外部EEPROM芯片(IIC总线数据存储元件原理实验)。
基于51单片机的矩阵键盘
case 4:wei_1=0;wei_2=1;wei_3=1;wei_4=1;break;
}
delay_ms(2)
P0=0x00;
//每次显示完后都要消隐,这非常重要!这句一缺数码管就会闪屏
wei_1=1;wei_2=1;wei_3=1;wei_4=1;
if(temp==1)key=key+0;
else if(temp==2)key=key+1;
if(temp==4)key=key+2;
else if(temp==8)key=key+3;
}
void led_init()
{
wei_1=1;wei_2=1;wei_3=1;wei_4=1;
P0=0x00;
break;
}
if(key_putdown())//这个if是转到第一个while的必要条件
break;
}
}
}
}
void main()
{
wei=1;
control=0;
led_init();
if(key_putdown())
while(1)
//这里用了两个while(1)嵌套
{
key_scan();
key_tem[control++]=key;
if(control==5){led_init();control=0;}
}
void led_disp(uchar wei2,uchar num)
{
P0=table[num];
switch(wei2)
51单片机_矩阵按键检测
}
returnk;//返回扫描到的键值
}
void main()
{
int num=0, tmp;
while(1)
{
tmp = MatrixKeyscan();//扫描键盘判断是否有按键按下
if(tmp != -1) num = tmp;//当有按键按下时,将键值赋给num(无键按下时扫描键盘返回值-1)
《51系列单片机_矩阵按键检测》
此程序使用单片机89SC52
//1、此程序实现矩阵按键的检测功能,按下按键时,数码管显示按键的相应键值
#include<reg52.h>
voiddelay_ms(int n)//延时函数,延时n毫秒
{
inti, j;
for(i=0; i<n; i++)
for(j=0; j<110; j++);
}
voiddisplay(int num)//控制数码管按位输出显示数值num
{
charBitSet[8] =
{
0x7f, 0xbf, 0xdf, 0xef,
0xf7, 0xfb, 0xfd, 0xfe
};//用于设置(低电平位选)数码管的位选信号,从低到高对应8个数码管
charNumberCode[16] =
for(i=0; i<4; i++)
{
P1 = line[i];//将行扫描值逐个送至P1端口
tmp = P1;//再读取P1口的值
if(tmp != line[i])//若读取的数值不等于送入的行扫描值,表示有按键被按下
{
delay_ms(10);//延时,重新读取判断,确认有键按下
基于MCS-51单片机的独立按键和矩阵按键检测实验
实验三基于MCS-51单片机的独立按键和矩阵按键检测实验一、支撑课程目标目标1:掌握微机和单片机的基本原理、编程技术、中断技术、系统扩展、定时器、串行接口和其他输入/输出接口技术,并且了解典型的单片机应用系统的设计思想和实现方法。
目标2:初步具备自行拟定实验步骤、检查和故障排除、分析和综合实验结果以及撰写实验报告的能力。
目标4:掌握MCS-51单片机/STM32F103单片机系统仿真工具和仿真流程,了解常用实验仪器、设备的基本工作原理,了解其正确使用方法,具备利用电子仪器设备和专业仿真软件对复杂工程问题进行分析和设计的能力。
二、实验类型:验证型( )、设计型(√)、研究创新型()三、预期学生学习的成果1、具有典型按键检测电路原理及消除抖动的必要性的认知。
2、理解程序设计消除抖动的实现过程。
3、掌握独立按键的程序查询检测编程实现。
4、掌握独立按键的中断检测编程实现。
5、理解矩阵键盘的行列扫描检测原理,具有矩阵键盘软硬件设计综合能力。
四、实验原理1、典型按键检测电路典型的按键检测电路具备检测按键的条件:检测引脚处在键按下前和后,要有电平变化,否则按键无法检测。
电路组成包括电源、上拉电阻、按键、接地组成,按下前,检测引脚高电平,按下后检测引脚低电平。
电阻防止按下电源短路,如图1(a)。
GND(a)(b)图 1 按键典型电路及对应检测电压2、按键抖动及消除如图1(b),理想条件下,按键未按下,在检测I/O端口是高电平,按下以后,检测I/O端口是低电平,手松后,按键弹起,检测I/O端口是高电平。
整个按键过程出现高电平到低电平又到高电平,有下降沿,也有上升沿。
实际过程中,由于人手的抖动,检测端电压如图1(c),检测电压出现“毛刺”抖动,假设单片机检测高电平阈值为VH,低电平阈值为VL,一次按键就会出现多次高电平到低电平变化,存在按键误检测可能。
常用消除办法之一:一旦检测到低电平,延迟u毫秒,u选择大于20,再次判断检测端是否是低电平,如果是,就判定为1次按键。
51单片机的矩阵按键扫描的设计C语言程序
51单片机的矩阵按键扫描的设计C语言程序以下为一个基于51单片机的矩阵按键扫描的设计C语言程序:```c#include <reg51.h>//定义端口连接到矩阵键盘sbit col1 = P2^0;sbit col2 = P2^1;sbit col3 = P2^2;sbit row1 = P2^3;sbit row2 = P2^4;sbit row3 = P2^5;sbit row4 = P2^6;//声明按键函数char read_keypad(;void maiwhile (1)char key = read_keypad(; // 读取按键值//根据按键值进行相应操作switch(key)case '1'://第一行第一列按键逻辑//在此处添加相应的代码break;case '2'://第一行第二列按键逻辑//在此处添加相应的代码break;//继续处理其他按键//...default://未识别到按键break;}}//按键扫描函数char read_keypacol1 = 0; col2 = 1; col3 = 1; // 激活第一列if (row1 == 0) { // 第一行第一列按键被按下while (row1 == 0); //等待按键释放return '1'; // 返回按键值}if (row2 == 0) { // 第二行第一列按键被按下while (row2 == 0); //等待按键释放return '4'; // 返回按键值}if (row3 == 0) { // 第三行第一列按键被按下while (row3 == 0); //等待按键释放return '7'; // 返回按键值}if (row4 == 0) { // 第四行第一列按键被按下while (row4 == 0); //等待按键释放return '*'; // 返回按键值}col1 = 1; col2 = 0; col3 = 1; // 激活第二列//处理第二列的按键逻辑//...col1 = 1; col2 = 1; col3 = 0; // 激活第三列//处理第三列的按键逻辑//...return '\0'; // 返回空字符表示未检测到按键```以上代码中,我们使用51单片机的P2端口连接到矩阵键盘的列和行,通过扫描不同的列和检测行的状态来判断按键是否被按下。
(word完整版)基于51单片机状态机矩阵键盘扫描数码管动态显示的时钟系统
/******************************************************************************程序功能:基于状态机的线性反转扫描方法实现按键扫描数码管动态显示开发环境:KeiL4硬件环境:STC12C5A60S2,11.0592接线说明:单片机P1口接底板JP29,具体接法为:P10—L1,P11—L2,P12—L3,P13-L4,P14-L5,P15-L6,P16-L7,P17-L8单片机P20~P21接底板JP26,具体接法:P20—DS,P21—SHCP,P22-STCP跳线说明:J70实验现象:数码管动态显示时钟时间同时显示当前被按下的键值可通过矩阵键盘对时钟进行开关已经参数调试******************************************************************************/#include <REG52。
h>typedef unsigned char uint8;typedef unsigned int uint16;#define KEY_PORT P1 //定义4x4键盘使用的单片机端口sbit SEG_DS = P2^0;//74HC595芯片的数据引脚sbit SEG_SHCP = P2^1;//74HC595芯片的控制引脚,上升沿移入数据sbit SEG_STCP = P2^2; //74HC595芯片的控制引脚,上升沿更新数据//*****************************************************************************//全局变量//*****************************************************************************char hour,min,sec; // 秒分时uint8 Clock_flag; //时钟开关标志位uint8 ct_flag;//按键长按标志位 //*****************************************************************************//反转法矩阵键盘的各个按键的计算值unsigned char tabLe[]={0xee,//00xed,//10xeb,//20xe7,//30xde,//40xdd,//50xdb,//60xd7,//70xbe,//80xbd,//90xbb,//100xb7,//110x7e,//120x7d,//130x7b,//140x77 //15};//共阳数码管的编码,并将数据定义在CODE区unsigned char code Seg_Data[]={0xc0,/*0*/0xF9,/*1*/0xA4,/*2*/0xB0,/*3*/0x99,/*4*/0x92,/*5*/0x82,/*6*/0xF8,/*7*/0x80,/*8*/0x90,/*9*/0x88,/*A*/0x83,/*b*/0xC6,/*C*/0xA1,/*d*/0x86,/*E*/0x8E,/*F*/};//数码管位选编码,控制显示8位中的第几位unsigned char code Seg_Addr[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0xFF,//ALL ON0x00 //OFF};//*****************************************************************************//函数声明//*****************************************************************************void SEG_Send595OneByte(unsigned char ucData); //向74HC595写入一个8位的数据//指定数码管显示定数字void DispLayOneCharOnAddr(unsigned char Data,unsigned char Addr);unsigned char Key_Scan(void); //基于状态机的按键扫描void Parameter_Setting(uint8 key_value_get); //按键参数设置void Timer0Configuration(); //定时器初始化void CLOCK(void); //时钟运行函数//*****************************************************************************//*****************************************************************************//*****************************************************************************//定时器0中断服务函数//*****************************************************************************void Timer0() interrupt 1{uint8 key_get,j;static uint8 i=0,key_value;static uint16 count=0;TH0 = (65536-922)/256;TL0 = (65536-922)%256;/***********************用户代码************************************/count++;if(962==count) //一秒运行一次时钟{if(Clock_flag)CLOCK(); //时钟走一次count=0; //定时计数清零}switch(i){case 0:i++;DispLayOneCharOnAddr(hour/10,0) ; //数码管动态显示第一位break;case 1:i++;DispLayOneCharOnAddr(hour%10,1) ; //数码管动态显示第二位break;case 2:i++;DispLayOneCharOnAddr(min/10,2);//数码管动态显示第三位break;case 3:i++;DispLayOneCharOnAddr(min%10,3) ; //数码管动态显示第四位break;case 4:i++;DispLayOneCharOnAddr(sec/10,4); //数码管动态显示第五位break;case 5:i++;DispLayOneCharOnAddr(sec%10,5) ; //数码管动态显示第六位break;case 6:i++;DispLayOneCharOnAddr(key_value,6); //数码管动态显示第七位break;case 7:i++; //数码管动态显示第八位break;case 8: i=0;key_get=Key_Scan(); //状态机按键扫描每9ms进行一次扫描(word完整版)基于51单片机状态机矩阵键盘扫描数码管动态显示的时钟系统 if(key_get) //按键没按下返回零{for(j=0;j<16;j++){if(key_get==tabLe[j]) //通过查表得出按键的号{key_value=j;break;}}Parameter_Setting(key_value); //按键参数调试函数输入按键号}break;default:break;}}//*****************************************************************************//主函数//*****************************************************************************void main(void){EA=0; //关总中断Timer0Configuration(); //定时器0初始化 1ms中断EA=1; //开总中断while(1) //循环等待中断到来{}}//***************************************************************************** //*****************************************************************************//向HC595发送一个字节void SEG_Send595OneByte(unsigned char ucData){unsigned char i;for(i = 0;i < 8;i++) //8位数据依次写入,先写最低位{SEG_DS = (ucData & 0x80);//先读入高位 x&0x80;SEG_SHCP = 0;SEG_SHCP = 1;SEG_SHCP = 0; //SHCP引脚的上升沿移入数据ucData <〈=1; //数据左移}}(word完整版)基于51单片机状态机矩阵键盘扫描数码管动态显示的时钟系统/*******************************************************函数功能:在指定位置显示一个数据参数说明:Data是要显示的数据,Addr是在第几位显示.Addr取值范围是0~9。
基于51单片机矩阵键盘程序
j=0;
for(k=0;k{
P3=table[k];//P3接有一排指示灯
delay (1000);//延时1S
}
}
}
}
主程序2:
main(){
int i,j,a[2][5]={10,15,25,15,75,15,45,65,85,95};
for(i=0;ifor(j=0;jprintf(“%d“,a[i][j]);
}
printf(“\n”);
}
主程序3:
由键盘输入一个3×4矩阵a,选出各列最小的元素组成一个一维数组b并输
出
由键盘输入一个3×4矩阵a,选出各列最小的元素组成一个一维数组b并输
出
#include“stdio.h”
#include“conio.h”
void main()
{
int i,j,a[3][4],b[4],min;
基于51单片机矩阵键盘程序
主程序1:
void main(){uch来自r i,j,ki=0;
j=0;
while(1)
{
i=key();//键盘循环扫描,其值赋给变量数组table
if(i!=0)//键盘子程序返回值非0,即有按键按下
{
table[j]=i;//将值存在变量数组中
j++;
}
if(j==6)
for(i=0;ifor(j=0;jscanf(“%d”,&a[i][j]);
for(i=0;ib[i]=a[0][i];
for(i=0;ifor(j=1;jif(a[i][j]for(i=0;iprintf(“%d”,b[i]);
getch();
}
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
基于tx-1c单片机的矩阵键盘的检测
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit dula=P2^6;//定义段选
sbit wela=P2^7;//定义位选
uchar code str[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71,
0};//数码管显示的字符
uchar num,num1,temp;
void delay(uchar z)
{
uchar i,j;
for(i=z;i>0;i--)
for(j=110;j>0;j--);
}//延时函数
uchar keyscan()
{
P3=0xfe;//对P3口赋初值,给矩阵键盘第一行通低电平
temp=P3;//将P3口值转给temp
temp=temp&0xf0;//将temp值与0xf0与运算,看哪一位变为低电平
while(temp!=0xf0)
{
delay(5);//延时
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0)//检测是否真的按下按键
{
switch(temp)//判断键位
{
case 0xe0:num=0;
break;
case 0xd0:num=1;
break;
case 0xb0:num=2;
break;
case 0x70:num=3;
break;
}
break;//跳出循环
}
break;//跳出循环
}//以下同上
P3=0xfd;
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0)
{
delay(5);
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0)
{
switch(temp)
{
case 0xe0:num=4;
break;
case 0xd0:num=5;
break;
case 0xb0:num=6;
break;
case 0x70:num=7;
break;
}
break;
}
break;
}
P3=0xfb;
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0)
{
delay(5);
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0)
{
switch(temp)
{
case 0xe0:num=8;
break;
case 0xd0:num=9;
break;
case 0xb0:num=10;
break;
case 0x70:num=11;
break;
}
break;
}
break;
}
P3=0xf7;
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0)
{
delay(5);
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0)
{
switch(temp)
{
case 0xe0:num=12;
break;
case 0xd0:num=13;
break;
case 0xb0:num=14;
break;
case 0x70:num=15;
break;
}
break;
}
break;
}
return num;
}
void main()
{
num=16;
wela=1;
P0=0x00;//所有数码管打开
wela=0;
while(1)
{
num1=keyscan();
dula=1;
P0=str[num1];//显示返回的num
dula=0;
}
}。