logo资料库

MSP430F5529_PWM信号发生及测量.doc

第1页 / 共11页
第2页 / 共11页
第3页 / 共11页
第4页 / 共11页
第5页 / 共11页
第6页 / 共11页
第7页 / 共11页
第8页 / 共11页
资料共11页,剩余部分请下载后查看
一、实验室名称:MSP430 单片机实验室 二、实验项目名称:PWM 波发生器及 PWM 波频率及占空比测量 三、实验原理: (1)PWM 信号的产生 PWM 信号是一种具有固定周期不定占空比的数字信号,如下图 4-1 所示: 图 4-1 PWM 信号波形 如果 Timer_A 定时器的计数器工作在增计数方式,输出采用输出模式 7(复位/置位模 式),则可利用寄存器 TAxCCR0 控制 PWM 波形的周期,用某个寄存器 TAxCCRx 控制占空 比。这样 Timer_A 就可以产生出任意占空比的 PWM 波形。如图 4-2 所示。 图 4-2 利用 Timer_A 产生任意占空比的 PWM 信号 可以随时间变化任意改变 PWM 信号的频率和占空比,具体做法:改变 CCR0 值(改变 周期),改变 CCRx 值(改变占空比)。如图 4-3 所示。 图 4-3 通过配置 CCR0 和 CCRx 值调整 PWM 信号的占空比 PWM 不需要修改频率和占空比时,CPU 在做完 Timer_A 初始化工作之后,Timer_A 就 1
能自动输出 PWM,而不需利用中断维持 PWM 输出,此时 CPU 就可以进入低功耗状态。 (2)捕获/比较器 Timer_A 有多个相同的捕获/比较模块,为实时处理提供灵活的手段,每个模块都可用 于捕获事件发生的时间或产生定时间隔。通过 TACCTLx 中的 CAP 位选择模式,该模块既 可用于捕获模式,也可用于比较模式。当发生捕获事件或定时时间到都将引起中断。捕获/ 比较模块的结构如图 4-4 所示。 图 4-4 捕获/比较模块的逻辑结构 捕获模式 当 TACCTLx 中的 CAP = 1,该模块工作在捕获模式。每个捕获/比较寄存器可以用来记 录时间事件,例如: ▲ 测量软件程序所用时间 ▲ 测量硬件事件之间的时间 ▲ 测量系统频率 用 CM1 和 CM0 位选择捕获条件,可以选择禁止捕获、上升沿捕获、下降沿捕获或者 上升沿下降沿都捕获。当捕获完成后,定时器的值被复制到 TAxCCRn 寄存器,并且中断 标志 CCIFG 置位。如果总的中断允许位 GIE 允许,相应的中断允许位 CCIE 也允许,则将 产生中断请求。 比较模式 2
当 TACCTLx 中的 CAP = 0,该模块工作在比较模式。比较方式主要用于为软件或应用 硬件产生定时,还可为 D/A 转换功能或者马达控制等各种用途产生脉宽调制(PWM)输出 信号。 在计数器 TAxR 计数到 TAxCCRn(n 代表具体的捕获比较寄存器)的值时: ▲ 中断标志 CCIFG 置位 ▲ 内部信号 EQUx=1 ▲ EQUx 根据输出模式影响输出 ▲ 输入信号 CCI 被锁存在 SCCI (3)独立按键 参见实验一中相关原理介绍。 (4)OLED 显示屏 参见实验一中相关原理介绍 四、实验目的: 要求学习 MSP430 单片机内部 PWM 波发生器和内部捕获/比较器的操作,实验板上附 带的独立按键及 OLED 的使用。学习基于 430 单片机集成编译仿真环境的代码调试。 五、实验内容: 利用 MSP430 内部 PWM 波发生器产生频率为 50Hz~1kHz,占空比为 10%~90%的 PWM 波,频率和占空比通过按键 S1 和 S2 分别往复设置(频率按 50Hz 步进,占空比按 5%步进), 并利用 MSP430 单片机的捕获/比较器测量该 PWM 波的频率和占空比,且显示于 OLED 上。 扩展要求:(1)在 OLED 上显示出你所产生的 PWM 波图形(2)产生两路刚好反相的 PWM 波,显示于 OLED 上。 六、实验器材(设备、元器件): MSP430F5529 开发板,OLED 显示屏,个人电脑(运行 IAR 软件),下载线,示波器。 七、实验步骤及实验数据结果分析: (1)实验的程序流程框图: 3
(2)实验的程序代码(含注释): #include "msp430f5529.h" #include "IIC.c" #include "math.h" unsigned int index1; unsigned int index2; int hz[20]={50}; int duty[17]={10}; unsigned int num[3]; unsigned int T,TP,D,flag; //定义频率数组 //定义占空比数组 int wave_B[120]; int wave_S[120]; int point_num_T[20]; 4
unsigned int wave_T; unsigned int wave_D; unsigned int a=0; unsigned int change=1; void turn_w(int wave_B[120]); void display_w(int wave_B[120]); int main( void ) { // Stop watchdog timer to prevent time out reset WDTCTL = WDTPW + WDTHOLD; for(unsigned int i=1;i<20;i++) hz[i]=hz[i-1]+50; for(unsigned int i=1;i<17;i++) duty[i]=duty[i-1]+5; index1=0; index2=0; UCSCTL4|=SELA_2; // //PWM 波产生 P1DIR|=BIT2; P1SEL|=BIT2; ACLK:32768HZ ////P1.2 为 PWM 输出口 TA0CCR0=(int)(32768/hz[index1]); TA0CCR1=(int)(TA0CCR0*(100-duty[index2])/100); TA0CCTL1|=OUTMOD_3; TA0CTL|=TASSEL_1+MC_1+TACLR; //置位/复位模式 //开始 //依频率计算 TA0CCR0 ////依占空比计算 TA0CCR1 //按键设置 P2DIR&=~BIT1; P2IFG=0x00; P2IE|=BIT1; P2IES|=BIT1; P2REN|=BIT1; P2OUT|=BIT1; P1DIR&=~BIT1; P1IFG=0x00; P1IE|=BIT1; P1IES|=BIT1; P1REN|=BIT1; 5
P1OUT|=BIT1; //捕获模式测瞬时频率及占空比 P2DIR&=~BIT4; P2SEL|=BIT4; //用 TIMER 2,上升沿捕获+同步捕获+捕获模式+开中断 TA2CCTL1|=CM_1+SCS+CAP+CCIE+CCIS_0; //选 SMCLK+连续计数+8 分频 TA2CTL|=TASSEL_2+MC_2+TACLR+ID_3; LCD_Init(); __enable_interrupt(); while(1) { if(change==1) { for(unsigned int i=0;i<20;i++) { point_num_T[i]=(int)(ceil(120/(i+1))); } wave_T=point_num_T[hz[index1]/50-1]; wave_D=(int)(ceil(wave_T*duty[index2]/100)); for(unsigned int i=0;i
LCD_ShowChar(32,4,':',16); LCD_ShowNum(40,4,T,4,16); LCD_ShowChar(16,6,'D',16); LCD_ShowChar(24,6,'U',16); LCD_ShowChar(32,6,'T',16); LCD_ShowChar(40,6,'Y',16); LCD_ShowChar(48,6,':',16); LCD_ShowNum(56,6,TP,4,16); LCD_CLS(); } } #pragma vector=TIMER2_A1_VECTOR __interrupt void timer2() { num[flag]=TA2CCR1; flag++; if(flag==1) { TA2CCTL1&=~CM_1; TA2CCTL1|=CM_2; } if(flag==2) { TA2CCTL1&=~CM_2; TA2CCTL1|=CM_1; } if(flag==3) { flag=0; T=num[2]-num[0]; TP=num[1]-num[0]; TA2CTL|=TACLR; } TA2CCTL1&=~CCIFG; } //周期时间 //高电平持续时间 #pragma vector=PORT2_VECTOR __interrupt void Port2_1() { if(P2IFG&BIT1) { 7
TA1CCR0=0xffff; TA1CTL|=TASSEL_1+MC_1+TACLR; while(TA1R<=655); if((P2IN&BIT1)==0) { //利用 timer1 延时 20ms index2++; if(index2==17) index2=0; } } TA0CCR0=(int)(32768/hz[index1]); TA0CCR1=(int)(TA0CCR0*(100-duty[index2])/100); //更改占空比 change=1; P2IFG&=~BIT1; } #pragma vector=PORT1_VECTOR __interrupt void Port1_1() { if(P1IFG&BIT1) { TA1CCR0=0xffff; TA1CTL|=TASSEL_1+MC_1+TACLR; while(TA1R<=655); if((P1IN&BIT1)==0) { index1++; if(index1==20) index1=0; } } TA0CCR0=(int)(32768/hz[index1]); TA0CCR1=(int)(TA0CCR0*(100-duty[index2])/100); //更改频率 change=1; P1IFG&=~BIT1; } //波形显示函数 void display_w(int wave_B[120]) { for(unsigned int i=0;i<120;i++) { if((wave_B[i]==1)&&(wave_B[i+1]!=0)) 8
分享到:
收藏