外贸网站源代码下载,深圳网站优化推广方案,怎么建设公益网站,深圳中装建设公司文章目录 前言CubeMX配置SPI驱动实现spi_driver.hspi_driver.c 额外的接口补充 前言
SPI#xff0c;想了很久没想明白其DMA或者IT比较好用的方法#xff0c;可能之后也会写一个 我个人使用场景大数据流不多#xff0c;如果是大批量数据交互自然是DMA更好用#xff0c;但考… 文章目录 前言CubeMX配置SPI驱动实现spi_driver.hspi_driver.c 额外的接口补充 前言
SPI想了很久没想明白其DMA或者IT比较好用的方法可能之后也会写一个 我个人使用场景大数据流不多如果是大批量数据交互自然是DMA更好用但考虑到多从机通讯感觉还是阻塞式更灵活一些毕竟大部分通讯片选延时1us但一个数据传进去也就不到1us。 以后有时间改个DMA或者IT升级版
spix new_SPI_Driver(SPIx_Port, CS_GPIOx, CS_Pin);//完成初始化
RxData spix-tr16(spix, TxData);//数据传递
spix-cs_l(spix);;//CS拉低
spix-cs_h(spix);;//CS拉搞SPI的多从机任务可以自己挂CS并在上层实现数据流读取 上层实现可以参考工程文件参考——ADS1118多从机驱动base on spi_driver 需要8位传输的可以自己改 CubeMX配置
开了就能用注意匹配下数据长度8bit还是16bit。MSB是先高位还是先低位以及CPOL与CPHA的设置。NSS硬件片选没什么用包括从机的NSS感觉不如外部触发中断。 CS直接开GPIO根据自己从机数量需求设计
SPI驱动实现
spi_driver.h
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __SPI_DRIVER_H
#define __SPI_DRIVER_H
/*
File name: __SPI_DRIVER_H
Author: Mr.NoFish
*/#ifdef __cplusplus
extern C {
#endif/* Includes ------------------------------------------------------------------*/#include main.h#include spi.htypedef struct SPI_Driver_ SPI_Driver;typedef void (*SPIfptrCS_H)(SPI_Driver*);
typedef void (*SPIfptrCS_L)(SPI_Driver*);
typedef uint16_t (*SPIfptrTranRecv16)(SPI_Driver*, uint16_t);
typedef void (*SPIfptrTran16)(SPI_Driver*, uint16_t);struct SPI_Driver_
{SPI_TypeDef* SPIx;GPIO_TypeDef* CS_GPIOx;uint32_t CS_Pin;uint16_t TxData;uint16_t RxData;SPIfptrCS_H cs_h;SPIfptrCS_L cs_l;SPIfptrTranRecv16 tr16;SPIfptrTran16 tran16;
};SPI_Driver* new_SPI_Driver(SPI_TypeDef* SPIx_Port, GPIO_TypeDef* CS_GPIOx, uint32_t CS_Pin);void spi_chip_select_set(SPI_Driver* const pSPIObj);
void spi_chip_select_reset(SPI_Driver* const pSPIObj);
void spi_transmit_16(SPI_Driver* const pSPIObj, uint16_t TxData);
uint16_t spi_transmit_receive_16(SPI_Driver* const pSPIObj, uint16_t TxData);
#endif
spi_driver.c
/*
File name: __SPI_DRIVER_C
Author: Mr.NoFish
*/
#include spi_driver.hSPI_Driver* new_SPI_Driver(SPI_TypeDef* SPIx_Port, GPIO_TypeDef* CS_GPIOx, uint32_t CS_Pin)
{SPI_Driver* pObj NULL;uint8_t i 0;pObj (SPI_Driver*)malloc(sizeof(SPI_Driver));if (pObj NULL){printf(WARN: SPI_Driver initialization failed.\r\n);return NULL;}pObj-SPIx SPIx_Port;pObj-CS_GPIOx CS_GPIOx;pObj-CS_Pin CS_Pin;pObj-cs_h spi_chip_select_set;pObj-cs_l spi_chip_select_reset;pObj-tran16 spi_transmit_16;pObj-tr16 spi_transmit_receive_16;pObj-cs_h(pObj);//LL_SPI_Enable(pObj-SPIx);printf(INFO: SPI_Driver initialization succeeded.\r\n);return pObj;
}void spi_chip_select_set(SPI_Driver* const pSPIObj)
{LL_GPIO_SetOutputPin(pSPIObj-CS_GPIOx, pSPIObj-CS_Pin);
}void spi_chip_select_reset(SPI_Driver* const pSPIObj)
{LL_GPIO_ResetOutputPin(pSPIObj-CS_GPIOx, pSPIObj-CS_Pin);
}void spi_transmit_16(SPI_Driver* const pSPIObj, uint16_t TxData)
{ pSPIObj-TxData TxData;while(!LL_SPI_IsActiveFlag_TXE(pSPIObj-SPIx));LL_SPI_TransmitData16(pSPIObj-SPIx, pSPIObj-TxData);
}uint16_t spi_transmit_receive_16(SPI_Driver* const pSPIObj, uint16_t TxData)
{ pSPIObj-TxData TxData;while(!LL_SPI_IsActiveFlag_TXE(pSPIObj-SPIx));LL_SPI_TransmitData16(pSPIObj-SPIx, pSPIObj-TxData);while(LL_SPI_IsActiveFlag_BSY(pSPIObj-SPIx));while(!LL_SPI_IsActiveFlag_RXNE(pSPIObj-SPIx));pSPIObj-RxData LL_SPI_ReceiveData16(pSPIObj-SPIx);return pSPIObj-RxData;
}额外的接口补充
LL_SPI_Enable(SPIx);别忘记自己加一下但留意别在初始化之前Enable。 SPI每个设备的实现方式都不同所以需要根据数据手册进一步实现上层设计。 这个库设计用来提供给多从机控制一些范例的应用可以参考如下文章。 工程文件参考——ADS1118多从机驱动base on spi_driver