Part Number:MSP430G2553
各位大神,我用信号源产生一个2kHz的正弦波信号,幅度1v,然会通过MSP430G2553的ADC10来采集信号,再将采集到数据通过UART发送到matlab中进行波形的还原,但是还原出来的信号总是会有毛刺(有时候也正常)。请问这是我程序哪里出问题了嘛?(信号源产生的信号是准确的,已经测试过了)。
下图为两种出现毛刺的情况
正常现象
#include <msp430.h>#include "stdint.h"
#define nn 100;
uint16_t adcbuff[100] = {0};
uint8_t combuff[20]={0};
uint8_t iscomend =0 ;
/**
* main.c
*/
void InitSystemClock(void)
{
DCOCTL = CALDCO_16MHZ;
BCSCTL1 = CALBC1_16MHZ;
BCSCTL2 &= ~SELS;
BCSCTL2 &= ~(DIVS0 | DIVS1);
}
void InitUART(void)
{
UCA0CTL1 |= UCSWRST;
UCA0CTL0 &= ~(UCMODE1 | UCMODE0);
UCA0CTL0 &= ~UCSYNC;
UCA0CTL1 |= (UCSSEL1 | UCSSEL0);
UCA0BR0=0x82;
UCA0BR1=0x06;
UCA0MCTL |= (UCBRS1| UCBRS2);
P1SEL |= BIT1 + BIT2;
P1SEL2 |= BIT1 + BIT2;
UCA0CTL1 &= ~UCSWRST;
IE2 |= UCA0RXIE;
IFG2 &= ~UCA0RXIFG ;
}
void InitADCTrigByTimerA(void)
{
ADC10CTL1 |= ADC10SSEL_2;
ADC10CTL1 |= SHS0;
ADC10CTL1 |= CONSEQ1;
ADC10CTL0 |= SREF_1;
ADC10CTL0 |= ADC10SHT_1;
ADC10CTL0 &= ~ADC10SR;
ADC10CTL0 |= REF2_5V;
ADC10CTL0 |= REFON;
ADC10CTL1 |= INCH_4;
ADC10AE0 |= 1 << 4;
ADC10DTC0 |= ADC10CT;
ADC10SA = (uint16_t)(adcbuff);
ADC10CTL0 |= ADC10ON;
ADC10CTL0 |= ENC;
}
void InitTimerA()
{
TA0CTL |=TASSEL1;
TA0CTL |= MC0;
TA0CCR0 =0x004F;
TA0CCR1= 0x002F;
TA0CCTL0 &= ~CAP;
TA0CCTL1 &= ~CAP;
TA0CCTL1 |= OUTMOD_6;
P1SEL |= BIT6;
P1DIR |= BIT6;
}
int main(void)
{
uint16_t cnt = 0;
WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer
InitSystemClock();
InitUART();
InitADCTrigByTimerA();
InitTimerA();
__bis_SR_register(GIE);
while(1)
{
if(iscomend)
{
iscomend =0;
for(cnt = 0; cnt<100;cnt ++)
{
while(UCA0STAT & UCBUSY);
UCA0TXBUF=*(adcbuff+cnt)/256;
__delay_cycles(30000);
while(UCA0STAT & UCBUSY);
UCA0TXBUF=*(adcbuff+cnt)%256;
__delay_cycles(30000);
}
}
}
return 0;
}
#pragma vector = USCIAB0RX_VECTOR
__interrupt void UART_Receive_ISR(void)
{
static uint8_t cnt2 = 0;
if(IFG2 & UCA0RXIFG)
{
IFG2 &= ~UCA0RXIFG;
combuff[cnt2++] = UCA0RXBUF;
cnt2 %= 20;
if(combuff[cnt2 – 1] == '#')
{
cnt2 = 0;
iscomend = 1;
}
}
}
pengfei liang:
可以等效成用G2553做一个示波器
,
Cherry Zhou:
您好我们已收到您的问题并升级到英文论坛,如有答复将尽快回复您。谢谢!
,
Cherry Zhou:
您好,信号上的毛刺可能会周期性地出现。 噪声可能是来自电源。 请您检查下 MCU VCC,如果可以的话尽可能使用 ADC 的外部电压基准。
> TA0CCR0 =0x004F ; // 配置 TA0CCR0 位 0x004F
这会在 (16MHz/80) =200ksps 时触发 ADC ,即每 5usec 一次采样。 (如果图表的 X 轴为 " sample number " ,我们看到每个信号周期有 10 个样本,对于 2kHz 信号来说,表示采样率为 20KSPS 而不是 200ksps。 请问以上是您实际使用的代码吗?)
> UCA0BR0=0x82 ; > UCA0BR1=0x06 ;
将 UART 配置为 (16MHz/1666) =9600bps。 在这个速度下,发送一个样本 (2 个字节) 大约需要 2msec 。在此期间,ADC (DTC) 将存储 (200*2) =400 个样本,UART 是跟不上的。 结果就是 main() 在 DTC 更新时读取 adcbuff ,这可能是出现毛刺的原因。
如果您要捕获 2kHz 信号,则需要将 UART 速度提高一点,可能还需要降低 ADC 的速度。 为了支持 200ksps 速率,UART 需要保持 (2bytes*10bits*200ksps)=4Mbps。 数据表的最大值为 2Mbps [ 参考数据表 (SLAS735J) 第 33 页,第一个表 ]。 在 G2 系列器件 (使用 DCO) 中,工程师从未成功地以超过大约 500kbps 的速度运行。
额外建议您:ADC10 使用 16MHz 时钟超出规格很多 [ 参考数据表 (SLAS735J) 第 39 页,中间表 ]。 我们建议您使用 ADC10OSC (ADC10SSEL=0)。
请您先参考以上回复,进一步的回复我再帮您确认下。
,
pengfei liang:
非常感谢!!
,
Cherry Zhou:
您好,您可以先试下降低 ADC 采样频率。 如果仍然能看到毛刺,那么请尝试隔离噪声。
,
Cherry Zhou:
使ADC10CT=0 并在 IF (iscomend) block的末端重启DTC (通过设置 ADC10SA)。
长期来说,设置ADC10SSEL=0 并稍微降低一点采样率—大概 TA0CCR0=100-1 。