51单片机006:利用动态扫描和定时器1在数码管上显示出从765开始以1/10秒的速度往下递减直至321并保持显示此数,与此同时利用定时器0以500MS速度进行流水灯从上至下移动,当数码管上数减到……
题目:利用动态扫描和定时器1在数码管上显示出从765开始以1/10秒的速度往下递减直至321并保持显示此数,与此同时利用定时器0以500MS速度进行流水灯从上至下移动,当数码管上数减到停止时,实验板上流水灯也停止然后全部开始闪烁,3秒后(用T0定时)流水灯全部关闭、数码管上显示出“HAO”。到此保持住。
思路:
1、“从765开始以1/10秒的速度往下递减直至321并保持显示此数”:
定义num变量,初始值为765,定时器定时0.1s,num--,完成向下递减效果,保持显示此数,可以通过控制TCON中的TR0/TR1运行控制寄存器,使定时器停止计时,num就不会向下递减。
2、“利用定时器0以500MS速度进行流水灯从上至下移动”:
一个简单的利用定时器实现流水灯
3、“当数码管上数减到停止时,实验板上流水灯也停止然后全部开始闪烁,3秒后(用T0定时)流水灯全部关闭、数码管上显示出“HAO”。到此保持住。”
数码管和LED可分为以下几个阶段:
阶段一:数码管数字递减,LED为流水灯
阶段二:数码管显示321,LED闪烁三秒
阶段三:数码管显示HAO,LED关闭
定义两个状态变量,flag和flag_led。
当flag == 0,flag_led == 0时:数码管递减,LED效果为流水灯
当flag == 1,flag_led == 0时:数码管显示为321,LED效果为闪烁3s
当flag_led == 1,flag == 1时:数码管显示为HAO,LED效果为关闭
原理图:
代码:
说明:由于进行数码管位选时和LED的引脚有些冲突,所以只选取了后三位LED灯进行流水灯演示。
#include "reg52.h" #include <intrins.h> //定义数码管位选信号控制脚 sbit LSA=P2^2; sbit LSB=P2^3; sbit LSC=P2^4; //定义LED位选信号控制脚 sbit led5=P2^5; sbit led6=P2^6; sbit led7=P2^7; //共阴极数码管显示0~F的段码数据 unsigned char gsmg_code[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f, //0-9 0x77,0x7c,0x39,0x5e,0x79,0x71,0x40,0x76,0x3f}; //a-f , h ,o unsigned int num = 765; unsigned int flag = 0; unsigned int flag_led = 0; unsigned int count_10ms; //定义10ms计时变量 unsigned int count_50ms; //定义50ms计时变量 //延时函数 void delay_10us(unsigned int ten_us) { while(ten_us--); } /*****************************数码管*****************************/ void shumaguan(unsigned char location,number) { P0=0x00; switch(location) { case 8:LSC=0;LSB=0;LSA=0;break; case 7:LSC=0;LSB=0;LSA=1;break; case 6:LSC=0;LSB=1;LSA=0;break; case 5:LSC=0;LSB=1;LSA=1;break; case 4:LSC=1;LSB=0;LSA=0;break; case 3:LSC=1;LSB=0;LSA=1;break; case 2:LSC=1;LSB=1;LSA=0;break; case 1:LSC=1;LSB=1;LSA=1;break; } P0=gsmg_code[number]; } void smg_display(unsigned int num) { if(flag == 0) { shumaguan(1,num/100); delay_10us(100); shumaguan(2,(num/10)%10); delay_10us(100); shumaguan(3,num%10); delay_10us(100); } if(flag_led == 1) { shumaguan(1,17); //H delay_10us(100); shumaguan(2,10); //A delay_10us(100); shumaguan(3,18); //O delay_10us(100); } } /****************************定时器********************************/ /*****定时器1********/ void time1_init(void) { TMOD|=0X10; //选择为定时器1模式,工作方式1 TH0=(65535-10000)/256; //10ms循环10次 TL0=(65535-10000)%256; ET1=1; //打开定时器1中断允许 EA=1; //打开总中断 TR1=1; //打开定时器 } void time1() interrupt 3 //定时器1中断函数 { TH0=(65535-10000)/256; //10ms循环10次 TL0=(65535-10000)%256; count_10ms++; } /*******定时器0**********/ void time0_init(void) { TMOD|=0X01; //选择为定时器0模式,工作方式1 TH0=(65535-50000)/256; //50ms定时10次 TL0=(65535-50000)%256; ET0=1; //打开定时器0中断允许 EA=1; //打开总中断 TR0=1; //打开定时器 } void time0() interrupt 1 //定时器0中断函数 { TH0=(65535-50000)/256; //50ms定时10次 TL0=(65535-50000)%256; count_50ms++; } void main() { time0_init(); time1_init(); while(1) { smg_display(num); if(count_10ms == 10) { count_10ms = 0; num--; smg_display(num); if(num == 321) { TR1 = 0; //停止计时 flag = 1; smg_display(num); } } if(flag == 0) //流水灯 { flag_led = 0; if(count_50ms==10) //500ms { led5=0;led6=1;led7=1; } if(count_50ms==20) //500ms { led5=1;led6=0;led7=1; } if(count_50ms==30) //500ms { led5=1;led6=1;led7=0; count_50ms = 0; } } else //led闪烁 { if(count_50ms <= 60) { led5=1;led6=1;led7=1; //全部熄灭 delay_10us(10); led5=0;led6=0;led7=0; //全部点亮 delay_10us(10); } //到了3s else { TR0 = 0; flag_led = 1; led5=1;led6=1;led7=1; //全部熄灭 } } } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)