使用PWM技术控制蜂鸣器发声

1 蜂鸣器分类

有源蜂鸣器

有源蜂鸣器只要接上额定电源就可以发出声音

无源蜂鸣器

无源蜂鸣器利用电磁感应原理,为音圈接入交变电流后形成的电磁和永磁铁相斥而推动振膜发声

2 PWM相关术语

2.0 Dead Zone(死区):

作用是在电平翻转时插入一个时间间隔,避免关闭前一个设备和打开后一个设备时因为开关速度的问题出现同时开启状态而增加负荷的情况(在没有彻底关闭前打开了后一个设备),尤其是电流过大时容易造成短路等损坏设备,如:互补PWM波输出在逆变器(直流交流)中的应用。

2.1占空比

占空间比就是输出的PWM中,高电平保持时间与该PWM的时钟周期的时间之比

2.2 分辨率

分辨率也就是占空比最小能达到多少,如8位的PWM,理论的分辨率就是1:255(单斜率),16位的PWM理论上就是1:65535

2.3 单斜率/双斜率

假设一个 PWM 从 0 计数到 80,之后又从 0 计数到 80… 这个就是单斜率。
假设一个 PWM 从 0 计数到 80,之后是从 80 计数到 0… 这个就是双斜率。
可见,双斜率的计数时间多了一倍,所以输出的 PWM 频率就慢了一半,但是分辨率却是
1:(80+80) =1:160,就是提高了一倍。

3 PWM 控制蜂鸣器实验(Exynos 4412 )

3.0 实验步骤如下

第N步 操作
1 查看电路图找到PWM对应引脚GPD0_0
2 查看芯片手册GPD0CON然后配置
3 查看芯片手册,找到PWM相关寄存器然后配置

3.1重要信息

3.1.0 电路图


即引脚GPD0_0需要配置

3.1.1 PWM外设图

3.2 实验过程

3.2.0 设置GPD0_0引脚模式


找到GDPD0CON设置GPD0CON[1]为TOUT_0,这决定了我们选择的PWM寄存器

3.2.1 设置PWM相关寄存器

通过电路图我们找到GPD0_0->通过配置GPD0CON得到TOUT_0->通过PWM外设图选择相关的PWM寄存器

红色框中的是相关寄存器,但是TCNTO0是一个观察寄存器,这里可以不管他
我们需要配置其他5个寄存器

3.2.1.0 设置TCFG0寄存器


Timer Input Clock Frequency = PCLK/({prescaler value + 1})/{divider value}
定时器输入时钟频率=PCLK/(预分频值)/分频值
这个寄存器用来设置死区长度和预分频值,死区长度默认设置即可,即我们要设置的是预分频值

3.2.1.1 设置TCFG1



设置分频值即divider value

3.2.1.2设置TCNTB0


设置递减值

3.2.1.3设置TCMPB0


设置设置高电平持续的递减计数值

3.2.1.4设置TCON


(1)设置自动装载即使能[3]位
(2)在初始化的时候需要先手动装载,然后再关闭手动装载,即使能[1]位和不使能第[1]位
(3)然后开启定时器timer0

3.3 实验代码

这里的timer的频率是指经过两次次分频的处理的PCLK(外围时钟源)提供的时钟周期

timer的频率 ÷ PWM中TCNTB0设置的递减值=PWM的频率

pwm的周期为pwm频率的倒数

而TCMPB0即占空比,即为Xtimer中占高电平的相对周期数量。

#include "exynos_4412.h"

/**
 * @description: 延时函数
 * @param {unsigned int} i-计数值
 * @return {*}
 */
void delay(unsigned int i)
{
	while(i--);
}

/**
 * @description: PWM0初始化
 * @param {*}
 * @return {*}
 */
void PWM0_Init()
{
	/* 设置蜂鸣器引脚为PWM输出模式 */
	GPD0.CON = GPD0.CON & (~(0xF << 0)) | (0x2 << 0);

	/* 设置1级分频,TCFG0,99=0x63 */
	PWM.TCFG0 = PWM.TCFG0 & (~(0xFF << 0)) | (0x63 << 0);

	/* 设置2级分频,TCFG1,1,因此递减频率为100MHz/(100*1)=1MHz */
	PWM.TCFG1 &= (~(0xF << 0)); 

	/* 打开自动重装载功能 */
	PWM.TCON |= (1 << 3);

	/* 设置PWM递减值,1000,因此PWM频率为1MHz/1000=1KHz */
	PWM.TCNTB0 = 1000;

	/* 设置高电平持续的递减计数值,600,占空比=600/1000=0.6 */
	PWM.TCMPB0 = 600;

	/* 打开手动更新,将TCNTB里的值复制进递减计数器里 */
	PWM.TCON |= (1 << 1);

	/* 关闭手动更新,因为之后TCNTB已经可以自动将值复制进递减计数器里了 */
	PWM.TCON &= (~(1 << 1));

	/* PWM使能 */
	PWM.TCON |= (1 << 0);
}

int main()
{
	PWM0_Init();

	while(1)
	{
		delay(100000);
		PWM.TCON &= (~(1 << 0));
		delay(100000);
		PWM.TCON |= (1 << 0);
	}
	return 0;
}

现象:蜂鸣器叫然后不叫,不停重复,中间间隔1s

物联沃分享整理
物联沃-IOTWORD物联网 » 使用PWM技术控制蜂鸣器发声

发表评论