STM32中的定时器实现呼吸灯效果

最近用32的定时器来做个呼吸灯,之前看其他博主的代码觉得有点难以理解。自己决定再动手写个代码用来记录STM32的学习。
中断的配置函数:

#include "timer_1.h"
#include "stm32f10x.h"
/*
1,时钟使能
2,配置预分频、自动重装值和重复计数值
3,清除中断标志位(否则会先进一次中断)
4,使能TIM中断,选择中断源
5,设置中断优先级
6,使能TIMx外设

arr:自动重装值  
psc:时钟预分频数  
*/

static void NVIC_init(void)
{
	 NVIC_InitTypeDef NVIC_InitStructure;  
	//设置优先级  
  NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_IRQn;    
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//先占优先级0级  
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;       //从优先级0级  
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  
  NVIC_Init(&NVIC_InitStructure);   
  TIM_Cmd(TIM1, ENABLE);  //使能TIMx外设  

}
void Timer1_Init(u16 arr,u16 psc)  
{  
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;  

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);				 //时钟使能  
  TIM_TimeBaseStructure.TIM_Period = arr; 										 //设置自动重装载寄存器周期值  
  TIM_TimeBaseStructure.TIM_Prescaler =(psc-1);				  			 //设置预分频值 
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;          			 //设置时钟分割  
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //向上计数模式  
  TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;						 //重复计数设置  
  TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);              //参数初始化  
  TIM_ClearFlag(TIM1, TIM_FLAG_Update);                        //清中断标志位  

  TIM_ITConfig(                                                //使能或者失能指定的TIM中断  
    TIM1,                                                      //TIM1  
    TIM_IT_Update  | 																					 //TIM 更新中断源  
    TIM_IT_Trigger,  																					 //TIM 触发中断源   
    ENABLE           																					 //使能  
    );  
	
  NVIC_init();																								 //设置优先级
}  

主函数:

#include "led.h"
#include "stm32f10x.h"
#include "delay.h"
#include "timer_1.h"
#include "oled.h"
int time=1000;
int num=0;
int flag=0;
void PWM_LED(int x)
{
	int i=x;
	while(--i)
	{
			GPIOB->ODR = 0<<12;
			delay_us(i);
		GPIOB->ODR = 1<<12;
			delay_us(x-i);
		}
	i=x;
		while(--i)
	{
			GPIOB->ODR = 1<<12;
			delay_us(i);
		GPIOB->ODR = 0<<12;
			delay_us(x-i);
		}
}
main()
{
	int num=0;
	//OLED_Init();
  LED_Init();									//PB12默认点亮
	//Timer1_Init(999,71);			//1ms中断    T(溢出时间) = ((arr+1)*(psc+1))/T(CK_INT) (默认是72MHZ) 	 
	//Timer1_Init(999,8);   			//125us中断,8预分频,现象:LED快速闪烁比PSC=71快很多
	//delay_ms(1000);
	Timer1_Init(7,8);						//1us中断
	while(1)
{
	/*GPIOB->ODR = 1<<12;
			delay_us(900);
		GPIOB->ODR = 0<<12;
			delay_us(1);*/
		//	PWM_LED(1000);

	}
}

void TIM1_UP_IRQHandler(void)   //TIM1中断
{
	if (TIM_GetITStatus(TIM1, TIM_IT_Update)!= RESET) //检查指定的TIM1中断发生与否:TIM1 中断源 
	{
	   TIM_ClearITPendingBit(TIM1,TIM_IT_Update);  //清除TIMx的中断待处理位:TIM1 中断源 
			time--;
	}
	
	if(time==0)	
	{	
		time = 1100;
		num++;
		if(num==1100)
		{
			num = 0;
			if(flag==2)
			  flag = 0;
			flag++;
		}
	}
	
	
	if(flag%2==0)
	{
		/************************************************************/
		if(time<num)		//从熄灭到最亮
	{
		GPIOB->ODR = 0<<12;	//亮
	}
else
		GPIOB->ODR = 1<<12;	//灭

	/************************************************************/
	}

	
	
	else if(flag%2==1)
	{
	/***********************************************************/
	if(time>num)		//从最亮到熄灭
	{
		GPIOB->ODR = 0<<12;	//亮
	}
else
		GPIOB->ODR = 1<<12;	//灭

	/***********************************************************/
		
	}
	
		
}

至于原理就将就着那个PWM_LED函数看看吧,我是照着它的运行思路写出来的。

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Ho_Yim

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

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

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

打赏作者

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

抵扣说明:

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

余额充值