吴鉴鹰单片机项目精讲(连载)之基于单片机的数字电子钟设计
- UID
- 1023166
- 性别
- 男
- 来自
- 燕山大学
|
吴鉴鹰单片机项目精讲(连载)之基于单片机的数字电子钟设计
(连载1)吴鉴鹰单片机项目精讲(连载)之基于单片机的数字电子钟设计
先关的原理图请点击下载:
吴鉴鹰基于单片机的数字电子钟.pdf (295.38 KB, 下载次数: 25)
现在来第一讲,详细解析如何制作基于单片机的数字时钟,提供详细的硬件原理图和软件程序。
开关K1:K1 = 0时,时钟正常运行,此时不允许调整时钟。数码管的高两位显示小时,后两位显示分钟,led每闪一次表示时钟运行一次,在调整的过程中,led是停止发亮的。
一、 按键、开关功能说明:
* 按键RESET:按下能复位程序。
* 按键PULSE:提供单脉冲,从而实现单片机对外部脉冲的计数,利用单脉冲实现相应的位加一。
* 开关K0:K0 = 0能调整分位,K0 = 1能调整时位。
* 开关K2:k2为高电平时,使单脉冲输入至INT1,通过外中断实现相应值的加一功能。
二、地址分配和链接
* P2.7: 和写信号一起组成字位口的片选信号,字位口的对应地址为8000H。
* P2.6: 和写信号一起组成字位口的片选信号,字位口的对应地址为4000H。
* D0~D7: 单片机的数据总线,LED显示的内容通过D0~D7数据线从单片机传到LED。
* P2.0~P2.5:单片机的P2口,和2764的高位地址线相连,决定2764中的存储单元的地址。
* P1.4~P1.7: 单片机的P1端口,和发光二极管L1~L4相连,通过单片机的P1.4~P1.7控制,所以显示秒表和时钟的时间变化。
* P1.0: 和开关K0相连,决定时间调整的字位。
* P1.1 : 和开关K1相连,决定时间运行的模式。
* P1.2: 和开关K2相连,决定外中断的模式选择。
三、整体功能简介
LED显示模块与单片机的链接中,对LED显示模块的读写和字位、段码的选择通过口P2.6\P2.7完成的。
外部存储器2764是通过锁存器373和单片机相连,并且通过P2端口的相关信号线进行地址的分配。地址范围是0000H~1FFFH。
四、程序设计
- /******************************************************
- *程序:吴鉴鹰数字电子钟的设计
- ** 这一讲的主要内容: 数字电子钟的设计原理和程序
- ** 功能描述:
- ** 输 入:
- ** 内容:
- ** 输 出:
- **
- ** 全局变量:
- ** 调用模块:
- **
- ** 作 者: 吴鉴鹰
- ** 日 期: 14.02.17
- 备注:有什么错误的地方,欢迎各大烧友指正
- O(∩_∩)O~
- *******************************************************/
- //变量定义和头文件的调用
- //定义头文件和各个输入管脚以及变量声明
- #include<reg52.h>
- #include<absacc.h>
- #define uint unsigned int
- #define uchar unsigned char
- /*定义字型字位口*/
- #define DIGPORT XBYTE [0X8000]
- #define WORDPORT XBYTE [0X4000]
- /*定义P1口各管脚*/
- sbit K0 = P1^0;
- sbit K1 = P1^1;
- sbit K2 = P1^2;
- sbit BEEP = P1^3;
- sbit L0 = P1^4;
- sbit L1 = P1^5
- sbit L2 = P1^6;
- sbit L3 = P1^7;
- uchar data BUFFER[2] = {0,0}; //显示的缓存数组,依次为低位、高位
- uchar data CLOCK[4] = {0,0,0,0};
- uchar data SECOND[2] = {0,0};
- /*定义运行状态*/
- uchar data STATE = 0;
- /*STATE = 0;秒表*/
- /*STATE = 4,或者7,时钟运行*/
- /* STATE = 6,时钟时调整 */
- bit bdata SND = 0; /* 秒表START(开始) */
- bit bdata RST = 0; /*秒表RESET(复位)*/
- /*数码管显示编码“0”-“9”,"A","-"*/
- uchar code TABLE[] = {0X3F,0X06,0X5B,0X4F,0X66,0X6D,0X7D,0X07,0X7F,0X6F,0X77,0X40};
- /******************************************************
- *程序:主程序
- ** 功能描述: 主干程序
- ** 输 入:
- ** 内容:
- ** 输 出:
- **
- ** 全局变量:
- ** 调用模块:
- **
- ** 作 者: 吴鉴鹰
- ** 日 期: 14.02.17
- 备注:有什么错误的地方,欢迎各大烧友指正
- O(∩_∩)O~
- *******************************************************/
- void main()
- {
- uchar stabak;
- P1 = 0X0F;
- EA = 1;
- IT1 = 1;
- ET0 = 1;
- TMOD = 0X61;
- TH0 = -5000/256;
- TL0 = -5000%256;
- TH1 = 0XFF;
- TL1 = 0XFF;
- T2CON = 0;
- TH2 = -5000/256;
- TL2 = -5000%256;
- K0 = 1;
- K1 = 1;
- K2 = 1;
- STATE = P1&0X07;
- stabak = STATE;
- for(;;)
- {
- switch()
- {
- case 0:
- {
- EX1 = 0;
- ET1 = 1;
- ET2 = 1;
- TR1 = 1;
- SND = 1;
- L1 = 1;
- L0 = 0;
- L2 = 0;
- SECOND[0] = 0;
- SECOND[1] = 0;
- }break;
- case 5:
- {
- IE1 = 0;
- EX1 = 1;
- ET1 = 0;
- ET2 = 0;
- TR0 = 0;
- L0 = 1;
- L1 = 0;
- L2 = 0;
- }break;
- case 6:
- {
- IE1 = 0;
- EX1 = 1;
- ET1 = 0;
- ET2 = 1;
- TR0 = 0;
- }break;
- default:
- {
- EX1 = 0;
- ET1 = 0;
- ET2 = 1;
- L1 = 0;
- L2 = 0;
- }
- }
- while(STATE == stabak)
- {
- switch(STATE)
- {
- case 0:
- {
- BUFFER[0] = SECOND[0];
- BUFFER[1] = SECOND[1];
- }break;
- case 5:
- {
- BUFFER[0] = CLOCK[2];
- BUFFER[1] = 101;/*A-*/
- }break;
- case 6:
- {
- BUFFER[0] = 110;/*A-*/
- BUFFER[1] = CLOCK[3];
- }break;
- default:
- {
- BUFFER[0] = CLOCK[2];
- BUFFER[1] = CLOCK[3];
- }break;
- default:
- {
- BUFFER[0] = CLOCK[2];
- BUFFER[1] = CLOCK[3];
- }
- }
- //显示函数
- display();
- K0 = 1;
- K1 = 1;
- K2 = 1;
- STATE = P1&0X07;
- }
- stabak = STATE;
- }
- }
- /******************************************************
- *程序:子函数(1):timer0(void)
- ** 功能描述: 用定时器0实现24小时的时钟显示
- ** 输 入:
- ** 内容:
- ** 输 出:
- **
- ** 全局变量:
- ** 调用模块:
- **
- ** 作 者: 吴鉴鹰
- ** 日 期: 14.02.17
- 备注:有什么错误的地方,欢迎各大烧友指正
- O(∩_∩)O~
- *******************************************************/
- void timer0(void) interrupt 1 using 1
- {
- /*重置定时器初值*/
- TH0 = -5000/256;
- TL0 = -5000%256;
- /*定时器处理*/
- CLOCK[0] = CLOCK[0]+1;
- if((CLOCK[0] == 50) && (STATE >= 4))
- {
- L0 = !L0;
- }
- if(CLOCK[0] == 100)
- {
- if(STATE >= 4) L0 = !L0;
- CLOCK[0] = 0;
- CLOCK[1] = CLOCK[1] + 1;
- if(CLOCK[1] == 60)
- {
- CLOCK[1] = 0;
- CLOCK[2] = CLOCK[2] + 1;
- if(CLOCK[2] == 60)
- {
- CLOCK[2] == 0;
- CLOCK[3] == CLOCK[3] + 1;
- if(CLOCK[3] == 24)
- {
- CLOCK[3] = 0;
- }
- }
- }
- }
- }
- /******************************************************
- *程序:子函数(2):intsvr1(void)
- ** 功能描述: 对外中断1的按键脉冲进行判断和计数,并完成对应的时间调整功能。
- ** 输 入:
- ** 内容:
- ** 输 出:
- **
- ** 全局变量:
- ** 调用模块:
- **
- ** 作 者: 吴鉴鹰
- ** 日 期: 14.02.17
- 备注:有什么错误的地方,欢迎各大烧友指正
- O(∩_∩)O~
- *******************************************************/
- void intsvr1(void) interrupt 2 using 2
- {
- if(STATE == 5)
- {
- CLOCK[2] == CLOCK[2] + 1;
- if(CLOCK[2] == 60) CLOCK[2] == 0;
- }
- if(STATE == 6)
- {
- CLOCK[3] == CLOCK[3] + 1;
- if(CLOCK[3] == 24) CLOCK[3] = 0;
- }
- }
- /******************************************************
- *程序:子函数(3):display(void)
- ** 功能描述: 用动态显示的方法,将当前的时间或秒表内容通过数码管显示。
- ** 输 入:
- ** 内容:
- ** 输 出:
- **
- ** 全局变量:
- ** 调用模块:
- **
- ** 作 者: 吴鉴鹰
- ** 日 期: 14.02.17
- 备注:有什么错误的地方,欢迎各大烧友指正
- O(∩_∩)O~
- *******************************************************/
- void diplay(void)
- {
- uchar i;
- uchar delay;
- uchar disp;
- uchar digit;
- digit = 0x08;
- for(i = 0;i < 2; i++)
- {
- if(BUFFET> 100)
- {
- disp = BUFFER%10 + 10;
- }
- else disp = BUFFER%10;
- DIGPORT = digit;
- WORDPORT = TABLE[disp];
- for(delay = 0;delay <= 200;delay ++);
- digit = digit >> 1;
- disp = BUFFER/10;
- DIGPORT = digit;
- WORDPORT = TABLE[disp];
- for(delay = 0;delay <= 200;delay ++);
- digit = digit >> 1;
- }
- }
复制代码 |
|
|
|
|
|