STM32F103 SPI 操作


本主記錄SPI 普通操作方式,主要為后續SPI設備提供基礎

1、MDK工程目錄(創建工程方式略),工程結構與前面 "STM32F103 DMA模式操作UART" 類式

 

2、spi 設備引腳初始在platform.c 文件下, 這里面列出SX1278 設備

platform.c 內容

/**
* @file platform.c 控制板GPIO引腳定義
*
* @author T0213-ZH
* @date 2018.06.13
*
* @note 使用STM32F103VC6 微處理器
*
* >>>> sx1278 模組接口定義 SPI1
* SPI1 引腳 PA5->CLK, PA6->MISO, PA7->MOSI PA2->CSN
* 控制引腳 PA3->RST, PA4->DIO0
*
*
* >>> 串口接口定義
* USART1 引腳 PA9->TX, PA10->RX
*
*/

#include "platform.h"

//******************************** SX1278 ******************************************************************

extern void Delayms(uint32_t ms);
void SX1278_spi_init(void){ GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //PA3->RST PA2->CSN GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_WriteBit(GPIOA, GPIO_Pin_3, Bit_RESET); GPIO_WriteBit(GPIOA, GPIO_Pin_2, Bit_SET); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE); //PA5->CLK PA6->MISO PA7->MOSI GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); //DIO0  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; GPIO_Init(GPIOA, &GPIO_InitStructure); SPI_ApiStructure.init(&sx1278_ApiStructre.spi); Delayms(10); GPIO_WriteBit(GPIOA, GPIO_Pin_3, Bit_SET); Delayms(10); } void SX1278_spi_csn(uint8_t enable){ GPIO_WriteBit(GPIOA, GPIO_Pin_2, (enable != 0x00) ? Bit_SET: Bit_RESET); } void sx1278_reset(uint8_t state){ GPIO_WriteBit(GPIOA, GPIO_Pin_3, (state == 0) ? Bit_RESET: Bit_SET); } uint8_t sx1278_read_Dio_0(void){ return GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_4); } SX1278_TypeDef sx1278_ApiStructre = { .spi.pfunc_csn = SX1278_spi_csn, .spi.SPIx = SPI1, .init = SX1278_spi_init, .reset = sx1278_reset, .rDio0 = sx1278_read_Dio_0, };

platform.h 文件內容,主要用於包含頭文件及對應設備提供接口

#ifndef __PLATFORM_H
#define __PLATFORM_H #include "stm32f10x.h" #include "stm32f10x\F103\driver\gpio.h" #include "stm32f10x\F103\driver\time.h" #include "stm32f10x\F103\driver\spi.h" #include "stm32f10x\F103\driver\uart.h" #include "SX1278\radio\radio.h" #include "SX1278\radio\sx1276-Hal.h" extern UART_TypeDef UART_TypeDef_param; extern SX1278_TypeDef sx1278_ApiStructre; extern volatile uint32_t TickCounter; #endif

 

3、spi 接口源文件

spi.h 內容 

#ifndef __SPI_H
#define __SPI_H

/**
* @brief SPI 控制參數
*/ typedef struct{ void (* pfunc_csn)(uint8_t enable); /*!< csn 控制的函數指針 */ SPI_TypeDef *SPIx; /*!< 對就的SPI組,如:SPI1,SPI2,SPI3 */ }SPI_CtrDef; /** * @brief SPI 接口函數 */ typedef struct{ uint8_t (* init)(SPI_CtrDef *p); /*!< 初始化spi */ uint8_t (* read_buf)(SPI_CtrDef *p, uint8_t reg, uint8_t *pbuf, uint8_t len); /*!< 讀多個數據 */ uint8_t (* write_buf)(SPI_CtrDef *p, uint8_t reg, uint8_t *pbuf, uint8_t len); /*!< 寫多個數據 */ uint8_t (* rwrite_onebyte)(SPI_CtrDef *p, uint8_t reg, uint8_t ch); /*!< 讀單個數據 */ uint8_t (* write_reg)(SPI_CtrDef *p, uint8_t reg); /*!< 寫寄存器 */ }SPI_ApiDef; extern const SPI_ApiDef SPI_ApiStructure; #endif

 spi.c 內容 

/**
* @file spi.c spi 驅動程序
*         
* @author T0213-ZH
* @date   2018.06.13 
*/

#include "platform.h"

/**
* @brief 初始化SPI 參數 
* @param p: 指向SPI設置參數指針
*
* @retval 返回初始結果 0-成功,1-失敗
*/
static uint8_t SPIx_Init(SPI_CtrDef *p){ SPI_InitTypeDef SPI_InitStructure; if(p->SPIx == SPI1){ RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); }else if(p->SPIx == SPI2){ RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE); }else if(p->SPIx == SPI3){ RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3, ENABLE); }else{ return 1; } SPI_Cmd(p->SPIx, DISABLE); SPI_InitStructure.SPI_Direction =SPI_Direction_2Lines_FullDuplex; SPI_InitStructure.SPI_Mode =SPI_Mode_Master; SPI_InitStructure.SPI_DataSize =SPI_DataSize_8b; SPI_InitStructure.SPI_CPOL =SPI_CPOL_Low; SPI_InitStructure.SPI_CPHA =SPI_CPHA_1Edge; SPI_InitStructure.SPI_NSS =SPI_NSS_Soft; SPI_InitStructure.SPI_BaudRatePrescaler =SPI_BaudRatePrescaler_8; SPI_InitStructure.SPI_FirstBit =SPI_FirstBit_MSB; SPI_InitStructure.SPI_CRCPolynomial =7; SPI_Init(p->SPIx,&SPI_InitStructure); SPI_Cmd(p->SPIx, ENABLE); return 0; } /** * @brief 讀寫1Bbyte數據 * @param SPIx: 指向SPI組 * @arg SPI1 使用SPI1 組 * @arg SPI2 使用SPI2 組 * * @retval 8-bit 數據 */ /*static*/ uint8_t SPI_RWbyte(SPI_TypeDef *SPIx, uint8_t ch){ while( SPI_I2S_GetFlagStatus(SPIx,SPI_I2S_FLAG_TXE) == RESET); SPI_I2S_SendData(SPIx, ch); while(SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_RXNE) ==RESET); return SPI_I2S_ReceiveData(SPIx); } /** * @brief 讀取指定寄存器中多個數據 * @param p: 指向SPI設置參數指針 * @param reg: 寄存器地址 * @param pbuf: 指向存儲數據的緩存指針 * @param len: 讀取長度 * * @retval 返回結果 */ static uint8_t SPIx_Read_buf(SPI_CtrDef *p, uint8_t reg, uint8_t *pbuf, uint8_t len){ uint8_t status, i; p->pfunc_csn(0); status = SPI_RWbyte(p->SPIx, reg); for(i=0; i<len; i++){ pbuf[i] = SPI_RWbyte(p->SPIx, 0xFF); } p->pfunc_csn(1); return status; } /** * @brief 向指定寄存器中寫多個數據 * @param p: 指向SPI設置參數指針 * @param reg: 寄存器地址 * @param pbuf: 指向寫數據的緩存指針 * @param len: 寫數據長度 * * @retval 返回結果 */ static uint8_t SPIx_Write_buf(SPI_CtrDef *p, uint8_t reg, uint8_t *pbuf, uint8_t len){ uint8_t status, i; p->pfunc_csn(0); status = SPI_RWbyte(p->SPIx, reg); for(i=0; i<len; i++){ SPI_RWbyte(p->SPIx, *pbuf++); } p->pfunc_csn(1); return status; } /** * @brief 向指定寄存器中寫讀1Byte個數據 * @param p: 指向SPI設置參數指針 * @param reg: 寄存器地址 * @param ch: 需寫入的數據 * * @retval 返回結果 */ static uint8_t SPIx_RWrite_Onebyte(SPI_CtrDef *p, uint8_t reg, uint8_t ch){ uint8_t value; p->pfunc_csn(0); SPI_RWbyte(p->SPIx, reg); value = SPI_RWbyte(p->SPIx, ch); p->pfunc_csn(1); return value; } /** * @brief 寫指定寄存器數據 * @param p: 指向SPI設置參數指針 * @param reg: 寄存器地址 * * @retval 返回結果 */ static uint8_t SPIx_Write_reg(SPI_CtrDef *p, uint8_t reg){ uint8_t status; p->pfunc_csn(0); status = SPI_RWbyte(p->SPIx, reg); p->pfunc_csn(1); return status; } /** * @brief SPI 接口函數 */ const SPI_ApiDef SPI_ApiStructure = { .init = SPIx_Init, /*!< 初始化SPI */ .read_buf = SPIx_Read_buf, /*!< 讀多個數據 */ .write_buf = SPIx_Write_buf, /*!< 寫多個數據 */ .rwrite_onebyte = SPIx_RWrite_Onebyte, /*!< 讀寫1Byte數據 */ .write_reg = SPIx_Write_reg, /*!< 寫指定寄存器 */ };

 

4、具體操作在下節 SX1278 驅動

.....

 

本節文件: https://files.cnblogs.com/files/T0213-ZH/stm32f103_spi.rar

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM