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
流逝的青春,奔走的年华,煮酒一杯,为谁!
QQ:1832071291