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.

[参考译文] LP-MSP430FR2476:从外部传感器读取故障

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1429982/lp-msp430fr2476-trouble-reading-from-external-sensor

器件型号:LP-MSP430FR2476

工具与软件:

尊敬的 MSP430 gurus:

我在与外部 温度传感器通信时似乎遇到了问题。   以下代码似乎不会填充任何寄存器、并且我收到一条消息、例如"error cannot load from non-primative location"(错误无法从非优先位置加载)

这里是我尝试从外部传感器读取的位置。  这里显然有什么东西吗?

谢谢

WDTCTL = WDTPW | WDTHOLD;
UCB0CTL1 = UCSWRST;//将 eUSCI 置于复位状态
UCB0CTL0 =(无符号字符)(UCCKPH | UCMSB | UCMST | UCSYNC);// 3引脚、8位 SPI 主器件
UCB0CTL1 = UCSSEL_2 | UCSWRST;//使用 SMCLK、使 eUSCI 保持复位状态
UCB0BR0 = 0x02;///2
UCB0BR1 = 0;//
P1SEL0 |= SCLK_PIN | MOSI_PIN | MISO_PIN;//设置 SPI 引脚
P1SEL1且=~(SCLK_PIN | MOSI_PIN | MISO_PIN);
UCB0CTL1 &=~μ s UCSWRST;
P1DIR |= CS_PIN;//将 CS 引脚设置为输出

unsigned int ctl0 = UCB0CTL0;
unsigned int ctl1 = UCB0CTL1;

P1OUT 且=~CS_PIN;
UCB0TXBUF = 0x00;//发送虚拟字节以启动 SPI 读取
while (! (UCB0IFG & UCRXIFG));//等待 RX 缓冲区准备就绪
TEMP = UCB0RXBUF << 8;//读取 MSB
UCB0TXBUF = 0x00;//发送虚拟字节以读取 LSB
while (! (UCB0IFG & UCRXIFG));//等待 RX 缓冲区准备就绪
TEMP |= UCB0RXBUF;//读取 LSB

P1OUT |= CS_PIN;

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

    在此处的某个位置(可能就在开头)您需要:

    > PM5CTL0并且=~μ A LOCKLPM5;//启用 GPIO

    当我建立这个代码时,我得到了一个关于遗漏的警告。

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

    您好、Bruce、添加行后、我看到行为没有变化...找不到标识符、当我尝试观察表达式窗口中的 UCB0寄存器时

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

    UCB0CTL0/1是 UCB0CTLW0两个部分的别名(宏)。 可能会导致"Expressions"视图出现问题。 [我实际上建议您将代码切换到使用 UCB0CTLW0、以确保位定义始终有效。]

    我通常对外设使用"寄存器"视图、因为它会为我解释位。

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

    使用 UCB0CTL0W 或正确的常数至关重要。 例如、UCSYNC 为0x0100。 显然不能使用字节写入。 有 UCSYNC 等版本用于字节访问、但字访问绝对更容易。 与 UCB0BRW 无关。

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

    感谢大家。  我已经更新了代码、以使用应该更具体的寄存器、但似乎仍然有问题。   以下是整个代码


    #include
    #include
    #include

    //#define CS_PIN BIT0
    //#define SCLK_PIN BIT1
    //#define MOSI_PIN BIT2
    //#define MISO_PIN BIT3


    void initSPI (void);
    void initCS (void);
    void setCSLow (void);
    void setCCSHigh (void);
    unsigned int readTemperature (void);

    int main (void){

    易失性 uint32_t i;

    //停止看门狗计时器
    WDT_A_HOLD (WDT_A_BASE);


    PM5CTL0 &=~μ A LOCKLPM5;//接合 GPIO
    // WDTCTL = WDTPW | WDTHOLD;//停止看门狗计时器
    initSPI();


    while (1){
    unsigned int temperature = readTemperature();
    //根据需要处理温度数据
    printf ("读数");
    __delay_cycles (1000000);//延迟以提高可读性
    }
    }
    void initSPI (void){
    //设置 SPI 引脚
    P1SEL1 |= BIT0 | BIT2 | BIT3;//将 P1.0、P1.2、P1.3设置为 SPI 引脚
    P1SEL0 &=~Ω(BIT0 | BIT2 | BIT3);

    //配置 CS 引脚
    P1DIR |= BIT1;//将 P1.1设置为输出
    P1OUT |= BIT1;//最初将 CS 设置为高电平

    //针对 SPI 操作配置 USCI_B0
    UCB0CTLW0 = UCSWRST;//将 eUSCI 状态机复位
    UCB0CTLW0 |= UCSSEL__SMCLK | UCSYNC | UCMST | UCCKPL | UCCKPH;// 3引脚、8位 SPI 主控器
    UCB0BRW = 0x01;///1时钟预分频器
    UCB0CTLW0 &=~μ s UCSWRST;//初始化 USCI 状态机
    }

    uint16_t readTemperature (void){
    uint8_t tempHigh = 0、tempLow = 0;
    uint16_t 温度= 0;

    //选择 ADT7320
    P1OUT 且=~BIT1;// CS LOW

    //发送读取温度命令
    while (! (UCB0IFG & UCTXIFG));//等待 TX 缓冲区准备就绪
    UCB0TXBUF = 0x54;//读取温度命令

    //读取高字节
    while (! (UCB0IFG & UCRXIFG));//等待 RX 缓冲区准备就绪
    tempHigh = UCB0RXBUF;

    //读取低字节
    while (! (UCB0IFG & UCTXIFG));//等待 TX 缓冲区准备就绪
    UCB0TXBUF = 0x00;//虚拟写入以生成时钟
    while (! (UCB0IFG & UCRXIFG));//等待 RX 缓冲区准备就绪
    tempLow = UCB0RXBUF;

    //取消选择 ADT7320
    P1OUT |= BIT1;// CS 高电平

    //组合高字节和低字节
    温度=(tempHigh << 8)| tempLow;

    回流温度;
    }

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    [报价 userid="628510" url="~/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1429982/lp-msp430fr2476-trouble-reading-from-external-sensor/5482727 #548272727"]

    P1SEL1 |= BIT0 | BIT2 | BIT3;//将 P1.0、P1.2、P1.3设置为 SPI 引脚
    P1SEL0 &=~Ω(BIT0 | BIT2 | BIT3);

    //配置 CS 引脚
    P1DIR |= BIT1;//将 P1.1设置为输出
    P1OUT |= BIT1;//最初将 CS 设置为高电平

    [报价]

    由于 P1.0是 STE、P1.1是 SPI 时钟、因此将出现问题。 您似乎在定义 SCLK_PIN 时知道这些特征。

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

    我重写了代码(如这里所示)、但似乎仍然没有进行通信。  在中间的某些时候、我正在将一些值输入到 RXBUF 中、但并不稳定。   考虑一下它可能还处于关闭状态的位置。   

    #include
    #include
    #include


    #define CS_PIN BIT0
    #define SCLK_PIN 位1
    #define MOSI_PIN 位2
    #define MISO_PIN 位3


    void GPIO_init (void)

    /*将所有 GPIO 设置为输出低电平以降低功耗*/
    GPIO_setAsOutputPin (GPIO_PORT_PA、GPIO_PIN_ALL16);
    GPIO_setAsOutputPin (GPIO_PORT_PB、GPIO_PIN_ALL16);
    GPIO_setAsOutputPin (GPIO_PORT_PC、GPIO_PIN_ALL16);
    GPIO_setAsOutputPin (GPIO_PORT_PD、GPIO_PIN_ALL16);
    GPIO_setAsOutputPin (GPIO_PORT_PE、GPIO_PIN_ALL16);
    GPIO_setOutputLowOnPin (GPIO_PORT_PA、GPIO_PIN_ALL16);
    GPIO_setOutputLowOnPin (GPIO_PORT_PB、GPIO_PIN_ALL16);
    GPIO_setOutputLowOnPin (GPIO_PORT_PC、GPIO_PIN_ALL16);
    GPIO_setOutputLowOnPin (GPIO_PORT_PD、GPIO_PIN_ALL16);
    GPIO_setOutputLowOnPin (GPIO_PORT_PE、GPIO_PIN_ALL16);

    //将 P4.0 (S1)设置为输入
    GPIO_setAsInputPinWithPullUpResistor (GPIO_PORT_P4、GPIO_PIN0);
    GPIO_enableInterrupt (GPIO_PORT_P4、GPIO_PIN0);
    GPIO_selectInterruptEdge (GPIO_PORT_P4、GPIO_PIN0、GPIO_HIGH_TO_LOW_TRANSITION);

    //将 P2.3 (S2)设置为输入
    GPIO_setAsInputPinWithPullUpResistor (GPIO_PORT_P2、GPIO_PIN3);
    GPIO_enableInterrupt (GPIO_PORT_P2、GPIO_PIN3);
    GPIO_selectInterruptEdge (GPIO_PORT_P2、GPIO_PIN3、GPIO_HIGH_TO_LOW_TRANSITION);

    //禁用 GPIO 上电默认高阻抗模式
    //激活以前配置的端口设置
    PMM_UNlockLPM5 ();

    GPIO_clearInterrupt (GPIO_PORT_P4、GPIO_PIN0);
    GPIO_clearInterrupt (GPIO_PORT_P2、GPIO_PIN3);
    }

    void SPI_init (void){
    //将 SPI 引脚设置为适当的功能
    P1SEL0 |= SCLK_PIN | MOSI_PIN | MISO_PIN;
    P1SEL1且=~(SCLK_PIN | MOSI_PIN | MISO_PIN);

    //将 eUSCI_B0置于复位状态
    UCB0CTLW0 = UCSWRST;

    //针对 SPI 操作配置 eUSCI_B0
    UCB0CTLW0 |= UCSYNC | UCMST | UCMSB | UCCKPL | UCCKPH | UCSSEL__SMCLK;
    // UCSYNC—同步模式
    // UCMST -主模式
    // UCMSB - MSB 优先
    // UCCKPL—时钟极性高
    // UCCKPH -在第二个时钟沿捕获的数据
    // UCSSEL__SMCLK - SMCLK 作为时钟源

    //设置波特率
    UCB0BRW = 0x01;//针对最大速度除以1

    //初始化 eUSCI 状态机
    UCB0CTLW0 &=~μ s UCSWRST;
    }


    void initSPI_ADI (void){
    // P1SEL1 |= SCLK_PIN | MOSI_PIN | MISO_PIN;//设置 SPI 引脚
    // P1SEL0 &=~(SCLK_PIN | MOSI_PIN | MISO_PIN);


    UCB0CTLW0|=UCSWRST;

    //针对 SPI 操作配置 eUSCI_B0
    UCB0CTLW0 |= UCSSEL__SMCLK | UCSYNC | UCMST | UCMSB | UCCKPH;
    // UCB0CTLW0 = UCSWRST;//将 eUSCI 置于复位状态
    // UCB0CTLW0 |= UCSSEL_2 | UCMST | UCSYNC | UCCKPL | UCMSB;// 3引脚8位 SPI 主器件
    UCB0BRW = 0x02;///2时钟分频器
    UCB0CTLW0并且=~μ s UCSWRST;//初始化 eUSCI
    P1SEL0 |= SCLK_PIN | MOSI_PIN | MISO_PIN;
    P1SEL1且=~(SCLK_PIN | MOSI_PIN | MISO_PIN);
    P1DIR |= CS_PIN;//将 CS 引脚设置为输出
    P1OUT |= CS_PIN;//将 CS 设置为高电平
    }


    uint8_t SPI_transfer (uint8_t data){
    //等待发送缓冲区准备就绪
    while (! (UCB0IFG 和 UCTXIFG));

    //发送数据
    UCB0TXBUF =数据;

    //等待数据被接收
    while (! (UCB0IFG 和 UCRXIFG));

    //返回接收到的数据
    返回 UCB0RXBUF;
    }

    void spiWrite (uint8_t reg、uint8_t data){
    P1OUT 且=~CS_PIN;// CS 低电平
    while (! (UCB0IFG & UCTXIFG));//等待 TX 缓冲区准备就绪
    UCB0TXBUF = reg;//发送寄存器地址
    while (! (UCB0IFG & UCTXIFG));//等待 TX 缓冲区准备就绪
    UCB0TXBUF = data;//发送数据
    while (UCB0STATW & UCBUSY);//等待传输完成
    P1OUT |= CS_PIN;// CS 高电平
    }

    uint8_t spiRead (uint8_t reg){
    uint8_t 数据;
    P1OUT 且=~CS_PIN;// CS 低电平
    while (! (UCB0IFG & UCTXIFG));//等待 TX 缓冲区准备就绪
    UCB0TXBUF = reg | 0x80;//发送寄存器地址和读取位
    while (! (UCB0IFG & UCTXIFG));//等待 TX 缓冲区准备就绪
    UCB0TXBUF = 0x00;//虚拟写入以启动读取
    while (! (UCB0IFG & UCRXIFG));//等待 RX 缓冲区准备就绪
    DATA = UCB0RXBUF;//读取数据
    P1OUT |= CS_PIN;// CS 高电平
    返回数据;
    }

    unsigned int readTemp_ADI (void){
    unsigned int temp;

    SpiWrite (0x01、0x80);
    TEMP = spiRead (0x00);
    TEMP = spiRead (0x03);
    TEMP = spiRead (0x04);
    TEMP = spiRead (0x05);
    TEMP = spiRead (0x06);
    TEMP = spiRead (0x07);
    Temp = spiRead (0x02)<<8;
    temp |= spiRead (0x02);
    //调试:打印原始温度值
    printf ("原始温度:%u\n"、temp);

    返回温度;
    }

    float convertTemp_ADI (unsigned int rawTemp){
    rawTemp >>= 3;// Shift 以获得13位温度值
    if (rawTemp & 0x1000){//检查温度是否为负值
    rawTemp -= 8192;
    }
    Return rawTemp * 0.0625;
    }

    int main (void){
    WDT_A_HOLD (WDT_A_BASE);//停止看门狗计时器

    GPIO_init ();//初始化 GPIO
    spi_init ();//初始化 SPI

    while (1){
    unsigned int rawTemp_ADI = readTemp_ADI ();
    float temperature_ADI = convertTemp_ADI (rawTemp_ADI);
    //在此处添加断点或输出状态以进行调试
    __delay_cycles (1000000);//在下一次读取之前延迟一段时间
    }
    }

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

    您读取温度的例程与 ADT7320 (您代码中提到的)数据表的读数不匹配。