spi是比較流行的一種串行外設,很多外設和集成IC都會使用到,如顯示,AD、DA、FALASH等等都會用到。雖然使用stm的cube庫也用着不錯,但每次使用時都得重新粘貼複製一遍很是麻煩,故纔會有此篇文章。模塊的設計格局與官方mbed有些地方是不一致的,讀的時候請注意一下。因爲是在項目過程中創建,模塊接口不夠全面,大家可以自行添加需要的API。
注意:中斷設計方法請參考
mbed serial_api模塊移植到stm32f107vc一文一、關聯文件
1、pinmap.h
/**
******************************************************************************
* File Name : pinmap.h
* Description :
******************************************************************************
*/
#ifndef _PIN_MAP_H
#define _PIN_MAP_H
/* 與mbed的pinmap結構有些不同 ,主意區別 */
typedef struct{
uint32_t pin; /* 外設引腳,必須使用pinnames.h中定義的引腳名稱 */
uint32_t pin_port; /* 引腳端口基地址,例如:GPIOB_BASE */
uint32_t peripheral; /* 外設基地址,例如:USART1_BASE */
uint32_t remap; /* 引腳重映射 */
uint32_t mode; /* 引腳輸入輸出模式 */
uint32_t pupd; /* 上下拉電阻 */
}pinmap_t;
/* 引腳配置函數 */
void pinmap_pinout(uint32_t pin,const pinmap_t *map);
/* 引腳端口合併 */
uint32_t pinmap_merge(uint32_t a,uint32_t b);
/* 查找引腳對應的外設,返回外設基地址 */
uint32_t pinmap_find_peripheral(uint32_t pin,const pinmap_t *map);
/* 調用 pinmap_find_peripheral,返回外設地址 */
uint32_t pinmap_peripheral(uint32_t pin,const pinmap_t *map);
#endif
2、pinmap.c
/**
******************************************************************************
* File Name : pinmap.c
* Description :
******************************************************************************
*/
#include "stm32f1xx.h"
#include "pinmap.h"
#include "pinnames.h"
#include "ierror.h"
#include "iassert.h"
/* private function *******************************************/
static void pin_function(const pinmap_t *map);
static void set_gpio_clock(const pinmap_t *map);
void pinmap_pinout(uint32_t pin, const pinmap_t *map) {
if (pin == NC)
return;
while (map->pin != NC) {
if (map->pin == pin) {
pin_function(map);
return;
}
map++;
}
error("could not pinout");
}
void pin_function(const pinmap_t *map)
{
I_ASSERT(map->pin != NC);
/* enable AFIO clock */
set_gpio_clock(map);
__HAL_RCC_AFIO_CLK_ENABLE();
/* configure alternate function */
if(map->remap>0){
switch(map->remap){
case AFIO_MAPR_SPI1_REMAP:
__HAL_AFIO_REMAP_SPI1_ENABLE();
break;
case AFIO_MAPR_I2C1_REMAP:
__HAL_AFIO_REMAP_I2C1_ENABLE();
break;
case AFIO_MAPR_USART1_REMAP:
__HAL_AFIO_REMAP_USART1_ENABLE();
break;
case AFIO_MAPR_USART2_REMAP:
__HAL_AFIO_REMAP_USART2_ENABLE();
break;
case AFIO_MAPR_USART3_REMAP_FULLREMAP:
__HAL_AFIO_REMAP_USART3_ENABLE();
break;
case AFIO_MAPR_USART3_REMAP_PARTIALREMAP:
__HAL_AFIO_REMAP_USART3_PARTIAL();
break;
case AFIO_MAPR_TIM1_REMAP_PARTIALREMAP:
__HAL_AFIO_REMAP_TIM1_PARTIAL();
break;
case AFIO_MAPR_TIM1_REMAP_FULLREMAP:
__HAL_AFIO_REMAP_TIM1_ENABLE();
break;
case AFIO_MAPR_TIM2_REMAP_PARTIALREMAP1:
__HAL_AFIO_REMAP_TIM2_PARTIAL_1();
break;
case AFIO_MAPR_TIM2_REMAP_PARTIALREMAP2:
__HAL_AFIO_REMAP_TIM2_PARTIAL_2();
break;
case AFIO_MAPR_TIM2_REMAP_FULLREMAP:
__HAL_AFIO_REMAP_TIM2_ENABLE();
break;
case AFIO_MAPR_TIM3_REMAP_PARTIALREMAP:
__HAL_AFIO_REMAP_TIM3_PARTIAL();
break;
case AFIO_MAPR_TIM3_REMAP_FULLREMAP:
__HAL_AFIO_REMAP_TIM3_ENABLE();
break;
case AFIO_MAPR_TIM4_REMAP:
__HAL_AFIO_REMAP_TIM4_ENABLE();
break;
default:
break;
}
}
GPIO_InitTypeDef gpio_initstruct;
gpio_initstruct.Pin = (uint32_t)(1<<(map->pin & 0xF));
gpio_initstruct.Mode = map->mode;
gpio_initstruct.Pull = map->pupd;
gpio_initstruct.Speed = GPIO_SPEED_HIGH;
HAL_GPIO_Init((GPIO_TypeDef *)map->pin_port,&gpio_initstruct);
if((map->pin == PA_13) || (map->pin == PA_14))
__HAL_AFIO_REMAP_SWJ_DISABLE(); /* JTAG-DP Disabled and SW-DP Disabled */
if((map->pin == PA_15) || (map->pin == PB_3))
__HAL_AFIO_REMAP_SWJ_NOJTAG(); /* JTAG-DP Disabled and SW-DP enabled */
}
void set_gpio_clock(const pinmap_t *map)
{
if(map == NULL)
return;
switch(map->pin_port){
case GPIOA_BASE:
__GPIOA_CLK_ENABLE();
break;
case GPIOB_BASE:
__GPIOB_CLK_ENABLE();
break;
case GPIOC_BASE:
__GPIOC_CLK_ENABLE();
break;
case GPIOD_BASE:
__GPIOD_CLK_ENABLE();
break;
case GPIOE_BASE:
__GPIOE_CLK_ENABLE();
break;
default:
error("Pinmap error: wrong port number.");
break;
}
}
uint32_t pinmap_merge(uint32_t a,uint32_t b)
{
// both are the same (inc both NC)
if (a == b)
return a;
// one (or both) is not connected
if (a == (uint32_t)NC)
return b;
if (b == (uint32_t)NC)
return a;
// mis-match error case
error("pinmap mis-match");
return (uint32_t)NC;
}
uint32_t pinmap_find_peripheral(uint32_t pin,const pinmap_t *map)
{
while(map->pin != NC){
if(map->pin == pin)
return map->peripheral;
map++;
}
return (uint32_t)NC;
}
uint32_t pinmap_peripheral(uint32_t pin,const pinmap_t *map)
{
uint32_t peripheral = (uint32_t)NC;
if(pin == NC)
return (uint32_t)NC;
peripheral = pinmap_find_peripheral(pin,map);
if((uint32_t)NC == peripheral)
error("pinmap not found for peripheral");
return peripheral;
}
3、pinnames.h
/**
******************************************************************************
* File Name : pinnames.h
* Description :
******************************************************************************
*/
#ifndef PIN_NAMES_H
#define PIN_NAMES_H
#ifdef __cplusplus
extern "C" {
#endif
// See stm32f3xx_hal_gpio.h and stm32f3xx_hal_gpio_ex.h for values of MODE, PUPD and AFNUM
#define STM_PIN_DATA(MODE, PUPD, AFNUM) ((int)(((AFNUM) << 7) | ((PUPD) << 4) | ((MODE) << 0)))
#define STM_PIN_MODE(X) (((X) >> 0) & 0x0F)
#define STM_PIN_PUPD(X) (((X) >> 4) & 0x07)
#define STM_PIN_AFNUM(X) (((X) >> 7) & 0x0F)
#define STM_MODE_INPUT (0)
#define STM_MODE_OUTPUT_PP (1)
#define STM_MODE_OUTPUT_OD (2)
#define STM_MODE_AF_PP (3)
#define STM_MODE_AF_OD (4)
#define STM_MODE_ANALOG (5)
#define STM_MODE_IT_RISING (6)
#define STM_MODE_IT_FALLING (7)
#define STM_MODE_IT_RISING_FALLING (8)
#define STM_MODE_EVT_RISING (9)
#define STM_MODE_EVT_FALLING (10)
#define STM_MODE_EVT_RISING_FALLING (11)
#define STM_MODE_IT_EVT_RESET (12)
// High nibble = port number (0=A, 1=B, 2=C, 3=D, 4=E, 5=F, 6=G, 7=H)
// Low nibble = pin number
#define STM_PORT(X) (((uint32_t)(X) >> 4) & 0xF)
#define STM_PIN(X) ((uint32_t)(X) & 0xF)
typedef enum {
PIN_INPUT,
PIN_OUTPUT
} PinDirection;
typedef enum {
PA_0 = 0x00,
PA_1 = 0x01,
PA_2 = 0x02,
PA_3 = 0x03,
PA_4 = 0x04,
PA_5 = 0x05,
PA_6 = 0x06,
PA_7 = 0x07,
PA_8 = 0x08,
PA_9 = 0x09,
PA_10 = 0x0A,
PA_11 = 0x0B,
PA_12 = 0x0C,
PA_13 = 0x0D,
PA_14 = 0x0E,
PA_15 = 0x0F,
PB_0 = 0x10,
PB_1 = 0x11,
PB_2 = 0x12,
PB_3 = 0x13,
PB_4 = 0x14,
PB_5 = 0x15,
PB_6 = 0x16,
PB_7 = 0x17,
PB_8 = 0x18,
PB_9 = 0x19,
PB_10 = 0x1A,
PB_11 = 0x1B,
PB_12 = 0x1C,
PB_13 = 0x1D,
PB_14 = 0x1E,
PB_15 = 0x1F,
PC_0 = 0x20,
PC_1 = 0x21,
PC_2 = 0x22,
PC_3 = 0x23,
PC_4 = 0x24,
PC_5 = 0x25,
PC_6 = 0x26,
PC_7 = 0x27,
PC_8 = 0x28,
PC_9 = 0x29,
PC_10 = 0x2A,
PC_11 = 0x2B,
PC_12 = 0x2C,
PC_13 = 0x2D,
PC_14 = 0x2E,
PC_15 = 0x2F,
PD_0 = 0x30,
PD_1 = 0x31,
PD_2 = 0x32,
PD_3 = 0x33,
PD_4 = 0x34,
PD_5 = 0x35,
PD_6 = 0x36,
PD_7 = 0x37,
PD_8 = 0x38,
PD_9 = 0x39,
PD_10 = 0x3A,
PD_11 = 0x3B,
PD_12 = 0x3C,
PD_13 = 0x3D,
PD_14 = 0x3E,
PD_15 = 0x3F,
PE_0 = 0x40,
PE_1 = 0x41,
PE_2 = 0x42,
PE_3 = 0x43,
PE_4 = 0x44,
PE_5 = 0x45,
PE_6 = 0x46,
PE_7 = 0x47,
PE_8 = 0x48,
PE_9 = 0x49,
PE_10 = 0x4A,
PE_11 = 0x4B,
PE_12 = 0x4C,
PE_13 = 0x4D,
PE_14 = 0x4E,
PE_15 = 0x4F,
PF_0 = 0x50,
PF_1 = 0x51,
PF_2 = 0x52,
PF_3 = 0x53,
PF_4 = 0x54,
PF_5 = 0x55,
PF_6 = 0x56,
PF_7 = 0x57,
PF_8 = 0x58,
PF_9 = 0x59,
PF_10 = 0x5A,
PF_11 = 0x5B,
PF_12 = 0x5C,
PF_13 = 0x5D,
PF_14 = 0x5E,
PF_15 = 0x5F,
PG_0 = 0x60,
PG_1 = 0x61,
PG_2 = 0x62,
PG_3 = 0x63,
PG_4 = 0x64,
PG_5 = 0x65,
PG_6 = 0x66,
PG_7 = 0x67,
PG_8 = 0x68,
PG_9 = 0x69,
PG_10 = 0x6A,
PG_11 = 0x6B,
PG_12 = 0x6C,
PG_13 = 0x6D,
PG_14 = 0x6E,
PG_15 = 0x6F,
PH_0 = 0x70,
PH_1 = 0x71,
PH_2 = 0x72,
PH_3 = 0x73,
PH_4 = 0x74,
PH_5 = 0x75,
PH_6 = 0x76,
PH_7 = 0x77,
PH_8 = 0x78,
PH_9 = 0x79,
PH_10 = 0x7A,
PH_11 = 0x7B,
PH_12 = 0x7C,
PH_13 = 0x7D,
PH_14 = 0x7E,
PH_15 = 0x7F,
// Arduino connector namings
A0 = PA_0,
A1 = PA_1,
A2 = PA_4,
A3 = PB_0,
A4 = PC_1,
A5 = PC_0,
D0 = PA_3,
D1 = PA_2,
D2 = PA_10,
D3 = PB_3,
D4 = PB_5,
D5 = PB_4,
D6 = PB_10,
D7 = PA_8,
D8 = PA_9,
D9 = PC_7,
D10 = PB_6,
D11 = PA_7,
D12 = PA_6,
D13 = PA_5,
D14 = PB_9,
D15 = PB_8,
// Not connected
NC = (uint32_t)0xFFFFFFFF
} PinName;
#ifdef __cplusplus
}
#endif
#endif
二、spi_api.h
/**
******************************************************************************
* File Name : spi_api.h
* Description :
******************************************************************************
*/
#ifndef SPI_API_H
#define SPI_API_H
/* include ******************************/
#include "stm32f1xx.h"
void spi_init(SPI_HandleTypeDef *hspi,
uint32_t mosi,
uint32_t miso,
uint32_t sck,
uint32_t ssel,
uint32_t nss);
void spi_free(SPI_HandleTypeDef *hspi);
void spi_format(SPI_HandleTypeDef *hspi,
uint32_t databits,
uint8_t clk_mode,
uint32_t slave);
void spi_baud(SPI_HandleTypeDef *hspi,uint32_t baud);
void spi_begin(SPI_HandleTypeDef *hspi);
void spi_end(SPI_HandleTypeDef *hspi);
void spi_transmit(SPI_HandleTypeDef *hspi,uint8_t *pdata,uint16_t size,uint32_t timeout);
void spi_receive(SPI_HandleTypeDef *hspi,uint8_t *pdata,uint16_t size,uint32_t timeout);
void spi_receive_it(SPI_HandleTypeDef *hspi,uint8_t *pdata,uint16_t size);
void spi_irq_set(SPI_HandleTypeDef *hspi,uint32_t preempt_prio,uint32_t sub_prio);
void spi_irq_enable(SPI_HandleTypeDef *hspi);
void spi_irq_disable(SPI_HandleTypeDef *hspi);
#endif
三、spi_api.c
/**
******************************************************************************
* File Name : spi_api.c
* Description :
******************************************************************************
*/
#include "stm32f1xx.h"
#include "spi_api.h"
#include "pinnames.h"
#include "pinmap.h"
#include "iassert.h"
#include "ierror.h"
const static pinmap_t SPI_MOSI_TAB[] = {
{PA_7, GPIOA_BASE,SPI1_BASE,0,GPIO_MODE_AF_PP,GPIO_NOPULL},
{PB_15,GPIOB_BASE,SPI2_BASE,0,GPIO_MODE_AF_PP,GPIO_NOPULL},
{PB_5, GPIOB_BASE,SPI3_BASE,0,GPIO_MODE_AF_PP,GPIO_NOPULL},
{PC_12,GPIOC_BASE,SPI3_BASE,AFIO_MAPR_SPI3_REMAP,GPIO_MODE_AF_PP,GPIO_NOPULL},
{NC, NC, NC, 0, NC, NC}
};
const static pinmap_t SPI_MISO_TAB[] = {
{PA_6, GPIOA_BASE,SPI1_BASE,0,GPIO_MODE_AF_PP,GPIO_NOPULL},
{PB_14,GPIOB_BASE,SPI2_BASE,0,GPIO_MODE_AF_PP,GPIO_NOPULL},
{PB_4, GPIOB_BASE,SPI3_BASE,0,GPIO_MODE_AF_PP,GPIO_NOPULL},
{PC_11,GPIOC_BASE,SPI3_BASE,AFIO_MAPR_SPI3_REMAP,GPIO_MODE_AF_PP,GPIO_NOPULL},
{NC, NC, NC, 0, NC, NC}
};
const static pinmap_t SPI_SCK_TAB[] = {
{PA_5, GPIOA_BASE,SPI1_BASE,0,GPIO_MODE_AF_PP,GPIO_NOPULL},
{PB_13,GPIOB_BASE,SPI2_BASE,0,GPIO_MODE_AF_PP,GPIO_NOPULL},
{PB_3, GPIOB_BASE,SPI3_BASE,0,GPIO_MODE_AF_PP,GPIO_NOPULL},
{PC_10,GPIOC_BASE,SPI3_BASE,AFIO_MAPR_SPI3_REMAP,GPIO_MODE_AF_PP,GPIO_NOPULL},
{NC, NC, NC, 0, NC, NC}
};
const static pinmap_t SPI_SSEL_TAB[] ={
{PA_4, GPIOA_BASE,SPI1_BASE,0,GPIO_MODE_AF_PP,GPIO_NOPULL},
{PB_12,GPIOB_BASE,SPI2_BASE,0,GPIO_MODE_AF_PP,GPIO_NOPULL},
{PA_15,GPIOA_BASE,SPI3_BASE,0,GPIO_MODE_AF_PP,GPIO_NOPULL},
{NC, NC, NC, 0,NC, NC}
};
/* soft nss,根據實際使用情況修改 */
const static pinmap_t SPI_CS_TAB[] = {
{PA_8,GPIOA_BASE,SPI1_BASE,0,GPIO_MODE_OUTPUT_PP,GPIO_NOPULL},
{PA_4,GPIOA_BASE,SPI3_BASE,0,GPIO_MODE_OUTPUT_PP,GPIO_NOPULL},
{NC, NC, NC, 0,NC, NC }
};
/* public variable ***************************************/
SPI_HandleTypeDef *hspi_instance[3] = {NULL,NULL,NULL};
/* private **********************************************/
/**
* biref initialize spi peripher
* retval none
* hspi - pointer to SPI_HandleTypeDef
* mosi - master out and slave input pin
* miso - msater in and slave out pin
* sck - spi sclk pin
* ssel - cs pin
* nss nss style
* -SPI_NSS_SOFT
* -SPI_NSS_HARD_INPUT,slave
* -SPI_NSS_HARD_OUTPUT,master
*/
void spi_init(SPI_HandleTypeDef *hspi,
uint32_t mosi,
uint32_t miso,
uint32_t sck,
uint32_t ssel,
uint32_t nss)
{
uint32_t spi_ssel;
uint32_t spi_mosi = (uint32_t)pinmap_peripheral(mosi,SPI_MOSI_TAB);
uint32_t spi_miso = (uint32_t)pinmap_peripheral(miso,SPI_MISO_TAB);
uint32_t spi_sck = (uint32_t)pinmap_peripheral(sck,SPI_SCK_TAB);
if(nss == SPI_NSS_SOFT){
spi_ssel = (uint32_t)pinmap_peripheral(ssel,SPI_CS_TAB);
}else{
spi_ssel = (uint32_t)pinmap_peripheral(ssel,SPI_SSEL_TAB);
}
uint32_t spi_data = (uint32_t)pinmap_merge(spi_mosi,spi_miso);
uint32_t spi_cntl = (uint32_t)pinmap_merge(spi_sck,spi_ssel);
uint32_t spi = (uint32_t)pinmap_merge(spi_data,spi_cntl);
I_ASSERT(spi != (uint32_t)NC);
hspi->Instance = (SPI_TypeDef *)spi;
if(spi == SPI1_BASE){
__SPI1_CLK_ENABLE();
hspi_instance[0] = hspi;
}
if(spi == SPI2_BASE){
__SPI2_CLK_ENABLE();
hspi_instance[1] = hspi;
}
if(spi == SPI3_BASE){
__SPI3_CLK_ENABLE();
hspi_instance[2] = hspi;
}
/* configurate spi pins */
pinmap_pinout(mosi,SPI_MOSI_TAB);
pinmap_pinout(miso,SPI_MISO_TAB);
pinmap_pinout(sck,SPI_SCK_TAB);
if(nss == SPI_NSS_SOFT){
pinmap_pinout(ssel,SPI_CS_TAB);
spi_end(hspi);
}else{
pinmap_pinout(ssel,SPI_SSEL_TAB);
}
hspi->Init.NSS = nss;
hspi->Init.Mode = SPI_MODE_MASTER;
hspi->Init.Direction = SPI_DIRECTION_2LINES;
hspi->Init.DataSize = SPI_DATASIZE_8BIT;
hspi->Init.CLKPolarity = SPI_POLARITY_LOW;
hspi->Init.CLKPhase = SPI_PHASE_1EDGE;
hspi->Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
hspi->Init.TIMode = SPI_TIMODE_DISABLE;
hspi->Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi->Init.CRCPolynomial = 10;
HAL_SPI_Init(hspi);
//__HAL_SPI_ENABLE(hspi);
}
void spi_free(SPI_HandleTypeDef *hspi)
{
if(hspi == NULL)
return;
if(hspi->Instance == SPI1){
__SPI1_FORCE_RESET();
__SPI1_RELEASE_RESET();
__SPI1_CLK_DISABLE();
}
if(hspi->Instance == SPI2){
__SPI2_FORCE_RESET();
__SPI2_RELEASE_RESET();
__SPI2_CLK_DISABLE();
}
if(hspi->Instance == SPI3){
__SPI3_FORCE_RESET();
__SPI3_RELEASE_RESET();
__SPI3_CLK_DISABLE();
}
}
/**
* hspi --poiter to instance
* databits --data bit,SPI_DATASIZE_8BIT OR SPI_DATASIZE_16BIT
* clk_mode --clk mode, = 0,1,2,3
* slave --spi mode, 0=MASTER,1=SLAVE
*/
void spi_format(SPI_HandleTypeDef *hspi,
uint32_t databits,
uint8_t clk_mode,
uint32_t slave)
{
hspi->Init.DataSize = databits;
switch(clk_mode)
{
case 0:
hspi->Init.CLKPolarity = SPI_POLARITY_LOW;
hspi->Init.CLKPhase = SPI_PHASE_1EDGE;
break;
case 1:
hspi->Init.CLKPolarity = SPI_POLARITY_LOW;
hspi->Init.CLKPhase = SPI_PHASE_2EDGE;
break;
case 2:
hspi->Init.CLKPolarity = SPI_POLARITY_HIGH;
hspi->Init.CLKPhase = SPI_PHASE_1EDGE;
break;
case 3:
hspi->Init.CLKPolarity = SPI_POLARITY_HIGH;
hspi->Init.CLKPhase = SPI_PHASE_2EDGE;
break;
default:
hspi->Init.CLKPolarity = SPI_POLARITY_LOW;
hspi->Init.CLKPhase = SPI_PHASE_1EDGE;
break;
}
if(hspi->Init.NSS != SPI_NSS_SOFT){
hspi->Init.NSS = (slave) ? SPI_NSS_HARD_INPUT : SPI_NSS_HARD_OUTPUT;
}
hspi->Init.Mode = (slave) ? SPI_MODE_SLAVE : SPI_MODE_MASTER;
HAL_SPI_Init(hspi);
}
/**
* hspi --point to instance of spi
* baud -- baud rate prescaler,
SPI_BAUDRATEPRESCALER_2,
SPI_BAUDRATEPRESCALER_4,
SPI_BAUDRATEPRESCALER_8,
SPI_BAUDRATEPRESCALER_16,
SPI_BAUDRATEPRESCALER_32,
SPI_BAUDRATEPRESCALER_64,
SPI_BAUDRATEPRESCALER_128,
SPI_BAUDRATEPRESCALER_256
*/
void spi_baud(SPI_HandleTypeDef *hspi,uint32_t baud)
{
hspi->Init.BaudRatePrescaler = baud;
HAL_SPI_Init(hspi);
}
void spi_begin(SPI_HandleTypeDef *hspi)
{
GPIO_TypeDef *port = NULL;
uint32_t gpio_pin;
if(hspi == NULL)
return;
for(uint8_t i=0;SPI_CS_TAB[i].peripheral != NC;i++){
if(hspi->Instance == (SPI_TypeDef *)SPI_CS_TAB[i].peripheral){
port = (GPIO_TypeDef *)SPI_CS_TAB[i].pin_port;
gpio_pin = 1<BSRR = (uint32_t)gpio_pin<<16;
return;
}
}
error("spi cs begin error\r\n");
}
void spi_end(SPI_HandleTypeDef *hspi)
{
GPIO_TypeDef *port = NULL;
uint32_t gpio_pin;
if(hspi == NULL)
return;
for(uint8_t i=0;SPI_CS_TAB[i].peripheral != NC;i++){
if(hspi->Instance == (SPI_TypeDef *)SPI_CS_TAB[i].peripheral){
port = (GPIO_TypeDef *)SPI_CS_TAB[i].pin_port;
gpio_pin = 1<BSRR = (uint32_t)gpio_pin;
return;
}
}
error("spi cs end error\r\n");
}
void spi_transmit(SPI_HandleTypeDef *hspi,uint8_t *pdata,uint16_t size,uint32_t timeout)
{
HAL_SPI_Transmit(hspi,pdata,size,timeout);
}
void spi_receive(SPI_HandleTypeDef *hspi,uint8_t *pdata,uint16_t size,uint32_t timeout)
{
HAL_SPI_Receive(hspi,pdata,size,timeout);
}
void spi_receive_it(SPI_HandleTypeDef *hspi,uint8_t *pdata,uint16_t size)
{
HAL_SPI_Receive_IT(hspi,pdata,size);
}
void spi_irq_set(SPI_HandleTypeDef *hspi,uint32_t preempt_prio,uint32_t sub_prio)
{
IRQn_Type irq;
if(hspi->Instance == SPI1)
irq = SPI1_IRQn;
if(hspi->Instance == SPI2)
irq = SPI2_IRQn;
if(hspi->Instance == SPI3)
irq = SPI3_IRQn;
HAL_NVIC_SetPriority(irq,preempt_prio,sub_prio);
HAL_NVIC_EnableIRQ(irq);
}
void spi_irq_enable(SPI_HandleTypeDef *hspi)
{
IRQn_Type irq;
if(hspi->Instance == SPI1)
irq = SPI1_IRQn;
if(hspi->Instance == SPI2)
irq = SPI2_IRQn;
if(hspi->Instance == SPI3)
irq = SPI3_IRQn;
HAL_NVIC_EnableIRQ(irq);
}
void spi_irq_disable(SPI_HandleTypeDef *hspi)
{
IRQn_Type irq;
if(hspi->Instance == SPI1)
irq = SPI1_IRQn;
if(hspi->Instance == SPI2)
irq = SPI2_IRQn;
if(hspi->Instance == SPI3)
irq = SPI3_IRQn;
HAL_NVIC_DisableIRQ(irq);
}
四、舉例
數碼管顯示配置實例
#include “spi_api.h”
SPI_HandleTypeDef led_spi;
void main(void)
{
spi_init(&led_spi,LED_SDI,LED_SDO,LED_SCK,LED_CS,SPI_NSS_SOFT);
spi_format(&led_spi,SPI_DATASIZE_8BIT,0,0);
spi_end(&led_spi);
發送代碼
spi_begin(&led_spi);
spi_transmit(&led_spi,(uint8_t*)ss_buf,SS_BUF_MAX,1000);
spi_end(&led_spi);
while(1);
}