【15系列】SYK-0806-A2S1 工业自动化控制之【06-输入信号延时控制输出】
大家好,我是『芯知识学堂』的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;
u8X00_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-定时器产生特定频率脉冲】”感谢大家的支持!
本章附件:
大家好,我是『芯知识学堂』的SingleYork,今天我们将继续探讨SYK-0806-A2S1在工业自动化控制中的应用,具体讲解如何通过定时器实现输入信号的延时控制输出。
功能描述
在本例中,我们需要实现以下功能:
1. 当输入信号X00从低电平变为高电平(即检测到一个上升沿,类似于按键按下并松开)时,启动两个定时器。
2. 第一个定时器(Timer0)延时500ms后,输出信号Y00置为ON。
3. 第二个定时器(Timer2)延时1000ms后,输出信号Y00置为OFF。
定时器配置
首先,我们需要配置两个定时器,使其基础定时周期为1ms。这一配置在bsptimer.c文件中的void Timerconfig(void)函数中完成。以下是配置代码:
c
include "bsptimer.h"
// 定时器配置
void Timerconfig(void)
{
TIMInitTypeDef TIMInitStructure;// 结构定义
TIMInitStructure.TIMMode = TIM16BitAutoReload;// 指定工作模式, TIM16BitAutoReload, TIM16Bit, TIM8BitAutoReload, TIM16BitAutoReloadNoMask
TIMInitStructure.TIMPolity = PolityLow;// 指定中断优先级(低到高) Polity0, Polity1, Polity2, Polity3
TIMInitStructure.TIMInterrupt = ENABLE;// 使能中断
TIMInitStructure.TIMClkSource = TIMCLK1T;// 时钟源选择, TIMCLK1T, TIMCLK12T
TIMInitStructure.TIMClkOut = DISABLE;// 禁止时钟输出
TIMInitStructure.TIMValue = 1000;// 定时器初值, 1ms定时
// 配置Timer0
TIMInit(TIM0, &TIMInitStructure);
TIMSetRunState(TIM0, DISABLE);// 初始状态为停止
// 配置Timer2
TIMInit(TIM2, &TIMInitStructure);
TIMSetRunState(TIM2, DISABLE);// 初始状态为停止
}
输入信号检测与定时器启动
接下来,我们需要检测输入信号X00的上升沿,并在检测到上升沿时启动两个定时器。以下是实现代码:
c
include "bspgpio.h"
include "bsptimer.h"
// 检测X00上升沿并启动定时器
void DetectX00RisingEdge(void)
{
static uint8t lastState = 0;// 上一次的输入状态
uint8t currentState = GPIOReadInputPin(GPIOPINX00);// 读取当前输入状态
if (lastState == 0 && currentState == 1)// 检测到上升沿
{
TIMSetRunState(TIM0, ENABLE);// 启动Timer0
TIMSetRunState(TIM2, ENABLE);// 启动Timer2
}
lastState = currentState;// 更新上一次的输入状态
}
定时器中断处理
在定时器中断处理函数中,我们需要根据定时器的计时情况来控制输出信号Y00的状态。以下是中断处理代码:
c
include "bspgpio.h"
include "bsptimer.h"
// Timer0中断处理函数
void TIM0IRQHandler(void)
{
static uint16t timer0Count = 0;
if (TIMGetITStatus(TIM0) == SET)// 检查中断标志
{
timer0Count++;
if (timer0Count >= 500)// 500ms到达
{
GPIOWriteOutputPin(GPIOPINY00, GPIOPINSET);// Y00置为ON
TIMSetRunState(TIM0, DISABLE);// 停止Timer0
timer0Count = 0;// 重置计数器
}
TIMClearITPendingBit(TIM0);// 清除中断标志
}
}
// Timer2中断处理函数
void TIM2IRQHandler(void)
{
static uint16t timer2Count = 0;
if (TIMGetITStatus(TIM2) == SET)// 检查中断标志
{
timer2Count++;
if (timer2Count >= 1000)// 1000ms到达
{
GPIOWriteOutputPin(GPIOPINY00, GPIOPINRESET);// Y00置为OFF
TIMSetRunState(TIM2, DISABLE);// 停止Timer2
timer2Count = 0;// 重置计数器
}
TIMClearITPendingBit(TIM2);// 清除中断标志
}
}
主函数
最后,在主函数中,我们需要初始化相关外设,并不断检测输入信号的状态。以下是主函数的实现:
c
include "bspgpio.h"
include "bsptimer.h"
int main(void)
{
// 初始化GPIO和定时器
GPIOInit();
Timerconfig();
while (1)
{
DetectX00RisingEdge();// 检测X00上升沿
}
}
总结
通过以上代码,我们实现了输入信号X00的上升沿检测,并通过两个定时器分别控制输出信号Y00的ON和OFF状态。这一功能在工业自动化控制中具有广泛的应用,例如在需要延时控制的设备启动、停止等场景中。
希望本文对大家理解定时器在工业自动化控制中的应用有所帮助。如果有任何问题或建议,欢迎在评论区留言讨论。感谢大家的阅读!
——『芯知识学堂』SingleYork
[本文内容由国芯人工智能辅助生成,仅供参考]
页:
[1]