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.

[参考译文] MSP430G2553:ADC10采样问题

Guru**** 2387820 points
Other Parts Discussed in Thread: MSP430G2553
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1067340/msp430g2553-adc10-sampling-issue

部件号:MSP430G2553

大家好,团队

客户提出的问题可能需要您的帮助:

2 kHz 正弦信号由信号源产生1 V 幅度,然后通过 MSP430G2553的 ADC10获得信号,并通过 UART 将采集的数据发送到 MATLAB 以恢复波形。 但恢复的信号总是出现故障(有时还可以)。 客户想知道该计划有什么问题吗? (来自源的信号准确且已测试)。

下图显示了故障的两种情况:

正常值如下所示:

#include <MSP4C.h>
#include "stdint.h"


#define nn 100;
UINT16_t adcbuy[100]={0};// nn 长度的数组
UINT8_t combuy[20]={0};//用于保存串行端口接受的命令
UINT8_t iscomend =0 ;//end of command? 用于确定是否已成功收到完整的命令
/**
*主要
*
使 InitSystemClock 无效(void)

DCOCTL = CALDCO_16MHz;
BCSCTL1 = CALBC1_16MHz;
BCSCTL2和=~;//选择 SMCLK 的来源
BCSCTL2 &=~(DIVS0 | DIVS1);//设置除数
}

作废 InitUART (作废)

UCA0CTL1 |= UCSWRST;//set UCSWRST
//初始化所有 UCSI 寄存器
UCA0CTL0 &=~(UCMODE1 | UCMODE0);//将 UCSI 模式00配置为 UART 模式
UCA0CTL0和=~UCSYNC;//选择异步模式
UCA0CTL1 |=(UCSSEL1 | UCSSEL0);//将时钟源10和11配置为 SMLCK

//配置波特率,查看 UCOS16,然后在用户手册中查找表15.4 UCBRx UCBRSx UCBRFx 最后两个实际位于 UCAxMCTL 中
UCA0BR0=0x82;
UCA0BR1=0x06;
UCA0MCTL |=(UCBRS1| UCBRS2);
//配置端口
P1SEL |= BIT1 + BIT2;
P1SEL2 |= BIT1 + BIT2;
//清除重置以启用 UART
UCA0CTL1 &=~UCSWRST;

IE2 |= UCA0RXIE;//打开串行端口的接收中断
IFG2和=~UCA0RXIFG;//清除接收中断标志
}

无效 InitADCTrigByTimerA (void)

ADC10CTL1 |= ADC10SSEL_2;//选择时钟源


ADC10CTL1 |= SHS0;//选择计时器 A OUT1 SHSx 进行采样,并为 Timer_A OUT1 00保留源01 (用于 ADC10SC 位)
ADC10CTL1 || CONSEQ1;//选择转换序列00至单通道单转换01至通道序列

ADC10CTL0 |= SREF_1;//set the reference,external or internal?(ADC10CTL0 |= SREF_1;//set the reference,外部还是内部?)
ADC10CTL0 |= ADC10SHT_1;//将 ADC10样本保持时间设置为16 CLK

ADC10CTL0和=~ADC10SR;//ADC10采样率

ADC10CTL0 |= Ref2_5V;//ADC 参考选择2.5 V
ADC10CTL0 |= REFON;//Turn on the reference (打开参考)

ADC10CTL1 |= inch_4;//选择 ADC 输入通道 A4

ADC10AE0 |= 1 <4;//允许 A4模拟输入

//DTC 传输模式
ADC10DTC0 |= ADC10CT;//at 1,数据将持续传输,并且只有在清除 ADC10CT 或写入 ADC10SA 时,DTC 才会停止运行

ADC10DTC1 = nn;//传输总数为50

ADC10SA =(uint16_t)(adcbuff);//ADC10SA 确定起始地址,该地址强制 adcbuff 的第一个地址为16位整数

/*打开 ADC*/
ADC10CTL0 |= ADC10ON;

/*允许转换*/
ADC10CTL0 |= ENC;

}

无效 InitTimerA()

TA0CTL |=TASSSEL1;//配置时钟位 SMLCk
TA0CTL |= MC0;// UP 模式,01为 up,向上为 TA0CCR0,10为连续模式,计时器计数为0FFFFh
//11升/降模式是计时器增加到 TCCR0,然后降低到0000h
TA0CCR0 =0x004F;//配置 TA0CCR0位0x004F
TA0CCR1= 0x002F;//设置占空比(TACCR0-TACR1)/TARRC0此时,占空比为1/2,频率= SMCLK/(TACCR0+1)/2 SMCLK 在时钟中设置。 例如,16 MHz/80/2大约为100 k,大约是采样频率和最大采样频率
TA0CCTL0和=~盖;
TA0CCTL1和=~盖;
TA0CCTL1 |= OUTMOD_6;
//设置 IO 多路复用
P1SEL |= BIT6;//
P1DIR |= BIT6;//

}

Int main (无效)

UINT16_t cnt = 0;

WDTCTL = WDTPW | WDTHOLD;//停止看门狗计时器
InitSystemClock();
InitUART();
InitADCTrigByTimerA();
InitTimerA();
__bis_SR_register (GIE);//打开全局中断

While (1)(同时)
      {
        IF (等结束)
         {
          等式=0;  
          对于(cnt = 0; cn<100;cnt ++)
            {  
                While (UCA0STAT 和 UCBUSY);
               UCA0TXBUF=*(adcbuy+cnt)/256;// adcbuys 中的数据被发送出去,先是8位高
               __delay_cycles (30000);  
               While (UCA0STAT 和 UCBUSY);
               UCA0TXBUF=*(adcbuy+cnt)%256;//然后降低8位
               __delay_cycles (30000);
             }

        }
      }
返回0;
}

#pragma vector = USAISCB0RX_vector
中断 void UART_receive_ISR (void)

      静态 uint8_t cnt2=0;
      如果(IFG2和 UCA0RXIFG)//检测接收中断是否为 USCI_A0,并且接收中断与 USCI_A0和 USIC_B0共享相同的量
        {
          IFG2和=~UCA0RXIFG;//清除标志位
           combuy[cnt2++]= UCA0RXBUF;//保存命令
          cnt2 %=20;//防止 cnt 大于20,导致缓冲区溢出
           如果(combuy[cnt2 - 1]='#')//如果检测到命令结束字符(带'#'的命令结束)
              {
                cnt2 = 0;//重置计数器
                iscomend = 1;//收到命令
              }
        }
}

注意: 这等同于使用 G2553作为示波器。

请帮您检查此案例? 谢谢。

此致,

樱桃

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好,

    信号出现故障时会定期出现。 噪音似乎来自电源。 检查 MCU VCC,并在可能的情况下使用 ADC 的外部电压参考。

    此致,

    现金很好

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    > TA0CCR0 =0x004F;//配置 TA0CCR0位0x004F

    这将触发 ADC (16MHz/80=200ksps),即每5usec 一次采样。 (如果这些图表的 X 轴是“样本数”,我会在每个信号周期中看到10个样本,对于2kHz 信号,这表示样本速率为20KSPS,而不是200ksps。 这是您实际使用的代码吗?)

    > UCA0BR0=0x82;
    > UCA0BR1=0x06;

    这将 UART 配置为(16MHz/1666)=9600bps。 以这种速度发送一个样本(2 字节)大约需要2毫秒,在此期间,ADC (DTC)将存储(200*2)=400个样本。 。 UART 将无法跟上。 结果是,当 DTC 更新时,main()正在读取 adcbuff,这可能是故障的原因。

    如果要捕获2kHz 信号,您需要将 UART 提高一个多速率,并可能降低 ADC 的速度。

    为了支持200ksps 速率,UART 需要保持(2bytes*10bits*200ksps)=4Mbps。 数据表最大值为2Mbps [参考数据表(SLAS735J)第33页,第一个表]。 在 G2系列设备(使用 DCO)中,我从未成功过比大约500kbps 更快(可靠)的速度。

    未经请求:为 ADC10使用16MHz 时钟远远超出规格[参考数据表(SLAS735J)第39页,中间表]。 我建议您使用 ADC10OSC (ADC10SSEL=0)。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我认为采样率和比特率之间的差异不是问题。

    ADC 用于一次捕获50个值。 在通过 UART 接收到所需命令之前,不会发送数据。 (考虑到输入时钟和比特率之间的差异很大,UART 实际上应该配置 uCOS=1。)

    源自 SMCLK 的 ADC 时钟明显超出其最大值。 但切换到 ADC10OSC 可能不起作用,因为转换时间可能比计时器触发器慢。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    在 ADC10CT=1 (连续)情况下,UART 代码将(始终)在由 DTC 写入缓冲区时读取缓冲区,这将引发故障。 如您所建议,修复此问题的一种方法是使用 ADC10CT=0,并在每次取回完成后重新启动 DTC (突发模式)。

    如果使用的是2张和5MHz 时钟,则每个样本将采用(16+13)/5MHz=5.8 usec,这确实会超过5usec 触发周期。 但是,使用更快的时钟运行它超出了规范范围,这就是为什么我建议降低 ADC (触发率)的速度。 使用6MHz ADC10CLK (以及足够快的 MCLK)实际上会取得成功,但在 G2系列上派生这样的时钟可能并不容易。

    此代码可以通过多种方式演变,我可能不想猜测 OP 喜欢哪种方式。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你好,现金,布鲁斯和大卫,

    非常感谢您的支持! 我是否可以知道哪一个答案是我向最终客户提供最新信息的最佳选择?

    谢谢,致以诚挚的问候,

    樱桃

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你好,Cherry,

    您可以让客户先尝试降低 ADC 采样频率。 如果他们仍然观察到故障,请尝试隔离噪音。

    此致,

    现金很好

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    退出 ADC10CT=0,然后在 IF(iscomend)块末尾设置 ADC10SA 以重新启动 DTC。

    长期而言,设置 ADC10SSEL=0并稍微降低采样率—可能是 TA0CCR0=100-1。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好,Cash 和 Bruce,

    感谢您的澄清和帮助!  

    此致,

    樱桃