矩阵键盘状态机之74HC164驱动数码管依次显示键值

合集下载

单片机C语言程序设计:数码管显示4X4矩阵键盘按键号

单片机C语言程序设计:数码管显示4X4矩阵键盘按键号
单片机 C 语言程序设计:数码管显示 4X4 矩阵键盘
按键号
/* 名称:数码管显示 4X4 矩阵 键盘按键号 说明:按下任意键时,数码 管都会显示其键的序号,扫描程 序首先判断按键发生在哪一列, 然后根据所发生的行附加不同的 值,从而得到按键的序号。 */ #include #defineucharunsignedchar
BEEP=0; while(1) { P1=0xf0; if(P1!=0xf0)Keys_Scan(); //获取键序号 if(Pre_KeyNo!=KeyNo) { P0=~DSY_CODE[KeyNo]; Beep(); Pre_KeyNo=KeyNo; } Del KeyNo=1;break; case4:KeyNo=2;break; case8: KeyNo=3;break; default:KeyNo=16;//无键按下 } P1=0xf0;//低 4 位置 0,放入 4 列 DelayMS(1); Tmp=P1>>4x0f;//按键后 f0 变成 XXXX0000,X 中有 1 个为 0,三个仍为 1;高 4 位转移到低 4 位并 异或得到改变的值 switch(Tmp)//对 0~3 行分别附加起始值 0,4,8,12 { case1: KeyNo+=0;break;
} 扩展阅读:4X4 矩阵键盘控制条形 LED 显示程序
case2: KeyNo+=4;break; case4: KeyNo+=8;break; case8: KeyNo+=12; } } //蜂鸣器 voidBeep() { uchari; for(i=0;i {
DelayMS(1); BEEP=~BEEP; } BEEP=0; } //主程序 voidmain() { P0=0x00;

74HC164应用实例:驱动数码管两例(电路图和源程序)

74HC164应用实例:驱动数码管两例(电路图和源程序)

74HC164应用实例:驱动数码管两例(电路图和源程序)————————————————————————————————作者:————————————————————————————————日期:4HC164应用实例:驱动数码管两例(电路图和源程序) 文章编号:100816210758 文章分类: 电路 > 电子元件 点击:... 关键词: 74HC164文章来源:百合电子工作室收集整理 摘要: 74HC164应用实例:驱动数码管的两个实例分别提供了汇编源程序和C 源程序...实例174HC164是串行输入,并行输出接口器件,可用在单向的并行输出/并行地址锁存等. 74HC164因为价格便宜,容易使用特别适合使用在在需要用到数码管显示IO 口又比较紧张的电子产品中,下面浅谈使用方法:1. 首先先了解他的引脚功能和逻辑图,如下图:图1 引脚名称和用途图2 真值表通过真值表我们可以了解到,A,B两个输入端是互锁的,CLK上升沿时数据移入移位寄存器中,CLEAR为清零用的,接低电平时所有端口都输出低电平,了解了真值表之后开始运用了,先给出如下原理图:图3 原理图图中,采用义隆的EM78P153作为控制芯片,P50作为CLK时钟信号,注意平时数据不传输时,时钟信号是不发送的应一直保持低电平或者高电平,数据需要传输的时候才输出时钟信号^_^ ,继续P51作为移位数据输出端,接到74HC164的B端,A端接高电平,当然也可以AB端短路,然后连接到DATA移位数据端,P52作为数码管的选通信号(也可以叫消隐^_^), 作用是使数据传输过程暂时关闭显示,以免显示出不需要的数据,原因是应为164不带锁存功能,数据传输过程是一位一位的向高位移位输出的,所以要等数据全部移入后才打开始点亮数码管.注意了哦,通过查看164的规格书发现,164输出高电平电流比输出低电平电流要小,亦称灌电流大,扇出电流弱,所以适合选用共阳数码管,如图,本人偷懒没有画出那个数码管的8字该介绍的介绍的差不多了,废话少说,该开始干活了,任务是: 显示0-9 每秒+1 ,到9后又返回0,一直循环显示,根据任务得到如下流程图:1. 显示部分:将需要显示的数值送入A ==>查表求得显示段码==>将段码逐位移入164==>8位移完后点亮数码管==>延时==>返回第一步执行2. 中断部分:进入中断==>保存现场(以备调查取证,送你入狱^_^)==>重置TCC==>够1秒钟将需要显示的数据+1,并重置,不够就退出;根据以上要求就开始写代码调试了,要注意一点,数据移位时一定要记得高位在前哦,否则显示错误别怪我没有说清楚,我当年实验时就因为这个数据移位方向反了排查了半天,甚至以为是时钟频率不对,又以为时许不对.....搞了半天,NND后来重看DATASHEET才发现,原来是低级错误啊,呜呼哀哉.......,希望你不要重蹈我覆辙,哎哟!! 谁! 谁! 谁扔砖头上来? 啥? 你扔的? 我废话太多.........,那俺少来两句,继续上菜, 咦好像没啥可说的了,上源程序吧1.;中断部分:2.3.;;;;;;;;;;中断;;;;;;;;4.INTPUT:5.MOV TEMPA, A;6.MOV A,@130;7.MOV TCC,A;255-130=1258.CLR RF;9.;;;;;此处填写250Us处理程序10. BS WKREG,T500US11.;;;;;;;;;;;;;;;;;;;;;;;;;12. DJZ R1MS13.JMP INTEXT;14.MOV A,@415.MOV R1MS,A;重置16. BS WKREG,T1MS17.;;;;;;;此处填写1ms处理程序18.19.;;;;;;;;;;;;;;;;;;;;;;;;;;20. DJZ R20MS21.JMP INTEXT;22.MOV A,@2023.MOV R20MS,A;重置24.;;;此处填写1秒处理程序25. BS WKREG,T20MS26.;;;;;;;;;;;;;;27. DJZ R1S28.JMP INTEXT;29.MOV A,@5030.MOV R1S,A;31.;;;;;;;;;32.INC NUMBER33.MOV A,NUMBER34. SUB A,@1035. JBS SR,236.JMP INTEXT37.MOV A,@038.MOV NUMBER,A39.40.41. INTEXT:42.MOV A,TEMPA;43.RETI;;;;;;;;;;;;;;;;;;;;;44.45.46.47.48.49.;显示部分:50.51.;==============TXDATA==============52.TXDATA:53. BS P5,CC154.MOV A,@855.MOV DATALOP,A;56.TXLOP:57. BC WKREG,T500US58. BS P5,CLK;clk=高59.NOP;60.NOP61. JBS DATA_BUF,762.JMP $+363. BS P5,DATA;64.JMP $+265. BC P5,DATA66.DD1MS: JBS WKREG,T500US67.JMP $-168. BC P5,CLK69. BC WKREG,T500US70. JBS WKREG,T500US71.JMP $-1;72.RLC DATA_BUF73. DJZ DATALOP74.JMP TXLOP75.;;;;;;;;;;76. BC WKREG,T500US77. BS P5,CLK;clk=高78. BC WKREG,T500US79. JBS WKREG,T500US80.JMP $-1;81. BC P5,CLK82.;;;;;;;;83. BC P5,CC184.85.RET;;;;;;;86.87.;数据查表88.;===============DSPTBL============89.DSPTBL: ADD PC,A90. RETL @0B01000000;091. RETL @0B01111001;192. RETL @0B00100100;293. RETL @0B00110000;394. RETL @0B00011001;495. RETL @0B00010010;596. RETL @0B00000010;697. RETL @0B01111000;798. RETL @0B00000000;899. RETL @0B00010000;9100.101.102.;循环体部分;103.104.;;;;;;;;;;主程序;;;;;;;;;;;105.MLOOP:106.MOV A,NUMBER107.CALL DSPTBL108.MOV DATA_BUF,A109.CALL TXDATA110. BC WKREG,T1MS111. JBS WKREG,T1MS112.JMP $-1113.NOP;114.115.JMP MLOOP;;;;;;;;;;;;;;;;;;;;实例2在实际应用中驱动数码管常用的方式分动态扫描和静态驱动。

三分钟让你掌握51单片机的4×4键盘识别与74LS164驱动数码显示

三分钟让你掌握51单片机的4×4键盘识别与74LS164驱动数码显示
D2:MOV R6,#2
D1:MOV R7,#248
DJNZ R7,$
DJNZ R6,D1
DJNZ R5,D2
RET
;---------------------------------------
END
RET
;-------------------------
K_ED:;有键按下
MOV 60H,R2 ;保存按键号码
CALL DELAY ;消除抖动
WAIT:
MOV P1,#0F0H
MOV A,P1
CJNE A,#0F0H,WAIT ;等待释放
CLR A
RET
;-------------------------
D_TAB:;段码表
DB 03FH,006H,05BH,04FH
DB 066H,06DH,07DH,007H
DB 07FH,06FH,077H,07CH
DB 039H,05EH,079H,071H,000H
;---------------------------------------
K_SCAN:
KEY_TAB:;键码表
DB 07EH,0BEH,0DEH,0EEH
DB 07DH,0BDH,0DDH,0EDH
DB 07BH,0BBH,0DBH,0EBH
DB 077H,0B7H,0D7H,0E7H
;---------------------------------------
DELAY:;延时
MOV R5,#10
MOV DPTR,#D_TAB ;码表首地址
MOVC A,@A + DPTR
CPL A
MOV R2,#8
INI1:

矩阵键盘 数码管显示

矩阵键盘 数码管显示

/****************************************************************************** **** 【函数功能】:矩阵键盘数码管显示* 【晶振】: 11.0592M* 【使用说明】:依次按下矩阵键盘的16个按键数码管上会显示1-16数字使用usb下载时,矩阵键盘B2按键会受到影响解决办法:取下下载选择2个红色短路帽即可******************************************************************************* ***//*预处理命令*/#include<reg52.h> //包含单片机寄存器的头文件#define uchar unsigned char#define uint unsigned int/* 函数申明-----------------------------------------------*/void delay(uint z);uint scan(void);void send595(uchar dat);void out595(void);void disp(uchar w,uchar d);void dispoff(void);/* 变量定义-----------------------------------------------*/sbit MOSIO=P2^2;sbit R_CLKa=P2^3;sbit S_CLKa=P2^4;uchar code duan[]={~0x3F,~0x06,~0x5B,~0x4F,~0x66,~0x6D,~0x7D,~0x07,~0x7F,~0x6F};//此表为LED数码管段选字模uchar code wei[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; //此表为LED数码管位选字模uchar num_key; //扫描按键计数uint num;/******************************************************************************** *** 函数名称:main(void)** 函数功能:主函数******************************************************************************* **/void main(){uint shi,ge;uint numb;while(1){ dispoff();numb=scan(); //调用键盘扫描if(numb<10){disp(6,0);delay(8);disp(7,numb);delay(8);}else{shi=numb/10;ge=numb%10;disp(6,shi);delay(8);disp(7,ge);delay(8);}}}/******************************************************************************** *** 函数名称:delay(uint z)** 函数功能:延时函数******************************************************************************* **/void delay(uint z){uint i,j;for(i=z;i>0;i--)for(j=100;j>0;j--);}/*********************************************************************************** 函数名称:scan(void)** 函数功能:按键扫描******************************************************************************* **/uint scan(void){uint num;P3=0xf7; //扫描第四排num_key=P3;num_key=num_key&0xf0;if(num_key!=0xf0){delay(5);P3=0xf7; //去抖动num_key=P3;num_key=num_key&0xf0;if(num_key!=0xf0)num_key=num_key|0x07;while(P3 !=0xf7){}}else{P3=0xfb; //扫描第三排num_key=P3;num_key=num_key&0xf0;if(num_key!=0xf0){delay(5);P3=0xfb; //去抖动num_key=P3;num_key=num_key&0xf0;if(num_key!=0xf0)num_key=num_key|0x0b;// while(P3 !=0xfb){}}else{P3=0xfd; //扫描第二排num_key=P3;num_key=num_key&0xf0;if(num_key!=0xf0){delay(5);P3=0xfd; //去抖动num_key=P3;num_key=num_key&0xf0;if(num_key!=0xf0)num_key=num_key|0x0d;// while(P3 !=0xfd){}}else{P3=0xfe; //扫描第一排num_key=P3;num_key=num_key&0xf0;if(num_key!=0xf0){delay(5);P3=0xfe; //去抖动num_key=P3;num_key=num_key&0xf0;if(num_key!=0xf0)num_key=num_key|0x0e;// while(P3 !=0xfe){}}}}}switch(num_key) //键盘扫描值num_key判断,即几号按键被按下{case 0xee :num=1;break; //B1按键case 0xde :num=2;break; //B2按键case 0xbe :num=3;break; //B3按键case 0x7e :num=4;break; //B4按键case 0xed :num=5;break; //B5按键case 0xdd :num=6;break; //B6按键case 0xbd :num=7;break; //B7按键case 0x7d :num=8;break; //B8按键case 0xeb :num=9;break; //B9按键case 0xdb :num=10;break; //B10按键case 0xbb :num=11;break; //B11按键case 0x7b :num=12;break; //B12按键case 0xe7 :num=13;break; //B13按键case 0xd7 :num=14;break; //B14按键case 0xb7 :num=15;break; //B15按键case 0x77 :num=16;break; //B16按键}return num;}/******************************************************************************** *** 函数名称:send595(uchar dat)** 函数功能:数据输入******************************************************************************* **/void send595(uchar dat) //数据输入{uchar i;for(i=0;i<8;i++){if((dat<<i)&0x80)MOSIO=1;else MOSIO=0;S_CLKa=0;S_CLKa=1;}}/******************************************************************************** *** 函数名称:out595** 函数功能:数据输出******************************************************************************* **/void out595(void) // 数据输出{R_CLKa=0;R_CLKa=1; //上升沿}/******************************************************************************** *** 函数名称:disp(uchar w,uchar d)** 函数功能:数码管显示函数******************************************************************************* **/void disp(uchar w,uchar d) //数码管显示函数:w-位码,d-段码{send595(wei[w]);send595(duan[d]);out595();}/******************************************************************************** *** 函数名称:dispoff(void)** 函数功能:关闭共阳数码管******************************************************************************* **/void dispoff(void) //关闭共阳数码管{send595(0);send595(0);out595();send595(0xff);out595();}。

基于矩阵键盘的加法器并用数码管显示

基于矩阵键盘的加法器并用数码管显示

基于矩阵键盘的加法器并用数码管显示一.任务解析用Verilog语言编写矩阵键盘驱动程序,实现“0~9,+,=”输入,数码管显示“加数”,按“+”键后再显示“被加数”,按“=”键后显示结果“和”。

二.实验方案键盘的识别有两种编程方法:方法一:module keyboard(clk,clr,keyv,C,L,k1);//输入行线[3:0]L input clk,clr; //输出扫描列线[3:0]C;input [3:0]L; //输出键值[3:0]keyv。

output[3:0]C;output k1;output [3:0]keyv;reg [1:0]scan;reg [3:0]C;reg k1;always @(posedge clk or negedge clr)begin//clk大概1000HZ if(!clr) scan=0;else beginscan=scan+2'h1;case(scan)2'H0:C=4'b1110;//列2'H1:C=4'b1101;2'H2:C=4'b1011;2'H3:C=4'b0111;endcaseendendreg [3:0]keyv;always @(negedge clk or negedge clr)begin if(!clr) begin keyv=0;k1=0;endelse begincase(L)4'HE:begin keyv={2'H0,scan};k1=1;end4'HD:begin keyv={2'H1,scan};k1=1;end4'HB:begin keyv={2'H2,scan};k1=1;end4'H7:begin keyv={2'H3,scan};k1=1;enddefault:k1=0;endcaseendendendmodule8 4 09 5 1+ 6 2= 7 3方法二:module key_recognize(clk,reset,row,col,key_value,key_flag);//50MHz clk,复位,行,列,键值input clk,reset;input [3:0]row;output [3:0]col;output [3:0]key_value;output key_flag;reg [3:0]col;reg [3:0]key_value;reg [5:0]count;//delay_20msreg [2:0]state;//状态标志reg key_flag;//按键标志位reg clk_500khz;//500KHZ时钟信号reg [3:0]col_reg;//寄存扫描列值reg [3:0]row_reg;//寄存扫描行值always @(posedge clk or negedge reset)if(!reset) begin clk_500khz<=0; count<=0; endelse beginif(count>=50) begin clk_500khz<=~clk_500khz;count<=0;end else count<=count+1;endalways @(posedge clk_500khz or negedge reset)if(!reset) begin col<=4'b0000;state<=0;endelsebegincase (state)0:begin col[3:0]<=4'b0000;key_flag<=1'b0;if(row[3:0]!=4'b1111) begin state<=1;col[3:0]<=4'b1110;end //有键按下,扫描第一行else state<=0;end1:beginif(row[3:0]!=4'b1111) begin state<=5;end//判断是否是第一行else begin state<=2;col[3:0]<=4'b1101;end//扫描第二行end2:beginif(row[3:0]!=4'b1111) begin state<=5;end//判断是否是第二行else begin state<=3;col[3:0]<=4'b1011;end//扫描第三行end3:beginif(row[3:0]!=4'b1111) begin state<=5;end//判断是否是第三一行else begin state<=4;col[3:0]<=4'b0111;end//扫描第四行end4:beginif(row[3:0]!=4'b1111) begin state<=5;end//判断是否扫描第一行else state<=0;end5:beginif(row[3:0]!=4'b1111) begincol_reg<=col;row_reg<=row;//保存扫描列、行值state<=5;key_flag<=1'b1;//有键按下endelse begin state<=0;endendendcaseendalways @(clk_500khz or col_reg or row_reg)beginif(key_flag==1'b1)begincase({col_reg,row_reg})8'b1110_1110:key_value<=0; 8'b1110_1101:key_value<=1; 8'b1110_1011:key_value<=2; 8'b1110_0111:key_value<=3; 8'b1101_1110:key_value<=4; 8'b1101_1101:key_value<=5; 8'b1101_1011:key_value<=6; 8'b1101_0111:key_value<=7; 8'b1011_1110:key_value<=8; 8'b1011_1101:key_value<=9; 8'b1011_1011:key_value<=10; 8'b1011_0111:key_value<=11; 8'b0111_1110:key_value<=12; 8'b0111_1101:key_value<=13; 8'b0111_1011:key_value<=14; 8'b0111_0111:key_value<=15;endcaseendendendmodule3 2 1 07 6 5 4= + 9 8三.重难点解析原理框图:从上图及以上两种按键识别程序可以看出,必须设置一个按键标志位以获取有效按键。

74HC164级联实现四位数码管显示电路

74HC164级联实现四位数码管显示电路

中北大学课程设计说明书学生姓名:XXXXXX 学号:1005xxxxx学院:信息与通信工程学院专业:电子信息科学与技术题目:74HC164级联实现四位数码管显示电路设计指导教师:程耀瑜职称: 教授李文强职称:讲师2013 年 1 月 17 日中北大学课程设计任务书2012/2013 学年第一学期学院:信息与通信工程学院专业:电子信息科学与技术学生姓名:xxxxxxx 学号:100xxxxxxx 课程设计题目:74HC164级联实现四位数码管显示电路设计起迄日期:1月4日~1月15日课程设计地点:中北大学指导教师:程耀瑜,李文强系主任:程耀瑜下达任务书日期: 2010 年 1 月 3 日课程设计任务书目录一、设计目的 (6)二、设计任务 (6)三、设计条件 (6)四、设计内容和要求 (6)1、74CH164的逻辑功能、逻辑图、引脚说明、波形图 (7)2、七段显示数码管 (9)3、74164QUARTUS 2仿真 (10)4、分步设计 (10)5、电路设计图 (11)6、仿真波形图 (12)六、设计总结 (15)1、设计总结 (15)2、设计中的优点与不足 (15)3、心得体会 (15)六、计参考资料 (16)一、设计目的本课程设计主要针对模拟电子技术和数字电子技术课程要求,培养学生在查阅资料的基础上,进行实用电路设计、计算、仿真、调试等多个环节的综合能力,同时培养学生用课程中所学的理论独立地解决实际问题的能力。

另外还培养学生用专业的、简洁的文字,清晰的图表来表达自己设计思想的能力。

二、设计任务设计一个74HC164级联实现四位数码管显示电路,通过在74HC164上输入时钟信号(CP)和控制信号(D),在数码管上显现出来相应的信号。

三、设计条件本设计是基于在学习过数字电子技术基础和模拟电子技术基础且在完成电子技术实验后设计的,通过在电脑上利用各种软件设计而成,包括Quartus II 5.0,Multisim2001等设计仿真软件。

矩阵键盘状态机之74HC164驱动数码管依次显示键值要点

矩阵键盘状态机之74HC164驱动数码管依次显示键值要点

用视图Web模式看uchar code smg_duan[]= //数码管(共阴)编码0-F,全灭; 按键对应的数字不是上图,而是-------------------------这里下面的{//用IO口P0,所以把A B C D E F G DP分别接到P0^0 P0^1 P0^2 P0^3 P0^4 P0^5 P0^6 PO^7 所以编码如下---------- --------------|-1--|-2--|-3--|-----------------------------------|-4--|-5--|-6--|-----------------------0X3f,0X06,0X5B,0X4f,0X66,0X6D,0X7D,0x07,0x7f,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x7 1,0X00---------------|-7--|-8--|-9--|-----------------//可以把0x71或任意一个改为0x00,这样就可以按下0x71这个案件时清楚显示了---------------|-C--|-0--|-E--|---------------------/* 0xfC,0x0C,0xDA,0xF2,0x66,0xB6,0xBE,0xE0,0xFE,0xF6,0xEE,0x3E,0x9C,0x7A,0x9E,0x8E,0x00 //多写了0x00,代表段选全部熄灭*/};0X3f,0X06,0X5B,0X4f,0X66,0X6D,0X7D,0x07,0x7f,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x7 1,0X00//可以把0x71或任意一个改为0x00,这样就可以按下0x71这个案件时清楚显示了完整程序如下:/*==========================================================* 开发人员:laowang* 当前版本:V1.0* 创建时间:11/26/2013* 修改时间:04/21/2017* 功能说明:对4*3矩阵键盘扫描,用4位共阴数码管进行显示,刚开始时不亮,依次按下按键时数码管依次显示0-F,扫描方法为状态机方法+定时器中断* 修改人员:梁超云*==========================================================*/#include<reg52.h>#include"Define.h"#include"display.h"#include"matrixkeyscan.h"#include "74HC164.h"void Timer0_init(); //定时器初始化函数uint flag1=0;uint flag=0; //按键扫描标志,每中断一次,扫描一次bit power_on=1;//主函数void main(){uchar key_state=0;uchar readkey;readkey=0xff;Timer0_init();Display_init(); //使之不亮while(1){if(flag==1){flag=0;flag1++;if(flag1>=4){flag1=0;}readkey=Keyscan();if (power_on==0){power_on=1;num2++;if(num2>=4){num2=0;}DisplayBUFF(readkey);}Display();}}}void Timer0() interrupt 1{// TH0=0xD8; //10Ms产生一次中断// TL0=0xF0;// TH0=0xB1; //20Ms产生一次中断// TL0=0xE0;// TH0=0xec; //5Ms产生一次中断// TL0=0x78;TH0=0x63; //40Ms产生一次中断TL0=0xc0;flag++;}void Timer0_init(){// TH0=0xD8; //12MHz--10Ms产生一次中断// TL0=0xF0;// TH0=0xB1; //20Ms产生一次中断// TL0=0xE0;// TH0=0xec; //5Ms产生一次中断// TL0=0x78;TH0=0x63; //40Ms产生一次中断TL0=0xc0;EA=1;ET0=1;TR0=1;}/*==================硬件电路===============================*说明:数码管为共阴数码管,驱动方式为74hc164扫描方式为动态扫描*==========================================================*/ //梁超云改为P0.0-P0.7直接数码管的A-H,P2接数码管位选#include<reg52.h>#include"Define.h" //把常用的宏定义写成了头文件,包含进来#include"display.h"#include "74HC164.h"#include"matrixkeyscan.h"uchar segbuff[4];uchar num2=0;//sbit wela=P3^5; //位选//sbit dula=P3^4; //段选uchar code smg_duan[]= //数码管(共阴)编码0-F,全灭;{//用IO口P0,所以把A B C D E F G GP分别接到P0^0 P0^1 P0^2 P0^3 P0^4 P0^5 P0^6 PO^7 所以编码如下0X3f,0X06,0X5B,0X4f,0X66,0X6D,0X7D,0x07,0x7f,0x6F,0x77,0x7C,0x39,0x5E,/*0x79*/0 x00,0x71,0X00//用IO口P0,所以把A B C D E F G GP分别接到P0^7 P0^6 P0^5 P0^4 P0^3 P0^2 P0^1 PO^0 所以编码如下//可以把0x79或任意一个改为0x00,这样就可以按下0x79这个案件时清楚显示了//0xfC,0x0C,0xDA,0xF2,0x66,0xB6,0xBE,0xE0,0xFE,0xF6,0xEE,0x3E,0x9C,0x7A,/*0x9E*/ 0X00,0x8E,0x00 //多写了0x00,代表段选全部熄灭};//uchar code smg_wei[]={0xfe,0xfd,0xfB,0xf7};//数据向左移动。

74HC164移位寄存器的驱动与应用

74HC164移位寄存器的驱动与应用

74HC164移位寄存器的驱动与应用2008-07-26 13:5374HC164的驱动和应用74HC164的几点说明:1.74HC164是串行输入,并行输出的;2.它的并行输出其实是有延时的,只是延时时间小,可以认为是并行输出;74hc164封装和真值表:A400EA04-DB1A5348-3B1DD4B0-E1417E40-1D636E94-1D4D6A58真值表中文解释说明:H-高电平 L -低电平 X -任意电平↑-低到高电平跳变(上升沿有效)QA0,QB0,QH0 -规定的稳态条件建立前的电平QAn,QGn -时钟最近的↑前的电平看真值表的第三条和第五条:就可以知道,在保持clear为 H clock为↑状态下,AB都为H时,移位寄存器移入H,而当移位寄存器移入L时,必须令B为L,而A不受约束。

所以可以把AB断相连再接入单片机数据端口。

还有一种是A脚直接接高电平,B脚连入单片机数据端(P2_7)电路仿真图:R为clear端, C1/->为clock端,&为A端(1脚)和B端(二角),3~13脚分表为QA~QH,源程序:/***74hc164是上升沿有效***/#include<regx51.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned intuchar ch;sbit DAT=P2^7;//A,B端接一块后接入DATsbit CLK=P2^6;char codeseg[16]={0x03,0x9f,0x25,0x0d,0x99,0x49,0x41,0x1f,0x01,0x09,0xff};/*0~9和全灭状态*//*数经过移位寄存器后低位数为高位数,高位数为低位数如:0000 0011移位以后为1100 0000*//*延时一毫秒函数*/void delay(uint ms){uchar i;for(;ms!=0;ms--)for(i=0;i<250;i++){_nop_();_nop_();_nop_();_nop_();}}/***把代码发送到移位寄存器***/void sendchar(ch){uchar i;for(i=0;i<8;i++)//8位数据传输完毕后才给数码管显示{DAT=ch&0x01;//P2_7=0000000x/*DAT一直保持该状态,等时钟脉冲触发传递数值*/CLK=0;//下面两句制造一个上升沿CLK=1;/*一个seg[]刚好八位,164是串行输入的,分成八位输入*/ch>>=1;/*DAT=ch&0x01和ch>>=1的功能是一次取出八位二进制ch的每一位赋值给74hc164*/}}void main(void){uint m=0;while(1){sendchar(seg[m]);if(++m==11) m=0;delay(200);}}类别:电子技术文档 | 添加到搜藏 | 分享到i贴吧 | 浏览(1665) | 评论(1)上一篇:C语言宏定义技巧(常用宏定义)下一篇:[转]从零开始,教你如何破解WEP...最近读者:登录后,您就出现在这里。

74hc164驱动数码管笔段问题

74hc164驱动数码管笔段问题
void out_simuseri(uchar data_buf)
{
uchar i;
i=8;
ACC=data__CLK=0;
simuseri_DATA=a0;
simuseri_CLK=1;
ACC=ACC>>1;
numer=dis_code[ge];
out_simuseri(numer); //个位移位显示
delay(5);
P2_0=1;
P2_1=0;
numer=dis_code[shi]; //十位移位
out_simuseri(numer);
0x74,0x61,0x21,0x7A,0x20,0x60, 0x01};
uchar numer,temp;
uchar ge,shi;
//----------------------------------------------------------------------------
// 函数名称:out_simuseri
// 输入参数:data_buf
// 输出参数:无
// 功能说明:8位同步移位寄存器,将data_buf的数据逐位输出到simuseri_DATA
//----------------------------------------------------------------------------
}
while(--i!=0);
}
/************************************/
void delay(uchar ms) //延时程序
{
uchar i;

单片机之用74LS164驱动数码管

单片机之用74LS164驱动数码管

单片机之用74LS164驱动数码管2011-09-26 16:31:39| 分类:单片机(AT89S52 | 标签:单片机|字号大中小订阅用74LS164驱动数码管,首先弄清74LS164的工作方式,然后是自己板子上的线路是如何连接的。

最后,说一说数码管的基础知识:使用数码管时,要注意区分这两种不同的接法:共阴极和共阳极。

共阴极时,为1则亮;共阳极时,为0则亮。

为了显示数字或字符,必须对数字或字符进行编码。

七段数码管加上一个小数点,共计8段。

这些段分别由字母a,b,c,d,e,f,g,dp来表示。

当数码管特定的段加上电压后,这些特定的段就会发亮,以形成我们眼睛看到的字样了。

比如共阴极的方式接数码管,显示“1”,则编码为0x3f,即00111111(dp g f e d c b a )。

==================================================================================================静态显示程序如下:/*-----------------------------------功能:数码管静态显示0-F单片机:AT89S52------------------------------------*/#include "reg52.h"#define uint unsigned int#define uchar unsigned charsbit DAT=P0^3;sbit CLK=P0^2;void sendbyte(uchar byte);void delay(uint z);uchar code tab[]={0xed,0x09,0xbc,0x9d,0x59,0xd5,0xf5,0x0d,0xfd,0xdd,0x7d,0xf1,0xe4,0xb9,0xf4,0x74,0x00} ; //0-F, 全灭/*========================主函数=========================*/void main(){unsigned char h;while(1){for(h=0;h<17;h++){delay(500); //延时大约是0.5ssendbyte(h);delay(500);}h=0;}}/*====================================用74LS164来输出一个8位的数据,点亮数码管相应的管脚,以显示数字=====================================*/void sendbyte(uchar byte){uchar num,c;num=tab[byte];for(c=0;c<8;c++){CLK=0;DAT=num&0x01; //每一位的输出CLK=1; //每一次上升沿,输出一位数据num>>=1; //右移位赋值,以供下一位的输出}}/*==============================延时子程序===============================*/void delay(uint z){uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}。

矩阵式键盘按键值的数码管显示实验

矩阵式键盘按键值的数码管显示实验

//矩阵式键盘按键值的数码管显示实验#include<reg52.h> //包含51单片机寄存器定义的头文件sbit P14=P1^4; //将P14位定义为P1.4引脚sbit P15=P1^5; //将P15位定义为P1.5引脚sbit P16=P1^6; //将P16位定义为P1.6引脚sbit P17=P1^7; //将P17位定义为P1.7引脚unsigned char codeTab[ ]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //数字0~9的段码unsigned char keyval; //定义变量储存按键值/**************************************************************函数功能:数码管动态扫描延时**************************************************************/void led_delay(void){unsigned char j;for(j=0;j<200;j++);}/**************************************************************函数功能:按键值的数码管显示子程序**************************************************************/void display(unsigned char k){P2=0xbf; //点亮数码管DS6P0=Tab[k/10]; //显示十位led_delay(); //动态扫描延时led_delay(); //动态扫描延时led_delay(); //动态扫描延时P0=0xff;P2=0x7f; //点亮数码管DS7P0=Tab[k%10]; //显示个位led_delay(); //动态扫描延时led_delay(); //动态扫描延时led_delay(); //动态扫描延时P0=0xff;}/**************************************************************函数功能:软件延时子程序**************************************************************/void delay20ms(void){unsigned char i,j;for(i=0;i<100;i++)for(j=0;j<60;j++);}/**************************************************************函数功能:主函数**************************************************************/void main(void){EA=1; //开总中断ET0=1; //定时器T0中断允许TMOD=0x01; //使用定时器T0的模式1TH0=(65536-500)/256; //定时器T0的高8位赋初值TL0=(65536-500)%256; //定时器T0的高8位赋初值TR0=1; //启动定时器T0keyval=0x00; //按键值初始化为0while(1) //无限循环{display(keyval); //调用按键值的数码管显示子程序led_delay(); //动态扫描延时}}/**************************************************************函数功能:定时器0的中断服务子程序,进行键盘扫描,判断键位**************************************************************/void time0_interserve(void) interrupt 1 using 1 //定时器T0的中断编号为1,使用第一组寄存器{TR0=0; //关闭定时器T0P1=0xf0; //所有行线置为低电平“0”,所有列线置为高电平“1”if((P1&0xf0)!=0xf0) //列线中有一位为低电平“0”,说明有键按下delay20ms(); //延时一段时间、软件消抖if((P1&0xf0)!=0xf0) //确实有键按下{P1=0xfe; //第一行置为低电平“0”(P1.0输出低电平“0”)if(P14==0) //如果检测到接P1.4引脚的列线为低电平“0”keyval=1; //可判断是S1键被按下if(P15==0) //如果检测到接P1.5引脚的列线为低电平“0”keyval=2; //可判断是S2键被按下if(P16==0) //如果检测到接P1.6引脚的列线为低电平“0”keyval=3; //可判断是S3键被按下if(P17==0) //如果检测到接P1.7引脚的列线为低电平“0”keyval=4; //可判断是S4键被按下P1=0xfd; //第二行置为低电平“0”(P1.1输出低电平“0”)if(P14==0) //如果检测到接P1.4引脚的列线为低电平“0”keyval=5; //可判断是S5键被按下if(P15==0) //如果检测到接P1.5引脚的列线为低电平“0”keyval=6; //可判断是S6键被按下if(P16==0) //如果检测到接P1.6引脚的列线为低电平“0”keyval=7; //可判断是S7键被按下if(P17==0) //如果检测到接P1.7引脚的列线为低电平“0”keyval=8; //可判断是S8键被按下P1=0xfb; //第三行置为低电平“0”(P1.2输出低电平“0”)if(P14==0) //如果检测到接P1.4引脚的列线为低电平“0”keyval=9; //可判断是S9键被按下if(P15==0) //如果检测到接P1.5引脚的列线为低电平“0”keyval=10; //可判断是S10键被按下if(P16==0) //如果检测到接P1.6引脚的列线为低电平“0”keyval=11; //可判断是S11键被按下if(P17==0) //如果检测到接P1.7引脚的列线为低电平“0”keyval=12; //可判断是S12键被按下P1=0xf7; //第四行置为低电平“0”(P1.3输出低电平“0”)if(P14==0) //如果检测到接P1.4引脚的列线为低电平“0”keyval=13; //可判断是S13键被按下if(P15==0) //如果检测到接P1.5引脚的列线为低电平“0”keyval=14; //可判断是S14键被按下if(P16==0) //如果检测到接P1.6引脚的列线为低电平“0”keyval=15; //可判断是S15键被按下if(P17==0) //如果检测到接P1.7引脚的列线为低电平“0”keyval=16; //可判断是S16键被按下}TR0=1; //开启定时器T0TH0=(65536-500)/256; //定时器T0的高8位赋初值TL0=(65536-500)%256; //定时器T0的高8位赋初值}。

74HC164驱动数码管

74HC164驱动数码管

只要用到一片164就够了,作动态扫描,下面程序是两个数码管动态扫描,164并行输出口再接一片功率驱动芯片,如TD62083。

程序如下:/**************************************//* 74LS164数码管动态显示*//**************************************///-------------------------------------库函数声明,管脚定义------------#include <at89x51.h>#define uchar unsigned charsbit simuseri_CLK=P1^1; //用P1^1模拟串口时钟sbit simuseri_DATA=P1^0; //用P1^0模拟串口数据sbit a0=ACC^0;unsigned char code dis_code[11]={0x28,0x7E,0xa2,0x62, //查表显示0, 1、、9 0x74,0x61,0x21,0x7A,0x20,0x60, 0x01};uchar numer,temp;uchar ge,shi;//----------------------------------------------------------------------------// 函数名称:out_simuseri// 输入参数:data_buf// 输出参数:无// 功能说明:8位同步移位寄存器,将data_buf的数据逐位输出到simuseri_DATA//----------------------------------------------------------------------------void out_simuseri(uchar data_buf){uchar i;i=8;ACC=data_buf;do{simuseri_CLK=0;simuseri_DATA=a0;simuseri_CLK=1;ACC=ACC>>1;}while(--i!=0);}/************************************/void delay(uchar ms) //延时程序{uchar i;while(ms--){for (i=0;i<125;i++);}}/***********************************/void main(){uchar m;while(1){for(temp=0;temp<99;temp++){ge=temp/10;shi=temp%10;for(m=0;m<20;m++) //显示频率200ms加1次{P2_0=0; //位段码numer=dis_code[ge];out_simuseri(numer); //个位移位显示delay(5);P2_0=1;P2_1=0;numer=dis_code[shi]; //十位移位out_simuseri(numer);delay(5);P2_1=1;}m=0;}}}/****************************************/#i nclude<reg51.h>#define uint unsigned int#define uchar unsigned charsbit DAT=P1^1; //模拟串口数据发送端sbit CLK=P1^2;//模拟时钟控制端uchar code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff};//0-9,-,全灭(共阳字段表)void sendbyte(uchar byte){uchar num,c;num=tab[byte];for(c=0;c<8;c++){CLK=0;DAT=num&0x80; //(0x80即十进制的128, 二进制的10000000 按位发送)CLK=1;num<<=1;}}void delay_50ms(unsigned int t) //50MS演示程序{unsigned int j;for(;t>0;t--)for(j=6245;j>0;j--){;}}main(){unsigned char h;while(1){for(h=0;h<10;h++){delay_50ms(1);sendbyte(h);delay_50ms(10);}h=0;}}下面这段是74ls164 驱动共阴数码管的程序源码#i nclude<reg51.h>#define uint unsigned int#define uchar unsigned charsbit DAT=P1^1;sbit CLK=P1^2;uchar code tab[]={0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xff,0xf6};//0-9,-,全灭void sendbyte(uchar byte){uchar num,c;num=tab[byte];for(c=0;c<8;c++){CLK=0;DAT=num&0x01;CLK=1;num>>=1;}}void delay_50ms(unsigned int t) {unsigned int j;for(;t>0;t--)for(j=6245;j>0;j--){;}}main(){unsigned char h;while(1){for(h=0;h<10;h++){delay_50ms(1);sendbyte(h);delay_50ms(10);}h=0;}}刚开始的时候把74HC164当成了74HC573使了,还看了原理图,半天摸不出个所以然,然后上网查了资料,才知道原来74HC164是串入并出的,此时才知道思考方向出错了。

PIC16f630使用74HC164驱动4位数码管

PIC16f630使用74HC164驱动4位数码管
#DEFINE WEI2 PORTC,0;---数码管第5位位选端
#DEFINE DAT_A PORTC,5;//数据移位输入端
#DEFINE CLK PORTC,4;;//数据移位时钟
#DEFINE BEEPER PORTC,2;----蜂鸣器输出端
#DEFINE LED_BP PORTC,1;----蜂鸣器报警指示灯
;------------------------------------------------------------
TABLE_TUBE:
ADDWF PCL,1
RETLW 3FH;0
RETLW 06H;1
RETLW 5BH;2
RETLW 4FH;3
RETLW 66H; 4
MOVLW 00H
MOVWF W_ADDR
MOVF TM_TEMPER,0
MOVWF W_DAT
CALL WR_EEP
RETURN
WR01;-------------------------------------写十位
; RC0---------------WEI_2
; RA0----WK1----WEI_3
; RA1----WK2----WEI_4
; RA4----WK3-----WEI_5
; RA3-----WK5----改为数字IO,做输入
;*/
#INCLUDE <P16F630.INC>
RETLW 6DH; 5
RETLW 7DH; 6
RETLW 07H;7
RETLW 7FH; 8
RETLW 6FH; 9
RETLW 00H;----段灭值,消影

矩阵键盘按键的数码管显示矩阵键盘按键的数码管显示

矩阵键盘按键的数码管显示矩阵键盘按键的数码管显示

一、矩阵键盘按‎键的数码管‎显示1.实验目的(1)掌握VHD‎L语言的语‎法规范,掌握时序电‎路描述方法‎(2)掌握多个数‎码管动态扫‎描显示的原‎理及设计方‎法2.实验所用仪‎器及元器件‎计算机一台‎实验板一块‎电源线一根‎扁平线一根‎下载线一根‎3.实验任务要求设计出‎4*4矩阵键盘‎对某一按键‎按下就在数‎码管显示一‎个数字。

按键从左上‎角到右下角‎依次为1,2, (16)4.实验原理按键模块原‎理键盘扫描的‎实现过程如‎下:对于4×4键盘,通常连接为‎4行、4列,因此要识别‎按键,只需要知道‎是哪一行和‎哪一列即可‎,为了完成这‎一识别过程‎,我们的思想‎是,首先固定输‎出4行为高‎电平,然后输出4‎列为低电平‎,在读入输出‎的4行的值‎,通常高电平‎会被低电平‎拉低,如果读入的‎4行均为高‎电平,那么肯定没‎有按键按下‎,否则,如果读入的‎4行有一位‎为低电平,那么对应的‎该行肯定有‎一个按键按‎下,这样便可以‎获取到按键‎的行值。

同理,获取列值也‎是如此,先输出4列‎为高电平,然后在输出‎4行为低电‎平,再读入列值‎,如果其中有‎哪一位为低‎电平,那么肯定对‎应的那一列‎有按键按下‎。

键盘键值的‎获取:键盘上的每‎一个按键其‎实就是一个‎开关电路,当某键被按‎下时,该按键的接‎点会呈现0‎的状态,反之,未被按下时‎则呈现逻辑‎1的状态。

扫描信号由‎r o w进入‎键盘,变化的顺序‎依次为11‎10-1101-1011-0111-1110。

每一次扫描‎一排,依次地周而‎复始。

例如现在的‎扫描信号为‎1011,代表目前正‎在扫描9,10,11,12这一排‎的按键,如果这排当‎中没有按键‎被按下的话‎,则由col‎umn读出‎的值为11‎11;反之当9这‎个按键被按‎下的话,则由col‎u mn读出‎的值为11‎10。

根据上面所‎述原理,我们可得到‎各按键的位‎置与数码关‎系如表所示‎:1110 1110 1110 1110 1101 1101 1101 1101row1110 1101 1011 0111 1110 1101 1011 0111 colum‎n1 2 3 4 5 6 7 8键值row 1011 1011 1011 1011 0111 0111 0111 0111colum‎n1110 1101 1011 0111 1110 1101 1011 0111键值9 10 11 12 13 14 15 16动态显示原‎理为使得输入‎控制电路简‎单且易于实‎现,采用动态扫‎描的方式实‎现设计要求‎。

矩阵式键盘控制数码管显

矩阵式键盘控制数码管显
去抖动处理
为了避免按键抖动造成的误判,微 控制器会对检测到的按键状态进行 去抖动处理,确保按键状态的准确 性。
键盘编码方式
行码与列码组合
01
每个按键都有一个唯一的行码和列码组合,用于标识按键的位
置。
编码表
02
建立一个包含所有按键行码和列码组合的编码表,用于将按键
位置映射到对应的编码值。
编码输出
03
键盘扫描程序
根据矩阵式键盘的原理,编写键盘扫描程序,实 现按键的检测与识别。
数码管显示程序
根据数码管的显示原理,编写数码管显示程序, 实现数码管的显示和控制。
主程序
主程序负责调用键盘扫描程序和数码管显示程序, 实现整个系统的控制逻辑。
系统调试与测试
硬件调试
检查硬件电路连接是否正确,确保各模块工作正常。
矩阵式键盘控制数码管显示系 统
目录
CONTENTS
• 矩阵式键盘控制原理 • 数码管显示技术 • 矩阵式键盘控制数码管显示系统设计 • 系统性能优化与改进 • 应用前景与发展趋势

01 矩阵式键盘控制原理
CHAPTER
矩阵式键盘结构
4x4矩阵式键盘结构
由16个按键组成的矩阵,行线和列线 交叉连接,每个按键位于行线和列线 的交叉点上。
根据按键位置在编码表中找到对应的编码值,通过微控制器输
出相应的编码信号,控制数码管显示相应的字符或数字。
02 数码管显示技术
CHAPTER
数码管工作原理
数码管由多个LED段组成,通过控制各段的亮灭来显示数字或字符。
数码管内部有8个LED段,通过电流的通断控制每个段的亮灭,从而显示不同的数字 或字符。
数码管驱动方式
点驱动方式

矩阵键盘的键值用数码管显示

矩阵键盘的键值用数码管显示

矩阵键盘的键值用数码管显示�矩阵按键项目:分别按下4*4 矩阵键盘,一共16 个按键,数码管会相应的显示1-16 不同的数字。

最终效果图:现象说明:效果图中我们看到:按 4 键,数码管上即显示04,同理按5 键数码管上即显示05。

上面显示的 2 个LED 灯是硬件上特意设计的,只要按键按下,相应的灯就亮了。

目前不用太在意。

此项目练习的目的:(1)认识矩阵键盘。

(2)了解矩阵键盘的原理。

(3)熟悉软件编程。

(4)熟悉软件的使用。

完整代码:(注意,代码中省略的部分是我们目前可以不关心的内容,在下一阶段将着重介绍,此代码已编译测试通过)#include <reg52.h> //头文件#include "digitron_drv.h" //调用数码管显示程序,现在可以把它当做一个主体#define uint unsigned int //宏定义#define uchar unsigned charuchar key_num; //矩阵键盘键值/*延时函数*/void delay(uchar x){uchar i,j;for(i = x;i > 0;i--)for(j = 100;j > 0;j--);}/*键盘键值显示*/void display(void){DigShowNumber(1,key_num%10,0); //个位除以10 取余DigShowNumber(2,key_num/10,0); //十位除以10 取整}/*键盘扫描*/void keyboard(void){uchar temp;P1=0xef; //将第1 列置位低电平,其余的为高电平temp=P1; //读取P1 口当前的状态,赋值给临时变量temp,用于后面的计算temp=temp&0x0f; //判断temp 的,低四位是否为0,if(temp!=0x0f) //如果temp 不等于0x0f,说明有按键按下{delay(10); //延时消抖temp=P1; //重新读一次P1 口数据temp=temp&0x0f;// 如果temp 仍然不等于0x0f,这次说明第1 列真的有按键按下if(temp!=0x0f){temp=P1;switch(temp) //判断按下的是该列的第几行{case 0xee: //如果读到P1 是0xee,说明是第1 列和第1 行的交叉键,即数字键7key_num=7;break;case 0xed: //如果读到P1 是0xed,说明是第1 列和第2 行的交叉键,即数字键4key_num=4;break;case 0xeb: //如果读到P1 是0xeb,说明是第1 列和第3 行的交叉键,即数字键1key_num=1;break;case 0xe7: //如果读到P1 是0xe7,说明是第1 列和第4 行的交叉键,即数字键0key_num=0;break;}}//在判断完按键序号后,还要等待按键被释放,检测释放语句如下:while(temp!=0x0f) //等待按键被释放{temp=P1;temp=temp&0x0f; //不断的读取P1 口数据,然后和0x0f“与”运算,只要结果不等于0x0f,说明按键没有被释放,直到按键被释放才退出whiledisplay();}}//以下程序意义同上,继续进行第2、3、4 列的检测P1=0xdf;temp=P1;temp=temp&0x0f;if(temp!=0x0f){delay(10);temp=P1;temp=temp&0x0f;if(temp!=0x0f){temp=P1;switch(temp){case 0xde:key_num=8;break;case 0xdd:key_num=5;break;case 0xdb:key_num=2;break;case 0xd7:key_num=10;break;}}while(temp!=0x0f){temp=P1;temp=temp&0x0f;display();}}P1=0xbf;temp=P1;temp=temp&0x0f; if(temp!=0x0f) {delay(10);temp=P1;temp=temp&0x0f; if(temp!=0x0f) {temp=P1;switch(temp){case 0xbe:key_num=9; break;case 0xbd:key_num=6; break;case 0xbb:key_num=3; break;case 0xb7:key_num=11; break;}}while(temp!=0x0f){ temp=P1;temp=temp&0x0f; display();}}P1=0x7f;temp=P1;temp=temp&0x0f; if(temp!=0x0f) {delay(10);temp=P1;temp=temp&0x0f; if(temp!=0x0f) {temp=P1;switch(temp){case 0x7e:key_num=12;break;case 0x7d:key_num=13;break;case 0x7b:key_num=14;break;case 0x77:key_num=15;break;}}while(temp!=0x0f){temp=P1;temp=temp&0x0f;display();}}}void main(void){while(1){keyboard();display();}}长见识:(1)按键实物:也称轻触开关按键之前也已经见过了,再回忆一下。

矩阵键盘及其数码管显示

矩阵键盘及其数码管显示

矩阵键盘及其数码管显示电路图如上图所示。

程序是用C语言编写的。

程序如下:#include<reg52.h>#define uint unsigned int#define uchar unsigned charuchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};sbit wela=P2^7;sbit dula=P2^6;uchar num=17,temp;void delay(uint z);void main(){wela=1;P1=0xc0;wela=0;dula=1;P1=0x00;dula=0;while(1){P3=0xfe;temp=P3;temp=temp&0xfe;while(temp!=0xfe){delay(5);temp=P3;switch(temp){case 0xee: num=1; break;case 0xde: num=2; break;case 0xbe: num=3; break;case 0x7e: num=4; break;}while(temp!=0xfe){temp=P3;temp=temp&0xfe;}dula=1;P1=table[num-1];dula=0;}P3=0xfd;temp=P3;temp=temp&0xfd;while(temp!=0xfd){delay(5);temp=P3;switch(temp){case 0xed: num=5; break;case 0xdd: num=6; break;case 0xbd: num=7; break;case 0x7d: num=8; break;}while(temp!=0xfd){temp=P3;temp=temp&0xfd;}dula=1;P1=table[num-1];dula=0;}P3=0xfb;temp=P3;temp=temp&0xfb;while(temp!=0xfb){delay(5);temp=P3;switch(temp){case 0xeb: num=9; break;case 0xdb: num=10; break;case 0xbb: num=11; break;case 0x7b: num=12; break;}while(temp!=0xfb){temp=P3;temp=temp&0xfb;}dula=1;P1=table[num-1];dula=0;}P3=0xf7;temp=P3;temp=temp&0xf7;while(temp!=0xf7){delay(5);temp=P3;switch(temp){case 0xe7: num=13; break;case 0xd7: num=14; break;case 0xb7: num=15; break;case 0x77: num=16; break;}while(temp!=0xf7){temp=P3;temp=temp&0xf7;}dula=1;P1=table[num-1];dula=0;}}}void delay(uint z){uint x,y;for(x=z;z>0;z--)for(y=100;y>0;y--); }。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

用视图Web模式看uchar code smg_duan[]= //数码管(共阴)编码0-F,全灭; 按键对应的数字不是上图,而是-------------------------这里下面的{//用IO口P0,所以把A B C D E F G DP分别接到P0^0 P0^1 P0^2 P0^3 P0^4 P0^5 P0^6 PO^7 所以编码如下---------- --------------|-1--|-2--|-3--|-----------------------------------|-4--|-5--|-6--|-----------------------0X3f,0X06,0X5B,0X4f,0X66,0X6D,0X7D,0x07,0x7f,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x7 1,0X00---------------|-7--|-8--|-9--|-----------------//可以把0x71或任意一个改为0x00,这样就可以按下0x71这个案件时清楚显示了---------------|-C--|-0--|-E--|---------------------/* 0xfC,0x0C,0xDA,0xF2,0x66,0xB6,0xBE,0xE0,0xFE,0xF6,0xEE,0x3E,0x9C,0x7A,0x9E,0x8E,0x00 //多写了0x00,代表段选全部熄灭*/};0X3f,0X06,0X5B,0X4f,0X66,0X6D,0X7D,0x07,0x7f,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x7 1,0X00//可以把0x71或任意一个改为0x00,这样就可以按下0x71这个案件时清楚显示了完整程序如下:/*==========================================================* 开发人员:laowang* 当前版本:V1.0* 创建时间:11/26/2013* 修改时间:04/21/2017* 功能说明:对4*3矩阵键盘扫描,用4位共阴数码管进行显示,刚开始时不亮,依次按下按键时数码管依次显示0-F,扫描方法为状态机方法+定时器中断* 修改人员:梁超云*==========================================================*/#include<reg52.h>#include"Define.h"#include"display.h"#include"matrixkeyscan.h"#include "74HC164.h"void Timer0_init(); //定时器初始化函数uint flag1=0;uint flag=0; //按键扫描标志,每中断一次,扫描一次bit power_on=1;//主函数void main(){uchar key_state=0;uchar readkey;readkey=0xff;Timer0_init();Display_init(); //使之不亮while(1){if(flag==1){flag=0;flag1++;if(flag1>=4){flag1=0;}readkey=Keyscan();if (power_on==0){power_on=1;num2++;if(num2>=4){num2=0;}DisplayBUFF(readkey);}Display();}}}void Timer0() interrupt 1{// TH0=0xD8; //10Ms产生一次中断// TL0=0xF0;// TH0=0xB1; //20Ms产生一次中断// TL0=0xE0;// TH0=0xec; //5Ms产生一次中断// TL0=0x78;TH0=0x63; //40Ms产生一次中断TL0=0xc0;flag++;}void Timer0_init(){// TH0=0xD8; //12MHz--10Ms产生一次中断// TL0=0xF0;// TH0=0xB1; //20Ms产生一次中断// TL0=0xE0;// TH0=0xec; //5Ms产生一次中断// TL0=0x78;TH0=0x63; //40Ms产生一次中断TL0=0xc0;EA=1;ET0=1;TR0=1;}/*==================硬件电路===============================*说明:数码管为共阴数码管,驱动方式为74hc164扫描方式为动态扫描*==========================================================*/ //梁超云改为P0.0-P0.7直接数码管的A-H,P2接数码管位选#include<reg52.h>#include"Define.h" //把常用的宏定义写成了头文件,包含进来#include"display.h"#include "74HC164.h"#include"matrixkeyscan.h"uchar segbuff[4];uchar num2=0;//sbit wela=P3^5; //位选//sbit dula=P3^4; //段选uchar code smg_duan[]= //数码管(共阴)编码0-F,全灭;{//用IO口P0,所以把A B C D E F G GP分别接到P0^0 P0^1 P0^2 P0^3 P0^4 P0^5 P0^6 PO^7 所以编码如下0X3f,0X06,0X5B,0X4f,0X66,0X6D,0X7D,0x07,0x7f,0x6F,0x77,0x7C,0x39,0x5E,/*0x79*/0 x00,0x71,0X00//用IO口P0,所以把A B C D E F G GP分别接到P0^7 P0^6 P0^5 P0^4 P0^3 P0^2 P0^1 PO^0 所以编码如下//可以把0x79或任意一个改为0x00,这样就可以按下0x79这个案件时清楚显示了//0xfC,0x0C,0xDA,0xF2,0x66,0xB6,0xBE,0xE0,0xFE,0xF6,0xEE,0x3E,0x9C,0x7A,/*0x9E*/ 0X00,0x8E,0x00 //多写了0x00,代表段选全部熄灭};//uchar code smg_wei[]={0xfe,0xfd,0xfB,0xf7};//数据向左移动。

要右移的话就uchar code smg_wei[]={0xf7,0xfB,0xfd,0xfe};/*==========================================================*函数名称:Display_init()*功能:对数码管进行初始化操作*入口参数:*出口参数:void*说明:刚上电时,所有的数码管均不显示*==========================================================*/void Display_init(){P1=0x00; //将所有的位选关闭,所有数码管不亮,// wela=1;// wela=0;P2=0xff; //将段选关闭。

// dula=1;// dula=0;}void Display(){sendbyte(segbuff[flag1%4]);P2=smg_wei[(flag1-1)%4];//保证每次都从左边开始亮,其实是看数码管硬件怎么排位置的// P2=smg_wei[(flag1+3)%4];}/*==========================================================*函数名称:Display(uchar)*功能:数码管静态扫描*入口参数:*出口参数:void*说明:进行段选的显示。

因为位选在刚开始的时候已经弄好了*==========================================================*/void DisplayBUFF(uchar num1)//更新显存{uchar i,x;// wela=1;i=num2%4;//四位数码管所以%4,6位%6,8位%8,以此类推segbuff[i]=smg_duan[num1];x=smg_duan[num1];if(x==0x00){segbuff[0]=0x00;segbuff[1]=0x00;segbuff[2]=0x00;segbuff[3]=0x00;num2=0;flag1=0;}//清空缓存// sendbyte(segbuff[i]);// wela=0;// dula=1;// dula=0;}/*==================硬件电路===============================**说明:矩阵键盘为4*4,数据口为P0,行线为P0.0-P0.3,列线为P0.4-P0.7 20170418梁超云改为P0口,显示字形码接在P1,位在P2*==========================================================*/#include<reg52.h>#include"Define.h"#include"matrixkeyscan.h"#define key P0 //矩阵键盘的数据口#define no_key 0xff //无按键按下#define key_state0 0 //状态0,此时无按键按下#define key_state1 1 //状态1,此时处于确定按键是否按下#define key_state2 2 //状态2,此时判断按键是否释放/*==========================================================*函数名称:Keyscan()*功能:对矩阵键盘进行扫描,扫描方式为状态机+定时器中断*入口参数:*出口参数:key_value,代表具体的键值*说明:有个缺陷,刚开始数码管就亮,还没找到是哪里出了问题(已解决)*==========================================================*/uchar Keyscan(){uchar key_state; //状态指示static uchar key_value; //键值返回uchar key_temp;uchar key1,key2;uchar last_key_value;bit bit_release=0;//释放标志位key=0xf0;key1=key;key1=key&0xf0; //确定哪一行的按键按下key=0x0f;key2=key;key2=key&0x0f; //确定哪一列的按键按下key_temp=key1|key2; //确定按键位置switch(key_state) //检测当前状态{case key_state0: //之前无按键被按下if(key_temp!=no_key) //说明有按键按下或者抖动{key_state=key_state1; //转换为状态1,然后去判断是否真的按下}break;case key_state1: //状态1,说明之前已经有按键按下或者抖动if(key_temp==no_key) //全为高电平,说明是抖动{key_state=key_state0; //返回到状态1,}else //确实有按键被按下{switch(key_temp) //当确定按键按下后,列举所有的按键情况{case 0xee: key_value=1;break;case 0xde: key_value=2;break;case 0xbe: key_value=3;break;//case 0x7e: key_value=13;break;case 0xed: key_value=4;break;case 0xdd: key_value=5;break;case 0xbd: key_value=6;break;//case 0x7d: key_value=10;break;case 0xeb: key_value=7;break;case 0xdb: key_value=8;break;case 0xbb: key_value=9;break;//case 0x7b: key_value=11;break;case 0xe7: key_value=12;break;case 0xd7: key_value=0;break;case 0xb7: key_value=14;break;//case 0x77: key_value=15;break;default: key_value=16;break;/*case 0xee: key_value=0;break;case 0xde: key_value=1;break;case 0xbe: key_value=2;break;case 0x7e: key_value=3;break;case 0xed: key_value=4;break;case 0xdd: key_value=5;break;case 0xbd: key_value=6;break;case 0x7d: key_value=7;break;case 0xeb: key_value=8;break;case 0xdb: key_value=9;break;case 0xbb: key_value=10;break;case 0x7b: key_value=11;break;case 0xe7: key_value=12;break;case 0xd7: key_value=13;break;case 0xb7: key_value=14;break;case 0x77: key_value=15;break;default: key_value=16;break;*/}key_state=key_state2; //跳到状态2,进而判断是否被释放}break;case key_state2: //状态2,判断是否被释放if(key_temp==no_key) //释放,转回到状态0{key_state=key_state0;bit_release=1;}break;}if(key_state==key_state0){last_key_value=key_value;if(bit_release){bit_release=0; /* bit_release 也就是释放标志位*/power_on=0; //解决:有个缺陷,刚开始数码管就亮,还没找到是哪里出了问题}return key_value;}elsereturn last_key_value;}/*==========================================================*74ls164为八位串行输入、并行输出的移位寄存器* 开发人员:梁超云* 当前版本:V1.0* 创建时间:04/21/2017* 修改时间:* 功能说明:74HC164驱动*==========================================================*/#include "reg52.h"#include "Define.h"#include "74HC164.h"void sendbyte(uchar byte) //发送一个字节高位在前{uchar num,c;num=byte;for(c=0;c<8;c++){CLK=0;DAT=num&0x80;CLK=1;num<<=1;}}/*void sendbyte(uchar byte) //发送一个字节低位在前{uchar num,c;num=byte;for(c=0;c<8;c++){CLK=0;DAT=num&0x01;CLK=1;num>>=1;}}*/#ifndef _DISPLAY_H_ //头文件保护符#define _DISPLAY_H_#include"Define.h"extern void Display_init();extern void DisplayBUFF(uchar num1);extern uchar i,num2;extern uchar segbuff[4];extern void Display();#endif#ifndef _MA TRIXKEYSCAN_H_ //头文件保护符#define _MATRIXKEYSCAN_H_#include"Define.h"extern uchar key_value;extern uchar last_key_value;extern uchar key_state;extern uchar Keyscan();extern bit power_on;#endif#ifndef _DEFINE_H_ //头文件保护符#define _DEFINE_H_#define uchar unsigned char //宏定义#define uint unsigned intextern uint flag1;extern uint flag;#endif/*--------------------------------------------------------------------------REG52.HHeader file for generic 80C52 and 80C32 microcontroller.Copyright (c) 1988-2002 Keil Elektronik GmbH and Keil Software, Inc. All rights reserved.--------------------------------------------------------------------------*/#ifndef __REG52_H__#define __REG52_H__/* BYTE Registers */sfr P0 = 0x80;sfr P1 = 0x90;sfr P2 = 0xA0;sfr P3 = 0xB0;sfr PSW = 0xD0;sfr ACC = 0xE0;sfr B = 0xF0;sfr SP = 0x81;sfr DPL = 0x82;sfr DPH = 0x83;sfr PCON = 0x87;sfr TCON = 0x88;sfr TMOD = 0x89;sfr TL0 = 0x8A;sfr TL1 = 0x8B;sfr TH0 = 0x8C;sfr TH1 = 0x8D;sfr IE = 0xA8;sfr IP = 0xB8;sfr SCON = 0x98;sfr SBUF = 0x99;/* 8052 Extensions */sfr T2CON = 0xC8;sfr RCAP2L = 0xCA;sfr RCAP2H = 0xCB;sfr TL2 = 0xCC;sfr TH2 = 0xCD;/* BIT Registers *//* PSW */sbit CY = PSW^7;sbit AC = PSW^6;sbit F0 = PSW^5;sbit RS1 = PSW^4;sbit RS0 = PSW^3;sbit OV = PSW^2;sbit P = PSW^0; //8052 only/* TCON */sbit TF1 = TCON^7;sbit TR1 = TCON^6;sbit TF0 = TCON^5;sbit TR0 = TCON^4;sbit IE1 = TCON^3;sbit IT1 = TCON^2;sbit IE0 = TCON^1;sbit IT0 = TCON^0;/* IE */sbit EA = IE^7;sbit ET2 = IE^5; //8052 only sbit ES = IE^4;sbit ET1 = IE^3;sbit EX1 = IE^2;sbit ET0 = IE^1;sbit EX0 = IE^0;/* IP */sbit PT2 = IP^5;sbit PS = IP^4;sbit PT1 = IP^3;sbit PX1 = IP^2;sbit PT0 = IP^1;sbit PX0 = IP^0;/* P3 */sbit RD = P3^7;sbit WR = P3^6;sbit T1 = P3^5;sbit T0 = P3^4;sbit INT1 = P3^3;sbit INT0 = P3^2;sbit TXD = P3^1;sbit RXD = P3^0;/* SCON */sbit SM0 = SCON^7;sbit SM1 = SCON^6;sbit SM2 = SCON^5;sbit REN = SCON^4;sbit TB8 = SCON^3;sbit RB8 = SCON^2;sbit TI = SCON^1;sbit RI = SCON^0;/* P1 */sbit T2EX = P1^1; // 8052 onlysbit T2 = P1^0; // 8052 only/* T2CON */sbit TF2 = T2CON^7;sbit EXF2 = T2CON^6;sbit RCLK = T2CON^5;sbit TCLK = T2CON^4;sbit EXEN2 = T2CON^3;sbit TR2 = T2CON^2;sbit C_T2 = T2CON^1;sbit CP_RL2 = T2CON^0;#endif#ifndef _74HC164_H_ //头文件保护符#define _74HC164_H_#include"Define.h"sbit DAT=P1^0;sbit CLK=P1^1;extern void sendbyte(uchar byte); #endif。

相关文档
最新文档