赞
踩
参考资料《 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主要是用来存储计数的值,最大为
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是用来设置重装载寄存器的值,最大不能超过重装载寄存器的值,当重装载寄存器的值减到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灯,代码如下
- #include "stm32f4xx_gpio.h"
-
- #define GPIO_R_Pin GPIO_Pin_10
- #define GPIO_R_Port GPIOH
-
- #define GPIO_G_Pin GPIO_Pin_11
- #define GPIO_G_Port GPIOH
-
- #define GPIO_B_Pin GPIO_Pin_12
- #define GPIO_B_Port GPIOH
-
- /************************控制LED灯亮灭的宏***************/
-
- /*直接操作寄存器的方法控制IO*/
-
- #define LED_PORT_OUT_HI(p,i) { p->BSRRL = i ;} //输出为高电平
- #define LED_PORT_OUT_LO(p,i) { p->BSRRH = i ;} //输出为低电平
- #define LED_PORT_OUT_Toggle(p,i) { p->BSRRL ^= i ;} //输出为反状态
-
- /*定义控制IO的宏*/
-
- #define LED_R_Toggle LED_PORT_OUT_Toggle(GPIO_R_Port,GPIO_R_Pin)
- #define LED_R_ON LED_PORT_OUT_LO(GPIO_R_Port,GPIO_R_Pin)
- #define LED_R_OFF LED_PORT_OUT_HI(GPIO_R_Port,GPIO_R_Pin)
-
- #define LED_G_Toggle LED_PORT_OUT_Toggle(GPIO_G_Port,GPIO_G_Pin)
- #define LED_G_ON LED_PORT_OUT_LO(GPIO_G_Port,GPIO_G_Pin)
- #define LED_G_OFF LED_PORT_OUT_HI(GPIO_G_Port,GPIO_G_Pin)
-
- #define LED_B_Toggle LED_PORT_OUT_Toggle(GPIO_B_Port,GPIO_B_Pin)
- #define LED_B_ON LED_PORT_OUT_LO(GPIO_B_Port,GPIO_B_Pin)
- #define LED_B_OFF LED_PORT_OUT_HI(GPIO_B_Port,GPIO_B_Pin)
-
- #define LED_RGBOFF LED_R_OFF;\
- LED_G_OFF;\
- LED_B_OFF
-
- void LED_GPIO_Config(void);

- #include "bsp_led.h"
-
- /**
- * @brief 初始化控制LED的IO
- * @param 无
- * @retval 无
- */
- void LED_GPIO_Config(void)
- {
- /*定义一个GPIO_InitTypeDef类型的结构体*/
- GPIO_InitTypeDef GPIO_InitStructure;
-
- /*开启LED相关的GPIO外设时钟*/
- RCC_AHB1PeriphClockCmd ( LED1_GPIO_CLK|
- LED2_GPIO_CLK|
- LED3_GPIO_CLK, ENABLE);
-
- /*选择要控制的GPIO引脚*/
- GPIO_InitStructure.GPIO_Pin = LED1_PIN;
-
- /*设置引脚模式为输出模式*/
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
-
- /*设置引脚的输出类型为推挽输出*/
- GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
-
- /*设置引脚为上拉模式*/
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
-
- /*设置引脚速率为2MHz */
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
-
- /*调用库函数,使用上面配置的GPIO_InitStructure初始化GPIO*/
- GPIO_Init(LED1_GPIO_PORT, &GPIO_InitStructure);
-
- /*选择要控制的GPIO引脚*/
- GPIO_InitStructure.GPIO_Pin = LED2_PIN;
- GPIO_Init(LED2_GPIO_PORT, &GPIO_InitStructure);
-
- /*选择要控制的GPIO引脚*/
- GPIO_InitStructure.GPIO_Pin = LED3_PIN;
- GPIO_Init(LED3_GPIO_PORT, &GPIO_InitStructure);
-
- /*关闭RGB灯*/
- LED_RGBOFF;
- }

配置好SysTick和LED后,接下来就开始写主函数
主函数如下
- int main(void)
- {
- /* LED 端口初始化 */
- LED_GPIO_Config();
-
- /* 配置SysTick 为10us中断一次,时间到后触发定时中断,
- *进入stm32fxx_it.c文件的SysTick_Handler处理,通过数中断次数计时
- */
- SysTick_Init();
-
- while(1)
- {
-
- LED_RED;
- Delay_us(100000); // 10000 * 10us = 1000ms
- //延时1s
-
- LED_GREEN;
- Delay_us(100000);
- //延时1s
-
- LED_BLUE;
- Delay_us(100000);
- //延时1s
-
-
- }
- }

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。