电路分析
由图可知
蜂鸣器:TIM4_CH1---->PB6
风扇:TIM1_CH1---->PE9
马达:TIM16_CH1---->PF6
可以用以下代码检查硬件是否正常
gpio toggle gpiob6
gpio toggle gpioe9
gpio toggle gpiof6
程序分析
1.分析RCC章节:相关控制器组使能 TIM4 TIM1 TIM16 gpiob gpioe gpiof
2.分析GPIO章节:MODER复用模式/复用功能(10)
AFRL和AFRH改为TIMx_CH!
4.分析TIM4章节:产生特定的方波
递减计数方式
比较/捕获寄存器
代码
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()
{
//PWM_蜂鸣器初始化-->TIM4-CH1 PB6
pwm_buzzer_init();
//PWM_风扇初始化-->TIM1-CH1 PE9
pwm_fan_init();
//PWM_马达初始化-->TIM16-CH1 PF6
pwm_motor_init();
while(1)
{
}
return 0;
}
pwm.h
#ifndef __PWM_H__
#define __PWM_H__
#include "stm32mp1xx_gpio.h"
#include "stm32mp1xx_rcc.h"
#include "stm32mp1xx_tim.h"
//PWM_蜂鸣器初始化-->TIM4-CH1 PB6
void pwm_buzzer_init();
//PWM_风扇初始化-->TIM1-CH1 PE9
void pwm_fan_init();
//PWM_马达初始化-->TIM16-CH1 PF6
void pwm_motor_init();
#endif
pwm.c
PWM_蜂鸣器初始化
#include "pwm.h"
//PWM_蜂鸣器初始化-->TIM4-CH1 PB6
void pwm_buzzer_init()
{
//RCC初始化
RCC->MP_AHB4ENSETR |=(0x1<<1); //GPIOB使能
RCC->MP_APB1ENSETR |=(0x1<<2); //TIME4使能
//GPIO初始化
GPIOB->MODER &=(~(0x3<<12));//pb6 //设置模式为复用功能
GPIOB->MODER |=(0x2<<12);
GPIOB->AFRL &=~(0xf<<24);//pb6 //设置复用功能为TIM4
GPIOB->AFRL |=(0x2<<24);
//TIME4初始化
TIM4->CR1 |=(0x1 <<7); //TIM4_CR1[7] = 1 ------>自动重载计数器预加载使能
TIM4->CR1 &=~(0x3<<5); //TIM4_CR1[6:5] = 00 ------>设置边沿对齐模式
TIM4->CR1 |=(0x1 <<4); //TIM4_CR1[4] = 1 ------>设置递减计数器
TIM4->CR1 |=(0x1 <<0); //TIM4_CR1[0] = 1 ------>设置计数器使能
TIM4->CCMR1 &= ~(0x1<<16); //TIM4_CCMR1[16][6:4] = 0110------>设置为PWM1模式
TIM4->CCMR1 |=(0x3<<5);
TIM4->CCMR1 &= ~(0x1<<4);
TIM4->CCMR1 |=(0x1<<3); //TIM4_CCMR1[3] = 1 ------>输出捕获预加载使能
TIM4->CCMR1 &=( ~(0x3<<0));//TIM4_CCMR1[1:0] =00 ------>设置为输出模式
TIM4->CCER &=(~(0x1<<3)); //TIM4_CCER1[3] = 1 ------>设置为输出模式
TIM4->CCER |=(0x1<<1); //TIM4_CCER1[1] = 0 ------>设置起始状态高电平
TIM4->CCER |=(0x1<<0); //TIM4_CCER1[0] = 1 ------>设置为输出使能
TIM4->PSC &=(~(0xffff)); //写入分频数
TIM4->PSC |=(0xd1);
TIM4->ARR &=(~(0xffff<<0)); //写入重载计数
TIM4->ARR |=(0xEA60);
TIM4->CCR1 &=(~(0xffffffff)); //写入捕获数
TIM4->CCR1 |=(0x7530);
}
PWM_风扇初始化
//PWM_风扇初始化-->TIM1-CH1 PE9
void pwm_fan_init()
{
//RCC初始化
RCC->MP_AHB4ENSETR |=(0x1<<4); //GPIOE使能
RCC->MP_APB2ENSETR |=(0x1<<0); //TIME1使能
//GPIO初始化
GPIOE->MODER &=(~(0x3<<18));//pe9 //设置模式为复用功能
GPIOE->MODER |=(0x2<<18);
GPIOE->AFRH &=~(0xf<<4);//pe9 //设置复用功能为TIM1
GPIOE->AFRH |=(0x1<<4);
//TIME1初始化
TIM1->CR1 |=(0x1 <<7); //TIM1_CR1[7] = 1 ------>自动重载计数器预加载使能
TIM1->CR1 &=~(0x3<<5); //TIM1_CR1[6:5] = 00 ------>设置边沿对齐模式
TIM1->CR1 |=(0x1 <<4); //TIM1_CR1[4] = 1 ------>设置递减计数器
TIM1->CR1 |=(0x1 <<0); //TIM1_CR1[0] = 1 ------>设置计数器使能
TIM1->CCMR1 &= ~(0x1<<16); //TIM1_CCMR1[16][6:4] = 0110------>设置为PWM1模式
TIM1->CCMR1 |=(0x3<<5);
TIM1->CCMR1 &= ~(0x1<<4);
TIM1->CCMR1 |=(0x1<<3); //TIM1_CCMR1[3] = 1 ------>输出捕获预加载使能
TIM1->CCMR1 &=( ~(0x3<<0));//TIM1_CCMR1[1:0] =00 ------>设置为输出模式
TIM1->CCER &=(~(0x1<<3)); //TIM1_CCER1[3] = 1 ------>设置为输出模式
TIM1->CCER |=(0x1<<1); //TIM1_CCER1[1] = 0 ------>设置起始状态高电平
TIM1->CCER |=(0x1<<0); //TIM1_CCER1[0] = 1 ------>设置为输出使能
TIM1->PSC &=(~(0xffff)); //写入分频数
TIM1->PSC |=(0xd1);
TIM1->ARR &=(~(0xffff<<0)); //写入重载计数
TIM1->ARR |=(0x3eb);
TIM1->CCR1 &=(~(0xffff)); //写入捕获数
TIM1->CCR1 |=(0x64);
TIM1->BDTR |=(0x1<<15);
}
PWM_马达初始化
//PWM_马达初始化-->TIM16-CH1 PF6
void pwm_motor_init()
{
//RCC初始化
RCC->MP_AHB4ENSETR |=(0x1<<5); //GPIOF使能
RCC->MP_APB2ENSETR |=(0x1<<3); //TIME16使能
//GPIO初始化
GPIOF->MODER &=(~(0x3<<12));//pf6 //设置模式为复用功能
GPIOF->MODER |=(0x2<<12);
GPIOF->AFRL &=~(0xf<<24);//pf6 //设置复用功能为TIM16
GPIOF->AFRL |=(0x1<<24);
//TIME16初始化
TIM16->CR1 |=(0x1 <<7); //TIM16_CR1[7] = 1 ------>自动重载计数器预加载使能
// TIM16->CR1 &=~(0x3<<5); //TIM16_CR1[6:5] = 00 ------>设置边沿对齐模式
// TIM16->CR1 |=(0x1 <<4); //TIM16_CR1[4] = 1 ------>设置递减计数器
TIM16->CR1 |=(0x1 <<0); //TIM16_CR1[0] = 1 ------>设置计数器使能
TIM16->CCMR1 &= ~(0x1<<16); //TIM16_CCMR1[16][6:4] = 0110------>设置为PWM1模式
TIM16->CCMR1 |=(0x3<<5);
TIM16->CCMR1 &= ~(0x1<<4);
TIM16->CCMR1 |=(0x1<<3); //TIM16_CCMR1[3] = 1 ------>输出捕获预加载使能
TIM16->CCMR1 &=( ~(0x3<<0));//TIM16_CCMR1[1:0] =00 ------>设置为输出模式
TIM16->CCER &=(~(0x1<<3)); //TIM16_CCER1[3] = 1 ------>设置为输出模式
TIM16->CCER |=(0x1<<1); //TIM16_CCER1[1] = 0 ------>设置起始状态高电平
TIM16->CCER |=(0x1<<0); //TIM16_CCER1[0] = 1 ------>设置为输出使能
TIM16->PSC &=(~(0xffff)); //写入分频数
TIM16->PSC |=(0xd1);
TIM16->ARR &=(~(0xffff<<0)); //写入重载计数
TIM16->ARR |=(0x3eb);
TIM16->CCR1 &=(~(0xffffffff)); //写入捕获数
TIM16->CCR1 |=(0x64);
TIM16->BDTR |=(0x1<<15);
}