大家好,我是『芯知识学堂』的SingleYork,前一篇文章给大家介绍了“SYK-0806-A2S1 工业自动化控制之【05-定时器控制的流水灯】”,
这一篇中,笔者要给大家介绍如何使用定时器在项目中的一些实际应用。
首先,我们先来介绍一下本例要实现的功能:
当X00信号由低电平变成高电平时(即一个上升沿,类似一个按键按下并松开),延时500ms(该延时由timer0实现),Y00输出ON;
延时1000ms(该延时由timer2实现),Y00输出OFF。
确定好功能后,我们便可以开始写代码了,首先 ,两个定时器的配置,跟上一讲的一样,基础定时均配置成1ms,
这个配置在bsp_timer.c文件中的void Timer_config(void)函数中完成:
- #include "bsp_timer.h"
-
- /************************ 定时器配置 ****************************/
- void Timer_config(void)
- {
- TIM_InitTypeDef TIM_InitStructure; //结构定义
-
- TIM_InitStructure.TIM_Mode = TIM_16BitAutoReload; //指定工作模式, TIM_16BitAutoReload,TIM_16Bit,TIM_8BitAutoReload,TIM_16BitAutoReloadNoMask
- TIM_InitStructure.TIM_Polity = PolityLow; //指定中断优先级(低到高) Polity_0,Polity_1,Polity_2,Polity_3
- TIM_InitStructure.TIM_Interrupt = ENABLE; //中断是否允许, ENABLE或DISABLE
- TIM_InitStructure.TIM_ClkSource = TIM_CLOCK_1T; //指定时钟源, TIM_CLOCK_1T,TIM_CLOCK_12T,TIM_CLOCK_Ext
- TIM_InitStructure.TIM_ClkOut = DISABLE; //是否输出高速脉冲, ENABLE或DISABLE
- TIM_InitStructure.TIM_Value = 65536UL - (MAIN_Fosc / 1000UL); //初值,
- TIM_InitStructure.TIM_Run = ENABLE; //是否初始化后启动定时器, ENABLE或DISABLE
- Timer_Inilize(Timer0,&TIM_InitStructure); //初始化Timer0 Timer0,Timer1,Timer2,Timer3,Timer4
-
- TIM_InitStructure.TIM_Mode = TIM_16BitAutoReload; //指定工作模式, TIM_16BitAutoReload,TIM_16Bit,TIM_8BitAutoReload
- TIM_InitStructure.TIM_Polity = PolityLow; //指定中断优先级, PolityHigh,PolityLow
- TIM_InitStructure.TIM_Interrupt = ENABLE; //中断是否允许, ENABLE或DISABLE
- TIM_InitStructure.TIM_ClkSource = TIM_CLOCK_1T; //指定时钟源, TIM_CLOCK_1T,TIM_CLOCK_12T,TIM_CLOCK_Ext
- TIM_InitStructure.TIM_ClkOut = DISABLE; //是否输出高速脉冲, ENABLE或DISABLE
- TIM_InitStructure.TIM_Value = 65536UL - (MAIN_Fosc / 1000UL); //初值,
- TIM_InitStructure.TIM_Run = ENABLE; //是否初始化后启动定时器, ENABLE或DISABLE
- Timer_Inilize(Timer2,&TIM_InitStructure); //初始化Timer1 Timer0,Timer1,Timer2,Timer3,Timer4
- }
复制代码
主要功能的实现,我们还是在app.c文件中完成,首先,在app.c文件中定义几个变量,如下:
- u16 timer0_cnt = 0;
- u16 timer2_cnt = 0;
-
- u8 X00_Step = 0;
- bit F_X00_Low = 0;
- bit F_X00_High = 0;
复制代码
其中,timer0_cnt和timer2_cnt主要用于timer0和timer2的计时,X00_Step用于动作流程的控制,
F_X00_Low和F_X00_High用于X00的高、低电平两种状态标记。
功能实现的代码主要是在app_run()函数中,分为两部分,第一部分,就是判断X00的状态,即判断“X00是否由低电平变成高电平”:
- if(!F_X00_Low)
- {
- if(!X00) //X00低电平
- {
- delay_ms(10);//10ms消抖
- if(!X00)
- {
- F_X00_Low = 1;//X00低电平标志置“1”
- F_X00_High= 0;//X00高电平标志清“0”
- }
- }
- }
- else
- {
- if(X00) //X00高电平
- {
- delay_ms(10);//10ms消抖
- if(X00)
- {
- F_X00_Low = 0;//X00低电平标志清“0”
- F_X00_High= 1;//X00高电平标志置“1”
- timer0_cnt= 0;//timer0定时计数清理
- X00_Step = 0;
- }
- }
- }
复制代码
第二部分就是Y00的动作逻辑,即,在识别到X00由低电平变成高电平后,延时500ms(该延时由timer0实现),Y00输出ON;
延时1000ms(该延时由timer2实现),Y00输出OFF:
- if(F_X00_High)
- {
- switch(X00_Step)
- {
- case 0:
- {
- if(timer0_cnt>=500)//timer0计时到500ms,Y00输出ON
- {
- Y00 = OutputT_ON;
- timer2_cnt= 0;//timer2定时计数清理
- X00_Step ++ ;
- }
- break;
- }
- case 1:
- {
- if(timer2_cnt>=1000)//timer2计时到500ms,Y00输出ON
- {
- Y00 = OutputT_OFF;
- X00_Step ++ ;
- F_X00_High= 0;
- }
- break;
- }
- default:break;
- }
- }
复制代码
定时器timer0和timer1的中断函数内容也很简单,只需要在中断函数里面分别对timer0_cnt和timer2_cnt计数加“1”即可,
然后,在每次需要用到计时的时候,先将timer0_cnt或timer2_cnt的计数值清零。
- /********************* Timer0中断函数************************/
- void timer0_int (void) interrupt TIMER0_VECTOR //1ms
- {
- timer0_cnt ++;
- }
-
- /********************* Timer0中断函数************************/
- void timer2_int (void) interrupt TIMER2_VECTOR //1ms
- {
- timer2_cnt ++;
- }
复制代码
至此,代码大功告成!好了,关于使用本节内容笔者就介绍到这里了,有疑问的小伙伴们可以给笔者留言或者直接参与评论,
下一节笔者将给大家介绍“如何利用定时器产生自己想要的频率”,详见“SYK-0806-A2S1 工业自动化控制之【07-定时器产生特定频率脉冲】”感谢大家的支持!
本章附件:
【STC15系列】SYK-0806-A2S1- 06-输入输出信号延时控制.rar
(65.78 KB, 下载次数: 1)
|