STM32F10x 学习笔记 2 (SysTick 定时器)

SysTick 定时器被集成在NVIC中。因此,只要是Cortex-M3 内核的单片机,就都有它。这个学习笔记就用SysTick 定时器来实现走马灯的功能。

SysTick 定时器非常简答,只有四个寄存器。这四个寄存器的含义在《Cortex-M3权威指南》那本书中讲的非常的清楚,这里不复述了,下面只讲讲在STM32SysTick有什么特殊之处。按照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端口的 PD2PD3PD4PD7

下面是例子程序,仍然先是直接设置寄存器。

#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 固件函数库提供的函数的例子。

#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 的值就不一定对了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值