PWM波启动无源蜂鸣器——基于STM32MP157A

一:原理解析

在编写代码前,首先要明白,PWM方波是怎么产生的。

 当定时器启动后,自动重载计数器中的值会自动加载到递减计数器中。递减计数器在CK_CNT时钟驱动下进行工作。每过一个时钟周期,递减计数器中的值会自动 -1。当减少到和捕获/比较寄存器中的值相同时,电平发生翻转,PWM方波信号就产生了。

二:电路分析

翻看芯片手册

由此可知:蜂鸣器引脚为TIM4_CH1

去主板上查找该引脚

 可知,主板引脚为PB6

所以可知

 RCC寄存器给TIM4相关控制器、GPIOB寄存器使能。由TIM4寄存器产生PWM方波信号,激活蜂鸣器。GPIOB寄存器控制蜂鸣器工作。

三:查看芯片手册,确定引脚功能

1:RCC章节分析

搜索可知,TIM寄存器,所在总线为APB1

起始地址为0x40002000 

GPIO寄存器,上篇文章已经找过了,不再过多赘述

GPIOB --> AHB4总线 -->起始地址:0x50003000

RCC对GPIOB使能

 即:

RCC_MP_AHB4ENSETR[1] = 1

RCC对TIM4使能

查找RCC_MP_APB1ENSETR寄存器

 即为:

RCC_MP_APB1ENSETR[2] = 1

 2:GPIO章节分析

GPIOx_MODER

设置PB6引脚为复用功能

 GPIOx_AFRL寄存器

6号引脚,在AFRL寄存器上

 但是,我们并不知道它的引脚填什么值,所以还需要再去看另一个芯片手册:《stm32mp157a》

 故,选择AF2模式(回到原芯片手册)

 即:

GPIOB_AFRL[27:24] = 0010

3:TIM4章节分析

工作原理最开始大致介绍,此处不再赘述,我们直接根据原理图顺序,开始寄存器分析

TIM4_PSC寄存器

分频寄存器,因为系统默认频率为209MHZ,所以,为了方便计算,我们把它设置为209-1 = 208

 即

TIM4_PSC[15:0] = 208    //即0xD0

TIM4_ARR寄存器

自动重载计数器,用以设置周期时长

0~15位设置为1000

TIM4_ARR[15:0] = 1000    //0x3E8

TIM4_CCMR1寄存器

 设置PWM模式

TIM4_CCMR1[16][6:4] = 0110------>设置为PWM1模式

 设置预加载使能

TIM4_CCMR1[3] = 1 ------>设置预加载使能

TIM4_CCMR1[1:0] = 00 ------>设置为输出模式

TIM4_CCER寄存器

 

TIM4_CCER[1] = 0    //高电平
TIM4_CCER[0] = 1

TIM4_CCR 1寄存器

比较捕获寄存器,影响方波高电平占比

TIM4_CCR1[15:0] = 700

TIM4_CR1寄存器

 

 

 

即:

TIM4_CR1[7] = 1 ------>自动重载计数器预加载使能
TIM4_CR1[6:5] = 00 ------>设置边沿对齐模式
TIM4_CR1[4] = 1 ------>设置递减计数器
TIM4_CR1[0] = 1 ------>设置计数器使能

 至此,芯片手册分析完毕

四:代码实现

把前面分析出的代码组合

本次头文件采用现成的库,封装原理可以参考鄙人上一篇文章

pwm.h

#ifndef __PWM_H__
#define __PWM_H__

#include "stm32mp1xx_gpio.h"
#include "stm32mp1xx_tim.h"
#include "stm32mp1xx_rcc.h"

//初始化
void pwm_init();

#endif

功能代码:pwm.c

#include "pwm.h"

void pwm_init()
{
/***********RCC初始化**************/
	//使能GPIOB
	RCC->MP_AHB4ENSETR = (0x1 << 1);
	RCC->MP_APB1ENSETR = (0x1 << 2);	
	/*****GPIO章节初始化*****/
	GPIOB->AFRL &= (~(0xf << 24));
	GPIOB->AFRL |= (0x2 << 24);
	//设置PB6引脚为输出模式
	//GPIOB_MODER[13:12] = 0b01
	GPIOB->MODER &= (~(0x3 << 12));
	GPIOB->MODER |= (0x2 << 12);

/***********TMI4寄存器**************/
	//TIM4_PSC寄存器
	TIM4->PSC &= ~(0xffff);
	TIM4->PSC |= 0xd0;  //208

	//TIM4_ARR寄存器   自动重载寄存器
	TIM4->ARR &= ~(0xffff);
	TIM4->ARR |= (0x3E8);  //1000
	
	//TIM4_CCMR1寄存器
	//设置pwm1模式TIM4_CCMR1 16 [6:4] = 0110
	TIM4->CCMR1 &= (~(0x1 << 16));  //16位置0
	TIM4->CCMR1 &= (~(0x7 << 4));  //6~4位清零
	TIM4->CCMR1 |= (0x6 << 4);     //置为110
	//设置预加载使能TIM4_CCMR1[3] = 1
	TIM4->CCMR1 |= (0x1 << 3);
	//设置为输出模式 TIM4_CCMR1[1:0] = 00
	TIM4->CCMR1 &= (~(0x3 << 0));

	//TIM4_CCER寄存器
	//设置起始位高电平
	TIM4->CCER &= (~(0x1 << 1));
	
	//配置输出使能
	TIM4->CCER |= (0x1 << 0);

	//TIME4_CCR1
	TIM4->CCR1 &= (~(0xffff));
	TIM4->CCR1 |= (0x12c);

	//TIM4_CR1寄存器
	//自动承载计数器预加载使能
	TIM4->CR1 |= (0x1 << 7);
	//设置边沿对齐模式
	TIM4->CR1 &= (~(0x3) << 5);
	//设置递减计数器
	TIM4->CR1 |= (0x1 << 4);
	//设置计数器使能
	TIM4->CR1 |= (0x1 << 0);
}
51单片机PWM(脉冲宽度调制)功能可以用来控制蜂鸣器的响声大小。下面是一个简单的实现这个功能的程序: 首先,我们需要在51单片机上选择一个合适的PWM输出引脚,比如P1.0引脚,作为控制蜂鸣器的引脚。 然后,在主程序的初始化部分,我们需要设置P1.0引脚为输出模式,并开启PWM功能。具体的代码如下: ```c #include <reg51.h> sbit buzzer = P1^0; // 设置控制蜂鸣器引脚 // 初始化PWM功能 void InitPWM() { TMOD |= 0x01; // 设置为16位定时器模式 TH0 = 0xFA; // 设置定时器初值,可以根据需要调整 TL0 = 0xFA; ET0 = 1; // 允许定时器0中断 EA = 1; // 允许总中断 TR0 = 1; // 启动定时器0 } // 定时器中断函数 void Timer0Interrupt() interrupt 1 { buzzer = !buzzer; // 控制蜂鸣器引脚电平翻转 } void main() { InitPWM(); // 初始化PWM功能 while(1) { // 在这里你可以通过改变PWM的初值TH0和TL0的值来控制蜂鸣器的响声大小 // 较小的初值会使蜂鸣器发出较低音调,较大的初值会使蜂鸣器发出较高音调 } } ``` 在这个程序中,定时器0的中断函数会不断地将蜂鸣器的引脚电平翻转,这个翻转的速度由定时器的初值TH0和TL0来决定。通过改变这两个初值的值,我们可以控制蜂鸣器的响声大小。较小的初值会使蜂鸣器发出较低音调,较大的初值会使蜂鸣器发出较高音调。 需要注意的是,这个程序只是一个简单的示例,实际应用中可能需要更精确的控制,具体的初值设置需要根据实际需要进行调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老K殿下

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值