查看: 3063|回复: 3

[项目] 《GD32-Colibri-F207ZE开发板玩家笔记》之Systick_Ticker

[复制链接]
  • TA的每日心情
    奋斗
    2018-10-29 22:48
  • 签到天数: 731 天

    连续签到: 1 天

    [LV.9]以坛为家II

    发表于 2016-2-20 12:51:57 | 显示全部楼层 |阅读模式
    分享到:
    Systick_Ticker工程实现的功能是,使用ARM处理器的Systick定时器计时,在定时器中断服务程序中控制三个LED灯闪烁的频率。
    需要考虑到几个设计要点:
    (1)应用Systick定时器,设定定时器的计时周期,并启用定时溢出中断。
    (2)应用GPIO驱动程序调用底层硬件控制可编程LED引脚的电平。
    (3)在Systick定时器中断服务程序中,使用软件实现的分频计数器,对Systick定时器的溢出频率进行分频,得到三个LED灯各自闪烁的频率。
    在程序主循环中,通过在串口终端中输入按键(任何字符均可),触发Systick定时器的启动和关闭:当Systick定时器启动时,可以观察到三个LED灯各自闪烁;当Systick定时器关闭时,LED灯停止闪烁,保持状态。
    开始编程:

    步骤一:创建工程
    考虑到要使用stdio的通信信道作为人机交互,同时要使用GPIO控制LED灯闪烁,在项目代码树的“\example”目录下,复制已经创建好的样例工程“GPIO_BlinkyLED”作为本工程的模板,改目录名为“Systick_Ticker”。Systick模块本身是ARM定义的一个标准模块,其相关的寄存器及操作函数被定义arm_cm3.h文件中,因此不需要额外引用外部驱动文件。
    在Keil集成开发环境下组织工程代码如图1所示。
    图1.png

    图1 Systick_Ticker工程组织
    步骤二:添加应用代码
    本工程基于GPIO_BlinkyLED,所以继承了关于控制LED灯的函数,包括:
    1. /* LED. */
    2. void LED_Configuration(void);
    3. void LED_LightOn(uint32_t ledIdx);
    4. void LED_LightOff(uint32_t ledIdx);
    5. void LED_LightSwitch(uint32_t ledIdx);
    复制代码
    在main.c文件中添加关于Systick定时器的程序代码如下:
    1. void Ticker_Configuration(uint32_t tickersPerSecond)
    2. {
    3.     SysTick_Config(SystemCoreClock / tickersPerSecond);
    4.     NVIC_SetPriority(SysTick_IRQn, 0x00);
    5.    
    6.     SysTick->LOAD  = (uint32_t)(SystemCoreClock / tickersPerSecond - 1UL); /* set reload register */
    7.     NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
    8.     SysTick->VAL   = 0UL;                                             /* Load the SysTick Counter Value */
    9.     SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk | /* Select the clock source. */
    10.                    SysTick_CTRL_TICKINT_Msk;      /* Enable SysTick IRQ. */
    11. }

    12. void Ticker_Start(void)
    13. {
    14.     SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
    15. }

    16. void Ticker_Pause(void)
    17. {
    18.     SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
    19. }
    复制代码
    其中,Ticker_Configuration()函数配置Systick定时器以传入参数tickersPerSecond为频率周期产生时钟滴答(Tick),并启用Systick中断在滴答到来之时被触发执行服务程序。Ticker_Start()和Ticker_Start()用于启动和暂停定时器。
    特别设计Systick定时器中断服务程序如下:

    1. /*
    2. * Interrupt Service Routine.
    3. */
    4. volatile uint32_t gTickerCounter[3] = {0};
    5. const uint32_t gLedSwitchTickers[3] = {100U, 200U, 400U};
    6. void SysTick_Handler(void)
    7. {
    8.     uint32_t i;
    9.    
    10.     for (i = 0U; i < 3U; i++)
    11.     {
    12.         if (gTickerCounter[i] >= gLedSwitchTickers[i])
    13.         {
    14.             gTickerCounter[i] = 0U;
    15.             LED_LightSwitch(i); /* Switch the LED. */
    16.         }
    17.         gTickerCounter[i]++;
    18.     }
    19. }
    复制代码
    此时,使用gLedSwitchTickers[]数组为三个LED灯指定闪烁频率的分频因子,分别为100、200、400。在Systick的中断服务程序SysTick_Handler中,基于分频后的节奏分别控制三个LED灯。
    最后,实现顶层的main函数如下:
    1. /*
    2. * Application Entry.
    3. */
    4. int main(void)
    5. {
    6.     BSP_InitStdioUART(115200U);

    7.     printf("\r\n\r\n# Systick_TickerInterrupt Exampler #\r\n");

    8.     /* Initialize the application. */
    9.     printf("# Initializing ...\r\n");
    10.    
    11.     LED_Configuration();
    12.     Ticker_Configuration(200U); /* 200 tickers per second. 1 ticker = 5ms. */
    13.    
    14.     printf("# Ready.\r\n");
    15.    
    16.     /* Print the user guide. */
    17.     printf("Press any key to toggle the ticker ...\r\n");
    18.    
    19.     while (1)
    20.     {
    21.         getchar();
    22.         Ticker_Start();
    23.         printf("Ticker_Start()\r\n");
    24.         getchar();
    25.         Ticker_Pause();
    26.         printf("Ticker_Pause()\r\n");
    27.     }
    28. }
    复制代码
    步骤三:下载程序,运行
    编译工程,下载到开发板。在上位机启动串口通信终端界面后,复位开发板运行程序。此时,根据终端输出的提示信息,在终端界面中输入回车(或者其它任何字符均可)启动Systick定时器,观察开发板即可发现三个LED灯以“二进制编码”递增序列闪烁。再次输入回车暂停Systick定时器,LED灯保持最后状态停止闪烁。如此反复。上位机的串口通信终端输入信息如图2所示。
    图2.png

    图2 Systick_Ticker终端界面输出





    回复

    使用道具 举报

  • TA的每日心情
    擦汗
    2019-8-27 21:30
  • 签到天数: 219 天

    连续签到: 1 天

    [LV.7]常住居民III

    发表于 2016-2-20 13:41:12 | 显示全部楼层
    这个终端是怎么调用生成的呢?
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    2018-10-29 22:48
  • 签到天数: 731 天

    连续签到: 1 天

    [LV.9]以坛为家II

     楼主| 发表于 2016-2-20 16:09:30 | 显示全部楼层
    michael_llh 发表于 2016-2-20 13:41
    这个终端是怎么调用生成的呢?

    用的Tera Term,具体使用可参见 https://www.cirmall.com/bbs/thread-46475-1-1.html
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    擦汗
    2019-8-27 21:30
  • 签到天数: 219 天

    连续签到: 1 天

    [LV.7]常住居民III

    发表于 2016-2-20 17:17:03 | 显示全部楼层
    suyong_yq 发表于 2016-2-20 16:09
    用的Tera Term,具体使用可参见 https://www.cirmall.com/bbs/thread-46475-1-1.html

    好的谢谢!
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /2 下一条



    手机版|小黑屋|与非网

    GMT+8, 2024-4-19 15:13 , Processed in 0.149609 second(s), 22 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2020, Tencent Cloud.