实验四 - PWM实验

1、PWM相关概念

pwm : 脉冲宽度调制
脉冲 :高低电平变化的方波信号

频率(单位Hz) : 1s钟产生方波信号的个数
周期(单位s) : 一个方波信号的时间
	周期和频率成倒数的关系 : T = 1s / F
	
占空比:一个方波周期内,高电平占整个方波周期的百分比。
	   __    __
	__|  |__|			占空比 = 50%

pwm使用的场合:无源蜂鸣器的驱动,电机的调速, 屏幕的背光

2、分析蜂鸣器的电路图

image-20230719111950698

image-20230719112012695

image-20230719112213213

有源蜂鸣器:
	有源蜂鸣器内部有一个震荡源,当给有源蜂鸣器供电时,
内部的震荡源就会按照一定的频率震荡产生一个一定频率的方波信号,
实现蜂鸣器的发声。因此有源蜂鸣器一般使用高低电平驱动。
无源蜂鸣器:
	无源蜂鸣器内部没有震荡源,因此需要人为的提供一个一定频率
变化的方波信号,最终实现控制无源蜂鸣器的发声。因此,无源蜂鸣器
的驱动使用PWM方波信号进行控制。
FSMP1A开发板使用的是有源蜂鸣器。

3、 分析芯片手册

image-20230719113345059

3.1 分析2.5.2章节,确定GPIOB,TIM4,RCC外设控制器分别接到哪根总线上,以及外设控制器寄存器对应的基地址

image-20230719113703590

image-20230719113637665

3.2 分析RCC章节,使用GPIOB,TIM4外设控制器的时钟源

image-20230719113741330

image-20230719113800347

image-20230719113817032

image-20230719113830344

3.3 分析GPIO章节,设置PB6引脚为TIM4_CH1的复用功能

image-20230719114007910

3.3.1 GPIOx_MODER寄存器

image-20230719114036112

GPIOx_OTYPER		: 默认为推挽输出
GPIOx_OSPEEDR		: 默认为低速模式
GPIOx_PUPDR			: 默认禁止上下拉电阻
以上三个寄存器可以设置,也可以不设置,使用默认值即可。

3.3.2 GPIOx_AFRL寄存器

image-20230719114159485

image-20230719114235341

image-20230719114306877

image-20230719114326670

3.4 分析TIM4章节,设置TIM4输出一个PWM方波信号

image-20230719133630194

up:递增计数器       down :递减计数器     up/down:递增递减计数器

image-20230719134634511

image-20230704113900449

image-20230719140711940

分频器的描述:

image-20230719143743010

递增计数器:

image-20230719144208187

image-20230719144546018

image-20230719144800174

递减计数器:

image-20230719144916922

递增递减计数器:

image-20230719144944406

2.4.1 TIMx_CR1寄存器

image-20230719145242286

image-20230719145346596

image-20230719145509830

image-20230719145543875

image-20230719145606545

2.4.2 TIMx_CCMR1寄存器

image-20230719145954938

image-20230719150518496

image-20230719150733494

image-20230719150831128

2.4.3 TIMx_CCER寄存器

image-20230719150937289

image-20230719151038912

image-20230719151118037

image-20230719151240098

2.4.4 TIMx_PSC寄存器

image-20230719151410723

2.4.5 TIMx_ARR寄存器

image-20230719151547559

2.4.6 TIMx_CCR1寄存器

image-20230719151559196

image-20230719151622898

image-20230606152419474

4、 编写驱动代码

beep.h

#ifndef _BEEP_H_
#define _BEEP_H_

#include "gpio.h"
#include "../common/include/stm32mp1xx_tim.h"


void hal_beep_init();







#endif /*_BEEP_H_*/

beep.c

#include "../include/beep.h"


void hal_beep_init(){
    //使能时钟
    RCC->MP_AHB4ENSETR |=(1<<1);
    RCC->MP_APB1ENSETR |=(1<<2);

    //GPIO
    GPIOB->MODER &=~(0b11<<12);
    GPIOB->MODER |=(0b10<<12);

    GPIOB->AFRL &=~(0b1111<<24);
    GPIOB->AFRL |=(0b0010<<24);

    //
    
    TIM4->CCMR1 &=~(1<<16);
    TIM4->CCMR1 &=~(0b111<<4);
    TIM4->CCMR1 |=(0b110<<4);
    TIM1->CCMR1 &=~(1<<3);//  OC1PE
    TIM4->CCMR1 &=~(0b11);

    TIM4->CCER &=~(1<<3);
    TIM4->CCER &=~1;
    TIM4->CCER |=1;
    TIM4->CCER &=~(1<<1);

    TIM4->PSC=208;
    TIM4->ARR=1000;
    TIM4->CCR1=700;

    TIM4->CR1 &=~(1<<7);
    TIM4->CR1 &=~(0b11<<5);
    TIM4->CR1 &=~(1<<4);
    TIM4->CR1 &=~(1);
    TIM4->CR1 |=1;

}

5、 编译,下载,调试

6、完成风扇和马达的实验

对于风扇和马达使用的时TIM1_CH1和TIM16_CH1, 要想输出PWM方波信号,
必须的设置TIMx_BDTR寄存器的MOE位,设置为主输出使能,方能输出PWM方波。

image-20230103165349781

image-20230103165422264

image-20230103165523425

image-20230103165547565

motor.h

#ifndef _MOTOR_H_
#define _MOTOR_H_

#include "gpio.h"
#include "../common/include/stm32mp1xx_tim.h"


void hal_motor_init();







#endif /*_MOTOR_H_*/

motor.c 

#include "../include/motor.h"


void hal_motor_init(){
    //使能时钟
    RCC->MP_AHB4ENSETR |=(1<<5);//使能GPIOE时钟
    RCC->MP_APB2ENSETR |=(1<<3);//使能TIM1时钟

    //GPIOF
    GPIOF->MODER &=~(0b11<<12);//MODER  10 复用模式 PE9
    GPIOF->MODER |=(0b10<<12);

    GPIOF->AFRL &=~(0b1111<<24);
    GPIOF->AFRL |=(0b0001<<24);//AFRH  0001

    //

    TIM16->CCMR1 &=~(1<<16);//TIM4->CCMR1[16,6:4]     0110
    TIM16->CCMR1 &=~(0b111<<4);
    TIM16->CCMR1 |=(0b110<<4);
    TIM16->CCMR1 &=~(1<<3);//  OC1PE
    TIM16->CCMR1 &=~(0b11);//CC1S

    TIM16->CCER &=~(1<<3);//CC1NP
    TIM16->CCER &=~1;//CC1P
    TIM16->CCER |=1;
    TIM16->CCER &=~(1<<1); //CC1E

    TIM16->PSC=208;
    TIM16->ARR=1000;
    TIM16->CCR1=500;

    TIM16->BDTR &=~(1<<15);
    TIM16->BDTR |=(1<<15);

    TIM16->CR1 &=~(1<<7);// TIM4->CR1[7]=0   ARPE=0  不用管
    TIM16->CR1 &=~(0b11<<5);// TIM4->CR1[6:5]=0b00  边沿对齐
    TIM16->CR1 &=~(1<<4);
    TIM16->CR1 |=(1<<4);// TIM4->CR1[4]=0  递减计数器
    TIM16->CR1 &=~(1);
    TIM16->CR1 |=1;// TIM4->CR1[1]=1  使能计数器

}

 fan.h

#ifndef _FAN_H_
#define _FAN_H_

#include "gpio.h"
#include "../common/include/stm32mp1xx_tim.h"


void hal_fan_init();







#endif /*_FAN_H_*/

fan.c

#include "../include/fan.h"


void hal_fan_init(){
    //使能时钟
    RCC->MP_AHB4ENSETR |=(1<<4);//使能GPIOE时钟
    RCC->MP_APB2ENSETR |=(1);//使能TIM1时钟

    //GPIO
    GPIOE->MODER &=~(0b11<<18);//MODER  10 复用模式 PE9
    GPIOE->MODER |=(0b10<<18);

    GPIOE->AFRH &=~(0b1111<<4);
    GPIOE->AFRH |=(0b0001<<4);//AFRH  0001

    //

    TIM1->CCMR1 &=~(1<<16);//TIM4->CCMR1[16,6:4]     0110
    TIM1->CCMR1 &=~(0b111<<4);
    TIM1->CCMR1 |=(0b110<<4);
    TIM1->CCMR1 &=~(1<<3);//  OC1PE
    TIM1->CCMR1 &=~(0b11);//CC1S

    TIM1->CCER &=~(1<<3);//CC1NP
    TIM1->CCER &=~1;//CC1P
    TIM1->CCER |=1;
    TIM1->CCER &=~(1<<1); //CC1E

    TIM1->PSC=208;
    TIM1->ARR=1000;
    TIM1->CCR1=500;

    TIM1->BDTR &=~(1<<15);
    TIM1->BDTR |=(1<<15);

    TIM1->CR1 &=~(1<<7);// TIM4->CR1[7]=0   ARPE=0  不用管
    TIM1->CR1 &=~(0b11<<5);// TIM4->CR1[6:5]=0b00  边沿对齐
    TIM1->CR1 &=~(1<<4);
    TIM1->CR1 |=(1<<4);// TIM4->CR1[4]=0  递减计数器
    TIM1->CR1 &=~(1);
    TIM1->CR1 |=1;// TIM4->CR1[1]=1  使能计数器

}

main.c

#include "include/led.h"
#include "include/key.h"
#include "include/uart4.h"
#include "include/beep.h"
#include "include/fan.h"
#include "include/motor.h"
void delay_ms(unsigned int ms){
        int i, j;
        for (i = 0; i < ms; i++)
            for (j = 0; j < 1800; j++)
                ;
    }
int my_strcmp(const char* src,const char *dst){
        int ret = 0;
    while( !(ret = *(unsigned char*)src - *(unsigned char*)dst) && *dst)
    {
        src ++;
        dst ++;
    }
    if( ret < 0) ret = -1;
    else if(ret > 0) ret = 1;
    return ret;
}
int main(){
    //hal_fan_init();
    hal_motor_init();
    //hal_beep_init();
    while (1){

    }
        
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值