【Proteus仿真】51单片机+74HC595驱动数码管60秒倒计时
- 📌相关篇《【Proteus仿真】51单片机定时器计数+共阴数码管驱动显示》
- 🔖Proteus仿真基础实验-
定时器计数+74HC595驱动共阴数码管60秒倒计时
。 - 🌿Proteus
8.12
平台 - 🌿本实验代码基于VSM Studio,采用SDCC编译器。
- 🎬仿真演示:
📝示例代码
/* Main.c file generated by New Project wizard
*
* Created: 2023-5-23
* Processor: 80C52
* Compiler: SDCC for 8051
*/
#include <mcs51reg.h>
#include <compiler.h> //NOP();
#define FOSC 11059200L
#define T1MS (65536-FOSC/12/1000) //1ms timer
typedef unsigned char uchar;
typedef unsigned int uint;
#define LED P2_1
#define ST_CP (P2_2) //串行寄存器时钟,上升沿有效
#define DS (P2_3) //串行数据输入
#define SH_CP (P2_4) //串行输入时钟,上升沿有效
#define wei1 (P2_5)
#define wei2 (P2_6)
uchar __code table[] = {
0x3f,0x06,0x5b,0x4f,// 0 1 2 3
0x66,0x6d,0x7d,0x07,// 4 5 6 7
0x7f,0x6f // 8 9
};
static unsigned int count = 0;
static unsigned int cnt = 0;
__sbit updata_flag = 0;
uchar mid_value;
void led_off()
{
wei1= 1;
wei2= 1;
}
//发送一个字节数据给595再并行输出
void SendTo595(uchar Data)
{
uchar i=0;
ST_CP = 0;
for(i;i<8;i++)
{
SH_CP = 0;
DS=0x80&Data;//&为按位运算符,即全1为1,有0为0,上式也就是 (1000 0000)&(1111 1111)=1000 0000,若高位为1则是1高位为0则这个式子为0
Data <<=1; //左移一位 将高位补给低位,如果二进制数为01010101 那么左移1位为10101010
SH_CP = 1; //上升沿让串行输入时钟变成高电平 并延时一个时钟周期
NOP();
}
/*位移寄存器完毕,转移到存储寄存器*/
ST_CP = 1; //上升沿,存储寄存器变为高电平 延迟两个时钟周期
NOP();
NOP();
}
void delayms(unsigned int ms)
{
unsigned int x, y;
for (y = ms; y > 0; y--) {
for (x = 227; x > 0; x--);
}
}
void Display()
{
uchar value;
value = cnt;
wei1=0,wei2=1;
SendTo595(table[value/10]);
delayms(14);
led_off();
delayms(2); //消隐
wei1=1,wei2=0;
SendTo595(table[value%10]);
delayms(14);
led_off();
delayms(2); //消隐
}
/*------------------------------------------------
定时器初始化子程序
------------------------------------------------*/
void Init_Timer0(void)
{
TMOD |= 0x01; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
TL0 = T1MS; //initial timer0 low byte
TH0 = T1MS >> 8; //initial timer0 high byte
TR0 = 1; //timer0 start running
ET0 = 1; //enable timer0 interrupt
EA = 1; //open global interrupt switch
}
/*------------------------------------------------
定时器中断子程序
------------------------------------------------*/
void Timer0_isr(void) __interrupt 1 __using 1
{
TL0 = T1MS; //reload timer0 low byte
TH0 = T1MS >> 8; //reload timer0 high byte
if (count-- == 0) //1ms * 1000 -> 1s
{
count = 968; //减去显示函数中的延时
LED = ! LED; //指示灯反相,可以看到闪烁
if(cnt-- == 0)
{
cnt = 60;
}
}
}
void main(void)
{
Init_Timer0();
led_off();
while (1)
{
Display();
}
}
📚仿真资源
链接: https://pan.baidu.com/s/1VZYTRCu-JF_nH5Q204NUkA
提取码: 8haq