历史上的今天
今天是:2024年11月11日(星期一)
2020年11月11日 | STM32F10x 学习笔记之SysTick 定时器
2020-11-11 来源:eefocus
SysTick 定时器被集成在NVIC中。因此,只要是Cortex-M3 内核的单片机,就都有它。这个学习笔记就用SysTick 定时器来实现走马灯的功能。
SysTick 定时器非常简答,只有四个寄存器。这四个寄存器的含义在《Cortex-M3权威指南》那本书中讲的非常的清楚,这里不复述了,下面只讲讲在STM32上SysTick有什么特殊之处。按照CMSIS 标准,用C语言访问这四个寄存器时使用的寄存器名称分别如下:
SysTick->CTRL
SysTick->LOAD
SysTick->VAL
SysTick->CALIB
SysTick->CALIB 的值固定为9000,因此,只有当系统嘀嗒时钟设定为9MHz(HCLK/8的最大值) ,产生1ms 时间基准。
STM32提供了2个时钟源:
0: AHB/8
1: Processor clock (AHB)
因此,SysTick->CTRL = 7 表示使用处理器时钟作为时钟源,使能SysTick,并且使能SysTick中断。SysTick->CTRL = 3 时频率降为原来的1/8。
我的开发板上有四个LED,分别对应的GPIO端口D 的 PD2、PD3、PD4和PD7。
下面是例子程序,仍然先是直接设置寄存器。
#include "stm32f10x.h"
#define RCC_GPIO_LED RCC_APB2Periph_GPIOD
#define GPIO_LED_PORT GPIOD
#define GPIO_LED1 GPIO_Pin_2
#define GPIO_LED2 GPIO_Pin_3
#define GPIO_LED3 GPIO_Pin_4
#define GPIO_LED4 GPIO_Pin_7
#define GPIO_LED_ALL GPIO_LED1 |GPIO_LED2 |GPIO_LED3 |GPIO_LED4
void LED_Spark(void)
{
static int state = 0;
switch (state)
{
case 0:
GPIO_SetBits(GPIO_LED_PORT, GPIO_LED_ALL);
GPIO_ResetBits(GPIO_LED_PORT, GPIO_LED1);
state ++;
break;
case 1:
GPIO_SetBits(GPIO_LED_PORT, GPIO_LED_ALL);
GPIO_ResetBits(GPIO_LED_PORT, GPIO_LED2);
state ++;
break;
case 2:
GPIO_SetBits(GPIO_LED_PORT, GPIO_LED_ALL);
GPIO_ResetBits(GPIO_LED_PORT, GPIO_LED3);
state ++;
break;
case 3:
GPIO_SetBits(GPIO_LED_PORT, GPIO_LED_ALL);
GPIO_ResetBits(GPIO_LED_PORT, GPIO_LED4);
state = 0;
break;
default:
state = 0;
break;
}
}
int main(void)
{
SystemInit();
RCC->APB2ENR |= 0x00000020;
GPIOD->CRL = 0x24422244; //PD2 PD3 PD4 PD7 Set to Output mode
SysTick->LOAD = 24000000/200;
SysTick->CTRL = 3;
for(;;)
{
}
}
/**
* @brief This function handles SysTick Handler.
* @param None
* @retval None
*/
void SysTick_Handler(void)
{
static int count = 0;
count ++;
if (count == 100)
{
LED_Spark();
count = 0;
}
}
然后是利用STM32 固件函数库提供的函数的例子。
[cpp] view plain copy
#include "stm32f10x.h"
#define RCC_GPIO_LED RCC_APB2Periph_GPIOD
#define GPIO_LED_PORT GPIOD
#define GPIO_LED1 GPIO_Pin_2
#define GPIO_LED2 GPIO_Pin_3
#define GPIO_LED3 GPIO_Pin_4
#define GPIO_LED4 GPIO_Pin_7
#define GPIO_LED_ALL GPIO_LED1 |GPIO_LED2 |GPIO_LED3 |GPIO_LED4
void LED_Spark(void)
{
static int state = 0;
switch (state)
{
case 0:
GPIO_SetBits(GPIO_LED_PORT, GPIO_LED_ALL);
GPIO_ResetBits(GPIO_LED_PORT, GPIO_LED1);
state ++;
break;
case 1:
GPIO_SetBits(GPIO_LED_PORT, GPIO_LED_ALL);
GPIO_ResetBits(GPIO_LED_PORT, GPIO_LED2);
state ++;
break;
case 2:
GPIO_SetBits(GPIO_LED_PORT, GPIO_LED_ALL);
GPIO_ResetBits(GPIO_LED_PORT, GPIO_LED3);
state ++;
break;
case 3:
GPIO_SetBits(GPIO_LED_PORT, GPIO_LED_ALL);
GPIO_ResetBits(GPIO_LED_PORT, GPIO_LED4);
state = 0;
break;
default:
state = 0;
break;
}
}
int main(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
SystemInit();
SysTick_Config(SystemCoreClock/100);
/* Enable GPIOB, GPIOC and AFIO clock */
RCC_APB2PeriphClockCmd(RCC_GPIO_LED, ENABLE); //RCC_APB2Periph_AFIO
/* LEDs pins configuration */
GPIO_InitStructure.GPIO_Pin = GPIO_LED_ALL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIO_LED_PORT, &GPIO_InitStructure);
for(;;)
{
}
}
/**
* @brief This function handles SysTick Handler.
* @param None
* @retval None
*/
void SysTick_Handler(void)
{
static int count = 0;
count ++;
if (count == 100)
{
LED_Spark();
count = 0;
}
}
需要说明的是,若是用 SysTick_Config 函数来设置SysTick的中断频率,时钟源就不能人为的指定了,这时使用的时钟源就是内核的频率。
SystemCoreClock 是个全局变量,它的值就是内核的运行频率,不过前提要调用 SystemInit() 函数来设置内核的频率。如果内核的频率是字节写寄存器来设置的,SystemCoreClock 的值就不一定对了。
史海拾趣
|
想问一下关于CPU利用率的问题,如果WINDOWS启动完后,什么都启动好了,查看CPU的利用率是0%,是不是这个时候CPU就没有工作了呢?但是在进程里却发现还有好多个进程在执行着,既然是0%,那为什么还有进程在执行呢?… 查看全部问答> |
|
最近写了一个PC与PLC 串口通信的小程序,我对PLC一点都不了解,主要是读取寄存器的值. 我想问问 1 PLC的地址怎么表示,只有一台PLC通过USB转串口连接PC 2 RTU模式读取数,我是不是也应该在PLC上设置成RTU? (施耐德的PLC 怎么设置?) … 查看全部问答> |
|
wince5.0下MFC中没有CBitmapButton类,请问有人实现图片按钮的自定义的类么? wince5.0下MFC中没有CBitmapButton类,请问有人实现图片按钮的自定义的类么?… 查看全部问答> |
|
有个工控设备,其中内置一台个人电脑(PC全内置主板),需要配备显示器和键盘。 因为安装空间太小,容纳不了普通CRT或笔记本LCD显示器。况且,该设备的用户界面很简单,只需要控制串口通讯以及操作一个简单的ACCESS数据库,使用带触摸的2.5~3.5寸 ...… 查看全部问答> |
|
VS2005下的类视图分页下,一个类在类列表里面看不到,怎么回事?.h和.cpp文件工程下都加进去了。 VS2005下的类视图分页下,一个类在类列表里面看不到,怎么回事?.h和.cpp文件工程下都加进去了。… 查看全部问答> |
|
EVC pocket pc 2003程序和VS2005 pocket pc SE2003程序区别及问题! EVC下pocket pc 2003和VS2005 pocket pc se 2003模拟器有什么区别???? 是这样的,我在EVC下pocket pc 2003下编译成功并能运行的一个.exe文件直接共享在VS2005 pocket pc se 2003下,但是却点击运行不了.出现如下错误: connot find \"mfctest\"(//我 ...… 查看全部问答> |
|
以下程序如果用STM8S207系列芯片在IAR上编译头文件是#include <iostm8s207sb.h>。哪我如果用103芯片,头文件应该怎样写?哪里这一方面的资料介绍? #include <iostm8s207sb.h> #define LED1_FLASH PD_ODR_ODR3 = ...… 查看全部问答> |




