stm32基于HAL库的uart外设的封装

项目开发中经常遇到uart的项目,各种不同外设,要求五花八门。在这过程中对uart的操作进行抽象。

封装:

1. 不同模式 polling it  DMA

2. 是否启用空闲中断

3. 不同接口,ttl  rs232 rs485 max3160

bsp_uart.h

#ifndef __BSP_UART_H
#define __BSP_UART_H

#include "stm32f4xx.h"

/**
* 封装不同使用类型串口  232  485 max3160
* 包含发送回调的GPIO操作
* 其他回调外部处理
*/
/*  485 3160 启用一个, 两个接口都有 MAX3160_ENABLE */
#define MAX485_ENABLE  0
#define MAX3160_ENABLE 1

#ifdef __cplusplus
	extern "C" {
#endif

#include <stdlib.h>
#include "main.h"

typedef enum 
{
  Uart_Interface_Default       	= 0x00U,
  Uart_Interface_485   			= 0x01U,
  Uart_Interface_Max3160_232     = 0x02U,
  Uart_Interface_Max3160_485     = 0x03U,
} Uart_Interface_Type_Typedef; 


typedef enum 
{
  Uart_Trans_Polling       	= 0x00U,
  Uart_Trans_IT   	= 0x01U,
  Uart_Trans_DMA     = 0x02U,
} Uart_Transmode_TypeDef;
 
typedef enum 
{
  Uart_IDLE_IT_DISABLE       	= 0x00U,
  Uart_IDLE_IT_ENABLE   	= 0x01U,
} Uart_IDLE_Enable_TypeDef;
 
typedef struct
{
    uint32_t size;
    uint8_t *buf;
}Record_Trans_Rcv_TypeDef;

/* -----------------------    variables     ---------------------------------*/
// extern UART_HandleTypeDef huart3;
// UART_HandleTypeDef *puarthelper = &huart3;

typedef  void ( *enable_func_gpio)  (void);
typedef  int ( *callback_fun)  (void *obj, void *buf, uint16_t size);

typedef struct 
{
	UART_HandleTypeDef *huart;
	Uart_Interface_Type_Typedef  interface_type; /* 0: default(TTL 232), 1: 485 ,2:3160-232  3: 3160-485*/
	Uart_IDLE_Enable_TypeDef enable_idle_it;

	Uart_Transmode_TypeDef trans_mode; /* 0 :polling, 1: IT  2: DMA*/
	Uart_Transmode_TypeDef rcv_mode;

	Record_Trans_Rcv_TypeDef *trans_record;
	// Record_Trans_Rcv_TypeDef *rcv_record;

	// uint8_t *trans_buf;
	// uint16_t trans_size;
	uint8_t *rcv_buf;
	uint16_t rcv_size;

	volatile uint8_t send_flag;
	volatile uint8_t send_tc_flag;  /* 0 开始发送, 1 发送完成*/
	volatile uint8_t transferring;
	// uint32_t timebase;

	enable_func_gpio enable_trans_gpio;
	enable_func_gpio enable_trans_cplt_gpio;

	void * obj;
	callback_fun callback;

	//  这个是供外部调用的; 中断是统一管理的, 中断会找到这里的接收回调,然后返回回去


// #if MAX485_ENABLE
// 	GPIO_TypeDef *de485_gpio;
// 	uint16_t de485_pin;
//     uint8_t de485;
// #endif

// #if MAX3160_ENABLE
// 	GPIO_TypeDef *de485_gpio;
// 	uint16_t de485_pin;
// 	GPIO_TypeDef *sel_gpio;
// 	GPIO_TypeDef *dplx_gpio;
// 	uint16_t sel_pin;
// 	uint16_t dplx_pin;
//     uint8_t sel;
//     uint8_t dplx;
// #endif

    // uint8_t dplx;
    // uint8_t sel;
    // uint8_t de485;
}UART_HELPER_TypeDef;

extern UART_HELPER_TypeDef *uarthelper;

UART_HELPER_TypeDef * UART_HELPER_Init( );
void UART_HELPER_Set_Huart(UART_HELPER_TypeDef * uarthelper, UART_HandleTypeDef *huart);
int UART_HELPER_Set_Interface_Type(UART_HELPER_TypeDef * uarthelper, uint8_t interface_type);

int UART_HELPER_Setup_Trans_mode( UART_HELPER_TypeDef * uarthelper, uint8_t trans_mode );
int UART_HELPER_Setup_Rcv_mode( UART_HELPER_TypeDef * uarthelper, uint8_t rcv_mode );

int UART_HELPER_Set_trans_GPIO( UART_HELPER_TypeDef * uarthelper, enable_func_gpio trans_gpio_func );
int UART_HELPER_Set_trans_cplt_GPIO( UART_HELPER_TypeDef * uarthelper, enable_func_gpio trans_cplt_gpio_func );
 
int UART_HELPER_Set_enable_idle( UART_HELPER_TypeDef * uarthelper, uint8_t enable_idle);

int UART_HELPER_Set_Rcv_Buf( UART_HELPER_TypeDef * uarthelper, uint8_t * buf, uint16_t size);
int UART_HELPER_Set_Trans_Buf( UART_HELPER_TypeDef * uarthelper, uint8_t * buf, uint16_t size);

int UART_HELPER_Set_Callback( UART_HELPER_TypeDef * uarthelper, void *obj, callback_fun func);


int UART_HELPER_Trans(UART_HELPER_TypeDef * uarthelper, uint8_t *buf, uint16_t size);
// int __UART_HELPER_Trans(UART_HELPER_TypeDef * uarthelper , uint8_t *buf, uint16_t size);
int UART_HELPER_Trans_TxCplt_Callback( UART_HELPER_TypeDef * uarthelper );
/* 接收方式 也有三种类型 */
int UART_HELPER_Start_Rcv(UART_HELPER_TypeDef * uarthelper, uint8_t *buf, uint16_t size);

int UART_HELPER_RCV_Cplt_Callback( UART_HELPER_TypeDef * uarthelper );
int UART_HELPER_RCV_IDLE_Callback( UART_HELPER_TypeDef * uarthelper, uint16_t size );

#endif

bsp_uart.c

#include "bsp_uart.h"
#include "elog.h"

UART_HELPER_TypeDef * UART_HELPER_Init( )
{
    UART_HELPER_TypeDef *Handle = (UART_HELPER_TypeDef *)malloc(sizeof(UART_HELPER_TypeDef));
    if (Handle == NULL)
    {
        return NULL;
    }
	Handle->interface_type = Uart_Interface_Default;
	Handle->enable_idle_it = Uart_IDLE_IT_DISABLE;
	Handle->trans_mode = Uart_Trans_Polling;
	Handle->rcv_mode = Uart_Trans_Polling;

	Handle->trans_record = (Record_Trans_Rcv_TypeDef *)malloc(sizeof(Record_Trans_Rcv_TypeDef));
	// Handle->rcv_record = (Record_Trans_Rcv_TypeDef *)malloc(sizeof(Record_Trans_Rcv_TypeDef));

	Handle->send_flag = 0;
	Handle->send_tc_flag = 0;
	Handle->transferring = 0;

	Handle->enable_trans_gpio =NULL;
	Handle->enable_trans_cplt_gpio =NULL;

	Handle->obj =NULL;
	Handle->callback =NULL;
    return Handle;
}

void UART_HELPER_Set_Huart(UART_HELPER_TypeDef * uarthelper, UART_HandleTypeDef *huart)
{
    uarthelper->huart = huart;
}

int UART_HELPER_Set_Interface_Type(UART_HELPER_TypeDef * uarthelper, uint8_t interface_type)
{
	uarthelper->interface_type = interface_type;
	return 0;
}

int UART_HELPER_Setup_Trans_mode( UART_HELPER_TypeDef * uarthelper, uint8_t trans_mode )
{
    /* 0 :polling, 1: IT  2: DMA*/
	uarthelper->trans_mode = trans_mode;
	uarthelper->rcv_mode = trans_mode;
	return 0;
}

int UART_HELPER_Setup_Rcv_mode( UART_HELPER_TypeDef * uarthelper, uint8_t rcv_mode )
{
    /* 0 :polling, 1: IT  2: DMA*/
	uarthelper->rcv_mode = rcv_mode;
	return 0;    
}

int UART_HELPER_Set_trans_GPIO( UART_HELPER_TypeDef * uarthelper, enable_func_gpio trans_gpio_func )
{
	uarthelper->enable_trans_gpio = trans_gpio_func;
	return 0;
}

int UART_HELPER_Set_trans_cplt_GPIO( UART_HELPER_TypeDef * uarthelper, enable_func_gpio trans_cplt_gpio_func )
{
    // enable rcv
    uarthelper->enable_trans_cplt_gpio = trans_cplt_gpio_func;
	return 0;
}



int UART_HELPER_Set_enable_idle( UART_HELPER_TypeDef * uarthelper, uint8_t enable_idle)
{
	uarthelper->enable_idle_it = enable_idle;
	return 0;
}


int UART_HELPER_Set_Rcv_Buf( UART_HELPER_TypeDef * uarthelper, uint8_t * buf, uint16_t size)
{
	uarthelper->rcv_buf = buf;
	uarthelper->rcv_size = size;

	// uarthelper->rcv_record->buf = buf;
	// uarthelper->rcv_record->size = size;

	return 0;

}
int UART_HELPER_Set_Trans_Buf( UART_HELPER_TypeDef * uarthelper, uint8_t * buf, uint16_t size)
{
	// uarthelper->trans_buf = buf;
	// uarthelper->trans_size = size;

	uarthelper->trans_record->buf = buf;
	uarthelper->trans_record->size = size;

	return 0;

}

int UART_HELPER_Set_Callback( UART_HELPER_TypeDef * uarthelper, void *obj, callback_fun func)
{
	uarthelper->obj = obj;
	uarthelper->callback = func;
	return 0;
}

int UART_HELPER_Start_Rcv(UART_HELPER_TypeDef * uarthelper, uint8_t *buf, uint16_t size)
{
	int st;
    switch ( uarthelper->rcv_mode)
    {
        case 0:
            st = HAL_UART_Receive(uarthelper->huart,  buf,  size  , 0xFFFF);
            return st;
            break;
        case 1:
            st = HAL_UART_Receive_IT(uarthelper->huart,  buf,  size);
            return st;
            break;
        case 2:
            /* 会出现 st ==2  huart->gState != HAL_UART_STATE_READY */
			if (uarthelper->enable_idle_it == 1) 
			{
            // log_i("dma rcv idle en... ");
				__HAL_UART_ENABLE_IT(uarthelper->huart, UART_IT_IDLE);
			}
            st = HAL_UART_Receive_DMA(uarthelper->huart,  buf,  size);
            // log_i("dma rcv ... ");
            return st;
            break;    
        default:
            break;
    }
    return st;
}

int UART_HELPER_Trans(UART_HELPER_TypeDef * uarthelper, uint8_t *buf, uint16_t size )
{
	int st;
    uarthelper->transferring = 1;
	if (uarthelper->enable_trans_gpio != NULL)
	{
		uarthelper->enable_trans_gpio();
	}

    switch ( uarthelper->trans_mode)
    {
        case 0:
            st = HAL_UART_Transmit(uarthelper->huart,  buf,  size  , 0xFFFF);
            return st;
            break;
        case 1:
            st = HAL_UART_Transmit_IT(uarthelper->huart,  buf,  size);
            return st;
            break;
        case 2:
            /* 会出现 st ==2  huart->gState != HAL_UART_STATE_READY */
            st = HAL_UART_Transmit_DMA(uarthelper->huart,  buf,  size);
            return st;
            break;    
        default:
            break;
    }
    return st;
}


int UART_HELPER_Trans_TxCplt_Callback( UART_HELPER_TypeDef * uarthelper )
{
    // log_i( " uarthelper tc callback...........");
    uarthelper->transferring = 0;
	if (uarthelper->enable_trans_cplt_gpio != NULL)
	{
        // log_i( " uarthelper tc callback... not null........");
		uarthelper->enable_trans_cplt_gpio();
	}
    return 0;
}

int UART_HELPER_RCV_Cplt_Callback( UART_HELPER_TypeDef * uarthelper )
{
    log_i( " UART_HELPER_RCV_Cplt_Callback  ........");

    // TODO
    
    if (uarthelper->enable_idle_it == 0)
    {
        uarthelper->callback( uarthelper->obj, uarthelper->rcv_buf,uarthelper->rcv_size);
    }
    if (uarthelper->enable_idle_it == 1)
    {
        // idle 中断处理, do nothing
    }
    return 0;
}


int UART_HELPER_RCV_IDLE_Callback( UART_HELPER_TypeDef * uarthelper, uint16_t size )
{
    // TODO
    // if (uarthelper->rcv_mode == 0)
    // {
    //     HAL_UART_DMAStop( uarthelper->huart );
    // }
        
    HAL_UART_DMAStop( uarthelper->huart );
    uarthelper->callback( uarthelper->obj, uarthelper->rcv_buf, size);
    UART_HELPER_Start_Rcv(uarthelper, uarthelper->rcv_buf, uarthelper->rcv_size);
    return 0;
}

调用方法

typedef struct 
{
    int (*init)(void);
    void (*port)(void);
    int (*test)(void);
    void (*start)(void);
    void (*stop)(void);
    osMessageQueueId_t cmdQueue;  // 队列可选

    volatile Module_PH_State_TypeDef state; 
    uint8_t data_ok;                 /* 接收数据完整可以处理 */

    uint8_t result_buf[1024];
    uint8_t size_received;

    uint64_t  timebase_ticks;
    uint64_t  timeout_ticks;
    uint8_t  event_flag;

}PH_TypeDef;

PH_TypeDef  ph ={
    PH_Init,
    PH_Port,
    PH_Test,
    PH_Start,
    PH_Stop,
    NULL,
    0,      // state
    0,      // data_ok
    {0},    // buf
    0,      // size_received
    0,      // time base
    1000,      // timeout ticks,  1000ms = 1S
    0,          // event_flag
};

int PH_Init( )
{
    ph_uart_helper = UART_HELPER_Init( );

    if (ph_uart_helper ==NULL)  return -1;

    // TODO 接口
    UART_HELPER_Set_Huart( ph_uart_helper, pPHUart );
    UART_HELPER_Set_Interface_Type(ph_uart_helper, Uart_Interface_Max3160_485);

    //  传输
    UART_HELPER_Setup_Trans_mode(  ph_uart_helper, Uart_Trans_DMA);
    // UART_HELPER_Setup_Rcv_mode( ph_uart_helper, Uart_Trans_IT );
    UART_HELPER_Set_enable_idle(  ph_uart_helper, Uart_IDLE_IT_ENABLE);

    //  回调GPIO 操作 数据操作
    UART_HELPER_Set_trans_GPIO(  ph_uart_helper, PH_Trans_GPIO );  // enbale rcv
    UART_HELPER_Set_trans_cplt_GPIO( ph_uart_helper, PH_Trans_Cplt_GPIO );

    UART_HELPER_Set_Callback( ph_uart_helper,&ph, PH_CallBack );

    // 设置 Buf
    UART_HELPER_Set_Rcv_Buf(ph_uart_helper, PH_RCV_BUF, sizeof(PH_RCV_BUF));
    UART_HELPER_Set_Trans_Buf( ph_uart_helper, PH_TRANS_BUF, sizeof(PH_TRANS_BUF) );

    //  GPIO 操作
    switch (ph_uart_helper->interface_type)
    {
        case Uart_Interface_Default:
            break;
        case Uart_Interface_485:
            usart6_send_enable();   
            break;
        case Uart_Interface_Max3160_232:
            PH_MAX3160_232();
            break;
        case Uart_Interface_Max3160_485:
            max3160_485_receive_mode();
            break;    
        default:
            break;
    }
    ph.state = PH_State_Waiting;
    ph.timebase_ticks = osKernelGetTickCount( );
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值