DAY21. PWM实验
如果出现图片无法查看可能是网络问题,我用的GitHub+图床保存的图片,可以参考我另外一篇文章GitHub的使用方法含网络问题解决
GitHub使用教程含网络问题_github加速器_肉丸子QAQ的博客-CSDN博客
相关作业和资料已上传,请在主页自行查看
1. PWM简介
蜂鸣器工作原理
-
蜂鸣器
-
有源蜂鸣器 只要接上额定电源就可以发出声音
-
无源蜂鸣器 无源蜂鸣器利用电磁感应原理,为音圈接入交变电流后形成的电磁铁与永磁铁相吸或相斥而推动振膜发声
-
GPIO控制
怎么让无源蜂鸣器响动
需要有方波,不断的来回推动振膜
while(1)
{
GPX2.DAT=GPX2.DAT | (1 << 7);
Delay(1000000);
GPX2.DAT=GPX2.DAT & (~(1 << 7)); c
Delay(1000000);
}
//方法不好用
PWM控制
PWM(Pulse Width Modulation)
即脉冲宽度调制,通过对脉冲的宽度进行调制,来获得所需要波形
PWM参数
- 周期
- 占空比
2. 4412下的PWM控制器
原理图
芯片手册
-
5个PWM控制器,前4个能产出连续的PWM控制外不断设备,最后一个没有引脚使用**,本质还是一个递减计数器**和看门狗差不多
-
使用PCLK时钟,一级分频器8位分频器可编程,
-
time0和time1共用一个分频器
-
每个定时器都有各自的二级分频器,2/4/8/16倍
PWM原理
产生一个低电平50,高电平109,周期就是159 占空比:109/159
- 初始化
TCNTBn
寄存器设置周期, 初始化TCMPBn
寄存器初始化设置高电平所占时间- 使能定时器
TCNTBn
的值加载到递减计数器中,然后在引脚上输出低- 如果递减后的值到和
TCMPBn
值一样时开始输出高电平- 当减到0时,PWM会产生中断(这个实验没用到)
- 递减计数器为0后会自动加载
TCNTBn
- 再重新一个周期
- 周期不仅和TCNTBn大小有关还和递减计数器的频率(就是时钟源分频后的)有关
逻辑框图
反向输出功能
默认是先输出低电平再高电平,可以进行反向输出,先输入高再低
比如默认是先50低电平,后109高电平,开启反转后就是先109高电平再50低电平
3. PWM寄存器详解
TCFG0寄存器
控制一级分频,多个共用,0和1共用, 2,34共用
TCFG1寄存器
控制二级分频且每个定时器都有自己的二级分频寄存器
TCON寄存器
定时器控制,time0,1,2,3,4的控制器
TCNTB0寄存器
控制time0的周期
TCMPB0寄存器
控制time0的高电平时间
需要注意的是TCMPB一定比TCNTB小
TCNTO0寄存器
存储递减计数器的值
4. PWM编程
#include "exynos_4412.h"
void Delay(unsigned int Time)
{
while(Time --);
}
int main()
{
/*1.将GPD0_0引脚设置成PWM0的输出引脚*/
GPD0.CON = GPD0.CON & (~(0xF)) | (0x2);
/*2.设置PWM0的一级分频 一级分频倍数设置为100倍*/
PWM.TCFG0 = PWM.TCFG0 & (~(0xFF)) | 99;
/*3.设置PWM0的二级分频 二级分频倍数设置为1倍 递减计数器递减频率 = PLCK / (99 + 1) / 1 = 1M*/
PWM.TCFG1 = PWM.TCFG1 & (~(0xF));
/*4.设置PWM0为自动重装载,使其能够产生连续的脉冲信号,第三位置1*/
PWM.TCON = PWM.TCON | (1 << 3);
/*5.设置PWM0的频率为500HZ*/
PWM.TCNTB0 = 2000;
/*6.设置PWM0的占空比为50%*/
PWM.TCMPB0 = 1000;
/*7.将TCNTB0中的值手动装载到递减计数器*/
PWM.TCON = PWM.TCON | (1 << 1);
/*8.关闭手动更新*/
PWM.TCON = PWM.TCON & (~(1 << 1));
/*9.使能PWM0,递减计数器开始递减*/
PWM.TCON = PWM.TCON | 1;
while(1)
{
PWM.TCON = PWM.TCON | 1;
Delay(1000000);
PWM.TCON = PWM.TCON & (~(1));
Delay(1000000);
}
return 0;
}
5. 作业
编程实现通过PWM控制蜂鸣器产生"嘀嘀"的声音
注:PWM的频率1000HZ,占空比%60
#include "exynos_4412.h"
void Delay(unsigned int Time)
{
while(Time --);
}
int main()
{
/*1.将GPD0_0引脚设置成PWM0的输出引脚*/
GPD0.CON = GPD0.CON & (~(0xF)) | (0x2);
/*2.设置PWM0的一级分频 一级分频倍数设置为100倍*/
PWM.TCFG0 = PWM.TCFG0 & (~(0xFF)) | 99;
/*2.设置PWM0的二级分频 二级分频倍数设置为1倍 递减计数器递减频率 = PLCK / (99 + 1) / 1 = 1M*/
PWM.TCFG1 = PWM.TCFG1 & (~(0xF));
/*4.设置PWM0为自动重装载,使其能够产生连续的脉冲信号,第三位置1*/
PWM.TCON = PWM.TCON | (1 << 3);
/*5.设置PWM0的频率为1000HZ*/
PWM.TCNTB0 = 1000;
/*6.设置PWM0的占空比为60%*/
PWM.TCMPB0 = 600;
/*7.将TCNTB0中的值手动装载到递减计数器*/
PWM.TCON = PWM.TCON | (1 << 1);
/*8.关闭第一次手动更新,变成自动更新*/
PWM.TCON = PWM.TCON & (~(1 << 1));
/*9.使能PWM0,递减计数器开始递减*/
PWM.TCON = PWM.TCON | 1;
while(1)
{
PWM.TCON = PWM.TCON | 1;
Delay(1000000);
PWM.TCON = PWM.TCON & (~(1));
Delay(1000000);
}
return 0;
}