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/MSP430FR4133:SPI 问题:ADS8353缺少通道1的 MSB、而不是通道2的 MSB

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/714913/ccs-msp430fr4133-spi-issue-ads8353-missing-msb-for-channel-1-but-not-channel-2

器件型号:MSP430FR4133
主题中讨论的其他器件: ADS8353

工具/软件:Code Composer Studio

SBAS584BGood 下午、

我目前正在尝试使用 MSP430FR4133与 ADS8353进行通信、以实现使用 SPI 的16位分辨率。 这是一个令人困惑的问题。 ADS8353发送的数据完全正确、与数据表匹配。 令人烦恼的是、它发送 15位来响应命令、然后发送16位通道1数据、16位通道2数据、再发送强制0、总共48位、又称为一帧。 (第41页 SBAS584B 表14:Launch Data Edge)。  

这与我们在示波器上看到的完全匹配。

发生了两件奇怪的事情。

  • 最重要的是、通道1的 MSB 会丢失。 我们为它接收一个0、它独立于它的实际值、然后是15个有意义的位。 然后、我们接收通道2的16个有意义的位、最后是上表中提到的尾0。 它正在发送、但 MSP 无法识别它。  
  • 被读取的值是一个周期后的值。 如果您发送、然后读取、那么我们将获得本应在8位周期之前的数据。  

#include
#include
#include
#include

void SYSTEMinit();
int writeUART (char*语句);

void sendZeros (int NumberOfTimes);

int main (空)

char buffer[50];
SYSTEMMINIT();
uint16_t 的值[8];
int j;
while (1)

P5OUT &=~ BIT0;       //打开 ADC

while ((UCB0IFG & UCTXIFG)=0);  
UCB0TXBUF = 0x00;
while ((UCB0IFG & UCRXIFG)=0);
值[0]= UCB0RXBUF;

while ((UCB0IFG & UCTXIFG)=0);  
UCB0TXBUF = 0x00;
while ((UCB0IFG & UCRXIFG)=0);
值[1]= UCB0RXBUF;

while ((UCB0IFG & UCTXIFG)=0);
UCB0TXBUF = 0x00;
while ((UCB0IFG & UCRXIFG)=0);
值[2]= UCB0RXBUF;

while ((UCB0IFG & UCTXIFG)=0);
UCB0TXBUF = 0x00;
while ((UCB0IFG & UCRXIFG)=0);
值[3]= UCB0RXBUF;

while ((UCB0IFG & UCTXIFG)=0);
UCB0TXBUF = 0x00;
while ((UCB0IFG & UCRXIFG)=0);
值[4]= UCB0RXBUF;

while ((UCB0IFG & UCTXIFG)=0);
UCB0TXBUF = 0x00;
while ((UCB0IFG & UCRXIFG)=0);
值[5]= UCB0RXBUF;

_DELAY_CYCLES (8);
P5OUT |= BIT0;
sprintf (buffer、"\n\r\n%u\t%u\t%u\t%u\t%u\t%u"、值[0]、值[1]、值[2]、值[3]、值[4]、值[5]、值[5]);
writeUART (buffer);
_DELAY_CYCLES (800000);

空 SYSTEMMINIT()

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

P5DIR = 0x00;//将所有 DIR 设置为 USCIB 所需的输入
P5DIR |= BIT0;//用作通道选择(SPI)的 I/O 引脚
P5OUT |= BIT0;//将通道选择引脚设置为低电平
P5SEL0 = 0x0E;//与上述相同。 将端口5引脚1-3的全部设置为1
P1SEL0 |= BIT0 + BIT1;//将2-UART 引脚设置为主要非 I/O 功能

//时钟配置。
FRCTL0 = FRCTLPW | NWAITS_1;//配置等待状态 thingy。 速度高于8MHz 时所需的
PM5CTL0 &=~LOCKLPM5;//将引脚锁定到位
CSCTL3 |= SELREF_REFOCLK;//将 REFO 设置为 FLL 基准源
CSCTL0 = 0;//清除 DCO 和 MOD 寄存器
CSCTL1 &=~(DCORSEL_7);//首先清除 DCO 频率选择位
CSCTL1 |= DCORSEL_3;//设置 DCO = 8MHz
CSCTL2 = FLLD_0 + 243;// DCODIV = 8MHz
CSCTL4 = SELMS_DCOCLKDIV;//默认 DCODIV SMCLK 源

UCA0CTLW0 |= UCSWRST;//允许配置 UART
UCA0CTLW0 |= UCSSEL_SMCLK;//选择 SMCLK 作为 UART 的时钟源
UCA0BR0 = 4;// 8MHz 至115.2k 波特率。 请参阅表(第589页)
UCA0MCTLW = 0x5500 | UCOS16 | UCBRF_5;
UCA0CTLW0 &=~UCSWRST;//初始化 eUSCI

_enable_interrupt ();
UCA0IE |= UCRXIE;//启用 USCI_A0 RX 中断

UCB0CTLW0 |= UCSWRST;//允许编辑几乎所有以下位。
UCB0CTLW0 &=~ UCCKPH;//数据在第一个边沿发生更改并在第二个边沿被捕捉
UCB0CTLW0 &=~ UCCKPL;//非活动状态为高电平
UCB0CTLW0 |= UCMSB;//最高有效位优先
UCB0CTLW0 &=~ UC7BIT;// 8位数据
UCB0CTLW0 |= UCMST;//将 MSP 设置为主控模式
UCB0CTLW0 |= UCMODE1;//低电平有效的4引脚模式、在 STE (M?)时使能从器件 = 0
UCB0CTLW0 |= UCSYNC;//同步模式,共享时钟
UCB0CTLW0 |= UCSSEL_SMCLK;//选择特定于器件的模式、即 SMCLK (8MHz)
UCB0BRW = 0x02;
UCB0CTLW0 |= UCSTEM;//为4线制从机生成使能信号
UCB0CTLW0 &=~ UCSWRST;//启用机器

P5OUT &=~ BIT0;
while (((UCB0IFG & UCTXIFG)=0);//轮询发送标志
UCB0TXBUF = 0x86;//配置 CFR (ADS5383上的配置寄存器)
SendZeros(5);
_delay_cycles (16);
P5OUT |= BIT0;
P5OUT &=~ BIT0;
while (((UCB0IFG & UCTXIFG)=0);//将 REFDAC_A 配置为2.5V
UCB0TXBUF = 0x91;
while ((UCB0IFG & UCTXIFG)=0);
UCB0TXBUF = 0xFF;
SendZeros(4);
_delay_cycles (16);
P5OUT |= BIT0;
P5OUT &=~ BIT0;
while (((UCB0IFG & UCTXIFG)=0);//将 REFDAC_B 配置为2.5V
UCB0TXBUF = 0xA1;
while ((UCB0IFG & UCTXIFG)=0);
UCB0TXBUF = 0xFF;
SendZeros(4);
_delay_cycles (16);
P5OUT |= BIT0;//关闭 ADS5383

_delay_cycles (1300000);

UCB0CTLW0 |= UCSWRST;//允许编辑几乎所有以下位。
UCB0CTLW0 |= UCCKPH;//数据在第一个边沿发生变化,在第二个边沿被捕捉
UCB0CTLW0 &=~ UCSWRST;

writeUART ("\n\rstart");

int writeUART (char*语句)

int i;
对于(i = 0;i < strlen (句子);i++){
while (!(UCA0IFG&UCTXIFG));
UCA0TXBUF =句子[i];

返回 i;

void sendZeros (int NumberOfTimes)

int i;
对于(i = 0;<NumberOfTimes; i++))

while (((UCB0IFG & UCTXIFG)=0);//轮询发送标志
UCB0TXBUF = 0x00;

这应该是所有相关代码。 如果您有任何问题、请告诉我!

谢谢、

奥斯汀

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您的 RXIFG 会逐个关闭。 将/CS (P5.0)置为高电平会复位从机状态、但不会清除 RXIFG、因此下次检查 RXIFG 时、它已经被置位。 最简单的修复方法可能是将其添加到 SendZeros()的末尾:

    > while (UCB0STATW 和 UCBUSY)/* empty*/;//等待零完成计时
    >(空) UCB0RXBUF; //读取和丢弃(清除 RXIFG)
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Bruce、您好!  


    您的建议完全正确。 这完全解决了接收计时问题!

    此外、ADC 的问题是硬件。 我们使用新的 ADS8353进行了试用、并根据需要工作。

    非常感谢、

    奥斯汀