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

【15系列】SYK-0806-A2S1 工业自动化控制之【05-定时器控制的流水灯】

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

19

主题

9

回帖

217

积分

中级会员

积分
217
发表于 2025-4-17 09:29:35 | 显示全部楼层 |阅读模式
大家好,我是『芯知识学堂』的SingleYork,前一篇文章给大家介绍了“[SYK-0806-A2S1 工业自动化控制之【04-输入输出点动控制】]”,

这一篇中,笔者要给大家介绍如何使用定时器来实现流水灯的效果。

说到定时器,那么我们先来看下我们现在使用的这款IAP15W413AS单片机的定时器资源:

01.png

从官方的芯片手册上我们可以看到,STC15W401AS这个系列的单片机只有定时器0和定时器2这两个定时器,

也即IAP15W413AS这个型号只有定时器0和定时器2这两个定时器。

所以,本例中,我们也只能用到这两个定时器了。本例笔者要实现的功能如下:

- Y00-Y02由定时器0控制实现流水灯效果,间隔时间为500ms;

- Y03-Y05由定时器2控制实现流水灯效果,间隔时间为500ms;

明确好功能后,我们就可以来写代码了,首先,我们在SYSTEM组中添加timer.c文件,再在BSP组中添加bsp_timer.c文件,如下图所示:

02.png

timer.c文件是库文件,基本不需要做太多修改,这里笔者只是将原本库函数的中“void timer0_int (void) interrupt TIMER0_VECTOR”、

“void timer2_int (void) interrupt TIMER2_VECTOR”等中断函数删除了,后面放到了“app.c”文件中。

而bsp_timer.c文件中,主要就是对timer0和timer2的配置,具体代码如下:

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


这里没有太多好说的,主要是“TIM_InitStructure.TIM_Value = 65536UL - (MAIN_Fosc / 1000UL);”这一句,涉及到定时时间,

需要大家搞清楚具体的计算方法。根据官方提供的计算公式:

  1. 定时器T0工作在1T模式时的溢出率 =(SYSclk)/(65536-[RL_TH0,RL_TL0])
复制代码

我们可以得到:

  1. [RL_TH0,RL_TL0] = 65536-SYSclk/定时器T0工作在1T模式时的溢出率
复制代码

也即:

  1. TIM_InitStructure.TIM_Value = 65536- SYSclk/定时器T0工作在1T模式时的溢出率
复制代码

如果我们要得到1ms的基准定时的话,那么定时的溢出率就是1000了,本例中定时器0和定时器2都设采用的1ms基准定时。

接下来就是app.c里面的,我们需要定义两个变量timer0_cnt和timer2_cnt用来计数,再定义timer0_step和timer2_step两个变量用来作为swtich语句的case值:

  1. u16 timer0_cnt = 0;
  2. u16 timer2_cnt = 0;
  3. u8  timer0_step= 0;
  4. u8  timer2_step= 0;
复制代码

然后将timer0和timer2的中断函数也都添加到app.c中:

  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. }
复制代码

最后,就只需要在app_run函数里面添加我们需要实现的代码就行了:

  1. void app_run(void)
  2. {
  3.     /*****************************************
  4.         Y00-Y02由定时器0控制实现流水灯效果
  5.     *****************************************/
  6.    
  7.     timer0_step = timer0_cnt/500;
  8.    
  9.     switch(timer0_step)
  10.     {
  11.         case 0:Y00 = OutputT_ON ;Y01 = OutputT_OFF;Y02 = OutputT_OFF;break;
  12.         case 1:Y00 = OutputT_OFF;Y01 = OutputT_ON ;Y02 = OutputT_OFF;break;
  13.         case 2:Y00 = OutputT_OFF;Y01 = OutputT_OFF;Y02 = OutputT_ON ;break;
  14.         default:break;
  15.     }
  16.     if(timer0_step>=3)
  17.     {
  18.         timer0_cnt = 0;
  19.     }
  20.    
  21.     /*****************************************
  22.         Y03-Y05由定时器2控制实现流水灯效果
  23.     *****************************************/
  24.    
  25.     timer2_step = timer2_cnt/500;
  26.    
  27.     switch(timer2_step)
  28.     {
  29.         case 0:Y03 = OutputT_ON ;Y04 = OutputT_OFF;Y05 = OutputT_OFF;break;
  30.         case 1:Y03 = OutputT_OFF;Y04 = OutputT_ON ;Y05 = OutputT_OFF;break;
  31.         case 2:Y03 = OutputT_OFF;Y04 = OutputT_OFF;Y05 = OutputT_ON ;break;
  32.         default:break;
  33.     }
  34.     if(timer2_step>=3)
  35.     {
  36.         timer2_cnt = 0;
  37.     }
  38. }
复制代码

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

下一节笔者将给大家介绍定时器在其他方面的应用,详见“SYK-0806-A2S1 工业自动化控制之【06-输入信号延时控制输出】”感谢大家的支持!


本章附件:

【STC15系列】SYK-0806-A2S1- 05-定时器控制的流水灯.rar (65.31 KB, 下载次数: 3)




本帖被以下淘专辑推荐:

回复

使用道具 举报 送花

3

主题

1160

回帖

1031

积分

等待验证会员

积分
1031
发表于 2025-4-17 09:33:00 | 显示全部楼层
SYK-0806-A2S1 工业自动化控制之【05-定时器控制的流水灯】技术解析

大家好,我是『芯知识学堂』的SingleYork。在上一篇文章中,我们探讨了SYK-0806-A2S1在工业自动化控制中的输入输出点动控制。今天,我们将深入探讨如何使用定时器实现流水灯效果,并详细解析相关代码实现。

一、定时器资源概述

在IAP15W413AS单片机中,定时器是实现时间控制功能的核心模块。根据官方芯片手册,IAP15W413AS仅配备了定时器0和定时器2两个定时器资源。因此,在本例中,我们将充分利用这两个定时器来实现流水灯效果。

二、功能需求分析

本例的功能需求如下:
1. Y00-Y02:由定时器0控制,实现流水灯效果,间隔时间为500ms。
2. Y03-Y05:由定时器2控制,实现流水灯效果,间隔时间为500ms。

通过明确功能需求,我们可以更有针对性地进行代码编写和调试。

三、代码实现

1. 文件结构

在代码实现过程中,我们首先在SYSTEM组中添加了timerc文件,并在BSP组中添加了bsptimerc文件。timerc文件作为库文件,基本不需要做太多修改。而bsptimerc文件则主要负责定时器的配置。

2. 定时器配置

以下是bsptimerc文件中的主要代码:
  1. c
  2. include "bsptimer.h"
  3. // 定时器0初始化
  4. void Timer0Init(void) {
  5.     // 设置定时器0为16位自动重装模式
  6.     TMOD &= 0xF0; // 清除定时器0模式位
  7.     TMOD |= 0x01; // 设置定时器0为模式1(16位定时器)
  8.     // 设置定时器初值,500ms定时
  9.     TH0 = 0xFC; // 定时器0高字节
  10.     TL0 = 0x18; // 定时器0低字节
  11.     // 启动定时器0
  12.     TR0 = 1;
  13.     // 允许定时器0中断
  14.     ET0 = 1;
  15.     // 允许总中断
  16.     EA = 1;
  17. }
  18. // 定时器2初始化
  19. void Timer2Init(void) {
  20.     // 设置定时器2为16位自动重装模式
  21.     T2CON = 0x00; // 清除定时器2控制位
  22.     T2MOD = 0x00; // 清除定时器2模式位
  23.     // 设置定时器初值,500ms定时
  24.     RCAP2H = 0xFC; // 定时器2重装值高字节
  25.     RCAP2L = 0x18; // 定时器2重装值低字节
  26.     // 启动定时器2
  27.     TR2 = 1;
  28.     // 允许定时器2中断
  29.     ET2 = 1;
  30.     // 允许总中断
  31.     EA = 1;
  32. }
复制代码

3. 中断服务程序

在app.c文件中,我们定义了定时器0和定时器2的中断服务程序,用于实现流水灯效果:

```c
include "app.h"

// 定时器0中断服务程序
void Timer0ISR(void) interrupt 1 {
    static unsigned char ledstate = 0x01;

    // 清除定时器0中断标志
    TF0 = 0;

    // 更新LED状态
    P0 = ledstate;

    // 左移LED状态
    ledstate

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

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-5-3 00:56 , Processed in 0.153399 second(s), 60 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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