打印

(转)GD32 USART 高级编程 让你的串口不在阻塞发送

[复制链接]
1776|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
wakayi|  楼主 | 2018-7-27 10:17 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式


  • #ifndef __USART_H__



  • #define __USART_H__







  • #include "stdio.h"







  • //#define infoprintf  printf("[%d-%s()] : ",__LINE__, __FUNCTION__);printf



  • #define infoprintf(...)











  • int usart_init(int usart_num, int baud_rate);



  • int usart_send(int usart_num, const void *_send_buf, const int send_count);



  • int usart_send_it(int usart_num, const void *_send_buf, const int send_count);



  • int usart_receive_read(int usart_num, void *_receive_buf, const int receive_count);



  • void usart_rbne_it(int usart_num);



  • void usart_tbe_it(int usart_num);



  • #endif


沙发
wakayi|  楼主 | 2018-7-27 10:18 | 只看该作者
/*******************************************************************************
file : platform_uasrt.c
author : huohongpeng
date : 2017-01-25
description : advance application for usart, base on gd lib
*******************************************************************************/
#include "platform_usart.h"
#include "gd32f1x0.h"

#define TX_BUF_SIZE 128
#define RX_BUF_SIZE 128

struct usart_dev
{
    unsigned char tx_buf[TX_BUF_SIZE];
    unsigned short tx_rd;
    unsigned short tx_wr;
    unsigned char rx_buf[RX_BUF_SIZE];
    unsigned short rx_rd;
    unsigned short rx_wr;
};

static struct usart_dev usart1_dev, usart2_dev;

/**
description : init uasrt1 and set baud rate
param :  usart_num - 1,2
         baud_rate - 4800,9600,14400, ...
retval : 0 - success
author : huohongpeng
date : 2017-01-25
*/
int usart_init(int usart_num, int baud_rate)
{
    GPIO_InitPara GPIO_InitParaStruct;
    USART_InitPara USART_InitParaStruct;
    USART_TypeDef * usart_index[] = {0, USART1, USART2};

    if(usart_num == 1)
    {
        RCC_APB2PeriphClock_Enable(RCC_APB2PERIPH_USART1, ENABLE);
        RCC_AHBPeriphClock_Enable(RCC_AHBPERIPH_GPIOA, ENABLE);

        /*usart1 Rx*/
        GPIO_InitParaStruct.GPIO_Mode = GPIO_MODE_AF;
        GPIO_InitParaStruct.GPIO_Pin = GPIO_PIN_10;
        GPIO_InitParaStruct.GPIO_PuPd = GPIO_PUPD_PULLUP;
        GPIO_InitParaStruct.GPIO_Speed = GPIO_SPEED_2MHZ;
        GPIO_Init(GPIOA, &GPIO_InitParaStruct);

        /*usart1 Tx*/
        GPIO_InitParaStruct.GPIO_Mode = GPIO_MODE_AF;
        GPIO_InitParaStruct.GPIO_OType = GPIO_OTYPE_PP;
        GPIO_InitParaStruct.GPIO_Pin = GPIO_PIN_9;
        GPIO_InitParaStruct.GPIO_Speed = GPIO_SPEED_2MHZ;
        GPIO_Init(GPIOA, &GPIO_InitParaStruct);
      
        GPIO_PinAFConfig(GPIOA, GPIO_PINSOURCE10, GPIO_AF_1);
        GPIO_PinAFConfig(GPIOA, GPIO_PINSOURCE9, GPIO_AF_1);
    }
    else if(usart_num == 2)
    {
        RCC_APB1PeriphClock_Enable(RCC_APB1PERIPH_USART2, ENABLE);
        RCC_AHBPeriphClock_Enable(RCC_AHBPERIPH_GPIOA, ENABLE);

        /*usart2 Rx*/
        GPIO_InitParaStruct.GPIO_Mode = GPIO_MODE_AF;
        GPIO_InitParaStruct.GPIO_Pin = GPIO_PIN_15;
        GPIO_InitParaStruct.GPIO_PuPd = GPIO_PUPD_PULLUP;
        GPIO_InitParaStruct.GPIO_Speed = GPIO_SPEED_2MHZ;
        GPIO_Init(GPIOA, &GPIO_InitParaStruct);

        /*usart2 Tx*/
        GPIO_InitParaStruct.GPIO_Mode = GPIO_MODE_AF;
        GPIO_InitParaStruct.GPIO_OType = GPIO_OTYPE_PP;
        GPIO_InitParaStruct.GPIO_Pin = GPIO_PIN_14;
        GPIO_InitParaStruct.GPIO_Speed = GPIO_SPEED_2MHZ;
        GPIO_Init(GPIOA, &GPIO_InitParaStruct);
      
        GPIO_PinAFConfig(GPIOA, GPIO_PINSOURCE14, GPIO_AF_1);
        GPIO_PinAFConfig(GPIOA, GPIO_PINSOURCE15, GPIO_AF_1);
    }
    else
    {
        return -1;
    }

    /*usartx attribute config*/
    USART_InitParaStruct.USART_BRR = baud_rate;
    USART_InitParaStruct.USART_HardwareFlowControl = USART_HARDWAREFLOWCONTROL_NONE;
    USART_InitParaStruct.USART_Parity = USART_PARITY_RESET;
    USART_InitParaStruct.USART_RxorTx = USART_RXORTX_RX |USART_RXORTX_TX;
    USART_InitParaStruct.USART_STBits = USART_STBITS_1;
    USART_InitParaStruct.USART_WL = USART_WL_8B;
    USART_Init(usart_index[usart_num], &USART_InitParaStruct);

    USART_Enable(usart_index[usart_num], ENABLE);
    USART_INT_Set(usart_index[usart_num], USART_INT_RBNE, ENABLE);

    return 0;
}

/**
description : usart send send_count characters
param : usart_num - 1, 2
        _send_buf - send buffer
        send_count - number of send
retval : 0 - success
author : huohongpeng
date : 2017-01-25
*/
int usart_send(int usart_num, const void *_send_buf, const int send_count)
{
    const char *send_buf = (const char *)_send_buf;
    USART_TypeDef * usart_index[] = {0, USART1, USART2};
    int i;

    if(usart_num < 1 || usart_num > 2)
    {
        return -1;
    }

    USART_INT_Set(usart_index[usart_num], USART_INT_RBNE, DISABLE);

    for(i = 0; i < send_count; i++)
    {
        while(USART_GetBitState(usart_index[usart_num], USART_FLAG_TBE) == RESET);
        USART_DataSend(usart_index[usart_num], send_buf[i]);     
    }
   
    USART_INT_Set(usart_index[usart_num], USART_INT_RBNE, ENABLE);

    return 0;
}

/**
description : rewrite fputc for printf
param : ...
retval : 0 - success
author : huohongpeng
date : 2017-01-25
other :
options->C/C++ compiler->preprocessor add symbal _DLIB_FILE_DESCRIPTOR
*/
int fputc(int ch, FILE  *f)
{
    usart_send_it(1, &ch, 1);
    return ch;
}

/**
description : usart send base on usart send interrupt
param : usart_num - 1, 2
        _send_buf - send buffer
        send_count - number of send
retval : 0 - success
author : huohongpeng
date : 2017-01-26
*/
int usart_send_it(int usart_num, const void *_send_buf, const int send_count)
{
    struct usart_dev *usart_dev;
    struct usart_dev *usart_dev_index[] = {0, &usart1_dev, &usart2_dev};
    USART_TypeDef* usart_index[] = {0, USART1, USART2};
    const char *send_buf = (const char *)_send_buf;
    int i;
   
    if(usart_num < 1 || usart_num > 2)
    {
        return -1;
    }

    usart_dev = usart_dev_index[usart_num];
    /*
     Write send data to send buffer and use interrupt send data.
     Wait buffer effective when send buffer is full.
     */
    for(i = 0; i < send_count; i++)
    {      
        while((usart_dev->tx_wr+1) % TX_BUF_SIZE == usart_dev->tx_rd);
        usart_dev->tx_buf[usart_dev->tx_wr++] = send_buf[i];     
        usart_dev->tx_wr %= TX_BUF_SIZE;
        USART_INT_Set(usart_index[usart_num], USART_INT_TBE, ENABLE);
    }
   
    return 0;
}


/**
description : read data from receive buffer
param : usart_num - 1, 2
        _receive_buf - receive buffer
        receive_count - number of receive
retval : -1 - success
         other - real read count
author : huohongpeng
date : 2017-01-26
*/
int usart_receive_read(int usart_num, void *_receive_buf, const int receive_count)
{
    struct usart_dev *usart_dev;
    struct usart_dev *usart_dev_index[] = {0, &usart1_dev, &usart2_dev};
    char *receive_buf = (char *)_receive_buf;
    int i, receive_count_real;
   
    if(usart_num < 1 || usart_num > 2)
    {
        return -1;
    }

    usart_dev = usart_dev_index[usart_num];

    /*
     Read data from receive buffer.
     The buffer have data that received from usart.
    */

    for(i = 0, receive_count_real = 0; i < receive_count; i++)
    {
        if(usart_dev->rx_rd == usart_dev->rx_wr)
        {
            return receive_count_real;
        }
        else
        {
            receive_buf[i] = usart_dev->rx_buf[usart_dev->rx_rd++];
            usart_dev->rx_rd %= RX_BUF_SIZE;
            receive_count_real++;
        }
    }

    return receive_count_real;
}

/**
description : usart receive not empty interrupt hander, call in intterrupt function
param : usart_num - 1, 2
retval : None
author : huohongpeng
date : 2017-01-26
*/
void usart_rbne_it(int usart_num)
{
    struct usart_dev *usart_dev;
    struct usart_dev *usart_dev_index[] = {0, &usart1_dev, &usart2_dev};
    USART_TypeDef* usart_index[] = {0, USART1, USART2};

    if(usart_num < 1 || usart_num > 2)
    {
        return;
    }
   
    usart_dev = usart_dev_index[usart_num];

    usart_dev->rx_buf[usart_dev->rx_wr++] = USART_DataReceive(usart_index[usart_num]);
    usart_dev->rx_wr %= RX_BUF_SIZE;

    /*
        overflow handle
    */
    if(usart_dev->rx_wr == usart_dev->rx_rd)
    {
        usart_dev->rx_rd++;
        usart_dev->rx_rd %= RX_BUF_SIZE;
    }
}

/**
description : usart transport empty interrupt hander, call in intterrupt function
param : usart_num - 1, 2
retval : None
author : huohongpeng
date : 2017-01-26
*/
void usart_tbe_it(int usart_num)
{
    struct usart_dev *usart_dev;
    struct usart_dev *usart_dev_index[] = {0, &usart1_dev, &usart2_dev};
    USART_TypeDef* usart_index[] = {0, USART1, USART2};

    if(usart_num < 1 || usart_num > 2)
    {
        return;
    }
   
    usart_dev = usart_dev_index[usart_num];

    if(usart_dev->tx_rd != usart_dev->tx_wr)
    {
        USART_DataSend(usart_index[usart_num], usart_dev->tx_buf[usart_dev->tx_rd++]);
        usart_dev->tx_rd %= TX_BUF_SIZE;
    }
    else
    {
        USART_INT_Set(usart_index[usart_num], USART_INT_TBE, DISABLE);
    }
}

使用特权

评论回复
板凳
jerow| | 2018-7-27 10:30 | 只看该作者
收藏学习下,有移植过程吗?有点没看懂

使用特权

评论回复
地板
观海| | 2018-7-28 09:56 | 只看该作者
我瞅了瞅 没太明白 难道GD的这个串口和别的串口不同吗

使用特权

评论回复
5
labasi| | 2018-8-6 12:52 | 只看该作者
看着没有什么热别的地方

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

88

主题

4087

帖子

1

粉丝