赞
踩
用数码管的前两位显示一个十进制数,变化范围为00~59,开始时显示00,每按下S2键一次,数值加1;每按下S3键一次,数值减1;每按下S4键一次,数值归零;按下S5键一次,利用定时器功能使数值开始自动每秒加1,再次按下S5键,数值停止自动加1,保持显示原数。(来自郭天祥老师的51单片机练习)
初始化函数:
- void Init()
- {
- LE = 0;//锁住led灯,防止实验过程中灯亮
-
- WLE = 1;//打开位选
- P0 = 0xfc;
- WLE = 0;//关闭位选
- P0 = 0xff;//消影
- DLE = 1;//打开段选
- P0 = Table[0];
- DLE = 0;//关闭段选
- delay_1ms(10);
-
- TMOD = 0x01;//定时器工作类型
- TH0 = (65536 - 45872) / 256;//50ms
- TL0 = (65536 - 45872) % 256;
- EA = 1;//总中断
- ET0 = 1;//T0中断
- TR0 = 0;//开启T0
-
- num = 0;
- tt = 0;
- }
1ms延时函数:
- //延时1ms函数
- void delay_1ms(uint z)
- {
- uint x,y;
- for(x = z;x > 0;x--)
- {
- for(y =110;y > 0;y--){}
- }
- }
四个独立按键函数:
- //按键2函数
- void Switch2()
- {
- while(SW2 == 0)
- {
- delay_1ms(10);//消抖
- if(SW2 == 0)
- {
- num++;//加1
- }
- while(SW2 == 0);//等待按键释放
- }
- }
-
- //按键3函数
- void Switch3()
- {
- while(SW3 == 0)
- {
- delay_1ms(10);//消抖
- if(SW3 == 0)
- {
- if(num == 0)
- {
- num = 59;
- }
- else
- {
- num--;//减1
- }
- }
- while(SW3 == 0);//等待按键释放
- }
- }
-
- //按键4函数
- void Switch4()
- {
- while(SW4 == 0)
- {
- delay_1ms(10);//消抖
- if(SW4 == 0)
- {
- num = 0;//归零
- }
- while(SW4 == 0);//等待按键释放
- }
- }
-
- //按键5函数
- void Switch5()
- {
- while(SW5 == 0)
- {
- delay_1ms(10);//消抖
- if(SW5 == 0)
- {
- if(TR0 == 0)
- {
- TR0 = 1;
- }
- else
- {
- TH0 = (65536 - 45872) / 256;//50ms
- TL0 = (65536 - 45872) % 256;
- TR0 = 0;
- }
- }
- while(SW5 == 0);//等待按键释放
- }
- }
数码管显示函数:
- //数码管显示函数
- void display()
- {
- uint ge,shi;
- //定时1s
- if(tt == 20)
- {
- tt = 0;
- num++;
- }
- //计算每秒个位与十位的变化
- if(num == 60)
- {
- num = 0;
-
- }
- shi = num / 10;//十位
- ge = num % 10;//个位
-
- //显示十位
- WLE = 1;
- P0 = 0xfe;
- WLE = 0;
- P0 = 0xff;//消影
- DLE = 1;
- P0 = Table[shi];
- DLE = 0;
- delay_1ms(5);//延时短,达到动态扫描的效果
-
- //显示个位
- WLE = 1;
- P0 = 0xfd;
- WLE = 0;
- P0 = 0xff;//消影
- DLE = 1;
- P0 = Table[ge];
- DLE = 0;
- delay_1ms(5);//延时短,达到动态扫描的效果
- }
定时器T0中断函数:
- void Timer0() interrupt 1
- {
- TH0 = (65536 - 45872) / 256;//50ms
- TL0 = (65536 - 45872) % 256;
- tt++;
- }
整个项目代码:
- #include <reg52.h>
-
- //【例4.1.1】用数码管的前两位显示一个十进制数,变化范围为00~59,开始时显示00,每按下S2键一次,数值加1;
- //每按下S3键一次,数值减1;每按下S4键一次,数值归零;按下S5键一次,利用定时器功能使数值开始自动每秒加1,再次按下S5键,数值停止自动加1,保持显示原数。
- //晶振为 11.0529MHz
-
- #define uint unsigned int
- #define uchar unsigned char
- sbit SW2 = P3^4;//S2键
- sbit SW3 = P3^5;//S3键
- sbit SW4 = P3^6;//S4键
- sbit SW5 = P3^7;//S5键
- sbit WLE = P2^7;//位选
- sbit DLE = P2^6;//段选
- sbit LE = P2^5;//led灯的锁存器
- //数码管的编码表
- uchar code Table[]={
- 0x3f,0x06,0x5b,0x4f,
- 0x66,0x6d,0x7d,0x07,
- 0x7f,0x6f,0x77,0x7c,
- 0x39,0x5e,0x79,0x71};
- uint num,tt;
-
- void Init();
- void delay_1ms(uint z);
- void Switch2();//也可以将四个按键都写在一个函数里面
- void Switch3();
- void Switch4();
- void Switch5();
- void display();
-
- void main()
- {
- Init();
- while(1)
- {
- Switch2();
- Switch3();
- Switch4();
- Switch5();
- display();
- }
- }
-
- void Init()
- {
- LE = 0;//锁住led灯,防止实验过程中灯亮
-
- WLE = 1;//打开位选
- P0 = 0xfc;
- WLE = 0;//关闭位选
- P0 = 0xff;//消影
- DLE = 1;//打开段选
- P0 = Table[0];
- DLE = 0;//关闭段选
- delay_1ms(10);
-
- TMOD = 0x01;//定时器工作类型
- TH0 = (65536 - 45872) / 256;//50ms
- TL0 = (65536 - 45872) % 256;
- EA = 1;//总中断
- ET0 = 1;//T0中断
- TR0 = 0;//开启T0
-
- num = 0;
- tt = 0;
- }
-
- //延时1ms函数
- void delay_1ms(uint z)
- {
- uint x,y;
- for(x = z;x > 0;x--)
- {
- for(y =110;y > 0;y--){}
- }
- }
-
- //按键2函数
- void Switch2()
- {
- while(SW2 == 0)
- {
- delay_1ms(10);//消抖
- if(SW2 == 0)
- {
- num++;//加1
- }
- while(SW2 == 0);//等待按键释放
- }
- }
-
- //按键3函数
- void Switch3()
- {
- while(SW3 == 0)
- {
- delay_1ms(10);//消抖
- if(SW3 == 0)
- {
- if(num == 0)
- {
- num = 59;
- }
- else
- {
- num--;//减1
- }
- }
- while(SW3 == 0);//等待按键释放
- }
- }
-
- //按键4函数
- void Switch4()
- {
- while(SW4 == 0)
- {
- delay_1ms(10);//消抖
- if(SW4 == 0)
- {
- num = 0;//归零
- }
- while(SW4 == 0);//等待按键释放
- }
- }
-
- //按键5函数
- void Switch5()
- {
- while(SW5 == 0)
- {
- delay_1ms(10);//消抖
- if(SW5 == 0)
- {
- if(TR0 == 0)
- {
- TR0 = 1;
- }
- else
- {
- TH0 = (65536 - 45872) / 256;//50ms
- TL0 = (65536 - 45872) % 256;
- TR0 = 0;
- }
- }
- while(SW5 == 0);//等待按键释放
- }
- }
-
- //数码管显示函数
- void display()
- {
- uint ge,shi;
- //定时1s
- if(tt == 20)
- {
- tt = 0;
- num++;
- }
- //计算每秒个位与十位的变化
- if(num == 60)
- {
- num = 0;
-
- }
- shi = num / 10;//十位
- ge = num % 10;//个位
-
- //显示十位
- WLE = 1;
- P0 = 0xfe;
- WLE = 0;
- P0 = 0xff;//消影
- DLE = 1;
- P0 = Table[shi];
- DLE = 0;
- delay_1ms(5);//延时短,达到动态扫描的效果
-
- //显示个位
- WLE = 1;
- P0 = 0xfd;
- WLE = 0;
- P0 = 0xff;//消影
- DLE = 1;
- P0 = Table[ge];
- DLE = 0;
- delay_1ms(5);//延时短,达到动态扫描的效果
- }
-
- void Timer0() interrupt 1
- {
- TH0 = (65536 - 45872) / 256;//50ms
- TL0 = (65536 - 45872) % 256;
- tt++;
- }
1.按键的代码编写过程中,要注意“消抖”(消除人在按动按键的过程中的抖动),这个过程大概延时10ms即可;
2.按键在按下去和释放的瞬间都会有抖动,但是实际过程中,只需要在按下去的时候消抖即可,释放时可以不用消抖;
3.在处理按键按下去的那段代码时,要注意加一个“等待释放”的过程,如果一直按着按键,程序就要等待在那,而不是一直加数;
4.数码管在遇到60的时候要显示0,在0与59之间的加减转换要衔接好;
5.定时器T0的TR0开启或关闭,可以将if else语句简化成TR0 = ~TR0代替;
6.因为P1^7口是第8个发光二极管的口,也是时钟SCLK的口,如果不将发光二极管的使能端LE = 0(锁住),那么在按下按键5的时候,会导致发光二极管亮;
7.可将Switch2()、Switch3()、Switch4()、Switch5()这四个按键写在一个函数里简化,依次判断即可。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。