一、基本原理
与9S12系列单片机作比较,PWM这个概念在两者中似乎没有什么区别,但是运用
起来的确还是有较大的不同。PWM的用途,一般可以控制电机等等等等,在这里就不多讲了,以后如果有机会,我拿一个实例来说明一下。
COLDFIRE(MCF52235,以后简称CF)的PWM模块相对来说比较简单,引脚只作为输出,输出一定占空比的波形就可以了。至于波形的占空比,周期,频率等等都使用某些特定的寄存器来设置。
本模块的主要特性在DATASHEET(以后简称DS)里是这样写的:
·双缓冲的周期和占空比
·左对齐和居中对齐的波形输出
·8个独立PWM通道
·周期和占空比的寄存器设置
·四个时钟源
第二条对齐方式要解释一下,左对齐是我们经常用的矩形波,而居中对齐计数方式是不一样的,在这里我没放贴图说明。如果不明白这个对齐方式,目前有资料可以查询,一是9S12 PWM的DS,相当详细,不过是英文的;二是我处即将出版的《嵌入式系统》教材,暂时还拿不到手。至于CF的DS讲没讲,我是忘了,因为我知道这两个概念是怎么回事,所以没怎么看。还有四个时钟源也许会存在疑问。我们知道PWM模块有8个独立通道,分别为0、1、4、5和2、3、6、7。
我们把“和”前面的当作A模块,后者为B。其中A可以选择两个时钟源为CLOCKA和CLOCKSA,其中CLOCKA是由总线频率分频得来的,CLOCKSA由CLOCKA分频得来,也就是说CLOCKSA比CLOCKA要慢。我们都知道PWM的频率不是越快越好,某些器件如果是PWM控制的,必须要求PWM的频率控制在一定范围内,否则“不认”。A模块可以通过设置选择使用CLOCKA还是CLOCKSA。同样B模块可以选择使用CLOCKB或CLOCKSB,其中B和SB的含义同上类似。具体时钟如何分频并且分成多少倍,在这里就不说了,请查阅相关资料,这里只是个原理性介绍。
二、寄存器设置
1、使能寄存器PWME
8位分别控制8个通道,很简单,不多说了。
2、PWM极性寄存器PWMPOL
设置波形先低后高,还是反着。
3、分频寄存器PWMPRCLK
负责CLOCKA和CLOCKB由总线时钟分频。
4、对齐方式寄存器
选择左、居中对齐。
5、控制寄存器
控制级联。其实级联很简单,如果各位有需要我以后可以给个例子,这里就不讲了。
6、SA分频寄存器PWMSCLA
给CLOCKSA分频。
7、SB分频寄存器PWMSCLB
给CLOCKSB分频。
8、计数寄存器PWMCNTn
反应计数值的。各位肯定明白小写的n代表什么。
9、周期寄存器PWMPERn
设置一个周期的计数值。
10、占空比寄存器PWMDTYn
设置占空比,在这里需要注意对齐方式。
11、关断寄存器PWMSDN
一些状态和控制位,并不是特别常用。
请注意学习PWM模块的重点和难点。重点包括对齐方式的理解,以及不同对齐方式的计数方式,时钟源的选择,级联等等。
三、例子程序
初始化后就可以正常工作了,具体实现的功能请自行编写。
void PWMInit(unsigned char enable_channel1,unsigned char
enable_channel2)
//channel1:0426.Duplicated with PORTTC(DTOUT).
//channel2:1357.Duplicated with PORTTD.
{
char i;
if(enable_channel1==LOGIC_TRUE)
{
MCF_GPIO_PTCPAR=0|
MCF_GPIO_PTCPAR_TIN0_PWM0|
MCF_GPIO_PTCPAR_TIN1_PWM2|
MCF_GPIO_PTCPAR_TIN2_PWM4|
MCF_GPIO_PTCPAR_TIN3_PWM6;
}
if(enable_channel2==LOGIC_TRUE)
{
MCF_GPIO_PTDPAR=0|
MCF_GPIO_PTDPAR_PWM1_PWM1|
MCF_GPIO_PTDPAR_PWM3_PWM3|
MCF_GPIO_PTDPAR_PWM5_PWM5|
MCF_GPIO_PTDPAR_PWM7_PWM7;
}
MCF_PWM_PWMPOL=0;//first low , subsequently high.
MCF_PWM_PWMCLK=0;//use CLOCKA and CLOCKB.
MCF_PWM_PWMPRCLK=0x77;//CLOCKA and CLOCKB prescaler
MCF_PWM_PWMCAE=0;//left aligned
MCF_PWM_PWMCTL=0;//8-bit channel each
MCF_PWM_PWMSCLA=0x04;
MCF_PWM_PWMSCLB=0x04;
for(i=0;i<7;i++)
{
MCF_PWM_PWMPER(i)=255;
}
for(i=0;i<7;i++)
{
MCF_PWM_PWMDTY(i)=120;
}
MCF_PWM_PWME=0xff;
}