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);
}
}