找回密码
 立即注册
查看: 50|回复: 1

【15系列】SYK-0806-A2S1 工业自动化控制之【06-输入信号延时控制输出】

[复制链接]
  • 打卡等级:偶尔看看I
  • 打卡总天数:15
  • 最近打卡:2025-04-21 13:00:02

19

主题

9

回帖

217

积分

中级会员

积分
217
发表于 2025-4-17 09:33:16 | 显示全部楼层 |阅读模式
大家好,我是『芯知识学堂』的SingleYork,前一篇文章给大家介绍了“SYK-0806-A2S1 工业自动化控制之【05-定时器控制的流水灯】”,

这一篇中,笔者要给大家介绍如何使用定时器在项目中的一些实际应用。

首先,我们先来介绍一下本例要实现的功能:

当X00信号由低电平变成高电平时(即一个上升沿,类似一个按键按下并松开),延时500ms(该延时由timer0实现),Y00输出ON;

延时1000ms(该延时由timer2实现),Y00输出OFF。

确定好功能后,我们便可以开始写代码了,首先 ,两个定时器的配置,跟上一讲的一样,基础定时均配置成1ms,

这个配置在bsp_timer.c文件中的void Timer_config(void)函数中完成:

  1. #include        "bsp_timer.h"
  2. /************************ 定时器配置 ****************************/
  3. void        Timer_config(void)
  4. {
  5.         TIM_InitTypeDef                TIM_InitStructure;                                                //结构定义
  6.    
  7.         TIM_InitStructure.TIM_Mode      = TIM_16BitAutoReload;            //指定工作模式,   TIM_16BitAutoReload,TIM_16Bit,TIM_8BitAutoReload,TIM_16BitAutoReloadNoMask
  8.         TIM_InitStructure.TIM_Polity    = PolityLow;                            //指定中断优先级(低到高) Polity_0,Polity_1,Polity_2,Polity_3
  9.         TIM_InitStructure.TIM_Interrupt = ENABLE;                                        //中断是否允许,   ENABLE或DISABLE
  10.         TIM_InitStructure.TIM_ClkSource = TIM_CLOCK_1T;                        //指定时钟源,     TIM_CLOCK_1T,TIM_CLOCK_12T,TIM_CLOCK_Ext
  11.         TIM_InitStructure.TIM_ClkOut    = DISABLE;                                    //是否输出高速脉冲, ENABLE或DISABLE
  12.         TIM_InitStructure.TIM_Value     = 65536UL - (MAIN_Fosc / 1000UL);                //初值,
  13.         TIM_InitStructure.TIM_Run       = ENABLE;                                        //是否初始化后启动定时器, ENABLE或DISABLE
  14.         Timer_Inilize(Timer0,&TIM_InitStructure);                                        //初始化Timer0          Timer0,Timer1,Timer2,Timer3,Timer4
  15.         TIM_InitStructure.TIM_Mode      = TIM_16BitAutoReload;            //指定工作模式,   TIM_16BitAutoReload,TIM_16Bit,TIM_8BitAutoReload
  16.         TIM_InitStructure.TIM_Polity    = PolityLow;                            //指定中断优先级, PolityHigh,PolityLow
  17.         TIM_InitStructure.TIM_Interrupt = ENABLE;                                    //中断是否允许,   ENABLE或DISABLE
  18.         TIM_InitStructure.TIM_ClkSource = TIM_CLOCK_1T;                            //指定时钟源, TIM_CLOCK_1T,TIM_CLOCK_12T,TIM_CLOCK_Ext
  19.         TIM_InitStructure.TIM_ClkOut    = DISABLE;                                    //是否输出高速脉冲, ENABLE或DISABLE
  20.         TIM_InitStructure.TIM_Value     = 65536UL - (MAIN_Fosc / 1000UL);                //初值,
  21.         TIM_InitStructure.TIM_Run       = ENABLE;                                    //是否初始化后启动定时器, ENABLE或DISABLE
  22.         Timer_Inilize(Timer2,&TIM_InitStructure);                                    //初始化Timer1          Timer0,Timer1,Timer2,Timer3,Timer4
  23. }
复制代码

主要功能的实现,我们还是在app.c文件中完成,首先,在app.c文件中定义几个变量,如下:

  1. u16 timer0_cnt = 0;
  2. u16 timer2_cnt = 0;
  3. u8  X00_Step   = 0;
  4. bit F_X00_Low  = 0;
  5. bit F_X00_High = 0;
复制代码

其中,timer0_cnt和timer2_cnt主要用于timer0和timer2的计时,X00_Step用于动作流程的控制,

F_X00_Low和F_X00_High用于X00的高、低电平两种状态标记。

功能实现的代码主要是在app_run()函数中,分为两部分,第一部分,就是判断X00的状态,即判断“X00是否由低电平变成高电平”:

  1.     if(!F_X00_Low)
  2.     {
  3.         if(!X00)         //X00低电平
  4.         {
  5.             delay_ms(10);//10ms消抖
  6.             if(!X00)
  7.             {
  8.                 F_X00_Low = 1;//X00低电平标志置“1”
  9.                 F_X00_High= 0;//X00高电平标志清“0”
  10.             }
  11.         }
  12.     }
  13.     else
  14.     {
  15.         if(X00)         //X00高电平
  16.         {
  17.             delay_ms(10);//10ms消抖
  18.             if(X00)
  19.             {
  20.                 F_X00_Low = 0;//X00低电平标志清“0”
  21.                 F_X00_High= 1;//X00高电平标志置“1”
  22.                 timer0_cnt= 0;//timer0定时计数清理
  23.                 X00_Step  = 0;
  24.             }
  25.         }
  26.     }
复制代码

第二部分就是Y00的动作逻辑,即,在识别到X00由低电平变成高电平后,延时500ms(该延时由timer0实现),Y00输出ON;

延时1000ms(该延时由timer2实现),Y00输出OFF:

  1.     if(F_X00_High)
  2.     {
  3.         switch(X00_Step)
  4.         {
  5.             case 0:
  6.             {
  7.                 if(timer0_cnt>=500)//timer0计时到500ms,Y00输出ON
  8.                 {
  9.                     Y00       = OutputT_ON;
  10.                     timer2_cnt= 0;//timer2定时计数清理
  11.                     X00_Step  ++ ;
  12.                 }
  13.                 break;
  14.             }
  15.             case 1:
  16.             {
  17.                 if(timer2_cnt>=1000)//timer2计时到500ms,Y00输出ON
  18.                 {
  19.                     Y00       = OutputT_OFF;
  20.                     X00_Step  ++ ;
  21.                     F_X00_High= 0;
  22.                 }
  23.                 break;
  24.             }
  25.             default:break;
  26.         }
  27.     }
复制代码

定时器timer0和timer1的中断函数内容也很简单,只需要在中断函数里面分别对timer0_cnt和timer2_cnt计数加“1”即可,

然后,在每次需要用到计时的时候,先将timer0_cnt或timer2_cnt的计数值清零。

  1. /********************* Timer0中断函数************************/
  2. void timer0_int (void) interrupt TIMER0_VECTOR //1ms
  3. {
  4.     timer0_cnt ++;
  5. }
  6. /********************* Timer0中断函数************************/
  7. void timer2_int (void) interrupt TIMER2_VECTOR //1ms
  8. {
  9.     timer2_cnt ++;
  10. }
复制代码

至此,代码大功告成!好了,关于使用本节内容笔者就介绍到这里了,有疑问的小伙伴们可以给笔者留言或者直接参与评论,

下一节笔者将给大家介绍“如何利用定时器产生自己想要的频率”,详见“SYK-0806-A2S1 工业自动化控制之【07-定时器产生特定频率脉冲】”感谢大家的支持!

本章附件:

【STC15系列】SYK-0806-A2S1- 06-输入输出信号延时控制.rar (65.78 KB, 下载次数: 1)




本帖被以下淘专辑推荐:

回复

使用道具 举报 送花

3

主题

1160

回帖

1031

积分

等待验证会员

积分
1031
发表于 2025-4-17 09:53:00 | 显示全部楼层
大家好,我是『芯知识学堂』的SingleYork,今天我们将继续探讨SYK-0806-A2S1在工业自动化控制中的应用,具体讲解如何通过定时器实现输入信号的延时控制输出。

功能描述

在本例中,我们需要实现以下功能:

1. 当输入信号X00从低电平变为高电平(即检测到一个上升沿,类似于按键按下并松开)时,启动两个定时器。
2. 第一个定时器(Timer0)延时500ms后,输出信号Y00置为ON。
3. 第二个定时器(Timer2)延时1000ms后,输出信号Y00置为OFF。

定时器配置

首先,我们需要配置两个定时器,使其基础定时周期为1ms。这一配置在bsptimer.c文件中的void Timerconfig(void)函数中完成。以下是配置代码:
  1. c
  2. include "bsptimer.h"
  3. // 定时器配置
  4. void Timerconfig(void)
  5. {
  6.     TIMInitTypeDef TIMInitStructure;  // 结构定义
  7.     TIMInitStructure.TIMMode = TIM16BitAutoReload;  // 指定工作模式, TIM16BitAutoReload, TIM16Bit, TIM8BitAutoReload, TIM16BitAutoReloadNoMask
  8.     TIMInitStructure.TIMPolity = PolityLow;  // 指定中断优先级(低到高) Polity0, Polity1, Polity2, Polity3
  9.     TIMInitStructure.TIMInterrupt = ENABLE;  // 使能中断
  10.     TIMInitStructure.TIMClkSource = TIMCLK1T;  // 时钟源选择, TIMCLK1T, TIMCLK12T
  11.     TIMInitStructure.TIMClkOut = DISABLE;  // 禁止时钟输出
  12.     TIMInitStructure.TIMValue = 1000;  // 定时器初值, 1ms定时
  13.     // 配置Timer0
  14.     TIMInit(TIM0, &TIMInitStructure);
  15.     TIMSetRunState(TIM0, DISABLE);  // 初始状态为停止
  16.     // 配置Timer2
  17.     TIMInit(TIM2, &TIMInitStructure);
  18.     TIMSetRunState(TIM2, DISABLE);  // 初始状态为停止
  19. }
复制代码

输入信号检测与定时器启动

接下来,我们需要检测输入信号X00的上升沿,并在检测到上升沿时启动两个定时器。以下是实现代码:
  1. c
  2. include "bspgpio.h"
  3. include "bsptimer.h"
  4. // 检测X00上升沿并启动定时器
  5. void DetectX00RisingEdge(void)
  6. {
  7.     static uint8t lastState = 0;  // 上一次的输入状态
  8.     uint8t currentState = GPIOReadInputPin(GPIOPINX00);  // 读取当前输入状态
  9.     if (lastState == 0 && currentState == 1)  // 检测到上升沿
  10.     {
  11.         TIMSetRunState(TIM0, ENABLE);  // 启动Timer0
  12.         TIMSetRunState(TIM2, ENABLE);  // 启动Timer2
  13.     }
  14.     lastState = currentState;  // 更新上一次的输入状态
  15. }
复制代码

定时器中断处理

在定时器中断处理函数中,我们需要根据定时器的计时情况来控制输出信号Y00的状态。以下是中断处理代码:
  1. c
  2. include "bspgpio.h"
  3. include "bsptimer.h"
  4. // Timer0中断处理函数
  5. void TIM0IRQHandler(void)
  6. {
  7.     static uint16t timer0Count = 0;
  8.     if (TIMGetITStatus(TIM0) == SET)  // 检查中断标志
  9.     {
  10.         timer0Count++;
  11.         if (timer0Count >= 500)  // 500ms到达
  12.         {
  13.             GPIOWriteOutputPin(GPIOPINY00, GPIOPINSET);  // Y00置为ON
  14.             TIMSetRunState(TIM0, DISABLE);  // 停止Timer0
  15.             timer0Count = 0;  // 重置计数器
  16.         }
  17.         TIMClearITPendingBit(TIM0);  // 清除中断标志
  18.     }
  19. }
  20. // Timer2中断处理函数
  21. void TIM2IRQHandler(void)
  22. {
  23.     static uint16t timer2Count = 0;
  24.     if (TIMGetITStatus(TIM2) == SET)  // 检查中断标志
  25.     {
  26.         timer2Count++;
  27.         if (timer2Count >= 1000)  // 1000ms到达
  28.         {
  29.             GPIOWriteOutputPin(GPIOPINY00, GPIOPINRESET);  // Y00置为OFF
  30.             TIMSetRunState(TIM2, DISABLE);  // 停止Timer2
  31.             timer2Count = 0;  // 重置计数器
  32.         }
  33.         TIMClearITPendingBit(TIM2);  // 清除中断标志
  34.     }
  35. }
复制代码

主函数

最后,在主函数中,我们需要初始化相关外设,并不断检测输入信号的状态。以下是主函数的实现:
  1. c
  2. include "bspgpio.h"
  3. include "bsptimer.h"
  4. int main(void)
  5. {
  6.     // 初始化GPIO和定时器
  7.     GPIOInit();
  8.     Timerconfig();
  9.     while (1)
  10.     {
  11.         DetectX00RisingEdge();  // 检测X00上升沿
  12.     }
  13. }
复制代码

总结

通过以上代码,我们实现了输入信号X00的上升沿检测,并通过两个定时器分别控制输出信号Y00的ON和OFF状态。这一功能在工业自动化控制中具有广泛的应用,例如在需要延时控制的设备启动、停止等场景中。

希望本文对大家理解定时器在工业自动化控制中的应用有所帮助。如果有任何问题或建议,欢迎在评论区留言讨论。感谢大家的阅读!

——『芯知识学堂』SingleYork

[本文内容由国芯人工智能辅助生成,仅供参考]
回复 支持 反对

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-5-3 00:47 , Processed in 0.125122 second(s), 57 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表