利用stm32定时器实现LED灯闪烁

本文采用芯片为stm32f103rc,定时器为systick。
SysTick—系统定时器是属于 CM3 内核中的一个外设,内嵌在 NVIC 中。系统定时器
是一个 24bit 的向下递减的计数器,计数器每计数一次的时间为 1/SYSCLK,一般我们设置系统时钟 SYSCLK 等于 72M。当重装载数值寄存器的值递减到 0 的时候,系统定时器就产生一次中断,以此循环往复。
先明确思路:总共分成4各部分来实现:
1、初始化定时器。
2、LED_GPIO 初始化。
3、计算精确延时,这里配置为1s。
4、点亮、熄灭LED灯。
编写初始化函数SysTick_Init();,从core_cm3中调用库函数SysTick_Config();

SysTick_Config();函数原型:
static __INLINE uint32_t SysTick_Config(uint32_t ticks)
{ 
  if (ticks > SysTick_LOAD_RELOAD_Msk)  return (1);            /* Reload value impossible */
                                                               
  SysTick->LOAD  = (ticks & SysTick_LOAD_RELOAD_Msk) - 1;      /* set reload register */
  NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);  /* set Priority for Cortex-M0 System Interrupts */
  SysTick->VAL   = 0;                                          /* Load the SysTick Counter Value */
  SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk | 
                   SysTick_CTRL_TICKINT_Msk   | 
                   SysTick_CTRL_ENABLE_Msk;                    /* Enable SysTick IRQ and SysTick Timer */
  return (0);                                                  /* Function successful */
}
void SysTick_Init(void)
{
	if (SysTick_Config(SystemCoreClock / 100000)) {  // SystemFrequency / 1000 1ms 中断一次
																				  //SystemFrequency / 100000 10us 中断一次
 																				//SystemFrequency / 1000000 1us 中断一次

 /* Capture error */
 while (1)
 {
 }
 }
}

LED_GPIO的初始化:启动时钟、配置引脚、设置输入输出、SPEED。经查原理图可知LED0对应引脚为PA8。

void LED_GPIO_config()
{
	  GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	  GPIO_InitStructure.GPIO_Pin=GPIO_Pin_8;
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_Init(GPIOA,&GPIO_InitStructure);
		//GPIO_ResetBits(GPIOA,GPIO_Pin_8);

}

计算延时:
当设置好中断时间 TINT 后,我们可以设置一个变量 t,用来记录进入中断的次数,那
么变量 t 乘以中断的时间 TINT就可以计算出需要定时的时间。定义一个微秒级别的延时函数,形参为 nTime,当用这个形参乘以中断时间TINT 就得出我们需要的延时时间,其中 TINT 我们已经设置好为 10us。
定义一下TimingDelay:uint32_t TimingDelay = 0;
`

 void Delay_us(__IO u32 nTime)
 {
 TimingDelay = nTime;
 
 while (TimingDelay != 0);
 }

函数 Delay_us()中我们等待 TimingDelay 为 0,当 TimingDelay 为 0 的时候表示延时时
间到。变量 TimingDelay 在中断函数中递减,即 SysTick 每进一次中断即 10us 的时间
TimingDelay 递减一次。
配置一下中断函数:这个函数在库函数stm32f10x_it.c中。

 void SysTick_Handler(void)
 {
 TimingDelay_Decrement();
 }

中断复位函数调用了另外一个函数 TimingDelay_Decrement(),原型如下:

 void TimingDelay_Decrement(void)
 {
 if (TimingDelay != 0x00) {
 TimingDelay--;
 }
 }

TimingDelay 的值等于延时函数中传进去的 nTime 的值,比如 nTime=100000,则延时
的时间等于 100000*10us=1s。因此我们能够精确得到1s的延时函数。
点亮、熄灭LED

GPIO_ResetBits(GPIOA,GPIO_Pin_8);//低电平
GPIO_SetBits(GPIOA,GPIO_Pin_8);//高电平

主函数:

#include "stm32f10x.h"
#include "stm32f10x_it.h"
int main()
{
	SysTick_Init();
	LED_GPIO_config();

	while(1)
	{
			GPIO_ResetBits(GPIOA,GPIO_Pin_8);
		Delay_us(100000);//延时1s;
			GPIO_SetBits(GPIOA,GPIO_Pin_8);
		Delay_us(100000);
		
	}
}

你可能感兴趣的:(项目)