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與其他兩個的區別;務必要檢測緩存區是否爲空。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章