C51定时器实验Proteus仿真C语言 一共三个程序 1. 实现0-59s的计时,每隔1S秒值加1并通过S1、S0两片数码管显示出来,当计时数据加到60时数值变为00,重新计时。 2. 定时器控制单只LED灯闪烁,点亮2s,再熄灭0.5s。 要求:采用查询法和中断法两种编程方式实现。 3. 编写0-99的手动计数程序,按下P3.5引脚上所接的负脉冲按钮,在S1和S0两片数码管上显示计数值,加到数值100则清零,继续从0加到99重复显示。
最近在折腾51单片机定时器的几个经典实验,用Proteus跑仿真的时候发现有些小坑。今天咱们直接上代码,边撸代码边聊实现细节,三个实验打包带走!
一、数码管60秒轮回计时
先来搞个基础款——0-59秒循环计时。核心思路是用定时器做1秒基准,配合数码管动态扫描。这里用定时器0模式1实现:
#include <reg51.h> #define uint unsigned int #define uchar unsigned char uchar code segment[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90}; //共阳段码 uchar count = 0, sec = 0; void timer0_init() { TMOD = 0x01; //模式1 TH0 = 0xFC; //1ms定时 TL0 = 0x66; ET0 = 1; EA = 1; TR0 = 1; } void display() { P2 = 0x01; //开个位 P0 = segment[sec%10]; for(uint i=0;i<500;i++); P2 = 0x02; //开十位 P0 = segment[sec/10]; for(uint i=0;i<500;i++); } void main() { timer0_init(); while(1) { display(); if(count >= 1000) { //累计1秒 sec++; count = 0; if(sec >= 60) sec = 0; } } } void timer0_isr() interrupt 1 { TH0 = 0xFC; //重装初值 TL0 = 0x66; count++; }关键点解析:
- 定时器中断里只做累加,主循环判断是否满1秒,避免在中断里处理复杂逻辑
- 动态扫描加了简单延时,实际项目建议用定时器控制刷新频率
- 段码表要根据实际数码管类型调整(共阳/共阴)
二、LED呼吸灯:两种姿势玩定时
姿势A:中断法(推荐)
#include <reg51.h> sbit LED = P1^0; uint flash_cnt = 0; bit state = 0; void timer0_init() { TMOD |= 0x01; TH0 = 0x3C; //50ms定时 TL0 = 0xB0; ET0 = 1; EA = 1; TR0 = 1; } void main() { timer0_init(); while(1); } void timer0_isr() interrupt 1 { TH0 = 0x3C; TL0 = 0xB0; if(++flash_cnt >= (state ? 40 : 10)) { //2s/0.5s state = !state; LED = ~state; flash_cnt = 0; } }姿势B:查询法(适合简单场景)
void main() { TMOD = 0x01; while(1) { TH0 = 0x3C; TL0 = 0xB0; TR0 = 1; while(!TF0); //死等标志位 TF0 = 0; //...类似中断内的计数逻辑 } }对比分析:
- 中断法CPU利用率高,适合多任务
- 查询法会阻塞主程序,适合简单场景
- 时间计算注意:50ms×40次=2s,50ms×10次=0.5s
三、手动计数器:按键的艺术
#include <reg51.h> sbit KEY = P3^5; uchar num = 0; void delay(uint i) { while(i--); } void check_key() { if(KEY == 0) { delay(1000); //消抖 if(KEY == 0) { num++; if(num >= 100) num = 0; while(!KEY); //等待松手 } } } void display() { //显示逻辑同实验一 } void main() { while(1) { check_key(); display(); } }防抖秘籍:
- 检测到低电平后延时10ms左右
- 再次确认按键状态
- 松手检测避免连击
- 实际项目建议用外部中断+定时器消抖
Proteus仿真Tips:
- 数码管记得接限流电阻
- 按键加10k上拉电阻
- LED电流设置2-5mA
- 定时器初值可用工具计算(如STC-ISP)
这三个实验涵盖了定时器的基本玩法,搞明白之后可以衍生出各种定时应用。下次试试把这三个功能整合到一个系统里,加上模式切换按键,立马变身多功能电子表!