mbed平臺是基於面向對象的c++語言實現的,serial_api是serial類的底層實現(c語言文件)。有些同學可能想在C工程中直接使用serial_api模塊(本人就是其中之一,也這麼做了,的確比直接調用hal抽象庫要好用一些),可惜的是直接將其用在工程中很明顯是不行的,至少中斷的實現策略就過不去。但是又想用,那麼這麼辦呢?很好辦,自己動手修改serial_api及其相關的底層關聯c文件(官方叫法“移植”),下面請圍觀移植過程:
一、移植文件列表
/* 包含引腳映射相關API */
pinmap.h
/* 引腳API實現 */
pinmap.c
/* gpio引腳命名 */
pinnames.h
/* gpio端口命名 */
portnames.h
/*(將serial_api.h修改爲serial.h) 串口API */
serial.h
/*(將serial_api.c修改爲serial.c)串口API實現 */
serial.c
二、中斷解耦實現策略
其實很簡單,在serial.c文件中定義一個 UART_HandleTypeDef *huart[5]指針數組,爲什麼是5呢?因爲STM32F1系列MCU最多也就5個物理串口外設。分別保存USART1,USART2,USART3,UART4,UART5的實例句柄,在stm32F1xx_it.c調用中斷服務程序是只需要傳入對應的句柄即可,例如:
void USART2_IRQHandler(void)
{
HAL_UART_IRQHandler(huart[1]);
}
在回調函數中則需要加一條判斷語句來處理對應的實例數據,如下:
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance == sensor_serial.Instance){
sensor_rx_ok = SET;
}
}
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance == sensor_serial.Instance){
HAL_UART_Receive_IT(&sensor_serial,(uint8_t *)sensor_rxbuf,64);
}
}
這種策略在進行串口初始化的時候(調用serial_init()時),實現應用實例與物理串口的綁定,從而實現應用時的解耦。當然,還有另外一種實現策略,就是函數指針,但是這種策略需要對每一個物理串口都實現一組接口,沒跟物理串口對應一個id,調用時通過ID來決定執行哪一個中斷服務程序。同時這種策略需要重新設定中斷向量。
三、pinnames.h
重新定義了引腳名稱,使用外設時必須引用這裏的引腳名稱,否則外設將不能正常使用,切記!切記!,同時,該文件是一個全局文件,不是串口外設的私有文件,後續的I2C,SPI,GPIO,TIM,CAN等都會用到此文件。
/**
******************************************************************************
* 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
/**
******************************************************************************
* 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
/**
******************************************************************************
* 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;
}
/**
******************************************************************************
* File Name : serial.h
* Description :
******************************************************************************
*/
#ifndef _SERIAL_H
#define _SERIAL_H
/* inlcude *********************************/
#include "stm32f1xx.h"
typedef enum{
UART_1 = (uint32_t)USART1_BASE,
UART_2 = (uint32_t)USART2_BASE,
UART_3 = (uint32_t)USART3_BASE,
UART_4 = (uint32_t)UART4_BASE,
UART_5 = (uint32_t)UART5_BASE
}UART_NAME;
/**
* 實際使用接口時的調用順序:
* 首先調用serial_init進行默認初始化
* 其次調用serial_baud設定波特率
* 再次調用serial_format格式化串口參數
* 最後調用serial_irq_set配置NVIC全局中斷並使能外部中斷
* */
void serial_init(UART_HandleTypeDef *handle,uint32_t tx,uint32_t rx);
void serial_free(UART_HandleTypeDef *huart);
void serial_baud(UART_HandleTypeDef *huart,uint32_t baud);
void serial_format(UART_HandleTypeDef *huart,uint32_t data_bits,uint32_t parity,uint32_t stop_bits);
void serial_irq_set(UART_HandleTypeDef *huart,uint32_t preempt_prio,uint32_t sub_prio);
void serial_irq_enable(UART_HandleTypeDef *huart);
void serial_irq_disable(UART_HandleTypeDef *huart);
#endif
/**
******************************************************************************
* File Name : serial.c
* Description :
******************************************************************************
*/
#include "serial.h"
#include "pinmap.h"
#include "pinnames.h"
#include "portnames.h"
#include "ierror.h"
#include "iassert.h"
/* private function */
static void init_uart(UART_HandleTypeDef *huart,uint32_t tx,uint32_t rx);
/* variable ************************************************/
/* 外設引腳映射表,每一個外設都會有這麼1個靜態映射表與之對應 */
/* 串口發送引腳TX映射表 */
const static pinmap_t UART_TX_TAB[]= {
{PA_9, GPIOA_BASE,UART_1,0,GPIO_MODE_AF_PP,GPIO_NOPULL},
{PB_6, GPIOB_BASE,UART_1,AFIO_MAPR_USART1_REMAP,GPIO_MODE_AF_PP,GPIO_NOPULL},
{PA_2, GPIOA_BASE,UART_2,0,GPIO_MODE_AF_PP,GPIO_NOPULL},
{PD_5, GPIOD_BASE,UART_2,AFIO_MAPR_USART2_REMAP,GPIO_MODE_AF_PP,GPIO_NOPULL},
{PB_10,GPIOB_BASE,UART_3,0},
{PD_8, GPIOD_BASE,UART_3,AFIO_MAPR_USART3_REMAP_FULLREMAP,GPIO_MODE_AF_PP,GPIO_NOPULL}, /* 全部重映射 */
{PC_10,GPIOC_BASE,UART_4,0,GPIO_MODE_AF_PP,GPIO_NOPULL},
{PC_12,GPIOC_BASE,UART_5,0,GPIO_MODE_AF_PP,GPIO_NOPULL},
{NC, NC, NC, 0,NC, NC}
};
/* 串口發送引腳RX映射表 */
const static pinmap_t UART_RX_TAB[]= {
{PA_10,GPIOA_BASE,UART_1,0,GPIO_MODE_INPUT,GPIO_NOPULL},
{PB_7, GPIOB_BASE,UART_1,AFIO_MAPR_USART1_REMAP,GPIO_MODE_INPUT,GPIO_NOPULL},
{PA_3, GPIOA_BASE,UART_2,0,GPIO_MODE_INPUT,GPIO_NOPULL},
{PD_6, GPIOD_BASE,UART_2,AFIO_MAPR_USART2_REMAP,GPIO_MODE_INPUT,GPIO_NOPULL},
{PB_11,GPIOB_BASE,UART_3,0,GPIO_MODE_INPUT,GPIO_NOPULL},
{PD_9, GPIOD_BASE,UART_3,AFIO_MAPR_USART3_REMAP,GPIO_MODE_INPUT,GPIO_NOPULL},
{PC_11,GPIOC_BASE,UART_4,0,GPIO_MODE_INPUT,GPIO_NOPULL},
{PD_2, GPIOD_BASE,UART_5,0,GPIO_MODE_INPUT,GPIO_NOPULL},
{NC, NC, NC, 0,NC, NC}
};
/* 保存串口實例句柄,用於中斷服務程序 */
UART_HandleTypeDef *huart[5] = {NULL,NULL,NULL,NULL,NULL};
/*****************************************************************************/
void serial_init(UART_HandleTypeDef *handle,uint32_t tx,uint32_t rx)
{
UART_NAME uart = (UART_NAME)NC;
UART_NAME uart_tx = (UART_NAME)pinmap_peripheral(tx,UART_TX_TAB);
UART_NAME uart_rx = (UART_NAME)pinmap_peripheral(rx,UART_RX_TAB);
uart = (UART_NAME)pinmap_merge(uart_tx,uart_rx);
I_ASSERT(uart != (UART_NAME)NC);
handle->Instance = (USART_TypeDef *)uart;
/* enable clock */
if(uart == UART_1){
__HAL_RCC_USART1_CLK_ENABLE();
huart[0] = handle;
}
if(uart == UART_2){
__HAL_RCC_USART2_CLK_ENABLE();
huart[1] = handle;
}
if(uart == UART_3){
__HAL_RCC_USART3_CLK_ENABLE();
huart[2] = handle;
}
if(uart == UART_4){
__HAL_RCC_UART4_CLK_ENABLE();
huart[3] = handle;
}
if(uart == UART_5){
__HAL_RCC_UART5_CLK_ENABLE();
huart[4] = handle;
}
pinmap_pinout(tx,UART_TX_TAB);
pinmap_pinout(rx,UART_RX_TAB);
init_uart(handle,tx,rx);
}
static void init_uart(UART_HandleTypeDef *huart,uint32_t tx,uint32_t rx)
{
huart->Init.BaudRate = 9600;
huart->Init.WordLength = UART_WORDLENGTH_8B;
huart->Init.StopBits = UART_STOPBITS_1;
huart->Init.Parity = UART_PARITY_NONE;
huart->Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart->Init.OverSampling = UART_OVERSAMPLING_16;
if(rx == NC){
huart->Init.Mode = UART_MODE_TX;
}else if(tx == NC){
huart->Init.Mode = UART_MODE_RX;
}else{
huart->Init.Mode = UART_MODE_TX_RX;
}
HAL_UART_Init(huart);
}
void serial_free(UART_HandleTypeDef *huart)
{
if(huart->Instance == USART1){
__USART1_FORCE_RESET();
__USART1_RELEASE_RESET();
__USART1_CLK_DISABLE();
HAL_NVIC_DisableIRQ(USART1_IRQn);
}
if(huart->Instance == USART2){
__USART2_FORCE_RESET();
__USART2_RELEASE_RESET();
__USART2_CLK_DISABLE();
HAL_NVIC_DisableIRQ(USART2_IRQn);
}
if(huart->Instance == USART3){
__USART3_FORCE_RESET();
__USART3_RELEASE_RESET();
__USART3_CLK_DISABLE();
HAL_NVIC_DisableIRQ(USART3_IRQn);
}
if(huart->Instance == UART4){
__UART4_FORCE_RESET();
__UART4_RELEASE_RESET();
__UART4_CLK_DISABLE();
HAL_NVIC_DisableIRQ(UART4_IRQn);
}
if(huart->Instance == UART5){
__UART5_FORCE_RESET();
__UART5_RELEASE_RESET();
__UART5_CLK_DISABLE();
HAL_NVIC_DisableIRQ(UART5_IRQn);
}
}
void serial_baud(UART_HandleTypeDef *huart,uint32_t baud)
{
huart->Init.BaudRate = baud;
HAL_UART_Init(huart);
}
void serial_format(UART_HandleTypeDef *huart,uint32_t data_bits,uint32_t parity,uint32_t stop_bits)
{
huart->Init.WordLength = data_bits;
huart->Init.Parity = parity;
huart->Init.StopBits = stop_bits;
HAL_UART_Init(huart);
}
void serial_irq_set(UART_HandleTypeDef *huart,uint32_t preempt_prio,uint32_t sub_prio)
{
IRQn_Type irq;
if(huart->Instance == USART1)
irq = USART1_IRQn;
if(huart->Instance == USART2)
irq = USART2_IRQn;
if(huart->Instance == USART3)
irq = USART3_IRQn;
if(huart->Instance == UART4)
irq = UART4_IRQn;
if(huart->Instance == UART5)
irq = UART5_IRQn;
HAL_NVIC_SetPriority(irq,preempt_prio,sub_prio);
HAL_NVIC_EnableIRQ(irq);
//NVIC_SetVector(
}
void serial_irq_enable(UART_HandleTypeDef *huart)
{
IRQn_Type irq;
if(huart->Instance == USART1)
irq = USART1_IRQn;
if(huart->Instance == USART2)
irq = USART2_IRQn;
if(huart->Instance == USART3)
irq = USART3_IRQn;
if(huart->Instance == UART4)
irq = UART4_IRQn;
if(huart->Instance == UART5)
irq = UART5_IRQn;
HAL_NVIC_EnableIRQ(irq);
}
void serial_irq_disable(UART_HandleTypeDef *huart)
{
IRQn_Type irq;
if(huart->Instance == USART1)
irq = USART1_IRQn;
if(huart->Instance == USART2)
irq = USART2_IRQn;
if(huart->Instance == USART3)
irq = USART3_IRQn;
if(huart->Instance == UART4)
irq = UART4_IRQn;
if(huart->Instance == UART5)
irq = UART5_IRQn;
HAL_NVIC_DisableIRQ(irq);
}
#include "stm32f1xx_hal.h"
#include "pinnames.h"
/* serial */
#define SENSOR_SERIAL_TX PD_5
#define SENSOR_SERIAL_RX PD_6
/* public variable ***********************************************************/
UART_HandleTypeDef sensor_serial;
uint8_t sensor_txbuf[64]={0};
uint8_t sensor_rxbuf[64]={0};
int32_t sensor_conc = -1;
uint8_t sensor_rx_ok = RESET;
/* Private function prototypes -----------------------------------------------*/
static void SystemClock_Config(void);
int main(void)
{
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* 初始化串口 */
serial_init(&sensor_serial,SENSOR_SERIAL_TX,SENSOR_SERIAL_RX);
serial_irq_set(&sensor_serial,1,0);
HAL_UART_Receive_IT(&sensor_serial,(uint8_t *)sensor_rxbuf,64);
while (1)
{
if(sensor_rx_ok == SET)
{
sensor_rx_ok = RESET;
}
}
}
/** System Clock Configuration
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_PeriphCLKInitTypeDef PeriphClkInit;
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE|RCC_OSCILLATORTYPE_LSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV5;
RCC_OscInitStruct.LSEState = RCC_LSE_OFF;
RCC_OscInitStruct.Prediv1Source = RCC_PREDIV1_SOURCE_PLL2;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL4;
RCC_OscInitStruct.PLL2.PLL2State = RCC_PLL2_ON;
RCC_OscInitStruct.PLL2.PLL2MUL = RCC_PLL2_MUL8;
RCC_OscInitStruct.PLL2.HSEPrediv2Value = RCC_HSE_PREDIV2_DIV5;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
{
Error_Handler();
}
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC;
PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
__HAL_RCC_PLLI2S_ENABLE();
/* SysTick_IRQn interrupt configuration */
HAL_NVIC_SetPriority(SysTick_IRQn, 15, 0);
}
/* usart callback function *********************************************/
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance == sensor_serial.Instance){
sensor_rx_ok = SET;
}
}
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance == sensor_serial.Instance){
HAL_UART_Receive_IT(&sensor_serial,(uint8_t *)sensor_rxbuf,64);
}
}
{
uint16_t* tmp;
uint32_t tmp_state = 0;
tmp_state = huart->State;
if((tmp_state == HAL_UART_STATE_BUSY_RX) || (tmp_state == HAL_UART_STATE_BUSY_TX_RX))
{
if(huart->Init.WordLength == UART_WORDLENGTH_9B)
{
tmp = (uint16_t*) huart->pRxBuffPtr;
if(huart->Init.Parity == UART_PARITY_NONE)
{
*tmp = (uint16_t)(huart->Instance->DR & (uint16_t)0x01FF);
huart->pRxBuffPtr += 2;
}
else
{
*tmp = (uint16_t)(huart->Instance->DR & (uint16_t)0x00FF);
huart->pRxBuffPtr += 1;
}
}
else
{
if(huart->Init.Parity == UART_PARITY_NONE)
{
*huart->pRxBuffPtr++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FF);
}
else
{
*huart->pRxBuffPtr++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x007F);
}
}
// if(--huart->RxXferCount == 0)
if(*(huart->pRxBuffPtr-1) == '\n')
{
__HAL_UART_DISABLE_IT(huart, UART_IT_RXNE);
/* Check if a transmit process is ongoing or not */
if(huart->State == HAL_UART_STATE_BUSY_TX_RX)
{
huart->State = HAL_UART_STATE_BUSY_TX;
}
else
{
/* Disable the UART Parity Error Interrupt */
__HAL_UART_DISABLE_IT(huart, UART_IT_PE);
/* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
__HAL_UART_DISABLE_IT(huart, UART_IT_ERR);
huart->State = HAL_UART_STATE_READY;
}
HAL_UART_RxCpltCallback(huart);
return HAL_OK;
}
return HAL_OK;
}
else
{
return HAL_BUSY;
}
}