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.

[参考译文] MSP430G2452:在 CCS 代码中重复 main 函数

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1172673/msp430g2452-repetition-of-main-function-in-ccs-code

器件型号:MSP430G2452
主题中讨论的其他器件: MSP-EXP430G2

大家好、我是 Noh。

我正在使用 MSP430G2452及其 LaunchPad、并尝试使用 I2C 总线控制一个语音合成 IC。

我使用的代码是基于 msp430g2xx2_USI_16.c 编写的、我从 GitHub 获取了该代码。

(请注意、代码是从 TI 示例代码修改的、因此其工作方式基本相似)

我已经解决了主函数不断重复的问题。

我只 希望 IC 只获得一次命令流、但命令流不会停止、并且从主函数的开始到结束一直重复。

是否有任何方法只传输一次命令流?

如果这是一个愚蠢的问题、我很抱歉。

感谢您的阅读

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

    您好、啊、

    您可以通过以下链接获取这些示例代码:

    https://dev.ti.com/tirex/explore/node?node=A__AD3l9a6Uvm5.ZFkNdW.cfg__msp430ware__IOGqZri__LATEST

    如果您只想发送一次数据、可以在 while (1)之前将函数移动到中:

    谢谢!

    此致

    Johnson

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

    您好、Johnson!

    首先,感谢您的回答:D

    在我现在使用的修改代码中、main 函数中没有 while 循环。

    我无法插入代码、因为出现了一些错误、但仍然会出现。

    我将把下面的代码 作为文本格式放置。

    请原谅我,可能很难阅读。

    --------------------------------------------------

    #include
    #include
    #include "USI_i2c.h"

    #include
    #include

    //内部状态
    静态 uint16_t const * i2c_sequence;
    静态 uint16_t i2c_seque_length;
    静态 uint8_t * i2c_receive_buffer;
    静态 uint16_t i2c_WAKEUP_SR_Bits;
    I2C_state_type i2c_state = I2C_IDLE;

    静态 uint8_t 状态;

    静态内联 void i2c_prepare_stop();
    静态内联 void i2c_preping_data_xmit_recv ();

    void i2c_send_sequence (uint16_t const * sequence、
    uint16_t seque_length、
    uint8_t *接收到的数据、
    uint16_t WAKEUP_SR_Bits){
    while (i2c_state!= I2C_IDLE);//在当前序列完成之前,我们无法启动另一个序列
    while ((status=0xEE)|(status=0xEF) P1OUT |= 0x01;
    P1OUT &=~0x01;
    I2C_sequence = sequence;
    I2C_SEQUEST_LENGTH = SEQUEST_LENGTH;
    I2C_Receive_buffer = Received_data;
    I2C_WAKEUP_SR_Bits = WAKEUP_SR_Bits;
    I2C_state = I2C_start;
    USICTL1 |= USIIFG;//实际开始通信

    静态内联 void i2c_prepare_stop(){
    USICTL0 |= USIOE;// SDA =输出
    USISRL = 0x00;
    USICNT |= 0x01;//位计数器= 1、SCL 高电平、SDA 低电平
    I2C_state = I2C_stop;

    静态内联 void i2c_preping_data_xmit_recv (){
    if (i2c_seque_length = 0){
    I2C_Prepare_stop ();//再也不做什么了,准备发送 STOP
    }否则{
    if (* i2c_sequence == I2C_restart){
    USICTL0 |= USIOE;// SDA =输出
    USISRL = 0xff;//准备并发送一个虚拟位、以便 SDA 为高电平
    USICNT =(USICNT & 0xE0)| 1;
    I2C_state = I2C_start;

    否则、if (* i2c_sequence == I2C_read){
    USICTL0 &=~USIOE;// SDA =输入
    USICNT =(USICNT & 0xE0)| 8;//位计数器= 8、RX 数据
    I2C_state = I2C_Received_data;//下一状态:测试数据和 ACK/NACK
    }否则{//写入
    //此时,我们应该有纯数据字节,而不是命令,所以(*i2c_sequence >>8)==0
    USICTL0 |= USIOE;// SDA =输出
    USISRL =(char)(* i2c_sequence);//加载数据字节
    USICNT =(USICNT & 0xE0)| 8;//位计数器= 8、启动 TX
    //这清除 USIIFG 并且生成 SCL
    //在所有8个位发送后、USIIFG 被置位并且 SCL 被停止
    I2C_state = I2C_Prepare_ACKNACK;//下一状态:准备接收数据 ACK/NACK

    I2C_SEQUEST++;
    I2C_SEQUEST_LENGTH--;


    #ifdef __GNU__
    __attribute__((interrupt (USI_vector)))
    其他
    #pragma vector = USI_vector
    _interrupt
    #endif
    void USI_TXRX (void)

    switch (__evo_in_range (i2c_state、12)){
    情况 I2C_IDLE:
    中断;

    案例 I2C_START://生成启动条件
    USISRL = 0x00;
    USICTL0 |=(USIGE|USIOE);
    USICTL0 &=~USIGE;
    I2C_Prepare_data_xmit_recv ();
    中断;

    Case I2C_Prepare_ACKNACK://准备接收 ACK/NACK
    USICTL0 &=~USIOE;// SDA =输入
    USICNT |= 0x01;//位计数器=1、接收(N) Ack 位进入 USISRL
    //这会清除 USIIFG
    I2C_state = I2C_Handle_RxTx;//转至下一状态:检查 ACK / NACK 并在必要时继续再次发出/接收
    中断;

    案例 I2C_Handle_RxTx://处理地址 Ack/Nack & handle 数据 TX
    if ((USISRL & BIT0)!= 0){//我们是否得到了否定应答?
    I2C_Prepare_stop ();
    }否则{
    I2C_Prepare_data_xmit_recv ();

    中断;

    案例 I2C_Received_data://接收数据、发送 ACK/NACK
    *i2c_receive_buffer = USISRL;
    I2C_Receive_buffer++;
    USICTL0 |= USIOE;// SDA =输出
    if (i2c_seque_length > 0){
    //如果这不是最后一个字节
    USISRL = 0x00;// ACK
    I2C_state = I2C_Handle_RxTx;//再次进入下一状态:data/rcv
    }否则{//最后一个字节:发送 NACK
    USISRL = 0xff;// NACK
    I2C_state = I2C_PREPARGE_STOP;//停止条件下一个

    USICNT |= 0x01;//位计数器= 1、发送 ACK/NACK 位
    中断;

    案例 I2C_Prepare_stop://准备停止条件
    I2C_Prepare_stop ();//准备停止,转到接下来的状态14
    中断;

    案例 I2C_STOP://生成停止条件
    USISRL = 0x0FF;// USISRL = 1来释放 SDA
    USICTL0 |= USIGE;//启用透明锁存器
    USICTL0 &=~(USIGE|USIOE);//锁存/SDA 输出被禁用
    I2C_state = I2C_IDLE;//为下一个 xmt 重置状态机
    if (i2c_WAKEUP_SR_Bits){
    _BIC_SR_REGISTER_ON_EXIT (i2c_WAKEUP_SR_Bits);//如果提示退出活动状态

    中断;

    USICTL1 &=~USIIFG;//清除挂起标志

    void main(){
    I2C_init (USIDIV_5、USISSEL_2);

    uint16_t PUP[]={0xEA、0x00};
    uint16_t PDWN[]={0xEA、0x20};

    uint16_t CVOL_POWERUP[]={0xEA、0xAF、0x00};
    uint16_t AMODE_POWERUP[]={0xEA、0x05、0x45};
    uint16_t AMODE_PowerDown []={0xEA、0x05、0x41};

    uint16_t RDSTAT_Command[]={0xEA、0xB0};
    uint16_t RDSTAT_READ[]={0xEB、I2C_READ};
    // uint8_t status;

    uint16_t start[]={0xEA、0x51};

    uint16_t Play ={0xEA、0x40、0x03};
    uint16_t stop[]={0xEA、0x61};

    I2C_SEND_SEQUENCE (PUP、2、&STATUS、LPM0_Bits);// 00

    I2C_SEND_SEQUENCE (CVOL_POWERUP、3、STATUS、LPM0_Bits);// AF 00
    I2C_SEND_SEQUENCE (AMODE_POWERUP、3、STATUS、LPM0_Bits);// 05 45
    I2C_SEND_SEQUENCE (PLAY、3、&STATUS、LPM0_Bits);// 40 03

    2C_SEND_SEQUENCE (RDSTAT_Command、2、STATUS、LPM0_Bits);// B0
    I2C_SEND_SEQUENCE (RDSTAT_READ、2、STATUS、LPM0_BITS);

    void i2c_init (uint16_t USI_clock_divider、uint16_t USI_clock_source){
    disable_interrupts ();
    USICTL0 = USIPE6|USIPE7|USIMST|USISWRST;//端口和 USI 模式设置
    USICTL1 = USII2C|USIIE;//启用 I2C 模式和 USI 中断
    USICKCTL = USI_CLOCK 分频器| USI_CLOCK _SOURCE | USICKPL;
    USICNT |= USIIFGCC;//禁用自动清除控制
    USICTL0 &=~USISWRST;//启用 USI
    USICTL1 &=~USIIFG;//清除挂起标志
    enable_interrupts ();

    P1OUT = 0xC0;// P1.6 & P1.7上拉、其它至0
    P1REN |= 0xC0;// P1.6 & P1.7上拉
    P1DIR = 0xFF;//未使用的引脚作为输出
    P2OUT = 0;
    P2DIR = 0xFF;

    --------------------------------------------------

    这是 Beagle 的通信结果。

    代码中没有循环函数、但命令流永远不会停止并重复。

    您是否碰巧知道它的工作原理是这样的??

    谢谢!

    此致

    Nh Ah-Hyun

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

    您好、啊、

    让我看看您的代码并提供您的反馈。

    谢谢!

    此致

    Johnson

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

    尊敬的 Johnson:

    非常感谢。

    我只是想知道问题不是由代码引起的。

    因此、您无需查看代码 (我对此感到不好、因为代码太长且难以读取)

    我认为调用 main()的任何内容都是循环调用它,

    这就是 main()命令流无限重复的原因。

    那么,您能告诉我什么代码调用并执行 main()吗?

    我认为这就是我所需要的:)

    谢谢!

    此致、

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

    除非您进行了更改,否则 main()仅调用一次。

    MPU 能否持续复位?

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

    您好、Keith、

    感谢您的回答。

    除了*。c 修改之外、我只添加了附加头文件(*。h)、并且 main()也没有循环。

    ( 存在函数和 i2c_state 的定义)

    是否有任何函数可通过硬件方式在 Launchpad (MSP-EXP430G2)中设置复位重复?

    因为这个焊盘是二手的、所以以前的用户可以设置一些东西。

    谢谢!

    此致、

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

    尝试将其添加为 main()的第一行:

    > WDTCTL = WDTPW | WDTHOLD;//停止看门狗计时器

    正如 Keith 所说的,通常情况下,如果你从 main()返回,你最终会进入一个循环(我认为)__exit()。 但是、如果看门狗仍然在运行、您的程序将在一段时间后重新启动。

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

    你好 Bruce。

    非常感谢您的帮助!  

    它起作用了:D

    原因是看门狗定时器。

    现在、命令只传输一次。

    再次感谢你