项目整理-----基于MSP430的SPWM实现(part one )
MSP430系列单片机,在1996年,由美国德州仪器(TI)首先推向市场。该系列单片机是16位超低功耗、精简指令集的混合信号处理器。
笔者在所做的项目中曾要求基于MSP430G2253设计实现正弦波发生器。项目完成之后对基础部分的实现做了简单整理,归纳如下:
实现基本要求: -----MSP430PWM振荡器的信号经滤波处理,同时产生频率为10Hz的正弦波信号,运放放大后产生的信号波形无失真;
----运放上的滑变电阻器调节输出正弦波幅度,产生的信号波形无失真。
----正弦波频率可调,频率范围尽可能大;
----FLASH保存正弦信号的幅度,数字显示的电路由七段共阴数码管完成,测量误差不大于±5%。
正弦波生成由看门狗定时,通过PWM及查表完成。
(1)查表法产生正弦波:由MATLAB仿真生成码表:

图中半周期的采样点数决定了码表的大小,也直接影响着采样后得到正弦波的频率高低。
码表部分如下:

(2)周期确定: 看门狗定时

改变count_time的值(1~999),即改变进入看门狗后产生一个sin曲线采样点的时间,就可以改变正弦波的周期。
1 /* 2 * ======== Standard MSP430 includes ======== 3 */ 4 #include <msp430.h> 5 6 /* 7 * ======== Grace related includes ======== 8 */ 9 #include <ti/mcu/msp430/csl/CSL.h> 10 11 /* 12 * ======== main ======== 13 */ 14 #define uchar unsigned char 15 #define uint unsigned int 16 17 const uint sin_tab[256] = {128,131,134,137,141,144,147,150,153,156,159, 18 162,165,168,171,174,177,180,183,186,188,191,194,196,199,202,204, 19 207,209,212,214,216,219,221,223,225,227,229,231,233,234,236,238, 20 239,241,242,244,245,246,247,249,250,250,251,252,253,254,254,255, 21 255,255,255,255,255,255,255,255,255,255,255,255,254,254,253,252, 22 251,250,250,249,247,246,245,244,242,241,239,238,236,234,233,231, 23 229,227,225,223,221,219,216,214,212,209,207,204,202,199,196,194, 24 191,188,186,183,180,177,174,171,168,165,162,159,156,153,150,147, 25 144,141,137,134,131,128,125,122,119,115,112,109,106,103,100,97, 26 94,91,88,85,82,79,76,73,70,68,65,62,60,57,54,52,49,47,44,42,40, 27 37,35,33,31,29,27,25,23,22,20,18,17,15,14,12,11,10,9,7,6,6,5,4,3 28 ,2,2,1,1,1,0,0,0,0,0,0,0,1,1,1,2,2,3,4,5,6,6,7,9,10,11,12,14,15, 29 17,18,20,22,23,25,27,29,31,33,35,37,40,42,44,47,49,52,54,57,60,62, 30 65,68,70,73,76,79,82,85,88,91,94,97,100,103,106,109,112,115,119 31 ,122,125}; 32 //uchar A0_flag = 0; //TA0CCR1 标志位 33 uint count = 0, i = 0, j = 0, x,y = 0; //Dog 计数时间,决定sin周期,100次/4us出10hz;1次/4us出10khz; 34 uint frequency = 10; //sin frequency 35 uint count_time = 100; //count times 36 uint temp_count[3] ={100}; 37 uint data_max = 0; //AD 38 uint data[128] = {0}; 39 uint volt_trans = 0,wei_1 = 0,wei_2 = 0, wei_3 = 0; //数码管显示 40 uchar dis_flag = 0; //数码管显示标志位 41 uint delay = 0; 42 const uchar smg_tab[11] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x7F}; //数码管码表 43 /* 0 1 2 3 4 5 6 7 8 9 . */ 44 45 float volt = 0; 46 void flash_erase(void); 47 void flash_write(unsigned char volt_int); 48 unsigned char flash_read(void); 49 char *flash_ptr; 50 51 int main(int argc, char *argv[]) 52 { 53 CSL_init(); 54 ADC10CTL0 |= ENC + ADC10SC; 55 _EINT(); 56 return (0); 57 } 58 59 void TA0CCR1_ISR() 60 { 61 62 } 63 void Dog_ISR() 64 { 65 count ++; 66 67 if(count == count_time){ 68 69 if((P1IN&0x08)==0x00){ 70 71 while((P1IN&0x08) == 0x00); 72 P1OUT ^= BIT0; 73 dis_flag++; 74 volt_trans = volt * 100; //只显示3位 75 // flash_write(volt_trans); 76 // volt_trans = flash_read(); 77 wei_1 = volt_trans/100; 78 wei_2 = volt_trans/10%10; 79 wei_3 = volt_trans%10; 80 // flash_write(volt_trans); 81 if(dis_flag%4 == 0){ 82 P2OUT = smg_tab[wei_1]; 83 } 84 if(dis_flag%4 == 1){ 85 P2OUT = smg_tab[10]; 86 } 87 if(dis_flag%4 == 2){ 88 P2OUT = smg_tab[wei_2]; 89 } 90 if(dis_flag%4 == 3){ 91 P2OUT = smg_tab[wei_3]; 92 } 93 } 94 95 count = 0; 96 TA0CCR1 = sin_tab[++i]; 97 if(i == 255){ 98 i = 0; 99 } 100 IE1 &= ~WDTIE; 101 } 102 }
这样产生的正弦波实际是有bug的,通过调试会发现周期是没有办法在大范围内调节的。笔者分析认为用查表的方式而不是方波滤波来产生正弦波,产生的波形更好,并且只要前级(滤波—放大)电路线性度足够好,那么产生的正弦波基本不会有失真,频率调节范围也能够相应的加大。但是看门狗的中断时间是4us/per,sin值变化一次(即PWM波占空比变化一次)所需的时间大于此中断时间,这样无法达到先前计算的频率。

由此提出改进措施: 减少采样点数或直接用方波滤波产生正弦波;
改进效果:

小结: 方波振荡电路产生的频率固然高于正弦波,但是其线性度无法与查表产生的正弦波相提并论,故退而求其次,采用查表法产生波形,同时减少采样点数。
浙公网安备 33010602011771号