This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
/*
*
*/
#include "msp430g2553.h"
#include "delay.h"
const unsigned int spwm[] = {
250, 327, 396, 452, 487, 499, 487, 452, 396, 327,
250, 172, 103, 47, 12, 0, 12, 47, 103, 172,
};
unsigned int n=0;
/*
*
*/
void TimerA_Init()
{
P1DIR |= BIT2;
P1SEL |= BIT2; // p1.2
TACCR0 = 500; // Init TACCR0 w/ sample prd=CCR0+1
TACCR1= spwm[n];
TACCTL1 = OUTMOD_7; // Set/reset
TACCTL0 = CCIE;
TACTL = TACLR + MC_1 + TASSEL_2 +ID_3; // clear TAR, up mode*/
}
void ini_sys(void)
{
WDTCTL=WDTPW+WDTHOLD; //STOP W D T
if (CALBC1_8MHZ ==0xFF || CALDCO_8MHZ == 0xFF)
{
while(1); // If calibration constants erased
// do not load, trap CPU!!
}
//1Mhz ~1008000
BCSCTL1 = CALBC1_16MHZ; // Set range
DCOCTL = CALDCO_16MHZ; // Set DCO step + modulation */
delay_ms(10);
}
/*
* main()
*/
void main()
{
ini_sys();
TimerA_Init();
_EINT();
//_BIS_SR(LPM0_bits + GIE);
while(1);
}
/*
* T0_A0 interrupt service
*/
#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer0_A0(void)
{
//一个周期内取180个点,点间隔2度
n = (n+1)%20;
TACCR1 = spwm[n];
}
在使用手册里有一句话:
The numbers at the right margin show the necessary CPU cycles for each instruction. The software
overhead for different interrupt sources includes interrupt latency and return-from-interrupt cycles, but not
the task handling itself. The latencies are:
• Capture/compare block TACCR0: 11 cycles
• Capture/compare blocks TACCR1, TACCR2: 16 cycles
首先你选择的是SMCLK作为timer的时钟源。一般进timer中断与出中断大概需要16个cycles,那么你选择太窄的pwm占空比本身是有问题的。
一种可能性:
1、在总程序中还有其它的“中断”,当Timer_A中的TACCR1在按预定的节奏输出预期信号期间,另外一个“中断”会间或插一杠子;
2、因为中断服务函数使用的都是MCLK,如果此时两个中断服务函数之间形成了“碰头冲突”,那么另外那个中断就可能对这个TACCR1的运行造成干扰。
我以前遇到过类似情况:当时我没用Timer_A而是用delay语句的方式直接输出PWM信号,结果发觉输出信号抖晃非常厉害,100思不得其解,最后发现是有其它中断服务在干扰,于是我在每次输出PWM期间就临时关闭系统所有中断(_DINT;),之后输出的PWM信号就非常稳定了!-------你也可尝试一下关闭除TACCR1之外的其它中断。
我也想发个波形的,不过还得拍照,就没发了。
确实是Peter_Zheng说的那个问题。
而且我发现
n = (n+1)%20;
这条语句竟然要运行150个cpu 周期。
后来我改成
TACCR1 = spwm[n++];
if(n == 20){
//n=0;
}
运行时间大概只有23个cpu周期了。加上Capture/compare block TACCR0: 11 cycles。大概是34个cpu周期。
我是smclk 8分频后给TA做时钟源。
我把spwm数组里面的 0 改成了大点的 3 。
现在输出基本可以了。
G2553最高只支持16MHz,不能调到25MHz,我想主要还是在实现方法上突破,一味调高主频并不可取。