STM32系统定时器闪烁LED灯

SysTick寄存器介绍

SysTick寄存器总汇

寄存器名称寄存器描述
CTRLSysTick控制及状态寄存器
LOADSysTick重装载数值寄存器
VALSysTick当前数值寄存器
CALIBSysTick校准数值寄存器

①SysTick控制及状态寄存器

位段名称类型复位值描述
16COUNTFLAGR/W0如果在上次读取本寄存器后,SysTick已经计到了0,则该位为1
2CLKSOURCER/W0时钟源选择位,0=AHB/8,1=处理器时钟AHB
1TICKINTR/W01:SysTick倒数计数到0时产生SysTick异常请求,0:计数到0时无动作
0ENABLER/W0SysTick定时器的使能位

②SystTick重装载数值寄存器

位段名称类型复位值描述
23:0RELOADR/W0当倒数计数至0时,将被重装载的值

③SysTick当前数值寄存器

位段名称类型复位值描述
23:0CURRENTR/W0读取时返回当前倒数计数的值,写它则使之清零,同时还会清除在SysTick控制及状态寄存器中的COUNTFLAG标志

SysTick定时实验

编程要点

1)设置重装载寄存器的值。
2)清除当前数值寄存器的值。
3)配置控制与状态寄存器。

bsp_led.c文件
#include "./led/bsp_led.h"   

void LED_GPIO_Config(void)
{		
		
		GPIO_InitTypeDef GPIO_InitStructure;
		RCC_APB2PeriphClockCmd( LED1_GPIO_CLK | LED2_GPIO_CLK | LED3_GPIO_CLK, ENABLE);
		GPIO_InitStructure.GPIO_Pin = LED1_GPIO_PIN;	
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
		GPIO_Init(LED1_GPIO_PORT, &GPIO_InitStructure);	
		GPIO_InitStructure.GPIO_Pin = LED2_GPIO_PIN;
		GPIO_Init(LED2_GPIO_PORT, &GPIO_InitStructure);
		GPIO_InitStructure.GPIO_Pin = LED3_GPIO_PIN;
		GPIO_Init(LED3_GPIO_PORT, &GPIO_InitStructure);
		GPIO_SetBits(LED1_GPIO_PORT, LED1_GPIO_PIN);
		GPIO_SetBits(LED2_GPIO_PORT, LED2_GPIO_PIN);	 
		GPIO_SetBits(LED3_GPIO_PORT, LED3_GPIO_PIN);
}
bsp_led.h文件
#ifndef __LED_H
#define	__LED_H

#include "stm32f10x.h"

#define LED1_GPIO_PORT    	GPIOB			         
#define LED1_GPIO_CLK 	    RCC_APB2Periph_GPIOB		
#define LED1_GPIO_PIN		GPIO_Pin_5			       

#define LED2_GPIO_PORT    	GPIOB			             
#define LED2_GPIO_CLK 	    RCC_APB2Periph_GPIOB		
#define LED2_GPIO_PIN		GPIO_Pin_0			      

#define LED3_GPIO_PORT    	GPIOB			            
#define LED3_GPIO_CLK 	    RCC_APB2Periph_GPIOB	
#define LED3_GPIO_PIN		GPIO_Pin_1			      

#define ON  0
#define OFF 1

#define LED1(a)	if (a)	\
					GPIO_SetBits(LED1_GPIO_PORT,LED1_GPIO_PIN);\
					else		\
					GPIO_ResetBits(LED1_GPIO_PORT,LED1_GPIO_PIN)

#define LED2(a)	if (a)	\
					GPIO_SetBits(LED2_GPIO_PORT,LED2_GPIO_PIN);\
					else		\
					GPIO_ResetBits(LED2_GPIO_PORT,LED2_GPIO_PIN)

#define LED3(a)	if (a)	\
					GPIO_SetBits(LED3_GPIO_PORT,LED3_GPIO_PIN);\
					else		\
					GPIO_ResetBits(LED3_GPIO_PORT,LED3_GPIO_PIN)

#define	digitalHi(p,i)		 {p->BSRR=i;}		
#define digitalLo(p,i)		 {p->BRR=i;}	

#define LED1_TOGGLE		 digitalToggle(LED1_GPIO_PORT,LED1_GPIO_PIN)
#define LED1_OFF		   digitalHi(LED1_GPIO_PORT,LED1_GPIO_PIN)
#define LED1_ON			   digitalLo(LED1_GPIO_PORT,LED1_GPIO_PIN)

#define LED2_TOGGLE		 digitalToggle(LED2_GPIO_PORT,LED2_GPIO_PIN)
#define LED2_OFF		   digitalHi(LED2_GPIO_PORT,LED2_GPIO_PIN)
#define LED2_ON			   digitalLo(LED2_GPIO_PORT,LED2_GPIO_PIN)

#define LED3_TOGGLE		 digitalToggle(LED3_GPIO_PORT,LED3_GPIO_PIN)
#define LED3_OFF		   digitalHi(LED3_GPIO_PORT,LED3_GPIO_PIN)
#define LED3_ON			   digitalLo(LED3_GPIO_PORT,LED3_GPIO_PIN)

void LED_GPIO_Config(void);

#endif /* __LED_H */

bsp_SysTick.h文件
#ifndef __SYSTICK_H
#define __SYSTICK_H

#include "stm32f10x.h"

void SysTick_Init(void);
void Delay_us(__IO u32 nTime);
#define Delay_ms(x) Delay_us(100*x)	 //单位ms

void SysTick_Delay_Us( __IO uint32_t us);
void SysTick_Delay_Ms( __IO uint32_t ms);


#endif /* __SYSTICK_H */
bsp_SysTick.c文件
#include "bsp_SysTick.h"
#include "core_cm3.h"
#include "misc.h"

static __IO u32 TimingDelay;
 
/*
  启动系统嘀嗒定时器
  */
void SysTick_Init(void)
{
	/* SystemCoreClock / 1000    1ms中断一次
	 * SystemCoreClock / 100000	 10us中断一次
	 * SystemCoreClock / 1000000 1us中断一次
	 */
	if (SysTick_Config(SystemCoreClock / 100000))
	{ 
		/* Capture error */ 
		while (1);
	}
}

/*
Delay_us(1):实现1x10us = 10us延时
*/
void Delay_us(__IO u32 nTime)
{ 
	TimingDelay = nTime;	

	//使能嘀嗒定时器
	SysTick->CTRL |=  SysTick_CTRL_ENABLE_Msk;

	while(TimingDelay != 0);
}

//获取节拍程序,在SysTick中断函数SysTick_Handler()中调用
void TimingDelay_Decrement(void)
{
	if (TimingDelay != 0x00)
	{ 
		TimingDelay--;
	}
}

#if 0
// 这个固件库函数在core_cm3.h中
static __INLINE uint32_t SysTick_Config(uint32_t ticks)
{ 
  // reload 寄存器为24bit,最大值为2^24
	if (ticks > SysTick_LOAD_RELOAD_Msk)  return (1);
  
  // 配置reload初始值	
  SysTick->LOAD  = (ticks & SysTick_LOAD_RELOAD_Msk) - 1;
	
  //配置中断优先级为:1<<4-1 = 15,优先级为最低
  NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); 
	
  //配置counter计数器的值
  SysTick->VAL   = 0;
	
	//配置systick的时钟为72M
	//中断使能
	//使能systick
  SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk|SysTick_CTRL_TICKINT_Msk|SysTick_CTRL_ENABLE_Msk;                    
  return (0); 
}
#endif

// couter减一的时间等于1/systick_clk
//当counter 从reload 的值减小到0的时候,为一个循环,如果开启了中断则执行中断服务程序。
//同时CTRL的countflag位会置1
//这一个循环的时间为:reload * (1/systick_clk)

void SysTick_Delay_Us( __IO uint32_t us)//SysTick微妙级延时
{
	uint32_t i;
	SysTick_Config(SystemCoreClock/1000000);
	
	for(i=0;i<us;i++)
	{
		//当计数器的值减到0的时候,CRTL寄存器的位16会置1
		while( !((SysTick->CTRL)&(1<<16)) );
	}
	//关闭SysTick定时器
	SysTick->CTRL &=~SysTick_CTRL_ENABLE_Msk;
}

void SysTick_Delay_Ms( __IO uint32_t ms)//SysTick毫秒级延时
{
	uint32_t i;	
	SysTick_Config(SystemCoreClock/1000);
	
	for(i=0;i<ms;i++)
	{
		//当计数器的值减少到0的时候,CRTL寄存器的位16会置1
		//当置1时,读取该位会清0
		while( !((SysTick->CTRL)&(1<<16)) );
	}
	//关闭SysTick定时器
	SysTick->CTRL &=~ SysTick_CTRL_ENABLE_Msk;
}

main.c文件
#include "stm32f10x.h"
#include "bsp_SysTick.h"
#include "bsp_led.h"

int main(void)
{	
	/* LED端口初始化 */
	LED_GPIO_Config();

	/* 配置SysTick 为10us中断一次*/
	SysTick_Init();
#if 0 
	for(;;)
	{

		LED1( ON ); 
	    Delay_us(100000);    	// 100000 * 10us = 1000ms
		//Delay_ms(100);
		LED1( OFF );
	  
		LED2( ON );
	    Delay_us(100000);		// 100000 * 10us = 1000ms
		//Delay_ms(100);
		LED2( OFF );
	
		LED3( ON );
	    Delay_us(100000);		// 100000 * 10us = 1000ms
		//Delay_ms(100);
		LED3( OFF );
	}     
#else
	for(;;)
	{

		LED1( ON ); 
		SysTick_Delay_Ms( 1000 );
		LED1( OFF );
	  
		LED2( ON );
		SysTick_Delay_Ms( 1000 );
		LED2( OFF );
	
		LED3( ON );
		SysTick_Delay_Ms( 1000 );
		LED3( OFF );
	} 
#endif	
}
运行结果

在这里插入图片描述

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
STM32是一款广泛应用于嵌入式系统的微控制器,通过定时器可以方便地实现LED闪烁功能。 首先,我们需要配置一个定时器来控制LED闪烁间隔。定时器可以选择使用内部的系统时钟作为时基,也可以通过外部时钟源提供时基。在本例中,我们选择使用内部时钟作为时基。 接下来,我们需要配置GPIO引脚来控制LEDSTM32有多个GPIO引脚可以用来控制LED的亮灭状态。我们将一个GPIO引脚配置为输出模式,并连接到LED。 然后,我们需要编写代码来配置定时器和GPIO引脚,并实现LED闪烁。 首先,我们使用CubeMX来配置STM32的时钟源和GPIO引脚。我们选择一个合适的时钟源作为定时器的时基,同时将一个GPIO引脚配置为输出模式,并连接到LED。 然后,我们打开Keil或其他编程软件,编写C语言代码来实现LED闪烁。在代码中,我们使用定时器的中断功能来控制LED的亮灭状态。 首先,我们初始化定时器并配置定时器的参数,如定时器的预分频值和计数器的重载值。然后,我们使能定时器的中断,并编写一个中断服务函数来处理定时器中断。 在中断服务函数中,我们使用一个计数变量来记录中断的次数。当计数变量达到我们需要的闪烁间隔时,我们改变LED的状态,即改变GPIO引脚的电平状态,使LED闪烁。 最后,我们在主函数中启动定时器,并进入一个无限循环来保持程序的运行。在无限循环中,我们不需要做任何操作,因为LED闪烁将由定时器中断来实现。 通过上述步骤,我们成功实现了STM32通过定时器来控制LED闪烁功能。这样,每当定时器中断触发时,LED的状态就会改变,从而实现了LED闪烁效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DS.小青龙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值