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:通过UART发送ADC值时出现问题

Guru**** 2609895 points


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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/658360/msp430g2553-problem-sending-adc-values-over-uart

部件号:MSP430G2553

我正在尝试读取传感器数据,并通过蓝牙将其发送到我的计算机,以便绘制图形。 为了进行测试,我只是在连接实际传感器之前尝试从函数发生器发送一个正弦波,但我只能获得大约2Hz的干净正弦波。 我的猜测是,该问题是由ADC采样和UART传输的不同速度引起的,但我对该问题很陌生,因此我无法确定我的问题是什么。  

#include <msp430g2553.h>/**

* main.c
*/
int main(void)
{
WDTCTL = WDTPW | WDTHOLD;	//停止看门狗计时器


//----------- 禁用端口2 ----------------------- //
P2OUT &= 0x00;
P2DIR &= 0x00;

//----------- 配置时钟----------------------- //
DCOCTL = 0; //选择最低DCOx和MODx设置
BCSCTL1 = CALC1_1MHz;//设置范围
DCOCTL = CALDCO_1MHz;//设置DCO步进+调制
	

//----------- 配置引脚--------------------------- //

P1SEL || BIT1 + BIT2;// WFP 1.1 UCA0RXD输入
P1SEL2 || BIT1 + BIT2;// WFP 1.2 UCA0TXD输出
P1DIR || BIT3 + BIT4 + BIT5;//WFP 1.3 ,1.4 ,1.5 设置为输出
P1DIR &=~BIT0 +~BIT6;//WFP 1.0 ,1.6 设置为输入


//----------- 配置ADC--------------------------- //
ADC10CTL0 &=~ENC;
ADC10CTL0 = ADC10SHT_1 + ADC10ON + ADC10SR + MSC + ADC10IE;
ADC10CTL1 = inch_0 + SHS_0 + ADC10DIV_0 + ADC10SSEL_0 + CONSEQ_0;
ADC10AE0 |= BIT0;


//----------- 配置UART(USCI_A0)----------------------- //

UCA0CTL1 |= UCSSEL_2 + UCSSWRST;// USCI时钟= SMCLK,USI_A0已禁用
UCA0BR0 = 104; //数据表中的104
UCA0BR1 = 0; //-选择波特率=9600,clk = SMCLK
UCA0MCTL = UCBRS_1; //数据表中的调制值= 1
UCA0CTL1 &=~UCSWRST; //清除UCSWRST以启用USI_A0

//----------- 启用中断----------------------- //

IE2 |= UCA0TXIE + UCA0RXIE; //启用Tx和Rx中断
_ BIS_SR (GIE); //启用全局中断



同时(1)
{
ADC10CTL0 &=~ENC;
While (ADC10CTL1和ADC10BUSY)
{}
__low_power模式0();
ADC10CTL0 |= ENC + ADC10SC;




}

}//------------------


////
发送和接收中断 ////--------------------------------------------
//

#pragma vector = USCIAB0TX_vector
__interrupt void TransmitInterrupt (void)
{
UCA0TXBUF = ADC10MEM >> 2;// UCA0TXUF IFG2中存储并发送的UART
&=~UCA0Vector IFG;//清除TX标志
}

#pragma = USCIAB0RX_CAvector
{void IS_CA10_INVector


CA10




__low_POWER_MODE_OFF_ON_EXIT();
}


 

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    就我所能知道的那样,提供的代码将只生成0x00字节的流(或者可能只是停止,取决于编译器生成的内容),因为它在进入low_power _mode_0 ("LPM0")之前不会启动ADC (ADC10SC)。 循环顺序不正确,但我建议您完全不要对ADC使用LPM。

    每个ADC转换大约需要(8+12+2)/5=~4 usec才能运行。 这是4个MCLK,或者大约是单个(典型) CPU指令的成本。 这是如此的快,以至于(a)你几乎从未在LPM中,(b)你很想在进入LPM0之前,ADC就已经完成了,你的程序就停止了。 因此:

    1)不要设置ADC10IE (您可以删除ISR),并将While (1)循环减少到:
    ADC10CTL0 |= ENC + ADC10SC; //开始转换
    while (ADC10CTL1和ADC10BUSY)/*空*/;//等待完成
    此外:
    2)不要在TX ISR中清除UCA0TXIFG,因为设置UCA0TXBUF会清除它。
    3)在RX ISR中输入一些代码之前,不要启用UCA0RXIE。 如果您不在ISR中读取UCA0RXBUF,ISR将永远循环。

    在9600bps的速度下,UART在9600/10=960sps的速度下进行“采样”,比ADC的采样速度慢得多,所以这将限制您的信号。 Nyquist说,在960sps中,您可以获得480Hz的频率,但只有速度慢得多的信号才会有保真度。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢您的回复。 我尝试了您建议的更改,但我仍然没有收到好的变化。 我附上了一张图片,说明我从50 Hz正弦波得到的图形是什么样子的。 我是否应该做一些事情来确保每个值在ADC读取另一个值之前发送? 我需要捕获的最快波只能在10 Hz左右,因此9600波特率的480 Hz应该足够了。 提前感谢!

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    此图似乎表明每个周期大约有4个样本,而不是预期的(960/50)=~20个样本,因此可能还有其他一些情况发生。 (或者可能是一种幻想。)

    您能否显示新代码? 由于它是结构化的,所以它的采样速度(~250:1)比它需要的要快得多,但因此,以UART速率发送的样本总是(我相信)新鲜。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好,James:

    我认为您应该在ADC ISR中或从LPM0唤醒后发送ADC数据,而不是使用UART TX中断。 在代码中,如果ADC未完成转换,UART TX ISR将发送旧的ADC数据。

    此致,
    冬季游
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    #include <msp430g2553.h>///////////////////////////
    0是输入//////////////////////////
    /**
    * main.c
    */
    
    int main(void){
    
    WDTCTL = WDTPW | WDTHOLD;	//停止看门狗计时器
    
    
    //----------- 禁用端口2 ----------------------- //
    P2OUT &= 0x00;
    P2DIR &= 0x00;
    
    //----------- 配置时钟----------------------- //
    DCOCTL = 0; //选择最低DCOx和MODx设置
    BCSCTL1 = CALC1_1MHz;//设置范围
    DCOCTL = CALDCO_1MHz;//设置DCO步进+调制
    
    //----------- 配置引脚--------------------------- //
    
    P1SEL || BIT1 + BIT2;// WFP 1.1 UCA0RXD输入
    P1SEL2 || BIT1 + BIT2;// WFP 1.2 UCA0TXD输出
    P1DIR || BIT3 + BIT4 + BIT5;//WFP 1.3 ,1.4 ,1.5 设置为输出
    P1DIR &=~BIT0 +~BIT6;//WFP 1.0 ,1.6 设置为输入
    
    
    //----------- 配置ADC--------------------------- //
    ADC10CTL0 &=~ENC;
    ADC10CTL0 = ADC10SHT_1 + ADC10ON + ADC10SR + MSC;//+ ADC10IE;//ADC中断已启用
    ADC10CTL1 = inch_0 + SHS_0 + ADC10DIV_0 + ADC10SSEL_0 + CONSEQ_0;
    ADC10AE0 |= BIT0;
    
    
    //----------- 配置UART(USCI_A0)----------------------- //
    
    UCA0CTL1 |= UCSSEL_2 + UCSSWRST;// USCI时钟= SMCLK,USI_A0已禁用
    UCA0BR0 = 104; //数据表中的104
    UCA0BR1 = 0; //-选择波特率=9600,clk = SMCLK
    UCA0MCTL = UCBRS_1; //数据表中的调制值= 1
    UCA0CTL1 &=~UCSWRST; //清除UCSWRST以启用USI_A0
    
    //----------- 启用中断----------------------- //
    
    IE2 |= UCA0TXIE;//+ UCA0RXIE; //启用Tx和Rx中断
    _ BIS_SR (GIE); //启用全局中断
    
    
    
    同时(1)
    {
    
    ADC10CTL0 |= ENC + ADC10SC;
    while (ADC10CTL1和ADC10BUSY);
    
    
    }
    
    }//------------------
    
    
    ////
    发送和接收中断 ////--------------------------------------------
    //
    
    #pragma vector = USCIAB0TX_vector
    __interrupt void TransmitInterrupt (void)
    {
    UCA0TXBUF = ADC10MEM >> 2;// UART存储并以UCA0TXBUF
    //IFG2 &=~UCA0TXIFG ;// clear TX flag =ADC10MEM >2;=USCIAB_ECT_RELAMP_POLEVEC_AD10/
    
    
    AVE_RELAMP_TO_POST_AD10/{_INTERVECTOR_E/ AVE_RELEVECT_AVIRADE_E/ AVIRADE_TO_CA0_CA0_TO_CAMP_E/ ECTOR_CA0_CA0_CA0_CA0_AD10/ AVIRADE_CAMP_CA0_CA0_
    
    
    
    
    
    
    
    
    
    
    
    
    

    这是我进行更改后的代码。 我对它的思考越多,我就越认为我的问题实际上可能与我的蓝牙模块或我用来接收和绘制数据的Python代码有关。 对于嵌入式代码,我愿意接受任何进一步的建议。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我尝试更改用于传输的代码行的位置,但我的计算机上没有收到任何内容。 我是否需要以不同的方式编写代码,以便在不同的位置传输,而不是仅将UCA0TXBUF设置为ADC10MEM? 除了Arduino之外,我还对编写嵌入式代码非常陌生,因此我还有很多知识要学习。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我同意这不一定是最有效的方法,但当我阅读您的代码时(我没有设备来尝试),它应该会产生更好的结果。

    是否有方法检查信号链中的其他元素(蓝牙,Python)?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    这就是我今天要做的。 我验证了Python代码是否正在从BT模块接收十六进制数据并将其正确转换为十进制值,因此现在我认为我的下一步是查看BT模块本身是否发生了奇怪的情况。 我正在使用的模块是一个AMS001,以防有经验的人使用它并可能会提供一些建议。 我也是BT通信的新手,所以我也很可能犯了一个简单的错误。 如果没有,我可能只需要看看我是否可以找到另一个论坛,在那里我可以获得一些帮助来解决BT问题。