lesson2.PWM的操作程序设计收获 1,编程时注意细节,本次编写时在PWM寄存器初始化完成后使能错误,因而导致前期检测不出来PWM波。 2,在占空比为10时已经可以驱动数码管,辉度已经完全可以满足显示。 3,貌似真没有PWM6号通道的输出口。 寄存器介绍1,PWME使能寄存器使用方法是PWME_PWME[0~7]=1;对应相应的PWM打开,PWM对应单片机的1~4号引脚和78~80引脚。 2,PWM极性寄存器PWMPOL:PPOL[7:0]=1,PWM通道输出在开始的时候为高电平,为0说明开始时为低电平。 3,PWM时钟选择寄存器PWMCLK:S12的PWM 共有四个时钟源,每一个 PWM输出通道都有两个时钟可供选择(ClockA、ClockSA 或Clock B、ClockSB))。其中0、1、4、5 通道可选用ClockA和ClockSA,2、3、6、7 通道可选用ClockB、ClockSB 通道。该寄存器用来实现几个通道时钟源的选择。 用法: PCLK0 = 1 --- 通道0(PTP0)的时钟源设为ClockSA PCLK2 = 0 --- 通道2(PTP2)的时钟源设为ClockB 4,PWM预分频寄存器PWMPRCLK,PWMPRCLK 寄存器包括ClockA预分频和ClockB预分频的控制位。ClockA、ClockB的值为总线时钟的1/2n (0≤n≤7),具体设置参照图4和图5 file:///C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\msohtml1\01\clip_image001.gif
图 4 Clock A 预分频设置 file:///C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\msohtml1\01\clip_image002.gif 图5 Clock B 预分频设置 PCKB0~PCKB2 是对ClockB进行预分频。 PCKA0~PCKA2 是对ClockA进行预分频。 5,PWM分频寄存器PWMSCLA、PWMSCLB PWMSCLA 寄存器每一位如图 6 所示: file:///C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\msohtml1\01\clip_image003.gif 图6 PWMSCLA寄存器 Clock SA 是通过对PWMSCLA 寄存器的设置来对ClockA 进行分频而产生的。其计算公式为: Clock SA=Clock A /(2*PWMSCLA) PWMSCLB 寄存器与PWMSCLA 寄存器相似,Clock SB 就是通过对PWMSCLB 寄存器的设置来对 ClockB 进行分频而产生的。其计算公式为: Clock SB=Clock B /(2*PWMSCLB) 6,PWM中间对齐使能寄存器PWMCAE:CAE[7:0]=1,采用中间对齐模式;CAE[7:0]=0,采用左对齐模式。 7,PWM通道周期寄存器(PWMPERX) 具体按如下公式计算,左对齐时:PWM周期=通道时钟周期*PWMPERX; 中间对齐时:PWM周期=通道时钟周期*2*PWMPERX; 8,PWM占空比寄存器PWMDTYX:PWM占空比计算和极性寄存器PWMPOL有关,当PPOLx=0时, 占空比=(周期寄存器值减去占空比寄存器值)除以周期寄存器值; 当PPOLx=1时, 占空比=占空比寄存器值除以周期寄存器值。 初始化步骤设置步骤: 禁止PWM 先选择相应的时钟源 设置对齐方式 设置周期和占空比 启动通道即使能PWM 例程设计#include <hidef.h> /* common defines and macros */ #include "derivative.h" /* derivative-specific definitions */ #include <MC9S12XS128.h> void delay(unsigned int t) //毫秒级延时 { unsigned int j; unsigned char a,b; for(j=0;j<t;j++) { for(b=2;b>0;b--) for(a=124;a>0;a--) { asm NOP; asm NOP; asm NOP; } } } void jingzhen(unsigned int pinl) { CLKSEL=0X00; PLLCTL=0XE1; switch (pinl) { //case 11:SYNR=6911;REFDV=9999;break; case 24:SYNR=2;REFDV=1;break; case 48:SYNR=5;REFDV=1;break; case 96:SYNR=5;REFDV=0;break; default:break; } PLLCTL=0X60; asmNOP; asmNOP; asmNOP; asmNOP; asmNOP; while(!(CRGFLG_LOCK==1)); delay(500); CLKSEL=0X80; } void PWM() { PWME_PWME0=0;//0 channel choose jinzhi PWMCAE_CAE0=1;//0 channel 中心对齐 shuchu,必须在pwm打开前进行设置 PWMCLK_PCLK0=0; //0 channel clock A choose PWMPOL_PPOL0=1;//中心对齐方式 PWMPRCLK_PCKA2=1; PWMPRCLK_PCKA1=1; PWMPRCLK_PCKA0=1; //clockA 128fenpin,clockA=24/128=187500Hz, PWMPER0=0x0a; // PWM 周期=通道时钟周期*2*PWMPER0=375k //PWMDTY0=0X05;//占空比 占空比=占空比寄存器值除以周期寄存器值!10% PWME_PWME0=1; //PWMDTY0=0X05; } void main(void) { /*put your own code here */ DDRP=0XFF; EnableInterrupts; jingzhen(24); delay(1000); PWM(); delay(500); for(;;) { _FEED_COP(); /* feeds the dog */ PWMDTY0=0;//输出 3750k 0%占空比 delay(3000); PWMDTY0=1;//输出 3750k 10%占空比 delay(3000); PWMDTY0=0;//输出 3750k 0%占空比 delay(3000); PWMDTY0=4;//输出 3750k 40%占空比 delay(3000); PWMDTY0=0;//输出 3750k 0%占空比 delay(3000); PWMDTY0=6;//输出 3750k 60%占空比 delay(3000); PWMDTY0=0;//输出 3750k 0%占空比 delay(3000); PWMDTY0=8;//输出 3750k 80%占空比 delay(3000); PWMDTY0=0;//输出 3750k 0%占空比 delay(3000); PWMDTY0=0x0a;//输出 3750k 100%占空比 delay(3000); PWMDTY0=0;//输出 3750k 100%占空比 delay(3000); }/* loop forever */ /*please make sure that you never leave main */ } |