从新建工程开始使用C++开发单片机(以STM32为例):五、串口篇(2)C++串口封装HardwareUART类(附代码)

一、HardwareUART介绍

之前的文章中介绍过了串口的c语言接口,并通过这些接口完成初始化、和串口读写功能。HardwareUART类主要基于这些接口进行封装,并且继承了outputStream和inputStream类的收发功能。在介绍outputStream和inputStream类中说过,outputStream设置了纯虚函数让子类来实现,使得不同的输出硬件可以使用相同的接口,inputStream的本质为接收缓存区的管理,所以HardwareUART类只需要完成串口的初始化函数、outputStream的纯虚函数、将inputStream的串口缓冲区指针指向串口对应的接收缓冲区,即可通过串口实现子类的收发功能,并不需要再去写许多复杂的发送/接收的代码。
在这里插入图片描述
以下为HardwareUART的声明:

class HardwareUART : public outputStream, public inputStream
{
    UART_enum uart_x;
    int baudrate;
    void set_buf_ptr();

public:
    HardwareUART(UART_enum uart)
    {
        // uart_init(uart, baudrate);
        uart_x = uart;
        set_buf_ptr();
    };

    int begin(int buadrate_in = 115200)
    {
        baudrate = buadrate_in;
        uart_init(uart_x, buadrate_in);
        return 1;
    };
    int end() { return 1; };

    virtual size_t write(uint8_t);
    virtual size_t write(const uint8_t *buffer, size_t size);
};

HardwareUART主要包含以下几个公共成员函数:
在这里插入图片描述

二、方法介绍

1.构造函数HardwareUART(UART_enum uart):
HardwareUART构造是需要传入一个串口的枚举,告诉类这个对象是哪个串口的。每一个串口对应一个对象。
对象声明后,不同串口间的使用互不干扰。
串口的枚举在my_usart.h文件中:

typedef enum
{
#ifdef HAVE_SERIAL1
  UART_1 = (uint32_t)USART1,
#endif
#ifdef HAVE_SERIAL2
  UART_2 = (uint32_t)USART2,
#endif
#ifdef HAVE_SERIAL3
  UART_3 = (uint32_t)USART3,
#endif
#ifdef HAVE_SERIAL4
  UART_4 = (uint32_t)UART4,
#endif
#ifdef HAVE_SERIAL5
  UART_5 = (uint32_t)UART5,
#endif
  UART_END//占位,没有用
} UART_enum;

示例:

HardwareUART Serial1(UART_1);
HardwareUART Serial2(UART_2);
//串口1和串口2分别对应两个对象,可以独立使用,其他串口也一样

2.初始化和释放:
初始化:int begin(int buadrate_in = 115200)
初始化一个串口并设定波特率(默认为115200),由于底层的C接口还不支持设置校验位、停止位等,所以目前还不能设置相关的参数(等以后添加了再来补充)。
释放:int end()释放串口资源
由于底层没有写释放的接口,所以暂时还没有用~
示例:

Serial1.begin(9600);//初始化串口1,并设置波特率位9600
Serial2.begin();//初始化串口2,比特率缺省值位115200既默认设置位115200

3.串口收发接口:
串口的收发功能继承自outputStream和inputStream类。
对于发送的函数,重写了size_t write(uint8_t); size_t write(const uint8_t *buffer, size_t size);两个来自基类的虚函数。

size_t HardwareUART::write(uint8_t data)
{
    uart_write_byte(uart_x, data);
    return 0;
}

size_t HardwareUART::write(const uint8_t *buffer, size_t size)
{
    uart_write_buffer(uart_x, buffer, size);
    return 0;
}

发送功能则是将基类的缓冲区指针指向了串口接收缓冲区。
使用示例:
收发功能的使用方法在之前介绍outputStream和inputStream类的文章中已经介绍的很详细了就,就不来凑字数了
从新建工程开始使用C++开发单片机(以STM32为例):六、C++输入输出流(附代码)

总结

从这里开始,使用设计outputStream和inputStream类的好处就已经体现出来了,可以看到只需要完成串口初始化以及覆盖基类的虚函数之后,串口类基本上不需要写很多的代码就可以完成强大的功能。而单片机中还有SPI、I2C等串行接口,以及屏幕的输出设备,都可以继承基类,只需要写很少的代码就可以实现其对应的功能。
并且由于硬件的底层操作都是在C语言层完成,所以在不同的单片机之间移植也会非常容易,只需要重写C语言的初始化、输出和接收接口就能非常轻松地移植这个类,节省大量地精力和时间。

代码

//file:hardWareUART.h
#ifndef __MCU_HARDWARE_HARDWARE_UART_H
#define __MCU_HARDWARE_HARDWARE_UART_H

#include "headfile.h"
#include "outputStream.h"
#include "inputStream.h"

class HardwareUART : public outputStream, public inputStream
{
    UART_enum uart_x;
    int baudrate;
    void set_buf_ptr();

public:
    HardwareUART(UART_enum uart)
    {
        // uart_init(uart, baudrate);
        uart_x = uart;
        set_buf_ptr();
    };

    int begin(int buadrate_in = 115200)
    {
        baudrate = buadrate_in;
        uart_init(uart_x, buadrate_in);
        return 1;
    };
    int end() { return 1; };

    virtual size_t write(uint8_t);
    virtual size_t write(const uint8_t *buffer, size_t size);
};

#endif
//file:hardwareUART.cpp
#include "hardwareUART.h"

void HardwareUART::set_buf_ptr()
{
    switch (uart_x)
    {
#ifdef HAVE_SERIAL1
    case UART_1:
        buf = &UART1_recbuf;
        return;
#endif
#ifdef HAVE_SERIAL2
    case UART_2:
        buf = &UART2_recbuf;
        return;
#endif
#ifdef HAVE_SERIAL3
    case UART_3:
        buf = &UART3_recbuf;
        return;
#endif
#ifdef HAVE_SERIAL4
    case UART_4:
        buf = &UART4_recbuf;
        return;
#endif
#ifdef HAVE_SERIAL5
    case UART_5:
        buf = &UART5_recbuf;
        return;
#endif
    default:
        buf = 0;
        return;
    }
}

size_t HardwareUART::write(uint8_t data)
{
    uart_write_byte(uart_x, data);
    return 0;
}

size_t HardwareUART::write(const uint8_t *buffer, size_t size)
{
    uart_write_buffer(uart_x, buffer, size);
    return 0;
}


  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值