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:Processorclock(AHB)
因此,SysTick->CTRL=7表示使用处理器时钟作为时钟源,使能SysTick,并且使能SysTick中断。SysTick->CTRL=3时频率降为原来的1/8。
我的开发板上有四个LED,分别对应的GPIO端口D的PD2、PD3、PD4和PD7。
下面是例子程序,仍然先是直接设置寄存器。
#include"stm32f10x.h"
#defineRCC_GPIO_LEDRCC_APB2Periph_GPIOD
#defineGPIO_LED_PORTGPIOD
#defineGPIO_LED1GPIO_Pin_2
#defineGPIO_LED2GPIO_Pin_3
#defineGPIO_LED3GPIO_Pin_4
#defineGPIO_LED4GPIO_Pin_7
#defineGPIO_LED_ALLGPIO_LED1|GPIO_LED2|GPIO_LED3|GPIO_LED4
voidLED_Spark(void)
{
staticintstate=0;
switch(state)
{
case0:
GPIO_SetBits(GPIO_LED_PORT,GPIO_LED_ALL);
GPIO_ResetBits(GPIO_LED_PORT,GPIO_LED1);
state++;
break;
case1:
GPIO_SetBits(GPIO_LED_PORT,GPIO_LED_ALL);
GPIO_ResetBits(GPIO_LED_PORT,GPIO_LED2);
state++;
break;
case2:
GPIO_SetBits(GPIO_LED_PORT,GPIO_LED_ALL);
GPIO_ResetBits(GPIO_LED_PORT,GPIO_LED3);
state++;
break;
case3:
GPIO_SetBits(GPIO_LED_PORT,GPIO_LED_ALL);
GPIO_ResetBits(GPIO_LED_PORT,GPIO_LED4);
state=0;
break;
default:
state=0;
break;
}
}
intmain(void)
{
SystemInit();
RCC->APB2ENR|=0x00000020;
GPIOD->CRL=0x24422244;//PD2PD3PD4PD7SettoOutputmode
SysTick->LOAD=24000000/200;
SysTick->CTRL=3;
for(;;)
{
}
}
/**
*@briefThisfunctionhandlesSysTickHandler.
*@paramNone
*@retvalNone
*/
voidSysTick_Handler(void)
{
staticintcount=0;
count++;
if(count==100)
{
LED_Spark();
count=0;
}
}
然后是利用STM32 固件函数库提供的函数的例子。
#include"stm32f10x.h"
#defineRCC_GPIO_LEDRCC_APB2Periph_GPIOD
#defineGPIO_LED_PORTGPIOD
#defineGPIO_LED1GPIO_Pin_2
#defineGPIO_LED2GPIO_Pin_3
#defineGPIO_LED3GPIO_Pin_4
#defineGPIO_LED4GPIO_Pin_7
#defineGPIO_LED_ALLGPIO_LED1|GPIO_LED2|GPIO_LED3|GPIO_LED4
voidLED_Spark(void)
{
staticintstate=0;
switch(state)
{
case0:
GPIO_SetBits(GPIO_LED_PORT,GPIO_LED_ALL);
GPIO_ResetBits(GPIO_LED_PORT,GPIO_LED1);
state++;
break;
case1:
GPIO_SetBits(GPIO_LED_PORT,GPIO_LED_ALL);
GPIO_ResetBits(GPIO_LED_PORT,GPIO_LED2);
state++;
break;
case2:
GPIO_SetBits(GPIO_LED_PORT,GPIO_LED_ALL);
GPIO_ResetBits(GPIO_LED_PORT, GPIO_LED3