楼主: 肖洛宸
102 0

基于STM32F407的定时器实现PWM呼吸灯(非阻塞) [推广有奖]

  • 0关注
  • 0粉丝

等待验证会员

学前班

40%

还不是VIP/贵宾

-

威望
0
论坛币
0 个
通用积分
0
学术水平
0 点
热心指数
0 点
信用等级
0 点
经验
20 点
帖子
1
精华
0
在线时间
0 小时
注册时间
2018-3-1
最后登录
2018-3-1

楼主
肖洛宸 发表于 2025-11-25 11:04:31 |AI写论文

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币

一、功能效果说明

系统运行时,呼吸灯效果与外部中断控制LED翻转可同时工作,两者操作独立,互不干扰,确保多任务并行执行的稳定性。

二、程序实现部分

1、main.c 模块

#include "stm32f4xx.h"                  // Device header
#include "Led.h"
#include "Key.h"
#include "usart.h"
#include <string.h>
#include "Delay.h"
#include "Timer.h"
#include "Pwm.h"


uint8_t buffer[100];
uint8_t size = 0;
uint8_t Over_Flag = 0; 	//串口接收完成标志

uint8_t Pwm_Dir = 0;	//Pwm方向。0表示增长,1表示减少
uint8_t Duty = 0;
int main(void)
{
	
	Led_Init();		
	Key_Init();
	Usart_Init();
	Timer6_Init();
	Pwm_Init();

	Pwm_Start();
	while(1)
	{
	
	 }
	
}

2、Timer.c 模块(核心部分)

#include "Timer.h"
#include "Led.h"
#include "Pwm.h"

uint8_t Timer6_Count = 0;
uint8_t Update_Time = 20;               //每20ms更新一次PWM占空比

void Timer6_Init(void)                  //1ms中断一次
{
	RCC->APB1ENR |= RCC_APB1ENR_TIM6EN; //开启时钟,APB1总线最高频率为42Mhz

    //由于分频系数不为1,则定时器时钟为总线频率*2,为84Mhz
    TIM6->PSC = 84-1;                   //配置预分频值为83
    TIM6->ARR = 1000-1;                 //配置重装载寄存器为999,表示计数1000次产生一次更新

    TIM6->DIER &= ~TIM_DIER_UIE;        //禁止更新中断
    TIM6->EGR |= TIM_EGR_UG;            //手动产生更新事件,将PSC的值直接刷进影子寄存器中
    TIM6->DIER |= TIM_DIER_UIE;         //更新中断使能
    
    NVIC_SetPriorityGrouping(4);
    NVIC_SetPriority(TIM6_DAC_IRQn,2);
    NVIC_EnableIRQ(TIM6_DAC_IRQn);

    TIM6->CR1 |= TIM_CR1_CEN;           //开启定时器
}

void TIM6_DAC_IRQHandler(void)
{
    TIM6->SR &= ~TIM_SR_UIF;             //清除中断标志位
    Timer6_Count++;
    
    if (Timer6_Count >= Update_Time)
    {
        Timer6_Count = 0;
        if (Pwm_Dir == 0)
        {
            Duty += 1;
            if (Duty >= 99)
            {
                Pwm_Dir = 1;
            }
            
        }
        else
        {
            Duty -= 1;
            if (Duty <= 0)
            {
                Pwm_Dir = 0;
            }
            
        }
        
    }
    Tim14_SetDuty(Duty);
    
    
}

3、Pwm.c 模块

#include "Pwm.h"

void Pwm_Init(void)
{
    RCC->APB1ENR |= RCC_APB1ENR_TIM14EN;    //开启定时器14时钟
    RCC->AHB1ENR |= RCC_AHB1ENR_GPIOFEN;    //开启GPIOF时钟
    
    //配置PF9为复用推挽输出
    GPIOF->MODER |= GPIO_MODER_MODER9_1;    //配置为复用功能
    GPIOF->OTYPER |= (0x00 << 18);          //配置为推挽输出
    GPIOF->AFR[1] |= (0x09 << 4);           //配置PF9的复用引脚(AF9)

    //定时器配置
    TIM14->PSC = 8400-1;                    //配置预分频值
    TIM14->ARR = 100-1;                     //配置自动重装载值

    TIM14->CR1 &= ~TIM_CR1_DIR;             //配置为向上自增模式
    TIM14->CCR1 = 0;                        //设置通道1的初始CCR值
    TIM14->CCMR1 &= ~TIM_CCMR1_CC1S;        //配置通道1为输出模式

    //配置通道1为PWM模式1(O1CM为:110)
    TIM14->CCMR1 |= TIM_CCMR1_OC1M_2;       
    TIM14->CCMR1 |= TIM_CCMR1_OC1M_1;
    TIM14->CCMR1 &= ~TIM_CCMR1_OC1M_0;

    TIM14->CCER |= TIM_CCER_CC1E;           //使能输出通道
}

void Pwm_Start(void)
{
    TIM14->CR1 |= TIM_CR1_CEN;
}

void Pwm_Stop(void)
{
    TIM14->CR1 &= ~TIM_CR1_CEN;
}

void Tim14_SetDuty(uint8_t Duty)
{
    TIM14->CCR1 = Duty;
}
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

关键词:PWM STM 定时器 Grouping include

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
jg-xs1
拉您进交流群
GMT+8, 2026-1-4 05:46