IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 从新建工程开始使用C++开发单片机(以STM32为例):五、串口篇(2)C++串口封装HardwareUART类(附代码) -> 正文阅读

[嵌入式]从新建工程开始使用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;
}


  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-08-19 19:22:29  更:2022-08-19 19:24:26 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 22:46:05-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码