基于STM32的PWM三色呼吸灯
通过按键控制三色呼吸灯。按键中断打开捕获使能,定时器中断使能,核心级中断使能,从而进入定时器中断服务子程序,进行pwm控制呼吸灯。
main.c文件程序
#include "stm32f4xx.h"
#include "key.h"
#include "interr.h"
#include "pwm_timer4.h"
int main(void)
{
key_init();
timer4_init();
interr_init();
while(1);
}
key.h文件程序
#ifndef KEY_H
#define KEY_H
#include "stm32f4xx.h"
#include "io_bit.h"
#define KEY0 PAin(0)
#define KEY1 PEin(2)
#define KEY2 PEin(3)
void key_init(void);
#endif
key.c文件程序
#include "key.h"
void key_init(void) //PA0 PE2 PE3
{
RCC->AHB1ENR|=1;
GPIOA->MODER&=~(0x3<<(0*2));
GPIOA->PUPDR&=~(0x3<<(0*2));
GPIOA->PUPDR|=(0x2<<(0*2)); //10 下拉
RCC->AHB1ENR|=1<<4;
GPIOE->MODER&=~(0xf<<(2*2)); //00
GPIOE->PUPDR&=~(0xa<<(2*2)); //01 上拉
}
interr.h文件程序
#ifndef INTERR_H
#define INTERR_H
#include "stm32f4xx.h"
void interr_init(void);
#endif
interr.c文件程序
#include "interr.h"
void interr_init(void)
{
RCC->APB2ENR|=1<<14;
SYSCFG->EXTICR[0]&=~(0xf<<0); //PA0
SYSCFG->EXTICR[0]&=~(0xff<<8);
SYSCFG->EXTICR[0]|=(0x44<<8); //PE2,3
EXTI->IMR|=1<<0; //中断屏蔽寄存器开启
EXTI->IMR|=0x3<<2;
EXTI->EMR&=~(0x1<<0); //事件屏蔽寄存器关闭
EXTI->EMR&=~(0x3<<2);
EXTI->RTSR|=0x1<<0; //PA0上升沿
EXTI->FTSR|=0x3<<2; //PE2,3下降沿
EXTI->SWIER&=~(0x1<<0); //软件屏蔽寄存器关闭
EXTI->SWIER&=~(0x3<<2);
/* u8 nvic_value;
nvic_value=NVIC_EncodePriority(7-2,1,2);
NVIC_SetPriority(EXTI0_IRQn,nvic_value);
NVIC_SetPriority(EXTI2_IRQn,nvic_value);
NVIC_SetPriority(EXTI3_IRQn,nvic_value);*/
NVIC_EnableIRQ(EXTI0_IRQn);
NVIC_EnableIRQ(EXTI2_IRQn);
NVIC_EnableIRQ(EXTI3_IRQn);
}
void EXTI0_IRQHandler(void)
{
if(EXTI->PR&(0x1<<0))
{
EXTI->PR|=0x1<<0;
TIM4->CCER|=(0x1<<4); //捕获使能
TIM4->DIER|=(0x1<<0); //中断使能
TIM4->CR1|=(0x1<<0); //计数器使能
NVIC_EnableIRQ(TIM4_IRQn); //核心级中断使能
}
}
void EXTI2_IRQHandler(void)
{
if(EXTI->PR&(0x1<<2))
{
EXTI->PR|=0x1<<2;
TIM4->CCER|=(0x1<<8);
TIM4->DIER|=(0x1<<0); //中断使能
TIM4->CR1|=(0x1<<0); //计数器使能
NVIC_EnableIRQ(TIM4_IRQn); //核心级中断使能
}
}
void EXTI3_IRQHandler(void)
{
if(EXTI->PR&(0x1<<3))
{
EXTI->PR|=0x1<<3;
TIM4->CCER|=(0x1<<12);
TIM4->DIER|=(0x1<<0); //中断使能
TIM4->CR1|=(0x1<<0); //计数器使能
NVIC_EnableIRQ(TIM4_IRQn); //核心级中断使能
}
}
pwm_time4.h文件程序
#ifndef PWM_TIMER4_H
#define PWM_TIMER4_H
#include "stm32f4xx.h"
void timer4_init(void);
#endif
pwm_time4.c文件程序
#include "pwm_timer4.h"
unsigned int flag;
void timer4_init(void)
{
RCC->AHB1ENR|=(0x1<<3);
GPIOD->MODER&=~(0x3f<<(2*13));
GPIOD->MODER|=(0x2a<<(2*13)); //复用
GPIOD->OTYPER&=~(0x7<<13); //推挽
GPIOD->OSPEEDR&=~(0x3f<<(2*13));
GPIOD->AFR[1]&=~(0xfff<<20);
GPIOD->AFR[1]|=(0x222<<20);
RCC->APB1ENR|=(0x1<<2); //开time4时钟
TIM4->CNT=0; //计数器清零
TIM4->PSC=84-1; //预分频
TIM4->ARR=1000-1; //重装载值
TIM4->CR1=0;
TIM4->CR1|=(0x1<<2); //允许中断
TIM4->CCR2=0; //亮度设置
TIM4->CCR3=0;
TIM4->CCR4=0;
TIM4->CCMR1=0;
TIM4->CCMR2=0;
TIM4->CCMR1|=(0x7<<12); //选择模式2
TIM4->CCMR2|=(0x7<<4);
TIM4->CCMR2|=(0x7<<12);
TIM4->CCER=0;
TIM4->CCER|=(0x1<<5); //低电平无效
TIM4->CCER|=(0x1<<9);
TIM4->CCER|=(0x1<<13);
TIM4->CCER&=~(0x1<<4); //捕获不使能
TIM4->CCER&=~(0x1<<8);
TIM4->CCER&=~(0x1<<12);
TIM4->DIER&=~(0x1<<0); //中断不使能
TIM4->CR1&=~(0x1<<0); //计数器不使能
NVIC_DisableIRQ(TIM4_IRQn); //核心级中断使能
}
void TIM4_IRQHandler(void)
{
if(TIM4->SR&(0x1<<0))
{
TIM4->SR&=~(0x1<<0);
if((TIM4->CCR2==500)&&(TIM4->CCR3==500)&&(TIM4->CCR4==500))
flag=1;
else if((TIM4->CCR2==0)&&(TIM4->CCR3==0)&&(TIM4->CCR4==0))
flag=0;
if(flag==0)
{
TIM4->CCR2+=1;
TIM4->CCR3+=1;
TIM4->CCR4+=1;
}
else
{
TIM4->CCR2-=1;
TIM4->CCR3-=1;
TIM4->CCR4-=1;
}
}
}
key电路图
共阴三色灯接口电路图
复位按键电路图
程序运行效果
基于STM32的PWM控制的三色呼吸灯