1.分析框图;
2.比较捕获寄存器(产生PWM方波);
工作原理:
1、系统提供一个时钟源209MHZ,需要通过分频器进行分频,设置分频器值为209分频;
2、当定时器启动之后,自动重载计数器中的值,会自动加载到递减计数器中;
3、时钟信号驱动递减计数器进行工作;
4、每来一个时钟周期,递减计数器中的值,进行减1操作;
5、当递减计数器中的值,和捕获比较寄存器中的值相等之后,电平发生翻转;
6、递减计数器中的值减到0之后;
7、自动重载计数器中的值,会再次自动加载到递减计数器中,开启下个时钟周期;
3.代码;
---pwm.h头文件---
#ifndef __PWM_H__
#define __PWM_H__#include "stm32mp1xx_gpio.h"
#include "stm32mp1xx_rcc.h"
#include "stm32mp1xx_tim.h"//PB6 TIM4_CH1 蜂鸣器初始化
void hal_beep_init();//PF6 TIM16_CH1 马达初始化
void hal_monitor_init();//PE9 TIM1_CH1 风扇初始化
void hal_fan_init();#endif
---pwm.c函数实现---
#include "pwm.h"//PB6 TIM4_CH1 蜂鸣器
void hal_beep_init()
{//RCC章节初始化//1.使能GPIOB组控制器RCC->MP_AHB4ENSETR |= (0x1 << 1);//2.使能TIM4组控制器RCC->MP_APB1ENSETR |= (0x1 << 2);//GPIO章节初始化//1.PB6引脚复用功能 [13:12]=10GPIOB->MODER &= (~(0x3 << 12));GPIOB->MODER |= (0x2 << 12);//2.复用功能为TIM4_CH1功能 [27:14]=0010GPIOB->AFRL &= (~(0xF << 24));GPIOB->AFRL |= (0x2 << 24);//TIM4章节初始化//1.系统时钟源为209MHZ,进行分频209-1TIM4->PSC = 209 -1;//产生PWM方波频率1000HZ//2.自动重载计数器 1000TIM4->ARR = 1000;//3.捕获寄存器值TIM4->CCR1 = 300; //4.CCER 设置比较寄存器默认输出极性TIM4->CCER &= (~(0x1 << 1)); //输出极性高电平TIM4->CCER &= (~(0x1 << 3)); TIM4->CCER |= (0x1 << 0); //比较寄存器使能//5.CCMR1 配置比较捕获寄存器TIM4->CCMR1 &= (~(0x1 << 16)); //PWM模式TIM4->CCMR1 &= (~(0x7 << 4)); TIM4->CCMR1 |= (0x6 << 4);TIM4->CCMR1 |= (0x1 << 3); //比较寄存器预加载使能TIM4->CCMR1 &= (~(0x3 << 0)); //通道1输出//6.CR1 初始化寄存器相关操作TIM4->CR1 |= (0x1 << 7); //自动重载预加载使能TIM4->CR1 &= (~(0x3 << 5)); //设置边沿对齐模式TIM4->CR1 |= (0x1 << 4); //设置递减计数方式TIM4->CR1 |= 0x1; //设置计数器使能}//PF6 TIM16_CH1 马达
void hal_monitor_init()
{//RCC章节初始化//1.使能GPIOF组控制器RCC->MP_AHB4ENSETR |= (0x1 << 5);//2.使能TIM16组控制器RCC->MP_APB2ENSETR |= (0x1 << 3);//GPIO章节初始化//1.PF6引脚复用功能 [13:12]=10GPIOF->MODER &= (~(0x3 << 12));GPIOF->MODER |= (0x2 << 12);//2.复用功能为TIM16_CH1功能 [27:24]=0001GPIOF->AFRL &= (~(0xF << 24));GPIOF->AFRL |= (0x1 << 24);//TIM16章节初始化//1.系统时钟源为209MHZ,进行分频209-1TIM16->PSC = 209 -1;//产生PWM方波频率1000HZ//2.自动重载计数器 1000TIM16->ARR = 1000;//3.捕获寄存器值TIM16->CCR1 = 300; //4.CCER 设置比较寄存器默认输出极性TIM16->CCER &= (~(0x1 << 1)); //输出极性高电平TIM16->CCER &= (~(0x1 << 3)); TIM16->CCER |= (0x1 << 0); //比较寄存器使能TIM16->CR1 &= (~(0x3 << 5)); //设置边沿对齐模式TIM16->CR1 |= (0x1 << 4); //设置递减计数方式//5.CCMR1 配置比较捕获寄存器TIM16->CCMR1 &= (~(0x1 << 16)); //PWM模式TIM16->CCMR1 &= (~(0x7 << 4)); TIM16->CCMR1 |= (0x6 << 4);TIM16->CCMR1 |= (0x1 << 3); //比较寄存器预加载使能TIM16->CCMR1 &= (~(0x3 << 0)); //通道1输出//6.CR1 只有默认递增计数TIM16->CR1 |= (0x1 << 7); //自动重载预加载使能TIM16->CR1 |= 0x1; //设置计数器使能//7.设置TIM16_CH1 通道主输出使能TIM16->BDTR |= (0x1 << 15);}//PE9 TIM1_CH1 风扇
void hal_fan_init()
{//RCC章节初始化//1.使能GPIOE组控制器RCC->MP_AHB4ENSETR |= (0x1 << 4);//2.使能TIM4组控制器RCC->MP_APB2ENSETR |= (0x1 << 0);//GPIO章节初始化//1.PE9引脚复用功能 [19:18]=10GPIOE->MODER &= (~(0x3 << 18));GPIOE->MODER |= (0x2 << 18);//2.复用功能为TIM1_CH1功能 AFRH[7:4]=0001GPIOE->AFRH &= (~(0xF << 4));GPIOE->AFRH |= (0x1 << 4);//TIM1章节初始化//1.系统时钟源为209MHZ,进行分频209-1TIM1->PSC = 209 -1;//产生PWM方波频率1000HZ//2.自动重载计数器 1000TIM1->ARR = 500;//3.捕获寄存器值TIM1->CCR1 = 300; //4.CCER 设置比较寄存器默认输出极性TIM1->CCER &= (~(0x1 << 1)); //输出极性高电平TIM1->CCER &= (~(0x1 << 3)); TIM1->CCER |= (0x1 << 0); //比较寄存器使能//5.CCMR1 配置比较捕获寄存器TIM1->CCMR1 &= (~(0x1 << 16)); //PWM模式TIM1->CCMR1 &= (~(0x7 << 4)); TIM1->CCMR1 |= (0x6 << 4);TIM1->CCMR1 |= (0x1 << 3); //比较寄存器预加载使能TIM1->CCMR1 &= (~(0x3 << 0)); //通道1输出//6.CR1 TIM1->CR1 |= (0x1 << 7); //自动重载预加载使能TIM1->CR1 &= (~(0x3 << 5)); //设置边沿对齐模式TIM1->CR1 |= (0x1 << 4); //设置递减计数方式TIM1->CR1 |= 0x1; //设置计数器使能//7设置TIM1_CH1 通道主输出使能TIM1->BDTR |= (0x1 << 15);
}
---main.c测试文件---
#include "pwm.h"extern void printf(const char *fmt, ...);void delay_ms(int ms){int i,j;for(i = 0; i < ms;i++)for (j = 0; j < 1800; j++);
}int main()
{while(1){hal_beep_init();hal_monitor_init();hal_fan_init();}return 0;}