Procházet zdrojové kódy

1.提交新增SPI GPIO模拟驱动,SPI HAL库驱动部分文件

libo před 2 roky
rodič
revize
96cbd62677
5 změnil soubory, kde provedl 369 přidání a 0 odebrání
  1. 213 0
      dev/dev_soft_spi.c
  2. 46 0
      dev/dev_soft_spi.h
  3. 28 0
      dev/dev_spi_conf.h
  4. 70 0
      dev/dev_spi_w25qxx.c
  5. 12 0
      dev/dev_spi_w25qxx.h

+ 213 - 0
dev/dev_soft_spi.c

@@ -0,0 +1,213 @@
+/**
+ * @file    softspi.c
+ * @author  Myth
+ * @version 0.2
+ * @date    2021.10.12
+ * @brief   STM32 SoftSPI Library
+ */
+
+#include "dev_soft_spi.h"
+
+#define SCLK_Set HAL_GPIO_WritePin(SoftSPIx->SCLK_GPIO, SoftSPIx->SCLK_Pin, GPIO_PIN_SET)
+#define SCLK_Clr HAL_GPIO_WritePin(SoftSPIx->SCLK_GPIO, SoftSPIx->SCLK_Pin, GPIO_PIN_RESET)
+
+#define MOSI_Set HAL_GPIO_WritePin(SoftSPIx->MOSI_GPIO, SoftSPIx->MOSI_Pin, GPIO_PIN_SET)
+#define MOSI_Clr HAL_GPIO_WritePin(SoftSPIx->MOSI_GPIO, SoftSPIx->MOSI_Pin, GPIO_PIN_RESET)
+
+#define MISO_Read HAL_GPIO_ReadPin(SoftSPIx->MISO_GPIO, SoftSPIx->MISO_Pin)
+
+#define SS_Set HAL_GPIO_WritePin(SoftSPIx->SS_GPIO, SoftSPIx->SS_Pin, GPIO_PIN_SET)
+#define SS_Clr HAL_GPIO_WritePin(SoftSPIx->SS_GPIO, SoftSPIx->SS_Pin, GPIO_PIN_RESET)
+
+#define Delay SoftSPI_Delay_us(SoftSPIx->Delay_Time)
+
+uint8_t SoftSPI_GPIOx_Pin_Init(GPIO_TypeDef *GPIOx, uint32_t Pin, uint32_t Mode, uint32_t Pull);
+
+HAL_StatusTypeDef SoftSPI_Init(SoftSPI_TypeDef *SoftSPIx)
+{
+    SoftSPIx->SCLK_GPIO = SoftSPIx->SCLK_GPIO;
+    SoftSPIx->SCLK_Pin = SoftSPIx->SCLK_Pin;
+
+    if (!SoftSPI_GPIOx_Pin_Init(SoftSPIx->SCLK_GPIO, SoftSPIx->SCLK_Pin, GPIO_MODE_OUTPUT_PP, GPIO_NOPULL))
+        return HAL_ERROR;
+
+    SoftSPIx->MOSI_GPIO = SoftSPIx->MOSI_GPIO;
+    SoftSPIx->MOSI_Pin = SoftSPIx->MOSI_Pin;
+
+    if (!SoftSPI_GPIOx_Pin_Init(SoftSPIx->MOSI_GPIO, SoftSPIx->MOSI_Pin, GPIO_MODE_OUTPUT_PP, GPIO_NOPULL))
+        return HAL_ERROR;
+
+    SoftSPIx->MISO_GPIO = SoftSPIx->MISO_GPIO;
+    SoftSPIx->MISO_Pin = SoftSPIx->MISO_Pin;
+
+    if (!SoftSPI_GPIOx_Pin_Init(SoftSPIx->MISO_GPIO, SoftSPIx->MISO_Pin, GPIO_MODE_INPUT, GPIO_NOPULL))
+        return HAL_ERROR;
+
+    SoftSPIx->SS_GPIO = SoftSPIx->SS_GPIO;
+    SoftSPIx->SS_Pin = SoftSPIx->SS_Pin;
+
+    if (!SoftSPI_GPIOx_Pin_Init(SoftSPIx->SS_GPIO, SoftSPIx->SS_Pin, GPIO_MODE_OUTPUT_PP, GPIO_NOPULL))
+        return HAL_ERROR;
+		
+		if(SoftSPIx->WP_GPIO != NULL)
+		{
+			SoftSPIx->WP_GPIO = SoftSPIx->WP_GPIO;
+			SoftSPIx->WP_Pin = SoftSPIx->WP_Pin;
+
+			//if (!SoftSPI_GPIOx_Pin_Init(SoftSPIx->WP_GPIO, SoftSPIx->WP_Pin, GPIO_MODE_INPUT, GPIO_NOPULL))
+			if (!SoftSPI_GPIOx_Pin_Init(SoftSPIx->WP_GPIO, SoftSPIx->WP_Pin, GPIO_MODE_OUTPUT_PP, GPIO_PULLUP))
+					return HAL_ERROR;
+			
+			HAL_GPIO_WritePin(SoftSPIx->WP_GPIO, SoftSPIx->WP_Pin, GPIO_PIN_SET);
+						
+		}
+		
+
+
+    SoftSPIx->Delay_Time = SoftSPIx->Delay_Time;
+
+    return HAL_OK;
+}
+
+void SoftSPI_SetSS(SoftSPI_TypeDef *SoftSPIx)
+{
+    SS_Set;
+}
+
+void SoftSPI_ClrSS(SoftSPI_TypeDef *SoftSPIx)
+{
+    SS_Clr;
+}
+
+uint8_t SoftSPI_WriteRead(SoftSPI_TypeDef *SoftSPIx, uint8_t byte)
+{
+    uint8_t data = 0;
+    uint8_t i;
+
+    for (i = 0; i < 8; i++)
+    {
+        SCLK_Clr;
+        Delay;
+
+        if (byte & 0x80)
+            MOSI_Set;
+        else
+            MOSI_Clr;
+
+        Delay;
+
+        byte <<= 1;
+        SCLK_Set;
+        Delay;
+
+        data <<= 1;
+        if (MISO_Read == GPIO_PIN_SET)
+            data |= 0x01;
+
+        Delay;
+    }
+
+    return data;
+}
+
+void SoftSPI_WriteReadBuff(SoftSPI_TypeDef *SoftSPIx, uint8_t *pWrite, uint8_t *pRead, uint32_t len)
+{
+    uint8_t data;
+    uint8_t byte;
+    uint8_t i, j;
+
+    for (j = 0; j < len; j++)
+    {
+        data = 0;
+        byte = pWrite[j];
+
+        for (i = 0; i < 8; i++)
+        {
+            SCLK_Clr;
+            Delay;
+
+            if (byte & 0x80)
+                MOSI_Set;
+            else
+                MOSI_Clr;
+
+            Delay;
+
+            byte <<= 1;
+            SCLK_Set;
+            Delay;
+
+            data <<= 1;
+            if (MISO_Read == GPIO_PIN_SET)
+                data |= 0x01;
+
+            Delay;
+        }
+
+        pRead[j] = data;
+    }
+
+}
+
+uint8_t SoftSPI_GPIOx_Pin_Init(GPIO_TypeDef *GPIOx, uint32_t Pin, uint32_t Mode, uint32_t Pull)
+{
+    switch ((uint32_t)(GPIOx))
+    {
+    case (uint32_t)GPIOA:
+    {
+        GPIO_InitTypeDef GPIO_Initure;
+        __HAL_RCC_GPIOA_CLK_ENABLE();
+
+        GPIO_Initure.Pin = Pin;
+        GPIO_Initure.Mode = Mode;
+        GPIO_Initure.Pull = Pull;
+        GPIO_Initure.Speed = GPIO_SPEED_HIGH;
+        HAL_GPIO_Init(GPIOA, &GPIO_Initure);
+    }
+    break;
+
+    case (uint32_t)GPIOB:
+    {
+        GPIO_InitTypeDef GPIO_Initure;
+        __HAL_RCC_GPIOB_CLK_ENABLE();
+
+        GPIO_Initure.Pin = Pin;
+        GPIO_Initure.Mode = Mode;
+        GPIO_Initure.Pull = Pull;
+        GPIO_Initure.Speed = GPIO_SPEED_HIGH;
+        HAL_GPIO_Init(GPIOB, &GPIO_Initure);
+    }
+    break;
+
+    case (uint32_t)GPIOC:
+    {
+        GPIO_InitTypeDef GPIO_Initure;
+        __HAL_RCC_GPIOC_CLK_ENABLE();
+
+        GPIO_Initure.Pin = Pin;
+        GPIO_Initure.Mode = Mode;
+        GPIO_Initure.Pull = Pull;
+        GPIO_Initure.Speed = GPIO_SPEED_HIGH;
+        HAL_GPIO_Init(GPIOC, &GPIO_Initure);
+    }
+    break;
+
+    case (uint32_t)GPIOD:
+    {
+        GPIO_InitTypeDef GPIO_Initure;
+        __HAL_RCC_GPIOD_CLK_ENABLE();
+
+        GPIO_Initure.Pin = Pin;
+        GPIO_Initure.Mode = Mode;
+        GPIO_Initure.Pull = Pull;
+        GPIO_Initure.Speed = GPIO_SPEED_HIGH;
+        HAL_GPIO_Init(GPIOD, &GPIO_Initure);
+    }
+    break;
+
+    default:
+        return 0;
+    }
+
+    return 1;
+}

+ 46 - 0
dev/dev_soft_spi.h

@@ -0,0 +1,46 @@
+/**
+ * @file    softspi.h
+ * @author  Myth
+ * @version 0.2
+ * @date    2021.10.12
+ * @brief   STM32 SoftSPI Library
+ */
+
+#ifndef DEV_SOFT_SPI_H
+#define DEV_SOFT_SPI_H
+
+#include "dev_spi_conf.h"
+
+/**
+ * @brief  SoftSPI Structure definition
+ */
+typedef struct
+{
+    GPIO_TypeDef *SCLK_GPIO;
+    uint32_t SCLK_Pin;
+
+    GPIO_TypeDef *MOSI_GPIO;
+    uint32_t MOSI_Pin;
+
+    GPIO_TypeDef *MISO_GPIO;
+    uint32_t MISO_Pin;
+
+    GPIO_TypeDef *SS_GPIO;
+    uint32_t SS_Pin;
+	
+	  GPIO_TypeDef *WP_GPIO;
+    uint32_t WP_Pin;
+
+    uint32_t Delay_Time;
+} SoftSPI_TypeDef;
+
+HAL_StatusTypeDef SoftSPI_Init(SoftSPI_TypeDef *SoftSPIx);
+
+void SoftSPI_SetSS(SoftSPI_TypeDef *SoftSPIx);
+void SoftSPI_ClrSS(SoftSPI_TypeDef *SoftSPIx);
+
+uint8_t SoftSPI_WriteRead(SoftSPI_TypeDef *SoftSPIx, uint8_t byte);
+
+void SoftSPI_WriteReadBuff(SoftSPI_TypeDef *SoftSPIx, uint8_t *pWrite, uint8_t *pRead, uint32_t len);
+
+#endif

+ 28 - 0
dev/dev_spi_conf.h

@@ -0,0 +1,28 @@
+/**
+ * @file    softspi_conf.h
+ * @author  Myth
+ * @version 0.2
+ * @date    2021.10.12
+ * @brief   STM32 SoftSPI Library Config File
+ */
+
+#ifndef DEV_SPI_CONF_H
+#define DEV_SPI_CONF_H
+
+// Set your HAL Library here.
+
+#include "stm32f7xx_hal.h"
+
+//#define USE_OBJ_SOFT_W25QXX
+
+#ifdef USE_OBJ_SOFT_W25QXX
+#undef USE_OBJ_HAL_W25QXX
+#else
+#define USE_OBJ_HAL_W25QXX
+#endif
+
+#include "sys_delay.h"
+// Set your owm Delay_us function here.
+#define SoftSPI_Delay_us(__time__) delay_us(__time__)
+
+#endif

+ 70 - 0
dev/dev_spi_w25qxx.c

@@ -0,0 +1,70 @@
+#include "dev_spi_w25qxx.h"
+
+SPI_HandleTypeDef SPI_W25Q_Handler;  //SPI句柄
+
+//以下是SPI模块的初始化代码,配置成主机模式 						  
+//SPI口初始化
+//这里针是对SPI2的初始化
+void SPI_W25Q_Init(void)
+{
+    SPI_W25Q_Handler.Instance=SPI2;                         //SP5
+    SPI_W25Q_Handler.Init.Mode=SPI_MODE_MASTER;             //设置SPI工作模式,设置为主模式
+    SPI_W25Q_Handler.Init.Direction=SPI_DIRECTION_2LINES;   //设置SPI单向或者双向的数据模式:SPI设置为双线模式
+    SPI_W25Q_Handler.Init.DataSize=SPI_DATASIZE_8BIT;       //设置SPI的数据大小:SPI发送接收8位帧结构
+    SPI_W25Q_Handler.Init.CLKPolarity=SPI_POLARITY_HIGH;    //串行同步时钟的空闲状态为高电平
+    SPI_W25Q_Handler.Init.CLKPhase=SPI_PHASE_2EDGE;         //串行同步时钟的第二个跳变沿(上升或下降)数据被采样
+    SPI_W25Q_Handler.Init.NSS=SPI_NSS_SOFT;                 //NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制
+    SPI_W25Q_Handler.Init.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_256;//定义波特率预分频的值:波特率预分频值为256
+    SPI_W25Q_Handler.Init.FirstBit=SPI_FIRSTBIT_MSB;        //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始
+    SPI_W25Q_Handler.Init.TIMode=SPI_TIMODE_DISABLE;        //关闭TI模式
+    SPI_W25Q_Handler.Init.CRCCalculation=SPI_CRCCALCULATION_DISABLE;//关闭硬件CRC校验
+    SPI_W25Q_Handler.Init.CRCPolynomial=7;                  //CRC值计算的多项式
+    HAL_SPI_Init(&SPI_W25Q_Handler);//初始化
+    
+    __HAL_SPI_ENABLE(&SPI_W25Q_Handler);                    //使能SPI2
+	
+    SPI_W25Q_ReadWriteByte(0Xff);                           //启动传输
+}
+
+//SPI2底层驱动,时钟使能,引脚配置
+//此函数会被HAL_SPI_Init()调用
+//hspi:SPI句柄
+void HAL_SPI_MspInit_w25qxx(SPI_HandleTypeDef *hspi)
+{
+    GPIO_InitTypeDef GPIO_Initure;
+    
+    __HAL_RCC_GPIOB_CLK_ENABLE();       //使能GPIOB时钟
+    __HAL_RCC_SPI2_CLK_ENABLE();        //使能SPI2时钟
+
+    //PB13,14,15
+    GPIO_Initure.Pin=GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15;
+    GPIO_Initure.Mode=GPIO_MODE_AF_PP;              //复用推挽输出
+    GPIO_Initure.Pull=GPIO_PULLUP;                  //上拉
+    GPIO_Initure.Speed=GPIO_SPEED_HIGH;             //快速            
+    GPIO_Initure.Alternate=GPIO_AF5_SPI2;           //复用为SPI2
+    HAL_GPIO_Init(GPIOB,&GPIO_Initure);
+}
+
+//SPI速度设置函数
+//SPI速度=fAPB1/分频系数
+//@ref SPI_BaudRate_Prescaler:SPI_BAUDRATEPRESCALER_2~SPI_BAUDRATEPRESCALER_2 256
+//fAPB1时钟一般为45Mhz:
+void SPI_W25Q_SetSpeed(uint8_t SPI_BaudRatePrescaler)
+{
+    assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_BaudRatePrescaler));//判断有效性
+    __HAL_SPI_DISABLE(&SPI_W25Q_Handler);            //关闭SPI
+    SPI_W25Q_Handler.Instance->CR1&=0XFFC7;          //位3-5清零,用来设置波特率
+    SPI_W25Q_Handler.Instance->CR1|=SPI_BaudRatePrescaler;//设置SPI速度
+    __HAL_SPI_ENABLE(&SPI_W25Q_Handler);             //使能SPI
+    
+}
+
+//SPI2 读写一个字节
+//TxData:要写入的字节
+//返回值:读取到的字节
+uint8_t SPI_W25Q_ReadWriteByte(uint8_t TxData)
+{
+		uint8_t Rxdata;
+		HAL_SPI_TransmitReceive(&SPI_W25Q_Handler,&TxData,&Rxdata,1, 100000);       
+		return Rxdata;          		    //返回收到的数据		
+}

+ 12 - 0
dev/dev_spi_w25qxx.h

@@ -0,0 +1,12 @@
+#ifndef DEV_SPI_W25QXX_H
+#define DEV_SPI_W25QXX_H
+#include "stm32f7xx_hal.h"
+#include "dev_spi_conf.h"
+
+
+extern SPI_HandleTypeDef SPI_W25Q_Handler;  //SPI¾ä±ú
+
+void 		SPI_W25Q_Init(void);
+void 		SPI_W25Q_SetSpeed(uint8_t SPI_BaudRatePrescaler);
+uint8_t SPI_W25Q_ReadWriteByte(uint8_t TxData);
+#endif