基于定时器的倒计时程序设计

1.模块化编程

模板参考:C盘 零基础入门资源包 协会第四次培训

User-用户名(main)

Driver-底层(固定)

建立工程模板--编写底层函数 Key Seg

.c编写底层函数

.h声明底层函数 .c 和.h 建议成双成对设置 每一个.c都要引用它的头文件.h

在.c中写完,在.h中声明

Key_Read() 按键底层

具体内容:

unsigned char Key_read() { unsigned char temp=0; if(P3_4==0) temp=1; if(P3_5==0) temp=2; if(P3_6==0) temp=3; if(P3_7==0) temp=4; return temp; }

//逻辑还是较为简单的

Seg_Disp() 数码管底层

具体内容:

image-20241130171529901

用到单片机引脚时要包含头文件<REGX52.h>

断码位码表:

unsigned char Seg_Dula[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};//数码管段码储存数组 unsigned char Seg_Wela[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};//数码管位码储存数组

Main函数框架

1.头文件声明

2.变量声明区

3.按键处理函数 Key_Proc //Proc是函数的简写

4.信息显示 Seg_Proc

5.Led的显示Led_Proc()

6.定时器零的初始化Timer0Init()

在isp中生成

image-20241202083540621

7.定时器中断服务函数 Server

image-20241202083517807

底层可背

8.主函数main

//头文件声明区 #include <REGX52.H> #include <Seg.h> #include <Key.h>

//变量声明区 unsigned char Key_Slow_Down;//按键减速专用变量 unsigned char Key_Val,Key_Down,Key_Old;//按键扫描专用变量 unsigned int Seg_Slow_Down;//数码管减速专用变量 unsigned char Seg_Pos;//数码管扫描变量 unsigned char Seg_Buf[6]={1,2,3,4,5,6};//数码管显示数据存放数组 unsigned char Seg_Mode; //数码管显示界面 0代表显示 1代表设置 <如果要多模式显示就要用到此变量>

//按键处理函数 void Key_Proc() { if(Key_Slow_Down) return; Key_Slow_Down=1;//按键减速程序

Key_Val = Key_Read();//实时读取键码值

Key_Down = Key_Val & (Key_Old ^ Key_Val);//捕捉按键下降沿 Key_Old = Key_Val;//辅助扫描变量 switch(Key_Down) { } }

//信息处理函数 void Seg_Proc() { if(Seg_Slow_Down) return; Seg_Slow_Down=1;//数码管减速程序

} //其他显示函数 void Led_Proc() {

} //定时器零初始化函数 void Timer0_Init(void) //1毫秒@12.000MHz { TMOD &= 0xF0; //设置定时器模式 TMOD |= 0x01; //设置定时器模式 TL0 = 0x18; //设置定时初始值 TH0 = 0xFC; //设置定时初始值 TF0 = 0; //清除TF0标志 TR0 = 1; //定时器0开始计时 ET0=1; EA=1; }

//定时器零中断服务函数 void Timer0Server()interrupt 1 { TL0 = 0x18; //设置定时初始值 TH0 = 0xFC; //设置定时初始值 if(++Key_Slow_Down==10) Key_Slow_Down=0; if(++Seg_Slow_Down==500) Seg_Slow_Down=0; if(++Seg_Pos==6) Seg_Pos=0; Seg_Disp(Seg_Pos,Seg_Buf[Seg_Pos]); }

//main void main() { Timer0_Init(); while(1) { Key_Proc(); Seg_Proc(); Led_Proc();

}

}

关于蜂鸣器

image-20241214141622317

image-20241214141712923

buzzer连接的是P2_3引脚 0灭 1亮

image-20241214141828158

仿真中FM 点 变蓝了就是响了 红色就是没响

要显示多种界面时 在信息处理函数中写代码

image-20241211212618123

显示多种界面时先往变量声明区写一个

image-20241214142452041

题目中要求中间三位数是熄灭的 故把Seg_Buf[6]里的数全改为10

模式标识倒计时界面要显示 1 设置时要为2 而我们所定义的变量是0/1 为显示正确,故要定义数码管第一位显示1/2 也就是Seg_Buf[0]=Seg_Mode+1

实现倒计时

先定义两个变量

image-20241214172529872

初值是三十 故声明变量时将Time_Count 初始化为30

image-20241214172857879

然后将1000ms标志位变量放到中断函数中去

题目中还要求第5 6 位显示出倒计时 故写上系统计时变量 并使其开始递减 同时改变显示数组里的第五六位,将倒计时显示出来

代码如下:

image-20241214173523633

倒计时已写好,现在开始写按键功能

image-20241214175448951

先定义一个标志位

题中按键一定义的是开始 那么在按键一按下的时候开始计时

image-20241214175848394

涉及到按键,故在按键处理函数中进行修改

image-20241214180121752

由于题目中要求按下1时开始 故使当Key_Down=1 时令系统标志位为1

即使其开始

题目中还要求按键1 和 2仅仅在显示中 有效 故在设置界面不能使其生效

于是在Key_Down = 1 后再加一个限制条件

image-20241214181159633

但此时只写了按下1代表它走,但没限制没按1时不走

在定时器0中断服务函数中进行修改

image-20241214181805060

现在开始写按键三 切换(注意等号前面有个取反符号^)

image-20241214182843339

然后开始写4按键 要求在15 30 60 来回切换 故初始化一个数组如下

image-20241214183420024

image-20241219133041621

利用改变第二个变量从而改变模式,即将第二个变量作为第一个数组的索引值,由于 题目最开始为30,故使索引值为1,即数组第二位

现在开始写设置界面下的代码,使最后两位显示设置的值(信息处理函数中写)

image-20241219133545920

此时代码与显示界面下大同小异,但这里要显示的是设置值,故只需将Time_Count改为刚刚定义的数组其中的值,并加上索引值以确定输出哪一个

现在界面已设置完成,正式开始写按键四(按键处理函数)按键四仅在设置界面有效,故还需要加上限制条件

image-20241219134202035

由于设置界面设置好的值还要保存到显示界面,故可以在按键处理函数的切换键中写一些代码更新切换后显示界面的值,即:

image-20241219134711863

再看题,还有个按键二(复位)没写

逻辑很简单,按一下按键二就要让Time_Count回到原位(Seg_Dat[Seg_Dat_Index]),且按键二只在显示界面生效,所以:

image-20241219135214922

image-20241219135420152

他要倒计时为零时所有LED点亮,复位后熄灭,就是让Time_Count为0时P0=0x00,LED显示属于其他显示函数,故在其他显示函数中修改:

image-20241219135723689

前面讲过蜂鸣器连接的是P2_3引脚,所以想要使其使能则使P2_3引脚获得低电平,除要求倒计时为0时所有灯点亮,蜂鸣器使能,还要求复位后所有灯灭,蜂鸣器停止,其实可以理解为只要倒计时不为零就让灯灭,蜂鸣器停止,故可写出上述代码

但仿真运行过后发现倒计时变为零后继续变为55,这是因为我们只让其一直--,而并未增加限制条件,使其到零后继续减,unsigned char中是没有负数的(0-255),故自动使其变为255,此时让255参与运算,打印出了55,所以,代码要进行以下优化(定时器中断服务函数)

image-20241219140646992

image-20241219140833170

要求一秒为周期进行闪烁即为要求500ms灯灭500ms灯亮

image-20241219140959441

定时器中断服务函数中:

image-20241219141131068

由于其要求的是设置界面下后两位闪烁,因此要在设置界面下去写,前面写了每500ms Seg_Flag异或取1(等于1时取0,不等于1 时取1),已设置1s为周期,只需要设置一个500ms内亮,另一个500ms内灭即可

image-20241219141333683

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值