当前位置:   article > 正文

SysTick_系统定时器实现流水灯_rgb灯定时时间

rgb灯定时时间

参考资料《 ARM Cortex™-M4F 技术参考手册》-4.5 章节 SysTick Timer(STK)

SysTick(系统滴答定时器),本质上就是一个内嵌在NVIC中的一个定时器,属于内核中的一个外设,是一个24位的向下递减的计数器,计数器每1/SYSCLK就减1,当寄存器的值减到0的时就会产生一次(硬件上的)中断,也有叫做滴答中断。主要的目的1、用来产生精确的延时。2、一般用于操作系统,用于产生时基,维持操作系统的心跳给操作系统提供一个单独的心跳(时钟)节拍。关于对于SyeTick的介绍我推荐看一下这位大神博客 https://blog.csdn.net/yx_l128125/article/details/7884423

SysTick的寄存器总共有四个,在使用SysTick产生定时的时候,只需配置前三个寄存器,最后一个校准值寄存器不需要使用。

接下来对各个寄存器的描述

SysTick控制及状态寄存器CTRL主要用来读取当前数值寄存器里的值、选择时钟源、使能异常请求、使能定时器。

SysTick重装载数值寄存器LOAD主要是用来存储计数的值,最大为2^{24}

SysTick当前数值寄存器VAL,每一个计数器每1/SYSCLK就减1,当减到0时,计数标志位置1,然后把重装载数值寄存器里的值写进当前数值寄存器,并清除计数标志位。

Sys校准数值寄存器CALIB

以上就是关于SysTick的介绍,接下来就要操作一下了,

我们要用SysTick来定时1S使LED灯状态变化一次,所以

1、首先,应先线配置SysTick相关寄存器,来产生1s的延时

2、初始化LED灯

3、编写主函数

由于Systick是嵌入在内核中的所以在硬件电路中只需要有LED模块即可,想要用SysTick实现流水灯1s切换一次状态的操作,首先就是要配置SysTick,这里我们直接用STM32官方额库函数SysTick_Config(uint32_t  ticks),在内核头文件core_cm4.h中,这个函数的功能是配置系统定时器和中断,并且打开SysTick,使计数器处于自由计数模式来产生一个周期性的中断。在这个函数中形参ticks是用来设置重装载寄存器的值,最大不能超过重装载寄存器的值2^{24},当重装载寄存器的值减到0时,就会产生一个中断,然后重装载寄存器的值又写入当前计数器中重新往下递减计数,以此循环。接下来这个库函数是给该中断配置中断优先级(关于中断优先级可以查看STM32中断及NVIC概述),然后给当前数值寄存器赋初值,接下来配置时钟源,使能中断,开启定时器。当返回0时,说明函数功能已经实现,返回1则表示失败。这个初始化函数主要是配置了SysTick中的三个寄存器:LOAD、VAL、CTRL,还调用了NVIC_SetPriority()配置中断优先级函数。

因为SysTick是内核中的外设,所以时钟选择为HCLK180MHz时钟

由于官方没有 SysTick的初始化函数,只有配置函数Config所以,我们自己简单的编写一个SysTick_Init()函数

因为HCLK为180MHz,所以当ticks=SystemFrequency/1000时(180 000 000/1000),每经过1/SystemFrequency一次,ticks的值就减1,所以计数时间为ticks/(1/SystemFrequency)=1ms,,所以我们配置的SysTick为10us进一次中断。

配置好SysTick后,我们只需要再定义一个变量来记录进入中断的次数N,N*SysTick就等于我们所要定时的时间。

nTime就是我进入SysTick中断的次数,每进入一次中断服务函数,TimingDelay就减1,当TimingDelay不等于0时,延时结束。

中断服务函数如下

关于SysTick配置已经描述完,接下来初始化LED灯。

关于LED的初始化我就不再做过多的描述,可以参考STM32固件库函数点亮LED灯,代码如下

  1. #include "stm32f4xx_gpio.h"
  2. #define GPIO_R_Pin GPIO_Pin_10
  3. #define GPIO_R_Port GPIOH
  4. #define GPIO_G_Pin GPIO_Pin_11
  5. #define GPIO_G_Port GPIOH
  6. #define GPIO_B_Pin GPIO_Pin_12
  7. #define GPIO_B_Port GPIOH
  8. /************************控制LED灯亮灭的宏***************/
  9. /*直接操作寄存器的方法控制IO*/
  10. #define LED_PORT_OUT_HI(p,i) { p->BSRRL = i ;} //输出为高电平
  11. #define LED_PORT_OUT_LO(p,i) { p->BSRRH = i ;} //输出为低电平
  12. #define LED_PORT_OUT_Toggle(p,i) { p->BSRRL ^= i ;} //输出为反状态
  13. /*定义控制IO的宏*/
  14. #define LED_R_Toggle LED_PORT_OUT_Toggle(GPIO_R_Port,GPIO_R_Pin)
  15. #define LED_R_ON LED_PORT_OUT_LO(GPIO_R_Port,GPIO_R_Pin)
  16. #define LED_R_OFF LED_PORT_OUT_HI(GPIO_R_Port,GPIO_R_Pin)
  17. #define LED_G_Toggle LED_PORT_OUT_Toggle(GPIO_G_Port,GPIO_G_Pin)
  18. #define LED_G_ON LED_PORT_OUT_LO(GPIO_G_Port,GPIO_G_Pin)
  19. #define LED_G_OFF LED_PORT_OUT_HI(GPIO_G_Port,GPIO_G_Pin)
  20. #define LED_B_Toggle LED_PORT_OUT_Toggle(GPIO_B_Port,GPIO_B_Pin)
  21. #define LED_B_ON LED_PORT_OUT_LO(GPIO_B_Port,GPIO_B_Pin)
  22. #define LED_B_OFF LED_PORT_OUT_HI(GPIO_B_Port,GPIO_B_Pin)
  23. #define LED_RGBOFF LED_R_OFF;\
  24. LED_G_OFF;\
  25. LED_B_OFF
  26. void LED_GPIO_Config(void);
  1. #include "bsp_led.h"
  2. /**
  3. * @brief 初始化控制LED的IO
  4. * @param 无
  5. * @retval 无
  6. */
  7. void LED_GPIO_Config(void)
  8. {
  9. /*定义一个GPIO_InitTypeDef类型的结构体*/
  10. GPIO_InitTypeDef GPIO_InitStructure;
  11. /*开启LED相关的GPIO外设时钟*/
  12. RCC_AHB1PeriphClockCmd ( LED1_GPIO_CLK|
  13. LED2_GPIO_CLK|
  14. LED3_GPIO_CLK, ENABLE);
  15. /*选择要控制的GPIO引脚*/
  16. GPIO_InitStructure.GPIO_Pin = LED1_PIN;
  17. /*设置引脚模式为输出模式*/
  18. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  19. /*设置引脚的输出类型为推挽输出*/
  20. GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  21. /*设置引脚为上拉模式*/
  22. GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  23. /*设置引脚速率为2MHz */
  24. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  25. /*调用库函数,使用上面配置的GPIO_InitStructure初始化GPIO*/
  26. GPIO_Init(LED1_GPIO_PORT, &GPIO_InitStructure);
  27. /*选择要控制的GPIO引脚*/
  28. GPIO_InitStructure.GPIO_Pin = LED2_PIN;
  29. GPIO_Init(LED2_GPIO_PORT, &GPIO_InitStructure);
  30. /*选择要控制的GPIO引脚*/
  31. GPIO_InitStructure.GPIO_Pin = LED3_PIN;
  32. GPIO_Init(LED3_GPIO_PORT, &GPIO_InitStructure);
  33. /*关闭RGB灯*/
  34. LED_RGBOFF;
  35. }

配置好SysTick和LED后,接下来就开始写主函数

主函数如下

  1. int main(void)
  2. {
  3. /* LED 端口初始化 */
  4. LED_GPIO_Config();
  5. /* 配置SysTick 为10us中断一次,时间到后触发定时中断,
  6. *进入stm32fxx_it.c文件的SysTick_Handler处理,通过数中断次数计时
  7. */
  8. SysTick_Init();
  9. while(1)
  10. {
  11. LED_RED;
  12. Delay_us(100000); // 10000 * 10us = 1000ms
  13. //延时1s
  14. LED_GREEN;
  15. Delay_us(100000);
  16. //延时1s
  17. LED_BLUE;
  18. Delay_us(100000);
  19. //延时1s
  20. }
  21. }

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Li_阴宅/article/detail/942228
推荐阅读
相关标签
  

闽ICP备14008679号