#ifndef __BSP_SPI_SOFT_H #define __BSP_SPI_SOFT_H #include "stm32f4xx_hal.h" #include "main.h" // #include "sys.h" #define CS_GPIO_PORT GPIOF #define CS_PIN GPIO_PIN_6 #define SCK_GPIO_PORT GPIOF #define SCK_PIN GPIO_PIN_7 #define MISO_GPIO_PORT GPIOF #define MISO_PIN GPIO_PIN_8 #define MOSI_GPIO_PORT GPIOF #define MOSI_PIN GPIO_PIN_9 // FPF6 ------> SPI5_CS // PF7 ------> SPI5_SCK // PF8 ------> SPI5_MISO // PF9 ------> SPI5_MOSI typedef enum { SPI_OK = 0x00, //IIC工作正常 SPI_WAIT_ACK_ERR = 0x01, //slave设备返回ACK错误 SPI_WRITE_ERR = 0x02, //向slave设备写入错误 SPI_READ_ERR = 0x04 //从slave设备读取错误 } SPI_STATUS; typedef struct { GPIO_TypeDef *cs_port; uint16_t cs_pin; GPIO_TypeDef *sclk_port; uint16_t sclk_pin; GPIO_TypeDef *miso_port; uint16_t miso_pin; GPIO_TypeDef *mosi_port; uint16_t mosi_pin; uint8_t sda_pin_num; //定义延时,以适应不同器件对速率的不同要求,具体值要在调试中确定 uint8_t addr; //器件地址 uint32_t delaytick; //定义延时,以适应不同器件对速率的不同要求,具体值要在调试中确定 uint8_t CPOL; //时钟极性,为0:空闲状态时,SCK保持低电平; 1: 表示在空闲状态时,SCK保持高电平。 uint8_t CPHA; // 时钟相位, 0:从第一个时钟边沿开始; 1:第二个时钟边沿开始。 uint16_t period ; //确定速度为大于0K小于等于400K的整数,默认为100K,>period=500/speed speed时钟频率 }SPI_SOFT_TypeDef; #define CS_H HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_SET) #define CS_L HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_RESET) #define SCLK_H HAL_GPIO_WritePin(GPIOC, GPIO_PIN_4, GPIO_PIN_SET) #define SCLK_L HAL_GPIO_WritePin(GPIOC, GPIO_PIN_4, GPIO_PIN_RESET) #define SDI_H HAL_GPIO_WritePin(GPIOC, GPIO_PIN_1, GPIO_PIN_SET) #define SDI_L HAL_GPIO_WritePin(GPIOC, GPIO_PIN_1, GPIO_PIN_RESET) #define SDO_R HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_1) #define SUCCESS 0 #define FAILURE 1 void SPI_Init(const SPI_SOFT_TypeDef *pSoftSPI); uint8_t WriteReg(const SPI_SOFT_TypeDef *pSoftSPI, uint32_t d); uint8_t ReadReg(const SPI_SOFT_TypeDef *pSoftSPI, uint32_t d); void SPI_Write_OneByte(const SPI_SOFT_TypeDef *pSoftSPI, uint8_t u8_writedata); uint8_t SPI_Read_OneByte(const SPI_SOFT_TypeDef *pSoftSPI); uint8_t SPI_ReadWriteByte(const SPI_SOFT_TypeDef *pSoftSPI, uint8_t TxData); uint32_t SPI_FLASH_ReadDeviceID( const SPI_SOFT_TypeDef *pSoftSPI); #endif /* 时序 CPOL CPHA 0 0 00 第一个 上升沿 0 1 01 第一个 下降沿 1 0 10 第二个 下降沿 1 1 11 第二个 上升沿 00 常用, 前置SCL拉低, 过程 SDA 输出, SCLK 拉高 延时 拉低 00 : // T____ // ______/ \______ 01 // ____T // ______/ \______ 10 : // * ____T _____ // \_______/ 11 // * ____ T_____ // \_______/ 00 空闲状态:片选信号SS为高,SCK输出低电平。 开始信号:片选信号SS变低,SCK输出低电平。 结束信号:片选信号SS变高,SCK输出低电平。 读取:SCK由低变高之后,读取MISO引脚信号。 写入:SCK输出低电平,MOSI引脚输出相应的电平,然后SCK输出高电平。 MISO:Master input slave output 主机输入,从机输出(数据来自从机); MOSI:Master output slave input 主机输出,从机输入(数据来自主机); MISO也可以是SIMO,DOUT,DO,SDO或SO(在主机端); MOSI也可以是SOMI,DIN,DI,SDI或SI(在主机端); SPI_SOFT_TypeDef sSPI ={ GPIOF, GPIO_PIN_6,GPIOF, GPIO_PIN_7,GPIOF, GPIO_PIN_8,GPIOF, GPIO_PIN_9, 6,0,1, } ; SPI_Init(&sSPI); uint8_t txData[4] = {0x9F, 0x00, 0x00, 0x00}; uint32_t hhhh =2667577344; uint8_t rxData[4] = {0}; // uint8_t rrr; // rrr = SPI_ReadWriteByte(&sSPI, txData[0]); // log_i("rrrr: 0x%02X\n", rrr); // 19 // delay_us(1); // rrr = SPI_ReadWriteByte(&sSPI, 0xFF); // log_i("rrrr: 0x%02X\n", rrr); // 19 // delay_us(1); // rrr = SPI_ReadWriteByte(&sSPI, 0xFF); // log_i("rrrr: 0x%02X\n", rrr); // 19 // delay_us(1); // rrr = SPI_ReadWriteByte(&sSPI, 0xFF); // log_i("rrrr: 0x%02X\n", rrr); // 19 // delay_us(1); hhhh = SPI_FLASH_ReadDeviceID(&sSPI); */