找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6795|回复: 1
打印 上一主题 下一主题
收起左侧

[零基础学习STM32]第五讲:SYSTICK定时器实验—定时点亮LED

[复制链接]
跳转到指定楼层
楼主
一、 概述
1、 时钟系统简介
(1)STM32时钟源分以下五类:
  • 高速内部时钟(HSI):RC振荡器,精度不高。
  • 高速外部时钟(HSE):可接石英/陶瓷谐振器或者接外部时钟源。
  • 低速内部时钟(LSI):RC振荡器,提供低功耗时钟。应用如WDG。
  • 低速外部时钟(LSE):接外部低频率石英晶体。应用如RTC。
  • 常闭不带复位:锁相环倍环输出(PLL):其时钟输入源可选择为HSI/2、HSE或者HSE/2。倍频倍数可调,但是其最大输出频率受限数值因芯片型号而异。
(2)系统时钟SYSCLK可来源于:HSI振荡器时钟、HSE振荡器时钟、PLL时钟。
2、SYTICK简介
     在STM32中,SysTick是内核CM4中的一个24位的递减计数器,也称系统嘀答定时器。SysTick的最大使命,就是定期地产生异常请求,作为系统的时基。操作系统需要这种“滴答”来推动任务和时间的管理。
     SysTick在设定初值并开启后,每经一个系统时钟周期,计数值减1,计数到0时,将从重载寄存器中自动重新装载定时初值并继续计数,同时内部的COUNTFLAG标志位置1,触发中断(中断允许情况下),中断响应属于NVIC异常,异常号为15,Systick中断优先级可设置。
3、SYTICK寄存器控制
     STM32内部有4个寄存器控制SysTick定时器。分别为:控制寄存器STK_CSR、重载寄存器STK_LOAD、当前值寄存器STK_VAL和校准值寄存器STK_CALRB。下面分别对这4个寄存器做详细介绍。
(1)控制寄存器STK_CSR(地址:0xE000E010)
       控制寄存器STK_CSR中有4个bit具有意义,其内容如图4_0、表4_0所示:
ENABLE(位0) Systick使能位。
0:关闭Systick功能;
1:开启Systick功能。
TICKINT(位1) Systick中断使能位。
0:关闭Systick中断;
1:开启Systick中断,systick倒数到零时产生systick异常中断。
CLKSOURCE(位2) Systick时钟源选择位。
0:使用HCLK/8作为Systick时钟(外部时钟);
1:使用HCLK作为Systick时钟(内核时钟)。
COUNTFLAG(位16) Systick计数比较标志,如果在上次读取本寄存器后,SysTick已经数到了0,则该位为1。如果读取该位,该位将自动清零。
           表4_0  控制寄存器STK_CSR的格式
(2)重载寄存器STK_LOAD(地址:0xE000E014)
           图4_1 重载寄存器STK_LOAD的格式
重载寄存器STK_LOAD为24位的寄存器(0:23有效),最大计数0xFFFFFF。SysTick定时器递减至0时,重载寄存器中的值就会被重新装载,继续开始递减计数。
(3)当前值寄存器STK_VAL(地址:0xE000E018)
          图4_2 当前值寄存器STK_VAL的格式
当前值寄存器STK_VAL为24位的寄存器,读取时返回当前计数的值,写它则使之清零,同时还会清除在SysTick控制及状态寄存器中的COUNTFLAG标志。
(4)校准值寄存器STK_CALRB(地址:0xE000E01C)




       图4_3 校准值值寄存器STK_CALRB的格式
NOREF 0:HCLK可用;
1:HCLK不可用。
SKEW 0:校准值是准确的10ms;
1:校准值不是准确的10ms。
TENMS 该值是10ms定时的重装值。其值取决于SKEW,它可以是精确的10ms,也可以是接近10ms的值。如果该值为0,则表示无法使用校准功能,这很可能是因为时钟是系统的一个未知输入或者时钟可以动态调节。
         表4_1寄存器STK_CALRB的格式
二、实验原理
     通过STM32的三个GPIO口驱动三色LED的三个通道;设定GPIO为推挽输出;采用灌电流的方式与LED连接,输出高电平LED灭,输出低电平LED亮。通过系统定时器实现1s定时,每秒变换一次LED颜色。
           图4_4 驱动示意图
三、源代码
1.主函数
  1. /*
  2. * Name                : main
  3. * Description         : ---
  4. * Author              : ysloveivy.
  5. *
  6. * History
  7. * --------------------
  8. * Rev                 : 0.00
  9. * Date                : 11/21/2015
  10. *
  11. * create.
  12. * --------------------
  13. */
  14. int main(void)
  15. {
  16.         static int work_status = 0;
  17.         led.initialize();
  18.         systick.initialize();
  19.         //每隔一秒三色灯进行交替循环闪烁
  20.         while(1){
  21. if(systick.second_flag == 1){ //每隔一秒标志位置1,执行一次
  22.                         systick.second_flag = 0;
  23.                         work_status += 1;
  24.                         if(work_status > 2)work_status = 0;
  25.                 }
  26.                 switch (work_status){
  27.                         case 0 :
  28.                                 LED_RED_ON;
  29.                                 LED_GREEN_OFF;
  30.                                 LED_BLUE_OFF;
  31.                                 break;

  32.                         case 1 :
  33.                                 LED_RED_OFF;
  34.                                 LED_GREEN_ON;
  35.                                 LED_BLUE_OFF;
  36.                                 break;

  37.                         case 2:
  38.                                 LED_RED_OFF;
  39.                                 LED_GREEN_OFF;
  40.                                 LED_BLUE_ON;
  41.                                 break;

  42.                         default:
复制代码
2.Systick初始化
   以下是Systick初始化及中断设置函数,主要实现定标志位的时1s,改变一次标志位,使用LED显色状态变换一次。
  1. /*
  2. * Name               : initialize
  3. * Description        : ---
  4. * Author             : ysloveivy.
  5. *
  6. * History
  7. * -------------------
  8. * Rev                : 0.00
  9. * Date               : 11/21/2015
  10. *
  11. * create.
  12. * -------------------
  13. */
  14. static int initialize(void)
  15. {
  16.         //定时1ms
  17.         if(SysTick_Config(SystemCoreClock / 1000)){
  18.                 while(1);
  19.         }
  20.         return 0;
  21. }
  22. /*
  23. * Name               : SysTick_Handler
  24. * Description        : ---
  25. * Author             : ysloveivy.
  26. * History
  27. * -------------------
  28. * Rev                : 0.00
  29. * Date               : 11/21/2015
  30. *
  31. * create.
  32. * -------------------
  33. */
  34. void SysTick_Handler(void)
  35. {
  36.         static int counter = 0;

  37.         if((counter ++ % 1000) == 0){ //每次中断counter自加1,判断是否整秒
  38.                 systick.second_flag = 1;
  39.         }
  40. }
复制代码
3.小知识
   在上面有两个重要的函数
   1.SysTick_Confing(uint32_t ticks)
    该函数的作用是初始化systick,时钟为HCLK(CM3一般为72M,CM4一般为168M),并开启中断。
  1. __STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
  2. {
  3.   if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)  //大于重载寄存器最大值0xFFFFFF
  4.   {
  5. return (1UL);                                //重新加载值不可能,返回错误           
  6. }
  7.   SysTick->LOAD  = (uint32_t)(ticks - 1UL);      //计数范围0到ticks-1                  
  8. NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL);
  9. //设置优先级
  10. SysTick->VAL   = 0UL;                              //当前值初始化为0   
  11.   //接下来设置控制寄存器,以位与的方式实现三个控制位的设置。
  12.   SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk | //选择时钟源
  13.                       SysTick_CTRL_TICKINT_Msk   |  //开启中断
  14.                       SysTick_CTRL_ENABLE_Msk;      //使能定时器               
  15.   return (0UL);                                       //初始化成功返回         
  16. }
复制代码
     回头看看程序中的SysTick_Config(SystemCoreClock / 1000)语句,该函数中的SystemCoreClock为时钟频率已在库函数中宏定义。如在iCore3双核心板ARM的HCLK为168M(每秒168M次计数),则程序中SystemCoreClock / 1000即意味每1ms中断一次。
    2.void SysTick_Handler(void)
    该函数是中断函数,即每次SysTick中断产生时运行一次函数,其在启动文件中已有设置,在驱动文件中使用时无需再次声明。
四、 实验现象
      iCore3的双核心板上与ARM相连的三色LED(PCB上标示为ARM·LED),红色、绿色、蓝色每秒交替点亮。
五、 代码包下载链接

iCore3_5_SYSTICK.rar

956.4 KB, 下载次数: 18, 下载积分: 黑币 -5

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:89134 发表于 2019-1-21 21:29 | 只看该作者
为什么没有同时亮
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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