基于Cortex-A9的pwm详解
Exynos PWM定时器的特性
1)5个32位定时器;
2)2个8位PCLK分频器提供一级预分,5个2级分频器用来预分外部时钟;3)可编程选择PWM独立通道。
4)4个独立的可编程的控制及支持校验的PWM通道。
5)静态配置:PWM停止;
6)动态配置:PWM启动;
7)支持自动重装模式及触发脉冲模式;
8)一个外部启动引脚。
9)两个PWM输出可带Dead-Zone 发生器。
10)中断发生器。
PWM内部模块图
工作的步骤:
当时钟PCLK被使能后,定时器计数缓冲寄存器(TCNTBn)把计数器初始值下载到递减计数器中。定时器比较缓冲寄存器(TCMPBn)把其初始值下载到比较寄存器中,并将该值与递减计数器的值进行比较。当递减计数器和比较寄存器值相同时,输出电平翻转。递减计数器减至0后,输出电平再次翻转,完成一个输出周期。这种基于TCNTBn和TCMPBn的双缓冲特性使定时器在频率和占空比变化时能产生稳定的输出。每个定时器都有一个专用的由定时器时钟驱动的16位递减计数器。当递减计数器的计数值达到0时,就会产生定时器中断请求来通知CPU定时器操作完成。当定时器递减计数器达到0的时候,如果设置了Auto-Reload 功能,相应的TCNTBn的值会自动重载到递减计数器中以继续下次操作。然而,如果定时器停止了,比如在定时器运行时清除TCON中定时器使能位,TCNTBn的值不会被重载到递减计数器中。TCMPBn 的值用于脉冲宽度调制。当定时器的递减计数器的值和比较寄存器的值相匹配的时候,定时器控制逻辑将改变输出电平。因此,比较寄存器决定了PWM 输出的开关时间。举例
下面我们举个实例来看下,
初始化寄存器 TCNTBn = 159 (50 + 109) ,TCMPBn =109.开启定时器: 通过设置TCON的开启位.寄存器TCNTBn 的值159将自动加载到递减寄存器down-counter, 同时输出引脚TOUTn 设置为低电平.当down-counter 的值递减打破和寄存器TCMPBn 的值109相同时, 输出引脚将从低拉到高.当down-counter递减到0时, 产生一个中断请求.如果我们设置成autoreload模式,那么down-counter会自动加载TCNTBn的值到down-counter,开启新的一个周期。
我们可以通过设置TCNTBn、TCMPBn来控制占空比,而每个pwm周期后都可以重新设置新的值到TCNTBn、TCMPBn,我们通过精确的计算来设置TCNTBn、TCMPBn的值并通过设置dead zone我们可以设计出各种复杂的矩形波。
如下图所示:
本例我们只需要产生规则的举行方波即可,所以我们只需要设置占空比为50%即可。
六、寄存器
由第四章可知,我们使用PWM控制器的timer 0,对应的寄存器组如下图所示:
1、TFCG0
定时器配置寄存器0(TFCG0) ,主要用于预分频设置。
我们是timer 0,所以只需要设置该寄存器的bite【7:0】即可,最终的输出频率和value的公式如下:
参考24.3.1节:
其中方波的频率必须在音频范围内,也就是20Hz到20KHZ之间, 但是20Hz到20KHZ的频率送给蜂鸣器后, 只有某一点的频率是最响的, 这个频率称为蜂鸣器的谐振频率, 离它越远, 蜂鸣器发出的声音越轻。
所以Prescaler 0 value值应该设置为255,divider value 应该是1/16,值由TCFG1设置。
PWM.TCFG0 = PWM.TCFG0 & (~(0xff))|0xf9;
2、TCFG1
定时器配置寄存器1(TCFG1) 主要用于PWM定时器的divider value设置。
由上一节分析,秩序设置TCFG1 bite【3:0】为0100即0x2即可。
PWM.TCFG1 = PWM.TCFG1 & (~(0xf)) | 0x2;
3、TCON
timer控制寄存器TCON
bite[3] : 设置定时器是只执行一个周期(One-shot)还是周期执行(auto-reload)bite[1]: 置为1,则更新TCNTB0 、TCMPB0 的值bit[0]:开启或者停止定时器
针对不同操作,我们可以设置不同的值:
装载 PWM.TCON = PWM.TCON & (~(0xff)) | (1 << 0) | (1 << 1) ;
开启定时器,蜂鸣器响PWM.TCON = PWM.TCON & (~(0xff)) | (1 << 0) | (1 << 3) ;
关闭定时器,蜂鸣器灭PWM.TCON = PWM.TCON & (~(1 << 0)) ;
4、TCNTB0
定时器计数缓冲寄存器(TCNTB0)根据测算,设置为100
TCNTB0 PWM.TCNTB0 = 100;
5、TCMPB0
定时器比较缓冲寄存器(TCMPB0 )设置为50,占空比为50%
PWM.TCMPB0 = 50;
七、代码
完整代码后台回复**【armprintf】**。
#include "exynos_4412.h"
void delay_ms(unsigned int num)
{ int i,j;
for(i=num; i>0;i--)
for(j=1000;j>0;j--);
}
void pwm_init(void)
{
GPD0.CON = GPD0.CON & (~(0xf))| 0x2;
PWM.TCFG0 = PWM.TCFG0 & (~(0xff))|0xf9;
PWM.TCFG1 = PWM.TCFG1 & (~(0xf)) | 0x2;
PWM.TCMPB0 = 50;
PWM.TCNTB0 = 100;
PWM.TCON = PWM.TCON & (~(0xff)) | (1 << 0) | (1 << 1) ;
}
void beep_on(void)
{
PWM.TCON = PWM.TCON & (~(0xff)) | (1 << 0) | (1 << 3) ;
}
void beep_off(void)
{
PWM.TCON = PWM.TCON & (~(1 << 0)) ;
}
#define SYS_SET_FREQUENCE 25000
void beep_set_frequence( unsigned int fre )
{ //若蜂鸣器的发声频率为0则返回
if( 0==fre )
return ;
PWM.TCMPB0 = SYS_SET_FREQUENCE/(fre+fre);//根据设定频率重新设定计数器比较的值
PWM.TCNTB0 = SYS_SET_FREQUENCE/fre; //根据频率重新调整计数值
}
int main (void)
{ pwm_init();
while(1)
{ beep_on(); //发出一个音
delay_ms(100);
beep_off(); //关闭蜂鸣器, 每个音播放完成后有间隔感
delay_ms(100);
}
return 0;
}
我们也可以通过修改频率和音响的时间来播放音乐。
图片新闻
技术文库
最新活动更多
-
即日-12.26立即报名>>> 【在线会议】村田用于AR/VR设计开发解决方案
-
1月8日火热报名中>> Allegro助力汽车电气化和底盘解决方案优化在线研讨会
-
1月9日立即预约>>> 【直播】ADI电能计量方案:新一代直流表、EV充电器和S级电能表
-
即日-1.14火热报名中>> OFweek2025中国智造CIO在线峰会
-
即日-1.16立即报名>>> 【在线会议】ImSym 开启全流程成像仿真时代
-
即日-1.20限时下载>>> 爱德克(IDEC)设备及工业现场安全解决方案
推荐专题
发表评论
请输入评论内容...
请输入评论/评论长度6~500个字
暂无评论
暂无评论