单片机/MCU论坛
直播中

方飞越

未满1年用户 3经验值
擅长:嵌入式技术
私信 关注
[问答]

MSP430FR2433的SPI通信为什么收不到?

在用MSP430FR2433控制ADXL362三轴加速度传感器,这个代码之前2355上写出来可以用,移植到2433时发现收不到数据,看了下波形感觉存在两种可能:
1、时钟上升沿时MOSI还未稳定(几乎是和时钟一同跳变)
2、2355上MOSI在时钟空闲时始终为低,而2433在空闲时会保持发送的最后一位电平(如图)
有没有高手能指点一二看看怎么解决
cgi-bin_mmwebwx-bin_webwxgetmsgimg_&MsgID=840957622966597381&skey=@crypt_f7eb4327_2dcf92cb33f86d0c3780c09b0ad82982&mmweb_appid=wx_webfilehelper.jpg

回帖(1)

杨勇

2025-11-28 18:07:27

根据您描述的问题,MSP430FR2433 SPI通信失败的两个关键原因是:MOSI数据建立时间不足(时钟跳变时数据不稳定)SPI空闲时MOSI电平状态异常。以下是针对性的解决方案:




根本原因分析




  1. MOSI建立时间不足

    MSP430FR2433的eUSCI模块与旧型号USCI存在时序差异。当CPHA=0(模式0)时,数据必须在SCLK上升沿之前半个时钟周期稳定。您的波形显示MOSI与时钟同步跳变,违反了建立时间要求。




  2. SPI空闲时MOSI电平问题

    MSP430FR2433在SPI空闲时保持MOSI为上一次发送的最后一位电平(如高电平),而ADXL362默认期望空闲时MOSI为低(模式0)。这会导致通信起始时出现额外的高电平脉冲,破坏数据帧。






解决方案


1. 调整SPI时序相位(关键步骤)


修改时钟相位寄存器 CPHA=1(模式3),确保数据在时钟下降沿采样:


   UCB0CTLW0 |= UCMSB;          // MSB First
   UCB0CTLW0 |= UCMST | UCSYNC; // Master mode, SPI
   UCB0CTLW0 |= UCCKPH;         // 时钟相位配置 CPHA=1(数据在下降沿采样)
   UCB0CTLW0 &= ~UCCKPL;        // 时钟极性 CPOL=0(空闲低电平)

原理:  



  • 模式3(CPHA=1)允许MOSI在SCLK上升沿变化,在下降沿被采样,避开建立时间问题。

  • ADXL362支持模式0和模式3(参见其数据手册),兼容性已验证。


2. 强制SPI空闲时MOSI为低电平


在SPI传输完成后,手动拉低MOSI引脚:


   void inline SPI_EndFrame(void) {
       // 切换MOSI为GPIO模式并强制拉低
       P1SEL0 &= ~BIT7;      // P1.7(MOSI) 切换为GPIO
       P1SEL1 &= ~BIT7;
       P1DIR  |= BIT7;       // 设置为输出
       P1OUT  &= ~BIT7;      // 输出低电平
   }

传输开始前重新启用SPI功能:


   void inline SPI_BeginFrame(void) {
       P1SEL0 |= BIT7;       // P1.7(MOSI) 恢复SPI功能
       P1SEL1 &= ~BIT7;
   }

调用示例


   uint8_t SPI_Transfer(uint8_t data) {
       SPI_BeginFrame();     // 启用SPI MOSI功能
       UCB0TXBUF = data;
       while (!(UCB0IFG & UCRXIFG));
       uint8_t res = UCB0RXBUF;
       SPI_EndFrame();       // 传输结束强制MOSI=0
       return res;
   }

3. 优化SPI时钟速度


降低时钟频率(尤其当线路较长时),增加时序裕量:


   UCB0BRW = 16; // 设置时钟分频(假设ACLK=16MHz → SPI CLK=1MHz)

4. 关键波形整改点



  • SCLK空闲状态:必须为低电平(CPOL=0)。

  • CSN片选时序:传输前拉低,结束后拉高并保持至少100ns。

  • MOSI建立时间:在SCLK上升沿前稳定(模式0)或下降沿稳定(模式3)。




完整配置代码参考


void SPI_Init(void) {
    // 引脚配置
    P1SEL0 |= BIT5 | BIT6 | BIT7;  // P1.5=SCLK, P1.6=MISO, P1.7=MOSI
    P1SEL1 &= ~(BIT5 | BIT6 | BIT7);

    // SPI主机模式设置
    UCB0CTLW0 = UCSWRST;           // 复位SPI
    UCB0CTLW0 |= UCMSB              // MSB First
              | UCMST              // 主机模式
              | UCSYNC             // SPI模式
              | UCCKPH             // CPHA=1(模式3)
              | UCSSEL__SMCLK;     // 选择SMCLK时钟源
    UCB0BRW = 16;                  // 分频至1MHz(若SMCLK=16MHz)
    UCB0CTLW0 &= ~UCSWRST;         // 释放复位

    // 初始拉低MOSI
    SPI_EndFrame();
}

// 单字节传输函数
uint8_t SPI_Transfer(uint8_t data) {
    SPI_BeginFrame();              // 启用MOSI SPI功能
    UCB0TXBUF = data;
    while (!(UCB0IFG & UCRXIFG));  // 等待接收完成
    uint8_t res = UCB0RXBUF;
    SPI_EndFrame();                // 强制MOSI=0
    return res;
}



验证要点



  1. 示波器检测

    • 确认SCLK空闲为低(CPOL=0),数据在下降沿稳定(CPHA=1)。

    • 检查CSN激活期间MOSI起始位为低电平。


  2. ADXL362寄存器读取
    尝试读取DEVID_AD寄存器(地址0x00),应返回固定值0xAD:
    uint8_t Read_ADXL_Reg(uint8_t addr) {
       CSN_LOW();                  // 片选使能
       SPI_Transfer(0x0B);         // 读命令
       SPI_Transfer(addr);
       uint8_t val = SPI_Transfer(0);
       CSN_HIGH();                 // 片选释放
       return val;
    }


通过上述调整,可同时解决建立时间不足和空闲电平问题,确保通信稳定性。务必检查硬件连接(尤其是CSN和VCC电平),必要时增加上拉电阻。

举报

更多回帖

发帖
×
20
完善资料,
赚取积分