姓名:周崇杰? ?學(xué)號(hào):16140120059? ? 專業(yè):機(jī)械設(shè)計(jì)制造及其自動(dòng)化
轉(zhuǎn)載自:http://blog.csdn.net/u011318735/article/details/17620315,有刪節(jié)
【嵌牛導(dǎo)讀】:STM32F1系列的產(chǎn)品的SysTick定時(shí)器操作簡(jiǎn)單,功能強(qiáng)大,本文將會(huì)通過庫(kù)函數(shù)講解該定時(shí)器的使用。
【嵌牛鼻子】:STM32單片機(jī),SysTick定時(shí)器。
【嵌牛提問】:STM32單片機(jī)的SysTick定時(shí)器如何操作以及編程呢?
【嵌牛正文】:
SysTick定時(shí)器被集成在NVIC中。因此,只要是Cortex-M3內(nèi)核的單片機(jī),就都有它。這個(gè)學(xué)習(xí)筆記就用SysTick定時(shí)器來實(shí)現(xiàn)走馬燈的功能。
SysTick定時(shí)器非常簡(jiǎn)答,只有四個(gè)寄存器。這四個(gè)寄存器的含義在《Cortex-M3權(quán)威指南》那本書中講的非常的清楚,這里不復(fù)述了,下面只講講在STM32上SysTick有什么特殊之處。按照CMSIS標(biāo)準(zhǔn),用C語言訪問這四個(gè)寄存器時(shí)使用的寄存器名稱分別如下:
SysTick->CTRL
SysTick->LOAD
SysTick->VAL
SysTick->CALIB
SysTick->CALIB的值固定為9000,因此,只有當(dāng)系統(tǒng)嘀嗒時(shí)鐘設(shè)定為9MHz(HCLK/8的最大值),產(chǎn)生1ms時(shí)間基準(zhǔn)。
STM32提供了2個(gè)時(shí)鐘源:
0:?AHB/8
1:?Processor?clock?(AHB)
因此,SysTick->CTRL?=?7表示使用處理器時(shí)鐘作為時(shí)鐘源,使能SysTick,并且使能SysTick中斷。SysTick->CTRL?=?3時(shí)頻率降為原來的1/8。
我的開發(fā)板上有四個(gè)LED,分別對(duì)應(yīng)的GPIO端口D的PD2、PD3、PD4和PD7。
下面是例子程序,仍然先是直接設(shè)置寄存器。
#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
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;//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
*/
voidSysTick_Handler(void)
{
staticintcount?=?0;
count?++;
if(count?==?100)
{
LED_Spark();
count?=?0;
}
}
然后是利用STM32 固件函數(shù)庫(kù)提供的函數(shù)的例子。
#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
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)
{
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
*/
voidSysTick_Handler(void)
{
staticintcount?=?0;
count?++;
if(count?==?100)
{
LED_Spark();
count?=?0;
}
}
需要說明的是,若是用 SysTick_Config 函數(shù)來設(shè)置SysTick的中斷頻率,時(shí)鐘源就不能人為的指定了,這時(shí)使用的時(shí)鐘源就是內(nèi)核的頻率。
SystemCoreClock 是個(gè)全局變量,它的值就是內(nèi)核的運(yùn)行頻率,不過前提要調(diào)用 SystemInit() 函數(shù)來設(shè)置內(nèi)核的頻率。如果內(nèi)核的頻率是字節(jié)寫寄存器來設(shè)置的,SystemCoreClock 的值就不一定對(duì)了。