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.

[参考译文] CCS/MSP430FR5994:无法对 Arduino 中的数据求平均值

Guru**** 2595805 points
Other Parts Discussed in Thread: MSP430FR5994

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/700816/ccs-msp430fr5994-unable-average-the-data-from-arduino

器件型号:MSP430FR5994

工具/软件:Code Composer Studio

您好!

我使用的是 MSP430FR5994 LP。 我每隔3秒就会从 Arduino 接收数据。 每读10次后、我打算取平均值并将其存储在 FRAM 中。 在 FRAM 中写入10个这样的数据后、我将通过 UART 通过 MSP430 CCS 串行监视器推送数据。 我无法使我的代码正常工作。 请帮帮我。

此致、

Prudhvi Sagar

#include 
#include 
#include 

#define WRITE_SIZE 10//128//void
FRAMWrite (void);

#pragma PERSISTENT (FRAM_WRITE)
unsigned long FRAM_WRITE[WRITE_SIZE]={0};

unsigned char count = 0;
volatile unsigned char TXData = 1;
long data[10]={0};
long data;
int d = 0;
int k = 0;
long avge =
0;******/
//引脚配置
//

#define LED_OUT P1OUT
#define LED_DIR P1DIR
#define LED0_PIN BIT0
#define LED1_PIN BIT1


//*********
// UART 初始化
//

#define SMCLK_115200 0
#define SMCLK_9600 1
#define ACLK_9600 2

#define UART_MODE SMCLK_9600

void initUART()
{
//将 USCI_A3配置为 UART 模式
UCA0CTLW0 = UCSWRST; //将 eUSCI 置于复位

#if UART_MODE = SMCLK_115200

UCA0CTLW0 |= UCSSEL_SMCLK; // CLK = SMCLK

//波特率设置
//使用系列用户指南中的表30-5
UCA0BR0 = 8;
UCA0BR1=0;
UCA0MCTLW |= UCOS16 | UCBRF_10 | 0xF700;//0xF700为 UCBRSx = 0xF7

#Elif UART_MODE = SMCLK_9600

UCA0CTLW0 |= UCSSEL_SMCLK; // CLK = SMCLK

//波特率设置
//使用系列用户指南中的表30-5
UCA0BR0 = 104;
UCA0BR1=0;
UCA0MCTLW |= UCOS16 | UCBRF_2 | 0xD600;//0xD600为 UCBRSx = 0xD6

#Elif UART_MODE = ACLK_9600

UCA0CTLW0 |= UCSSEL_ACLK; // CLK = ACLK
//波特率计算
// 32768/(9600)= 3.4133
//分数部分= 0.4133
//使用系列用户指南中的表24-5
UCA0BR0=3; // 32768/9600
UCA0BR1=0;
UCA0MCTLW |= 0x9200;//0x9200为 UCBRSx = 0x92

#else
#错误"请将波特率指定为115200或9600 "
#endif

UCA0CTLW0 &=~UCSWRST; //初始化 eUSCI
UCA0IE |= UCRXIE; //启用 USCI_A3 RX 中断

//将 USCI_A3配置为 UART 模式
UCA3CTLW0 = UCSWRST; //将 eUSCI 置于复位状态

#if UART_MODE = SMCLK_115200

UCA3CTLW0 |= UCSSEL_SMCLK; // CLK = SMCLK

//波特率设置
//使用系列用户指南中的表30-5
UCA3BR0 = 8;
UCA3BR1=0;
UCA3MCTLW |= UCOS16 | UCBRF_10 | 0xF700;//0xF700为 UCBRSx = 0xF7

#elif UART_MODE = SMCLK_9600

UCA3CTLW0 |= UCSSEL_SMCLK; // CLK = SMCLK

//波特率设置
//使用系列用户指南中的表30-5
UCA3BR0 = 104;
UCA3BR1=0;
UCA3MCTLW |= UCOS16 | UCBRF_2 | 0xD600;//0xD600为 UCBRSx = 0xD6

#Elif UART_MODE = ACLK_9600

UCA3CTLW0 |= UCSSEL_ACLK; // CLK = ACLK
//波特率计算
// 32768/(9600)= 3.4133
//分数部分= 0.4133
//使用系列用户指南中的表24-5
UCA3BR0=3; // 32768/9600
UCA3BR1=0;
UCA3MCTLW |= 0x9200;//0x9200为 UCBRSx = 0x92

其他
#错误"请将波特率指定为115200或9600 "
#endif

UCA3CTLW0 &=~UCSWRST; //初始化 eUSCI
UCA3IE |= UCRXIE; //启用 USCI_A3 RX 中断
}

//*********
//设备初始化
//

void initGPIO()
{
//LED
LED_DIR |= LED0_PIN | LED1_PIN;
LED_OUT &=~(LED0_PIN | LED1_PIN); //关闭 LED

//配置 UART
// P2SEL1 &=~(BIT0 | BIT1); //0 USCI_A3 UART 操作
// P2SEL0 |= BIT0 | BIT1;

P2SEL1 |= BIT0 | BIT1; // 1 USCI_A0 UART 操作
P2SEL0 &=~(BIT0 | BIT1); //0

//配置 UART
P6SEL1 &=~(BIT0 | BIT1); // USCI_A3 UART 操作
P6SEL0 |= BIT0 | BIT1;

//为外部晶体振荡器配置 PJ.5 PJ.4
PJSEL0 |= BIT4 | BIT5; //表示 XT1

//禁用 GPIO 上电默认高阻抗模式以激活
//先前配置的端口设置
PM5CTL0 &=~LOCKLPM5;
}

void sensor_reading (long data)
{
int c = 0;
int t = 0;

datanow[d]=数据;

//对前10个数据取平均值..... 然后存储在 FRAM 中。。。 当 FRAM 达到10时、发回接收到的数据(必须发送所有数据)
if (d == 9) //仅在10条 UART 消息后输入
{
for (c = 0;c < 10;c++)
{
avge = avge +数据流[c];
if (c == 9) //每10条 UART 消息输入一次
{avge =(avge/10);
P1OUT ^= BIT0; //检查
FRAM_WRITE[k]= avge;
K++; //每10条消息最多添加一条
如果(k = 9)
{
对于(t = 0;t < 9;t++)
{
P1OUT ^= BIT0;
UCA0TXBUF = FRAM_WRITE[t];//为单个数字提供数据...如果需要完整的缓冲器、则应为每个数字提供数据
_DELAY_CYCLES (1400);
}
K = 0;
}
avge = 0;
}
}
D = 0;
}

}
void initClockTo16MHz()
{
//根据 MCLK 的器件数据表的要求配置一个 FRAM 等待状态
//在配置时钟系统之前在8MHz 以上运行。
FRCTL0 = FRCTLPW | NWAITS_1;

//时钟系统设置
CSCTL0_H = CSKKEY_H; //解锁 CS 寄存器
CSCTL1 = DCOFSEL_0; //将 DCO 设置为1MHz
//设置 SMCLK = MCLK = DCO、ACLK = LFXTCLK (如果 VLOCLK 不可用)
CSCTL2 = SELA_LFXTCLK | SELESS__DCOCLK | SELM_DCOCLK;
//每个器件勘误表在将频率更改为之前将分频器设置为4
//防止因过冲瞬态而超出规格运行
CSCTL3 = DIVA__4 | DIVM_4;//针对勘误表将所有相应的时钟源设置为4分频
CSCTL1 = DCOFSEL_4 | DCORSEL; //将 DCO 设置为16MHz
//延迟~10us 以使 DCO 稳定。 60个周期= 20个周期缓冲器+(10us /(1/4MHz))
_DELAY_CYCLLES (60);
CSCTL3 = DIVA__1 | DIVM_1 | DIVM__1;//针对16MHz 运行将所有分频器设置为1

CSCTL4 &=~LFXTOFF;
操作
{
CSCTL5 &=~LFXTOFFG; //清除 XT1故障标志
SFRIFG1 &=~OFIFG;
} while (SFRIFG1&OFIFG); //测试振荡器故障标志

CSCTL0_H = 0; //锁定 CS 寄存器
}

//*********
//主要内容
如果使用 SMCLK、//进入 LPM0并等待 UART 中断。 如果使用 ACLK *
//、则器件将改为进入 LPM3模式。 UART RX 中断处理*
//接收到的字符并进行回波。 *
//*********

int main (void)
{
WDTCTL = WDTPW | WDTHOLD; //停止看门狗
//int d = 0;
initGPIO();
initClockTo16MHz();
initUART();
P1OUT &=~BIT0; //清除已定义上电状态
P1DIR 的 P1.0输出锁存器|= BIT0;
printf ("Hello World");//将 P1.0设置为输出方向
// UCA0TXBUF ='7';
// while (!(UCA0IFG & UCTXIFG)));
// UCA0TXBUF = TXData; //将数据加载到缓冲

区#if UART_MODE = ACLK_9600
_bis_SR_register (LPM3_bits + GIE); //由于 ACLK 是源,所以进入 LPM3,中断被使能
#else
_bis_SR_register (LPM0_bits + GIE); //由于 SMCLK 是源,因此进入 LPM0,中断被启用
#endif
__no_operation(); //调试
器}

//*********
// UART 中断
//

#if defined (__TI_Compiler_version__)|| defined (__IAR_systems_icc_)
#pragma vector=USCI_A3_vector
__interrupt void USCI_A3_ISR (void)
#Elif defined (__GNU__)
void __attribute__((interrupt (USCI_A3_vector))))#USCI_A3_COMPLETE!


#endif
{
switch (__even_in_range (UCA3IV、USCI_UART_UCTXCPTIFG))
}{
USCI_NONE 案例:中断;
USCI_UART_UCRXIFG 案例:
while (!(UCA3IFG&UCTXIFG));
UCA0TXBUF = UCA3RXBUF;
SENSOR_READING (UCA3RXBUF);
D++; // UART 数据的计数器
__no_operation();
中断;
案例 USCI_UART_UCTXIFG:中断;
案例 USCI_UART_UCSTTIFG:中断;
案例 USCI_UART_UCTXCPTIFG:break;
}
}

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

    您能否提供有关哪些功能不正常的更多详细信息? 您是否进行了一些调试、也可以共享这些调试? 谢谢!
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    当 LED 从 FRAM 发送数据时、我将打开它。 这必须每收到100个数字就完成一次、但在这里、它每20次发生一次。 它不发送我需要的全部10个数字,只是发送一个随机字符。

    此致、

    Prudhvi Sagar

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    >它只是发送一个随机字符
    您是否正在尝试以 ASCII 格式查看这些字节? 如果是、它们可能无法正常显示。
    --------------------------------------
    >当 LED 从 FRAM 发送数据时、它将打开。
    它实际上是切换 LED。 如果我已经正确计数、它将在输入采样11-20、31-40等期间打开。 您看到的是这种情况吗?
    --------------------------------------
    > UCA0TXBUF = FRAM_WRITE[t];//为单个数字提供数据...如果需要完整的缓冲器、则应为每个数字提供数据
    > _DELAY_CYCLES (1400);
    如果您的时钟确实是16MHz、那么这几乎不足以等待字节发送。 以9600bps 发送一个字节大约需要1ms、或者16MHz/1000=16000个周期。 在 TXBUF 准备就绪前将数据输入它将丢失数据。 通常的等待方法是在 UCTXIFG 上旋转(如 ISR 中所示)。

    在 ISR 中执行此操作将锁定 Rx 侧(并丢弃任何传入数据)至少10ms。 Arduino 提供的数据速度有多快?
    --------------------------------------
    > while (!(UCA3IFG&UCTXIFG));
    > UCA0TXBUF = UCA3RXBUF;
    这将反映您在 UCA3 (Arduino 数据)上获得的任何内容到 UCA0 (结果)。 这是故意的吗? 我觉得这会使您的数据流变得混乱、但这由您决定。 (您应该在 UCA0IFG 上旋转、而不是在 UCA3IFG 上旋转。)
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    --------------------------------------
    > while (!(UCA3IFG&UCTXIFG));
    > UCA0TXBUF = UCA3RXBUF;
    这将反映您在 UCA3 (Arduino 数据)上获得的任何内容到 UCA0 (结果)。 这是故意的吗? 我觉得这会使您的数据流变得混乱、但这由您决定。 (您应该在 UCA0IFG 上旋转、而不是在 UCA3IFG 上旋转。)
    >>> 是的,这是有意的… Arduino 发送的字节回显效果不好、我得到 ASCII 值...如果我也使用 USB 发送到 TTL 转换器而不是连接 Arduino、我就得到良好回显。

    --------------------------------------
    >它只是发送一个随机字符
    您是否正在尝试以 ASCII 格式查看这些字节? 如果是、它们可能无法正常显示。
    >>> 那么问题只会出现吗? 我的平均值计算是否正确?

    --------------------------------------
    >当 LED 从 FRAM 发送数据时、它将打开。
    它实际上是切换 LED。 如果我已经正确计数、它将在输入采样11-20、31-40等期间打开。 您看到的是这种情况吗?
    >>> Arduino LED 每发送20个数字就会切换一次。 为什么会发生这种情况? Arduino 发送的每100个数据点都不应发生这种情况。

    --------------------------------------
    >UCA0TXBUF = FRAM_WRITE[t];//为单个数字提供数据...如果需要完整的缓冲器、则应为每个数字提供数据
    >_DELAY_CYCLES (1400);
    如果您的时钟确实是16MHz、那么这几乎不足以等待字节发送。 以9600bps 发送一个字节大约需要1ms、或者16MHz/1000=16000个周期。 在 TXBUF 准备就绪前将数据输入它将丢失数据。 通常的等待方法是在 UCTXIFG 上旋转(如 ISR 中所示)。

    在 ISR 中执行此操作将锁定 Rx 侧(并丢弃任何传入数据)至少10ms。 Arduino 提供的数据速度有多快?
    >>> 我已经添加了这个,正如你建议的"while (!(UCA0IFG&UCTXIFG));"--工作顺利。
    --------------------------------------

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


    --------------------------------------
    >当 LED 从 FRAM 发送数据时、它将打开。
    它实际上是切换 LED。 如果我已经正确计数、它将在输入采样11-20、31-40等期间打开。 您看到的是这种情况吗?
    >>> Arduino LED 每发送20个数字就会切换一次。 为什么会发生这种情况? Arduino 发送的每100个数据点都不应发生这种情况。

    $$$$$$$$$$$$$$ 我犯了一个错误,添加了另一个检查,这是意外的。。。 当我在 FRAM 循环内进行检查并对从 Arduino 收到的每10个数据进行另一次检查时... 它们可以完美切换。 我从 FRAM 接收到的数据是不可理解的、但您是否认为这只是表示问题、但内部取平均值是可以接受的? 我是否可以检查它,可悲的是我的 printf 不起作用:(。

    我现在已将数据发送到 Arduino (而不是 CCS 串行)并检查了其串行监视器...一切似乎都正常...感谢您的支持