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/MSP432P401R:使用DMA时SPI出现故障

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/576524/ccs-msp432p401r-trouble-with-spi-using-dma

部件号:MSP432P401R

工具/软件:Code Composer Studio

我将带有SPI的FRAM连接到EUSCI_B0。

我按如下所示配置了SPI端口。

//配置SPI接口
EUSCI_B0->CTLW0 |= EUSCI_B_CTLW0_SWRST;//将eUSCI状态机置于复位状态
EUSCI_B0->CTLW0 = EUSCI_B_CTLW0_SWRST |//在复位中保持eUSCI状态机
EUSCI_B_CTLW0_MST |//设置为SPI主中继器
EUSCI_B_CTLW0_SYNC |//设置为同步模式
EUSCI_B_CTLW0_CKPL |//设置时钟极性高
EUSCI_B_CTLW0_MSB;// MSB优先

EUSCI_B0->CTLW0 |= EUSCI_B_CTLW0_sel__SMCLK;// SMCLK=24MHz 2017-2-21
EUSCI_B0->BRW = 0x00;// fBitClock = fBRCLK/(UCBRx+1)。 0 = 24MHz CLK 2017-2-23
EUSCI_B0->CTLW0 &=~EUSCI_B_CTLW0_SWRST;//初始化USCI状态机


我尝试按如下所示将256个数据=512字节写入FRAM。

int i;
Int16_t fram_data = 0;// FRAM的16位数据
uINT32_t d1;


对于(i=0;i<256;i++)

d1 =(fram_data >> 8)和0x0ff;
同时(!(EUSSCI_B0->IFG & EUSCI_B_IFG_TXIFG));
EUSCI_B0->TXBUF = D1;//数据B15至B8
while (!(EUSSCI_B0->IFG & EUSCI_B_IFG_RXIFG));
IDdata = EUSCI_B0->RXBUF;

d1 = fram_data和0x0ff;
同时(!(EUSSCI_B0->IFG & EUSCI_B_IFG_TXIFG));
EUSCI_B0->TXBUF = d1;// data b7 to b0
while (!(EUSSCI_B0->IFG & EUSCI_B_IFG_RXIFG));
IDdata = EUSCI_B0->RXBUF;

FRAM_DATA++;
}

这样,我就可以写数据了。

(我使用背面通道UART转储FRAM数据。)

fRAM_DATA = 0800至0900 =写入256个数据
fRAM_READ_DATA =
0800 0801 0802 0803 0804 0805 0806 0807 0808 0809 080A 080B 080C 080D 080E 080F
0810 0811 0812 0813 0814 0815 0816 0817 0818 0819 081A 081B 081C 081D 081E 081F
0820 0821 0822 0823 0824 0825 0826 0827 0828 0829 082A 082B 082C 082D 082E 082F
0830 0831 0832 0833 0834 0835 0836 0837 0838 0839 083A 083B 083C 083D 083E 083F
0840 0841 0842 0843 0844 0845 0846 0847 0848 0849 084A 084B 084C 084D 084E 084F
0850 0851 0852 0853 0854 0855 0856 0857 0858 0859 085A 085B 085C 085D 085E 085F
0860 0861 0862 0863 0864 0865 0866 0867 0868 0869 086A 086B 086C 086D 086E 086F
0870 0871 0872 0873 0874 0875 0876 0877 0878 0879 087A 087B 087C 087D 087E 087F
0880 0881 0882 0883 0884 0885 0886 0887 0888 0889 088A 088B 088C 088D 088E 088F
0890 0891 0892 0893 0894 0895 0896 0897 0898 0899 089A 089B 089C 089D 089E 089F
08A0 08A1 08A2 08A3 08A4 08A5 08A6 08A7 08A8 08A9 08AA 08AB 08AC 08AD 08AE 08AF
08B0 08B1 08B2 08B3 08B4 08B5 08B6 08B7 08B8 08B9 08BA 08BB 08BC 08BD 08BE 08BF
08C0 08C1 08C2 08C3 08C4 08C5 08C6 08C7 08C8 08C9 08CA 08CB 08CC 08CD 08CE 08CF
08D0 08D1 08D2 08D3 08D4 08D5 08D6 08D7 08D8 08D9 08DA 08DB 08DC 08DD 08DE 08DF
08E0 08E1 08E2 08E3 08E4 08E5 08E6 08E7 08E8 08E9 08EA 08EB 08EC 08ED 08EE 08EF
08F0 08F1 08F2 08F3 08F4 08F5 08F6 08F7 08F8 08F9 08FA 08FB 08FC 08FD 08FE 08FF


但是,当我尝试使用DMA写入相同的数据时,

#pragma data_align(D8, 512)
联合DATA16B8B{
uINT16_t D16[256];
uINT8_t D8[512];
};

Union DATA16B8B data16b8b;

void SPI_fram_write_dma( uint8_t mstxData[],int n )

/*将DMA通道0分配给EUSCI_B0_TX0,通道1分配给EUSCI_B0_RX0 */
MAP_DMA_赋 值通道(DMA_CH0_EUSCIB0TX0);

/*设置TX传输特性和缓冲区*/
MAP_DMA_setChannelControl(DMA_CH0_EUSCIB0TX0 | UDMA_PRI_SELECT,
UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARB_1);
MAP_DMA_setChannelTransfer (DMA_CH0_EUSCIB0TX0 | UDMA_PRI_SELECT,
udma_mode_basic,mstxData,
(void *) MAP_SPI_getTransmitBufferAddressForDMA(EUSI_B0_BASE),
n);
MAP_DMA_enableChannel(0);
}

对于(i=0;i<256;i++)

data16b8b.d16[i]= fram_data;
FRAM_DATA++;
}

spi_fram_write_dma (&data16b8b.d8 [0],512);


数据的某些部分看起来不错,但有很多奇怪的数据。

FRAM_DATA = 0900至0A00 =写入256个数据
fRAM_READ_DATA =
0000 0901 0902 0903 0904 0905 0907 0907 0907 0908 90.909万A 090B 090C 090D 090E 090F
0910 0911 0912 0913 0914 0915 0916 0917 0918 0919 091A 091B 091C 091D 091E 091F
0920 0921 0922 0923 0924 0925 0926 0927 0928 0929 092A 092B 092C 092D 092E 092F
0930 0931 0932 0933 0934 0935 0936 0937 0938 0939 093A 093B 093C 093D 093E 093F
0940 0941 0942 0943 0944 0945 0946 0947 0948 0949 094A 094B 094C 094D 094E 094F
0950 0951 0952 0953 0954 0955 0956 0957 0958 0959 095A 095B 095C 095D 095E 095F
0960 0961 0962 0963 0964 0965 0966 0967 0968 0969 096A 096B 096C 096D 096E 096F
0970 0971 0972 0973 0974 0975 0976 0977 0978 0979 097A 097B 097C 097D 097E 097F
0980 0981 0982 0983 0984 0985 0986 0987 0988 0989 098A 098B 098C 098D 098E 098F
0990 0991 0992 0993 0994 0995 0996 0997 0998 0999 099A 099B 099C 099D 099E 099F
09A0 09A1 09A2 09A3 09A4 09A5 09A6 09A7 09A8 09A9 09AA 09AB 09AC 09AD 09AE 09AF
09B0 09B1 09B2 09B3 09B4 09B5 09B6 09B7 09B8 09B9 09BA 09BB 09BC 09BD BE09 BF09
C009 C109 C209 C309 C409 C509 C609 C709 C809 C909 CA09 CB09 CC09 CD09 CE09 CF09
D009 D109 D209 D309 D409 D509 D609 D709 D809 D909 DA09 DB09 DC09 DD09 DE09 DF09
E009 E109 E209 E309 E409 E509 E609 E709 E809 E909 EA09 EB09 EC09 ED09 EE09 EF09
F009 F109 F209 F309 F409 F509 F609 F709 F809 F909 FA09 FB09 FC09 F09 FE09 FF09

我现在应该怎么做?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好,
    我建议首先尝试使用较慢的时钟速度和无DMA,以确保问题与DMA配置有关,而不是SPI设置。 当速度较慢的配置工作后,添加DMA,然后最终提高到所需的速度。

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

    我做到了!

    我尝试了16kHz时钟,没有DMA。  

    一切都很好 (写入和读取)

    我已将频率更改为12MHz,但不使用DMA。

    一切都很好  (写入和读取)

    现在,我尝试了DMA,得到了奇怪的结果,并在想。  

    我使用DMA更改了写入部分。  

    所以,我的DMA程序有问题。  

    还是与"易失性"再次有关?

    我应该检查FRAM输入端的波形。  

    希望能尽快得到一些答复!

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

    e2e.ti.com/.../DMA_5F00_SPI_5F00_TX_5F00_01.cHello。

      我已提供了一个示例来帮助提供一些指导。  其中一个问题是SPI的最大数据速率被指定为16MHz。  为了获得16MHz输出,SMCLK必须为16MHz (eUSCI的最大指定时钟输入为24MHz,否则我将输入32MHz)。  

     查看您提供的代码,我看不到任何问题。  希望您能够利用或至少将此代码与您拥有的全部代码进行比较。  我使用另一个MSP432测试以验证数据,因此如果您还需要该代码,请告诉我。  

    此致,

    Chris  

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

    非常感谢您的示例计划。  

    对于SPI时钟频率<=16 MHz,  

    我发现您在SLAS826B中提到的行是正确的。

    1器件概述1.1  具有  串行通信  SPI (高达16 Mbps)

    我查看了"msp432p401r.pdf"和"MSP432P4xx系列技术参考手册用户指南slau356e.pdf"。  

    我发现,SOMI:从机输出主机输入= SPI读取缓慢,但SIMO:从机输入主机输出= SPI写入非常快。  

    连接MSP432 SPI主控制器和MSP432 SPI从控制器时,SPI时钟应低于16 MHz。  

    但是,当我连接MSP432 SPI主控制器和FRAM SPI从控制器时,我认为我可以将时钟速度提高到24 MHz。  

    我要将CY15B104Q 4_Mbit(512K_8) Serial (SPI)_RAM连接到MSP432p401r。  

    CY15B104的 最大SPI时钟速度为40MHz。  

    我想将采样率为1MHz的14位A/D数据连续保存到FRAM中。  

    因此,如果我在写入FRAM时将时钟速度设置为24MHz,我可以解决我的问题。  

    在检查了两个芯片的计时表后,我认为可以在24MHz时通过SPI将数据从MSP432写入FRAM(CY15B104)。  

    当我通过SPI从FRAM读取到MSP432的数据时,也许我必须将时钟降低到12MHz。  

    SPI是否可以使用非对称时钟速度?

    或者,是否必须将时钟速度降低到16MHz?  

    我是否需要使用两个SPI接口连接两个FRAM,以1Msps的速度保存14位A/D数据?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    很抱歉耽误你的时间。 希望您能够根据您的建议值继续进行测试。 为了说明,技术指标(数据表)将外设的最大速度限制为24MHz。 不幸的是,eUSCI中的除法器不支持分数值,因此2/3不是位速率字段的有效输入。 您需要将频率降低到16MHz。

    对于ADC-DMA-SPI,您建议,我尚未测试实现,我不确定是否要处理与eUSCI的1字节接口的两字节转换值。 DMA提供了一种散点收集机制,这似乎是一种逻辑选择。

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

    我决定现在不使用通过SPI接口连接的外部FRAM。
    (可能您的下一个MSP432版本将具有更多的高速SPI接口。)

    我决定将实时数据存储大小降低到20ms = 1Msps 14位ADC的2万 样本。
    我决定使用内部SRAM存储器-每个样本2字节,2万 样本40KB。
    我可以正确获取20毫秒原始波形分层数据。

    顺便说一下,MSP432上的FPU可以计算132uS中14位ADC数据的200个样本的RMS (均方根)值。 1MSPS 14位ADC数据*200 = 200US。 我可以获得5ksps的RMS值(=1Msps / 200)。
    DMA允许将1Msps 14位ADC数据同时存储在内部SRAM中。
    因此,我可以使用连续以921.6kbps运行的UART以5ksps的速度发送实时RMS值。

    我曾经在PC上执行浮点数据处理。
    通过在MSP432上的FPU内执行浮点数据处理,
    UART速度瓶颈现已移除。
    对于调试,20毫秒分层原始波形数据已足够。

    非常感谢您的帮助!