基于STM32F429的呼吸灯

一、项目要求:

混合彩色呼吸灯,通过PC端串口小助手控制呼吸灯速率,开发板上按键控制呼吸灯的颜色。

二、设计说明:

在这里插入图片描述

三、效果示意图:

在这里插入图片描述

四、相关代码:

/********************************************************************************************************
******************************* 野火开发板STM32F429 LED呼吸灯 ********************************************
********************************************************************************************************/

#include "stm32f4xx_hal.h"

/*****************************************************************************************************
****************************    基础定义	***************************************************************
*******************************************************************************************************/
TIM_HandleTypeDef TIM5_Handler;         //定时器5 PWM句柄 
TIM_OC_InitTypeDef TIM5_CH1Handler;	    //定时器5 通道句柄

GPIO_InitTypeDef  gpio_init;
UART_HandleTypeDef uart_handler;

uint8_t  RxBUF[10];
int arr = 700;
uint8_t pdata[1]; 
int ccr = 1;
int ccr2 = 3;
uint32_t channel1;
uint32_t channel2;

/*****************************************************************************************************
****************************    LED初始化	*************************************************************
*******************************************************************************************************/
void LED_Init(void)
{
	__HAL_RCC_GPIOH_CLK_ENABLE();
	
	gpio_init.Pin = GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12;  //初始化引脚
	gpio_init.Mode = GPIO_MODE_AF_PP; 						//复用推挽输出
	gpio_init.Pull = GPIO_PULLUP; 								//不上下拉
	gpio_init.Speed = GPIO_SPEED_FREQ_VERY_HIGH;  //速度非常高
	gpio_init.Alternate = GPIO_AF2_TIM5;  				//复用为定时器5(PH10-PH12 对应TIM5的CH1-CH3)
	
	 HAL_GPIO_Init(GPIOH , &gpio_init);	
}
/*****************************************************************************************************
****************************    TIMER PWM 初始化配置 	************************************************
*******************************************************************************************************/
void TIME_PWM_Init()
{
	TIM5_Handler.Instance = TIM5;             //定时器5
	TIM5_Handler.Init.Prescaler = 90-1;       //定时器预分频系数
	TIM5_Handler.Init.CounterMode = TIM_COUNTERMODE_UP;	//向上计数模式
	TIM5_Handler.Init.Period = 1000-1;                	//自动重装载值
	TIM5_Handler.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
	HAL_TIM_PWM_Init(&TIM5_Handler);       		//初始化PWM

	TIM5_CH1Handler.OCMode = TIM_OCMODE_PWM1; 	//模式选择(PWM模式1:向上计数时,TIMx_CNT < TIMx_CCR1时为有效电平,否则为无效电平)
	TIM5_CH1Handler.Pulse = 500;           		 	//设置比较值,此值用来确定占空比,默认比较值为自动重装载值的一半,即占空比为50%
	TIM5_CH1Handler.OCPolarity = TIM_OCPOLARITY_LOW; 	//输出比较极性为低 即低电平有效
    
}
void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim)
{
	if((htim->Instance) == TIM5)
	{
		__HAL_RCC_TIM5_CLK_ENABLE();			//使能定时器
		LED_Init();
	}
}

void MY_PWM_Init_1(uint32_t channel)
{
		channel1 = channel;  //保存上一次更改的通道
		HAL_TIM_PWM_ConfigChannel(&TIM5_Handler,&TIM5_CH1Handler,channel);  //配置TIM5通道
    HAL_TIM_PWM_Start(&TIM5_Handler,channel);//开启PWM通道
}
void MY_PWM_Init_2(uint32_t channel)
{
		channel2 = channel;  //保存上一次更改的通道
		HAL_TIM_PWM_ConfigChannel(&TIM5_Handler,&TIM5_CH1Handler,channel);  //配置TIM5通道
    HAL_TIM_PWM_Start(&TIM5_Handler,channel);//开启PWM通道
}

 /*****************************************************************************************************
****************************    设置计算器比较值函数		*************************************************
*******************************************************************************************************/
void TIM_SetTIM5Compare(int ccr,uint32_t compare)
{
	if(ccr == 3){
		TIM5->CCR3 = compare; 
	}else if(ccr == 2){
		TIM5->CCR2 = compare; 
	}else if(ccr == 1){
		TIM5->CCR1 = compare; 
	}
}
void TIM_SetTIM5Compare_2(int ccr2,uint32_t compare)
{
	if(ccr2 == 3){
		TIM5->CCR3 = compare; 
	}else if(ccr2 == 2){
		TIM5->CCR2 = compare; 
	}else if(ccr2 == 1){
		TIM5->CCR1 = compare; 
	}
}

/*****************************************************************************************************
****************************   外部中断初始化	*********************************************************
*******************************************************************************************************/
void EXTI_init(void)
{
	
	GPIO_InitTypeDef gpio_init;
	__HAL_RCC_GPIOA_CLK_ENABLE();
	__HAL_RCC_GPIOC_CLK_ENABLE();
	
	gpio_init.Pin = GPIO_PIN_0;
	gpio_init.Mode = GPIO_MODE_IT_RISING;  //上升沿触发
	gpio_init.Pull = GPIO_PULLDOWN;
	gpio_init.Speed = GPIO_SPEED_FREQ_HIGH;
	HAL_GPIO_Init(GPIOA,& gpio_init);
	
	gpio_init.Pin = GPIO_PIN_13;
	HAL_GPIO_Init(GPIOC,& gpio_init);
	
	HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_2);  //分组仅仅设置一次
	HAL_NVIC_SetPriority(EXTI0_IRQn, 2, 2);
	HAL_NVIC_EnableIRQ(EXTI0_IRQn);
	
	HAL_NVIC_SetPriority(EXTI15_10_IRQn, 1, 1);
	HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);
	

}
/*****************************************************************************************************
****************************   外部中断服务函数	*******************************************************
*******************************************************************************************************/
void EXTI0_IRQHandler(void)
{
	HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
	
}
void EXTI15_10_IRQHandler(void)
{
	HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_13);
	
}

/*******************************************************************************************************
****************************   外部中断回调函数 - 重写弱函数	 *******************************************
*******************************************************************************************************/
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	if(GPIO_Pin == GPIO_PIN_0){
		
		HAL_TIM_PWM_Stop(&TIM5_Handler,channel1);
		HAL_TIM_PWM_Stop(&TIM5_Handler,channel2);
		MY_PWM_Init_1(TIM_CHANNEL_1);
		MY_PWM_Init_2(TIM_CHANNEL_3);
		ccr = 1;
	}else if(GPIO_Pin == GPIO_PIN_13){
		
		HAL_TIM_PWM_Stop(&TIM5_Handler,channel1);
		HAL_TIM_PWM_Stop(&TIM5_Handler,channel2);
		MY_PWM_Init_1(TIM_CHANNEL_2);
		MY_PWM_Init_2(TIM_CHANNEL_3);
		ccr = 2;
	}
}



/*******************************************************************************************************
****************************   串口初始化	**************************************************************
*******************************************************************************************************/
void UART_init(uint32_t  BaudRrate)
{
	uart_handler.Instance = USART1;
	uart_handler.Init.BaudRate = BaudRrate;
	uart_handler.Init.WordLength = USART_WORDLENGTH_8B;
	uart_handler.Init.StopBits = USART_STOPBITS_1;
	uart_handler.Init.Parity = USART_PARITY_NONE;
	uart_handler.Init.Mode = USART_MODE_TX_RX;
	
	HAL_UART_Init(&uart_handler);
	
	HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_2);  //分组仅仅设置一次
	HAL_NVIC_SetPriority(USART1_IRQn, 1, 1);
	HAL_NVIC_EnableIRQ(USART1_IRQn);
}
 
void HAL_UART_MspInit(UART_HandleTypeDef *husart)
 {
	 	__HAL_RCC_USART1_CLK_ENABLE();
	  __HAL_RCC_GPIOA_CLK_ENABLE();
		 
	 gpio_init.Pin = GPIO_PIN_9 | GPIO_PIN_10;
	 gpio_init.Mode = GPIO_MODE_AF_PP;
	 gpio_init.Pull = GPIO_MODE_IT_RISING;
	 gpio_init.Speed = GPIO_SPEED_FREQ_HIGH;
	 gpio_init.Alternate = GPIO_AF7_USART1;
		 
	 HAL_GPIO_Init(GPIOA,&gpio_init);

 }

 /******************************************************************************************************
****************************  串口服务函数  *************************************************************
*******************************************************************************************************/
void USART1_IRQHandler(void)
{
	 HAL_UART_IRQHandler(&uart_handler);
}
/*******************************************************************************************************
****************************    串口接收回调函数	 *******************************************************
*******************************************************************************************************/ 
 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *husart)
{
	HAL_UART_Receive_IT(&uart_handler , pdata , 1); 

	uint8_t ch;
	ch = pdata[0];
	if(('0'< ch )&&(ch<= '5')&&(pdata[1] == 0)){
		switch (ch){
			case '1':
				arr = 100;
				break;
			case '2': 
				arr = 200;
				break;
			case '3':
				arr = 400;
				break;
			case '4':
				arr = 600;
				break;
			case '5':
				arr = 800;
				break;
		}
			
	}else{
		arr = 1000;
		HAL_UART_Transmit(&uart_handler ,"Error!Please enter a new number between 1 and 5.\r\n" ,50,100);
	}

}
/*************************************************************************************************
****************************   延时函数	**********************************************************
*************************************************************************************************/ 
void delay_ms(int x)
{
	int y;
	while(x--)
	{
		for(y=0;y<1000;y++);
	}
}
/*************************************************************************************************
****************************   主函数		 *********************************************************
*************************************************************************************************/
int main(void)
{
	uint8_t dir = 1;  //亮暗方向。占空比大,亮度大;占空比小,亮度小。
  uint16_t ledpwmval = 0; //设置值
	
	TIME_PWM_Init();
	MY_PWM_Init_1(TIM_CHANNEL_3);
	MY_PWM_Init_2(TIM_CHANNEL_3);
	EXTI_init();
	UART_init(115200);
	HAL_UART_Receive_IT(&uart_handler, pdata, 1);   //只要有中断就有回调函数
	HAL_UART_Transmit(&uart_handler ,"Please enter a number between 1 and 5.\r\n" ,40,100);
	while(1)
    {
			delay_ms(10);	 	
			if(dir)ledpwmval++;				 				//dir==1 由暗变亮 ledpwmval递增
				else ledpwmval--;				    			//dir==0 ledpwmval递减 
			if(ledpwmval>arr)dir=0;						//ledpwmval到达300后,方向为递减
			if(ledpwmval==0)dir=1;			  			//ledpwmval递减到0后,方向改为递增
			TIM_SetTIM5Compare(ccr,ledpwmval);	//修改比较值,修改占空比
			TIM_SetTIM5Compare_2(ccr2,ledpwmval);	//修改比较值,修改占空比
    }
}

发布了8 篇原创文章 · 获赞 10 · 访问量 871

猜你喜欢

转载自blog.csdn.net/qq_44277244/article/details/104616544