STM32的SPI1、SPI2、SPI3初始化及RF1101的应用(标准库与HAL库)

STM32的SPI1、SPI2、SPI3初始化及RF1101的应用(标准库与HAL库)

——基于STM32F103RCT6

---- 标准库:

说明:相关文件共有两个:bsp_spi_cc1101.h;bsp_spi_cc1101.c;以SPI2为例。
1、“bsp_spi_cc1101.h”中的参数定义:

#ifndef _BSP_SPI_1101_H_
#define _BSP_SPI_1101_H_

#include <stdio.h>
#include "stm32f10x.h"
#include "misc.h"
#include "os_cfg_app.h"
#include "os.h"
#include "core_cm3.h"
#include "bsp.h" 
#include "stm32f10x_spi.h"

#define					CSN_CC1101_GPIO						GPIOB
#define					CSN_CC1101_GPIO_PIN					GPIO_Pin_12

#define					SPI_CC1101_GPIO						GPIOB
#define					SCK_CC1101_GPIO_PIN					GPIO_Pin_13
#define					MISO_CC1101_GPIO_PIN					GPIO_Pin_14
#define					MOSI_CC1101_GPIO_PIN					GPIO_Pin_15

#define					GDO0_CC1101_GPIO						GPIOA
#define					GDO0_CC1101_GPIO_PIN					GPIO_Pin_11
	
#define					SPI_GPIO_RCC_1							RCC_APB2Periph_GPIOB
#define					SPI_GPIO_RCC_2							RCC_APB2Periph_GPIOA

#define					CC1101_SPI								SPI2

#define					CSN_SET									GPIO_SetBits(GPIOB,GPIO_Pin_12)
#define					CSN_RESET								GPIO_ResetBits(GPIOB,GPIO_Pin_12)

void SPI_CC1101_Init(void);
u8 SPI2_ReadWriteByte(u8 TxData);
#endif

2、“bsp_spi_cc1101.c”中的引脚及SPI功能初始化:

#include "bsp_spi_cc1101.h"

void SPI_CC1101_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	SPI_InitTypeDef SPI_InitStructure;
	RCC_APB2PeriphClockCmd(SPI_GPIO_RCC_1 | SPI_GPIO_RCC_2,ENABLE); 	//初始化GPIO时钟  	
	
	/*********SPI1初始化内容****			
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1,ENABLE); 				//初始化SPI1时钟
	 ******SPI1初始化内容******/	
	 
	/*********SPI2初始化内容************/			
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2,ENABLE);   			//初始化SPI2时钟
	      										   
	/********SPI3需要初始化的内容********
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2,ENABLE);   			//初始化SPI3时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);				//初始化复用IO时钟,重定向IO口
	GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);			//由于SPI3占用JTAG口,所以需要关闭JTAG
	******SPI3需要初始化的内容*******/
	
	//片选设定成通用IO模式
	GPIO_InitStructure.GPIO_Pin=CSN_CC1101_GPIO_PIN;	
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;          
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;            							 			
	GPIO_Init(CSN_CC1101_GPIO,&GPIO_InitStructure);		

	//SCK时钟IO初始化
	GPIO_InitStructure.GPIO_Pin=SCK_CC1101_GPIO_PIN;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;             			 						
	GPIO_Init(SPI_CC1101_GPIO,&GPIO_InitStructure);
	
	//MISO的IO初始化
	GPIO_InitStructure.GPIO_Pin=MISO_CC1101_GPIO_PIN;          
	GPIO_Init(SPI_CC1101_GPIO,&GPIO_InitStructure);
	
	//MOSI的IO初始化
	GPIO_InitStructure.GPIO_Pin=MOSI_CC1101_GPIO_PIN;         
	GPIO_Init(SPI_CC1101_GPIO,&GPIO_InitStructure);
	
	//RF1101中用到的GDO0的IO初始化
	GPIO_InitStructure.GPIO_Pin=GDO0_CC1101_GPIO_PIN;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;          
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;            							 					 
	GPIO_Init(GDO0_CC1101_GPIO,&GPIO_InitStructure);	
	
	//SPI模式设置	
	SPI_InitStructure.SPI_Direction=SPI_Direction_2Lines_FullDuplex;   				//全双工模式			
	SPI_InitStructure.SPI_Mode=SPI_Mode_Master;										//主设备模式															
	SPI_InitStructure.SPI_DataSize=SPI_DataSize_8b;									//8字节数据通信												
	SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;										//时钟空闲时为低电平															
	SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;										//时钟奇数边沿采样															
	SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; 										//软件控制NSS(CSN)位								
	SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; 			//通信速率设定,波特率预分频值	
	SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;								//数据传输从MSB开始	
	SPI_InitStructure.SPI_CRCPolynomial = 7; 											//CRC计算多项式							
	SPI_Init(CC1101_SPI, &SPI2_InitStructure);										//初始化
    SPI_Cmd(CC1101_SPI, ENABLE);														//使能
    SPI2_ReadWriteByte(0xFF);                           								//RF1101启动传输			
}

u8 SPI2_ReadWriteByte(u8 TxData)
{
	u8 Rxdata;
	uint32_t SPITimeout =0x1000;
	while (SPI_I2S_GetFlagStatus(CC1101_SPI , SPI_I2S_FLAG_TXE) == RESET)			//检测发送缓存区是否为空
	{
		if((SPITimeout--) == 0) 
			return 0;
  	}
	SPI_I2S_SendData(CC1101_SPI,TxData);												//发送一个字节
	 
	while (SPI_I2S_GetFlagStatus(CC1101_SPI , SPI_I2S_FLAG_RXNE) == RESET)			//检测接收缓存区是否为空
 	{
 		if((SPITimeout--) == 0) return 0;
  	}
	Rxdata = SPI_I2S_ReceiveData(CC1101_SPI);											//存储一个字节
	
 	return Rxdata;          		    									
}

---- HAL库:

以SPI1为例:

SPI_HandleTypeDef SPI1_Handler;  

void SPI1_Init(void)
{
    GPIO_InitTypeDef GPIO_Initure;
    __HAL_RCC_GPIOA_CLK_ENABLE();      							//使能GPIOA时钟
    __HAL_RCC_SPI1_CLK_ENABLE();        							//使能SPI1时钟
    
    //NSS配置成通用IO口
    GPIO_Initure.Pin=GPIO_PIN_4;
    GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP;         				
    GPIO_Initure.Pull=GPIO_PULLUP;                  				
    GPIO_Initure.Speed=GPIO_SPEED_HIGH;           				           
    HAL_GPIO_Init(GPIOA,&GPIO_Initure);	

	//SPI引脚初始化
    GPIO_Initure.Pin=GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
    GPIO_Initure.Mode=GPIO_MODE_AF_PP;             			 				
    GPIO_Initure.Pull=GPIO_PULLUP;                 							
    GPIO_Initure.Speed=GPIO_SPEED_HIGH;             							          
    HAL_GPIO_Init(GPIOA,&GPIO_Initure);
	
	//SPI功能配置
    SPI1_Handler.Instance=SPI1;                         						//SPI1
    SPI1_Handler.Init.Mode=SPI_MODE_MASTER;            						//主模式
    SPI1_Handler.Init.Direction=SPI_DIRECTION_2LINES;   						//双线模式
    SPI1_Handler.Init.DataSize=SPI_DATASIZE_8BIT;       						//发送接收8位帧结构
    SPI1_Handler.Init.CLKPolarity=SPI_POLARITY_LOW;    						//时钟的空闲状态为高电平
    SPI1_Handler.Init.CLKPhase=SPI_PHASE_1EDGE;         						//串行同步时钟的第二个跳变沿(上升或下降)数据被采样
    SPI1_Handler.Init.NSS=SPI_NSS_SOFT;                 						//NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制
    SPI1_Handler.Init.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_256;			//定义波特率预分频的值:波特率预分频值为256
    SPI1_Handler.Init.FirstBit=SPI_FIRSTBIT_MSB;        						//指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始
    SPI1_Handler.Init.TIMode=SPI_TIMODE_DISABLE;        						//关闭TI模式
    SPI1_Handler.Init.CRCCalculation=SPI_CRCCALCULATION_DISABLE;				//关闭硬件CRC校验
    SPI1_Handler.Init.CRCPolynomial=7;                  						//CRC值计算的多项式
    HAL_SPI_Init(&SPI1_Handler);												//初始化
    
    __HAL_SPI_ENABLE(&SPI1_Handler);                   						//使能SPI1
    SPI1_ReadWriteByte(0xFF);                           						//RF1101启动传输
}

//SPI底层驱动,时钟使能,引脚配置
//此函数会被HAL_SPI_Init()调用
//hspi:SPI句柄
void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi)
{
    GPIO_InitTypeDef GPIO_Initure;
    
    __HAL_RCC_GPIOA_CLK_ENABLE();       //使能GPIOA时钟
    __HAL_RCC_SPI1_CLK_ENABLE();        //使能SPI1时钟
    
    //PB13,14,15
    GPIO_Initure.Pin=GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
    GPIO_Initure.Mode=GPIO_MODE_AF_PP;           
    GPIO_Initure.Pull=GPIO_PULLUP;                 
    GPIO_Initure.Speed=GPIO_SPEED_HIGH;                     
    HAL_GPIO_Init(GPIOA,&GPIO_Initure);
}
void SPI1_SetSpeed(u8 SPI_BaudRatePrescaler)
{
    assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_BaudRatePrescaler));						//判断有效性
    __HAL_SPI_DISABLE(&SPI1_Handler);            										//关闭SPI
    SPI1_Handler.Instance->CR1&=0XFFC7;          										//位3~5清零,用来设置波特率
    SPI1_Handler.Instance->CR1|=SPI_BaudRatePrescaler;									//设置SPI速度
    __HAL_SPI_ENABLE(&SPI1_Handler);             										//使能SPI
}

u8 SPI1_ReadWriteByte(u8 TxData)
{
	u8 Rxdata;
	HAL_SPI_TransmitReceive(&SPI1_Handler,&TxData,&Rxdata,1, 1000);       
 	return Rxdata;          		    
}

注:与HAL库有一定的区别;重点注意SPI3与其他两个的区别;务必要检测缓存区是否为空。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值