查看: 2696|回复: 1

[原创] [经验分享]spi用法三连之两种基本用法

[复制链接]

该用户从未签到

656

主题

6312

帖子

0

超级版主

Rank: 8Rank: 8

积分
19933
最后登录
2024-4-19
发表于 2020-7-16 09:30:48 | 显示全部楼层 |阅读模式
Spi双方通信测试。
Spi配置为片选低电平有效,在时钟第一个上升沿获取数据,在第一个下降沿改变数据。SOUT空闲时候呈现高电平,SIN呈现低电平。

轮询法:
主机轮询:
1、首先配置SIN,SOUT,SCK,PCS以及使能对应时钟
CLOCK_EnableClock(kCLOCK_PortD);
PORT_SetPinMux(PORTD, PIN0_IDX, kPORT_MuxAlt2);/* PORTD0 (pin93)  SPI0_PCS0 */
  PORT_SetPinMux(PORTD,PIN1_IDX, kPORT_MuxAlt2); /* PORTD1 (pin 94) SPI0_SCK */
  PORT_SetPinMux(PORTD, PIN2_IDX,kPORT_MuxAlt2); /* PORTD2 (pin 95) SPI0_SOUT */
  PORT_SetPinMux(PORTD, PIN3_IDX,kPORT_MuxAlt2); /* PORTD3 (pin 96) SPI0_SIN */

2、配置主机模式属性
       使用CTAR0,波特率为500kHz,每帧有8位,时钟极性为高电平有效,时钟相位为第一个边沿。传输高位在前,片选到时钟延迟时间2000ns,最后的时钟到片选延迟时间2000ns,传输间延迟时间2000ns,pcs0作为片选引脚,片选有效信号为低电平,禁用连续时钟,禁用接收fifo覆写,禁用改变时间格式,采样点为第一个边沿采样。
    masterConfig.whichCtar= kDSPI_Ctar0;
    masterConfig.ctarConfig.baudRate=TRANSFER_BAUDRATE;
    masterConfig.ctarConfig.bitsPerFrame= 8U;
    masterConfig.ctarConfig.cpol=kDSPI_ClockPolarityActiveHigh;
    masterConfig.ctarConfig.cpha=kDSPI_ClockPhaseFirstEdge;
   masterConfig.ctarConfig.direction= kDSPI_MsbFirst;
    masterConfig.ctarConfig.pcsToSckDelayInNanoSec=2000
   masterConfig.ctarConfig.lastSckToPcsDelayInNanoSec=2000
   masterConfig.ctarConfig.betweenTransferDelayInNanoSec=2000
    masterConfig.whichPcs= EXAMPLE_DSPI_MASTER_PCS_FOR_INIT;
   masterConfig.pcsActiveHighOrLow = kDSPI_PcsActiveLow;
   masterConfig.enableContinuousSCK      = false;
    masterConfig.enableRxFifoOverWrite      = false;
   masterConfig.enableModifiedTimingFormat = false;
   masterConfig.samplePoint               = kDSPI_SckToSin0Clock;
3、主机初始化,
DSPI_MasterInit(EXAMPLE_DSPI_MASTER_BASEADDR,&masterConfig, srcClock_Hz);
4发送数据配置:
       将发送数据指针传递,设置传输字节大小。
masterXfer.txData = masterTxData;
masterXfer.rxData = NULL;
masterXfer.dataSize = TRANSFER_SIZE;
masterXfer.configFlags = kDSPI_MasterCtar0| EXAMPLE_DSPI_MASTER_PCS_FOR_TRANSFER | kDSPI_MasterPcsContinuous;
5、发送数据
       DSPI_MasterTransferBlocking(EXAMPLE_DSPI_MASTER_BASEADDR,&masterXfer);

从机中断:
1、 设置从机传输属性,从机只能使用CTAR0,每帧8位,时钟极性有效电平位高电平,时钟相位是第一个边沿。禁用连续时钟,禁用接收fifo覆写,禁用可变时间格式,采样点位第一个边沿。
slaveConfig.whichCtar                  = kDSPI_Ctar0;
slaveConfig.ctarConfig.bitsPerFrame    = 8U;
slaveConfig.ctarConfig.cpol            = kDSPI_ClockPolarityActiveHigh;
slaveConfig.ctarConfig.cpha            = kDSPI_ClockPhaseFirstEdge;
slaveConfig.enableContinuousSCK        = false;
slaveConfig.enableRxFifoOverWrite      = false;
slaveConfig.enableModifiedTimingFormat= false;
   slaveConfig.samplePoint               = kDSPI_SckToSin0Clock;
2、 从机初始化DSPI_SlaveInit(EXAMPLE_DSPI_SLAVE_BASEADDR, &slaveConfig);
3、 设置从机传输句柄,定义从机回调函数
DSPI_SlaveTransferCreateHandle(EXAMPLE_DSPI_SLAVE_BASEADDR,&g_s_handle, DSPI_SlaveUserCallback, NULL);
4、 设置传输配置(接收),传递接收地址,数据大小
slaveXfer.txData      = NULL;
       slaveXfer.rxData      = slaveRxData;
       slaveXfer.dataSize    =TRANSFER_SIZE;
       slaveXfer.configFlags = kDSPI_SlaveCtar0;
DSPI_SlaveTransferNonBlocking(EXAMPLE_DSPI_SLAVE_BASEADDR,&g_s_handle,&slaveXfer);接收数据。

EDMA:
主机EDMA:
1、初始化DMAMUX,使能SPI0接收和发送通道
DMAMUX_Init(EXAMPLE_DSPI_MASTER_DMA_MUX_BASEADDR);
DMAMUX_SetSource(EXAMPLE_DSPI_MASTER_DMA_MUX_BASEADDR,masterRxChannel,
                    (uint8_t)EXAMPLE_DSPI_MASTER_DMA_RX_REQUEST_SOURCE);
DMAMUX_EnableChannel(EXAMPLE_DSPI_MASTER_DMA_MUX_BASEADDR,masterRxChannel);
DMAMUX_SetSource(EXAMPLE_DSPI_MASTER_DMA_MUX_BASEADDR,
                    (uint8_t)EXAMPLE_DSPI_MASTER_DMA_TX_REQUEST_SOURCE);
DMAMUX_EnableChannel(EXAMPLE_DSPI_MASTER_DMA_MUX_BASEADDR,masterTxChannel);

2、EDMA初始化
EDMA_GetDefaultConfig(&userConfig);
EDMA_Init(EXAMPLE_DSPI_MASTER_DMA_BASEADDR,&userConfig);

3、配置SPI,初始化。使用CTAR0,波特率为500kHz,每帧有8位,时钟极性为高电平有效,时钟相位为第一个边沿。传输高位在前,片选到时钟延迟时间2000ns,最后的时钟到片选延迟时间2000ns,传输间延迟时间2000ns,pcs0作为片选引脚,片选有效信号为低电平,禁用连续时钟,禁用接收fifo覆写,禁用改变时间格式,采样点为第一个边沿采样。
masterConfig.whichCtar                                = kDSPI_Ctar0;
masterConfig.ctarConfig.baudRate                      = TRANSFER_BAUDRATE;
masterConfig.ctarConfig.bitsPerFrame  = 8;
masterConfig.ctarConfig.cpol  = kDSPI_ClockPolarityActiveHigh;
masterConfig.ctarConfig.cpha  = kDSPI_ClockPhaseFirstEdge;
masterConfig.ctarConfig.direction  = kDSPI_MsbFirst;
masterConfig.ctarConfig.pcsToSckDelayInNanoSec=1000000000U / TRANSFER_BAUDRATE;
masterConfig.ctarConfig.lastSckToPcsDelayInNanoSec=1000000000U/TRANSFER_BAUDRATE;
masterConfig.ctarConfig.betweenTransferDelayInNanoSec=1000000000U/TRANSFER_BAUDRATE;
masterConfig.whichPcs           = EXAMPLE_DSPI_MASTER_PCS_FOR_INIT;
masterConfig.pcsActiveHighOrLow =kDSPI_PcsActiveLow;
masterConfig.enableContinuousSCK        = false;
masterConfig.enableRxFifoOverWrite      = false;
masterConfig.enableModifiedTimingFormat =false;
masterConfig.samplePoint                = kDSPI_SckToSin0Clock;
srcClock_Hz = DSPI_MASTER_CLK_FREQ;
DSPI_MasterInit(EXAMPLE_DSPI_MASTER_BASEADDR,&masterConfig, srcClock_Hz);

5、 EDMA创建接收,发送,中间媒介句柄,初始化句柄,传入回调函数。
EDMA_CreateHandle(&(dspiEdmaMasterRxRegToRxDataHandle),EXAMPLE_DSPI_MASTER_DMA_BASEADDR, masterRxChannel);
EDMA_CreateHandle(&(dspiEdmaMasterTxDataToIntermediaryHandle),
EXAMPLE_DSPI_MASTER_DMA_BASEADDR,masterIntermediaryChannel);
EDMA_CreateHandle(&(dspiEdmaMasterIntermediaryToTxRegHandle),EXAMPLE_DSPI_MASTER_DMA_BASEADDR, masterTxChannel);
DSPI_MasterTransferCreateHandleEDMA(EXAMPLE_DSPI_MASTER_BASEADDR,&g_dspi_edma_m_handle,DSPI_MasterUserCallback,NULL,&dspiEdmaMasterRxRegToRxDataHandle,
&dspiEdmaMasterTxDataToIntermediaryHandle,
&dspiEdmaMasterIntermediaryToTxRegHandle);

6、发送前,配置发送属性
masterXfer.txData      = masterTxData;
masterXfer.rxData      = NULL;
masterXfer.dataSize    = TRANSFER_SIZE;
masterXfer.configFlags = kDSPI_MasterCtar0| EXAMPLE_DSPI_MASTER_PCS_FOR_TRANSFER | kDSPI_MasterPcsContinuous;
DSPI_MasterTransferEDMA(EXAMPLE_DSPI_MASTER_BASEADDR,&g_dspi_edma_m_handle, &masterXfer)

7、 接收前,配置接收属性
isTransferCompleted    = false;
masterXfer.txData      = NULL;
masterXfer.rxData      = masterRxData;
masterXfer.dataSize    = TRANSFER_SIZE;
masterXfer.configFlags = kDSPI_MasterCtar0| EXAMPLE_DSPI_MASTER_PCS_FOR_TRANSFER | kDSPI_MasterPcsContinuous;
DSPI_MasterTransferEDMA(EXAMPLE_DSPI_MASTER_BASEADDR,&g_dspi_edma_m_handle, &masterXfer)

从机EDMA:
1、 初始化DMAMUX,使能SPI0接收和发送通道
DMAMUX_Init(EXAMPLE_DSPI_SLAVE_DMA_MUX_BASEADDR);
DMAMUX_SetSource(EXAMPLE_DSPI_SLAVE_DMA_MUX_BASEADDR,slaveRxChannel,
                    (uint8_t)EXAMPLE_DSPI_SLAVE_DMA_RX_REQUEST_SOURCE);
DMAMUX_EnableChannel(EXAMPLE_DSPI_SLAVE_DMA_MUX_BASEADDR,slaveRxChannel);
DMAMUX_SetSource(EXAMPLE_DSPI_SLAVE_DMA_MUX_BASEADDR,slaveTxChannel,
                    (uint8_t)EXAMPLE_DSPI_SLAVE_DMA_TX_REQUEST_SOURCE);
DMAMUX_EnableChannel(EXAMPLE_DSPI_SLAVE_DMA_MUX_BASEADDR,slaveTxChannel);
2、初始化EDMA
EDMA_GetDefaultConfig(&userConfig);
EDMA_Init(EXAMPLE_DSPI_SLAVE_DMA_BASEADDR,&userConfig);
3、 配置从机SPI属性,初始化从机。设置从机传输属性,从机只能使用CTAR0,每帧8位时钟极性有效电平位高电平,时钟相位是第一个边沿。禁用连续时钟,禁用接收fifo覆写,禁用可变时间格式,采样点位第一个边沿。
slaveConfig.whichCtar                  = kDSPI_Ctar0;
slaveConfig.ctarConfig.bitsPerFrame    = 8U;
slaveConfig.ctarConfig.cpol            = kDSPI_ClockPolarityActiveHigh;
slaveConfig.ctarConfig.cpha            = kDSPI_ClockPhaseFirstEdge;
slaveConfig.enableContinuousSCK        = false;
slaveConfig.enableRxFifoOverWrite      = false;
slaveConfig.enableModifiedTimingFormat =false;
slaveConfig.samplePoint                = kDSPI_SckToSin0Clock;
DSPI_SlaveInit(EXAMPLE_DSPI_SLAVE_BASEADDR,&slaveConfig);
4、 创建EDMA收发句柄,初始化句柄
EDMA_CreateHandle(&(dspiEdmaSlaveRxRegToRxDataHandle),EXAMPLE_DSPI_SLAVE_DMA_BASEADDR, slaveRxChannel);
EDMA_CreateHandle(&(dspiEdmaSlaveTxDataToTxRegHandle),EXAMPLE_DSPI_SLAVE_DMA_BASEADDR, slaveTxChannel);
DSPI_SlaveTransferCreateHandleEDMA(EXAMPLE_DSPI_SLAVE_BASEADDR,&g_dspi_edma_s_handle, DSPI_SlaveUserCallback, NULL,
&dspiEdmaSlaveRxRegToRxDataHandle,&dspiEdmaSlaveTxDataToTxRegHandle);
5、 配置接收属性,调用接收函数
slaveXfer.txData      = NULL;
slaveXfer.rxData      = slaveRxData;
slaveXfer.dataSize    = TRANSFER_SIZE;
slaveXfer.configFlags = kDSPI_SlaveCtar0;
DSPI_SlaveTransferEDMA(EXAMPLE_DSPI_SLAVE_BASEADDR,&g_dspi_edma_s_handle, &slaveXfer))
6、 配置发送属性,调用发送函数
slaveXfer.txData      = slaveRxData;
slaveXfer.rxData      = NULL;
slaveXfer.dataSize    = TRANSFER_SIZE;
slaveXfer.configFlags = kDSPI_SlaveCtar0;
DSPI_SlaveTransferEDMA(EXAMPLE_DSPI_SLAVE_BASEADDR,&g_dspi_edma_s_handle, &slaveXfer))

主机发送数据:
1.png
                              

从机将收到数据发送
2.png



回复

使用道具 举报

  • TA的每日心情
    奋斗
    2021-6-30 17:11
  • 签到天数: 3 天

    [LV.2]偶尔看看I

    5

    主题

    426

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    1097
    最后登录
    2024-4-1
    发表于 2020-7-17 15:14:17 | 显示全部楼层
    学习了
    加油
    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2024-4-19 17:36 , Processed in 0.107139 second(s), 21 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表