HPM6750系列--第十一篇 Uart讲解(轮询模式)

news2024/9/28 9:25:47

一、目的

        在介绍完GPIO的相关内容下一个必须介绍的就是uart了,因为串口一个主要用途就是用于调试信息打印。

        HPM6750在uart的配置上也是相当炸裂,有17个串口;结合HPM6750的高主频高内存,完全可以作为一个串口服务器。

        ​​​​​​​

        

二、介绍

        1.框图 

        TX FIFO 包含待发送的数据,并将数据传送到 TX 移位寄存器。TX 移位寄存器为并行-串行转换器,把发送数据转换成串行的比特流。

        TXFIFO 的写入口是THR寄存器 (Transmitter Holding Register)。用户需要把FCR寄存器 (FIFO Control Reg- ister) 的 FIFOE 位置 1,来打开 TXFIFO。

        RX 控制器使用波特率控制模块生成的过采样时钟,对输入的每一位进行采样,并把收到的每一位移入 RX 移 位寄存器。RX 移位寄存器对数据进行串行-并行转换,并把数据存入 RX FIFO。RX FIFO 的读入口是RBR寄存器 (Receiver Buffer Register),用户需要把FCR寄存器 (FIFO Control Register)的 FIFOE 位置 1,来打开 RXFIFO。

         

        2.基本特征
  • 支持 5∼8 位数据长度
  • 可配置停止位:1 位,1.5 位或者 2 位
  • 可配置奇偶校验位:奇校验,偶校验,粘校验位
  • 支持 DMA 数据传输
  • 支持可配置波特率,支持独立的波特率生成时钟
  • 支持硬件流控
  • 支持奇偶校验错误,数据 FIFO 溢出等错误检测
  • 16 字节的 TXFIFO 和 RXFIFO
  • 支持各类中断
        3.功能时钟(输入时钟)、过采样率、波特率三者之间的关系

        在时钟章节我们讲到每个外设都可以八选一选择一个功能时钟,并且设置分频。 

         

         

        上图中我们通过clock_set_source_divider设置uart0选择clk_src_osc24m=24MHz时钟源,不分频,也就是说上图中的配置uart0输入时钟为24MHz。

        UART 时钟与波特率的比率就是过采样率OSC。    

        RX 控制器利用过采样时钟对输入数据进行采样。假设过采样率OSC为 16 当检测到输入信号第一个下降沿 时 (起始 START 位),计数器从 1 开始计数直到 16,在计数到 8 时,RX 控制器对输入数据采样。计数器在计数 到 16 后,会复位到 1,以此采样下一位数据,循环往复,直到停止 STOP 位。TX 控制器同样利用过采样时钟来 生成输出数据流。 

        uart外设内部还有一个时钟分频寄存器(16位)Divisor。分频值的 MSB 位于DLM寄存器 (Divisor Latch MSB),而 LSB 位于DLL寄存器 (Divisor Latch LSB)。

        三者之间的关系如下:

                  

        在SDK中有一个函数专门用于计算分频系数和过采样率,对于开发者来讲,只需要设置输入时钟和波特率即可。

         

       4.引脚配置(以uart0为例)

        由于uart0使用PY06/07作为TXD/RXD, 而PY06/07属于电源管理域的引脚,所以必须先通过HPM_PIOC先将引脚映射到HPM_IOC中,然后由HPM_IOC再将PY06/07复用为外设引脚。

        5.API接口说明 

        

typedef struct hpm_uart_config {
    uint32_t src_freq_in_hz;                    /**< Source clock frequency in Hz */
    uint32_t baudrate;                          /**< Baudrate */
    uint8_t num_of_stop_bits;                   /**< Number of stop bits */
    uint8_t word_length;                        /**< Word length */
    uint8_t parity;                             /**< Parity */
    uint8_t tx_fifo_level;                      /**< TX Fifo level */
    uint8_t rx_fifo_level;                      /**< RX Fifo level */
    bool dma_enable;                            /**< DMA Enable flag */
    bool fifo_enable;                           /**< Fifo Enable flag */
    uart_modem_config_t modem_config;           /**< Modem config */
#if defined(UART_SOC_HAS_RXLINE_IDLE_DETECTION) && (UART_SOC_HAS_RXLINE_IDLE_DETECTION == 1)
    uart_rxline_idle_config_t  rxidle_config;   /**< RX Idle configuration */
#endif
#if defined(UART_SOC_HAS_TXLINE_IDLE_DETECTION) && (UART_SOC_HAS_TXLINE_IDLE_DETECTION == 1)
    uart_rxline_idle_config_t  txidle_config;   /**< TX Idle configuration */
#endif
#if defined(UART_SOC_HAS_RXEN_CFG) && (UART_SOC_HAS_RXEN_CFG == 1)
    bool rx_enable;                             /**< RX Enable configuration */
#endif
} uart_config_t;

        各个字段含义:

src_freq_in_hz 输入时钟,八选一,并且可以分频(注意uart内部可以再次分频)
baudrate波特率
num_of_stop_bits

停止位

typedef enum num_of_stop_bits {
    stop_bits_1 = 0,
    stop_bits_1_5,
    stop_bits_2,
} num_of_stop_bits_t;

word_length

字长

typedef enum word_length {
    word_length_5_bits = 0,
    word_length_6_bits,
    word_length_7_bits,
    word_length_8_bits,
} word_length_t;

parity

奇偶校验位

typedef enum parity {
    parity_none = 0,
    parity_odd,
    parity_even,
    parity_always_1,
    parity_always_0,
} parity_setting_t;

tx_fifo_level发送触发阈值
rx_fifo_level接收触发阈值
dma_enable使能DMA
fifo_enable使能FIFO
modem_config

流控

typedef struct uart_modem_config {
    bool auto_flow_ctrl_en;     /**< Auto flow control enable flag */
    bool loop_back_en;          /**< Loop back enable flag */
    bool set_rts_high;          /**< Set signal RTS level high flag */
} uart_modem_config_t;

                uart_init函数用于设置波特率、字长、停止位、奇偶校验以及FIFO阈值。

hpm_stat_t uart_init(UART_Type *ptr, uart_config_t *config)
{
    uint32_t tmp;
    uint8_t osc;
    uint16_t div;

    /* disable all interrupts */
    ptr->IER = 0;
    /* Set DLAB to 1 */
    ptr->LCR |= UART_LCR_DLAB_MASK;

    if (!uart_calculate_baudrate(config->src_freq_in_hz, config->baudrate, &div, &osc)) {
        return status_uart_no_suitable_baudrate_parameter_found;
    }
    ptr->OSCR = (ptr->OSCR & ~UART_OSCR_OSC_MASK)
        | UART_OSCR_OSC_SET(osc);
    ptr->DLL = UART_DLL_DLL_SET(div >> 0);
    ptr->DLM = UART_DLM_DLM_SET(div >> 8);

    //设置奇偶校验
    /* DLAB bit needs to be cleared once baudrate is configured */
    tmp = ptr->LCR & (~UART_LCR_DLAB_MASK);

    tmp &= ~(UART_LCR_SPS_MASK | UART_LCR_EPS_MASK | UART_LCR_PEN_MASK);
    switch (config->parity) {
    case parity_none:
        break;
    case parity_odd:
        tmp |= UART_LCR_PEN_MASK;
        break;
    case parity_even:
        tmp |= UART_LCR_PEN_MASK | UART_LCR_EPS_MASK;
        break;
    case parity_always_1:
        tmp |= UART_LCR_PEN_MASK | UART_LCR_SPS_MASK;
        break;
    case parity_always_0:
        tmp |= UART_LCR_EPS_MASK | UART_LCR_PEN_MASK
            | UART_LCR_SPS_MASK;
        break;
    default:
        /* invalid configuration */
        return status_invalid_argument;
    }
    //设置停止位
    tmp &= ~(UART_LCR_STB_MASK | UART_LCR_WLS_MASK);
    switch (config->num_of_stop_bits) {
    case stop_bits_1:
        break;
    case stop_bits_1_5:
        tmp |= UART_LCR_STB_MASK;
        break;
    case stop_bits_2:
        if (config->word_length < word_length_6_bits) {
            /* invalid configuration */
            return status_invalid_argument;
        }
        tmp |= UART_LCR_STB_MASK;
        break;
    default:
        /* invalid configuration */
        return status_invalid_argument;
    }
    //设置字长
    ptr->LCR = tmp | UART_LCR_WLS_SET(config->word_length);

    //复位FIFO并设置FIFO阈值

#if defined(UART_SOC_HAS_FINE_FIFO_THR) && (UART_SOC_HAS_FINE_FIFO_THR == 1)
    /* reset TX and RX fifo */
    ptr->FCRR = UART_FCRR_TFIFORST_MASK | UART_FCRR_RFIFORST_MASK;
    /* Enable FIFO */
    ptr->FCRR = UART_FCRR_FIFOT4EN_MASK
        | UART_FCRR_FIFOE_SET(config->fifo_enable)
        | UART_FCRR_TFIFOT4_SET(config->tx_fifo_level)
        | UART_FCRR_RFIFOT4_SET(config->rx_fifo_level)
        | UART_FCRR_DMAE_SET(config->dma_enable);

#else
    /* reset TX and RX fifo */
    ptr->FCR = UART_FCR_TFIFORST_MASK | UART_FCR_RFIFORST_MASK;
    /* Enable FIFO */
    tmp = UART_FCR_FIFOE_SET(config->fifo_enable)
        | UART_FCR_TFIFOT_SET(config->tx_fifo_level)
        | UART_FCR_RFIFOT_SET(config->rx_fifo_level)
        | UART_FCR_DMAE_SET(config->dma_enable);
    ptr->FCR = tmp;
    /* store FCR register value */
    ptr->GPR = tmp;
#endif

    uart_modem_config(ptr, &config->modem_config);

#if defined(UART_SOC_HAS_RXLINE_IDLE_DETECTION) && (UART_SOC_HAS_RXLINE_IDLE_DETECTION == 1)
    uart_init_rxline_idle_detection(ptr, config->rxidle_config);
#endif
#if defined(UART_SOC_HAS_RXEN_CFG) && (UART_SOC_HAS_RXEN_CFG == 1)
    if (config->rx_enable) {
        ptr->IDLE_CFG |= UART_IDLE_CFG_RXEN_MASK;
    }
#endif
    return status_success;
}

        读取字节


hpm_stat_t uart_receive_byte(UART_Type *ptr, uint8_t *byte)
{
    uint32_t retry = 0;

    while (!(ptr->LSR & UART_LSR_DR_MASK)) {
        if (retry > HPM_UART_DRV_RETRY_COUNT) {
            break;
        }
        retry++;
    }

    if (retry > HPM_UART_DRV_RETRY_COUNT) {
        return status_timeout;
    }

    *byte = ptr->RBR & UART_RBR_RBR_MASK;
    return status_success;
}

        不断查询LSR寄存器的UART_LSR_DR_MASK是否置位(存在有效的接收数据时该位置 1),如果置位说明可读,此时RBR寄存器存储的就是当前可读字节。

        写入字节

hpm_stat_t uart_send_byte(UART_Type *ptr, uint8_t c)
{
    uint32_t retry = 0;

    while (!(ptr->LSR & UART_LSR_THRE_MASK)) {
        if (retry > HPM_UART_DRV_RETRY_COUNT) {
            break;
        }
        retry++;
    }

    if (retry > HPM_UART_DRV_RETRY_COUNT) {
        return status_timeout;
    }

    ptr->THR = UART_THR_THR_SET(c);
    return status_success;
}

         不断查询LSR寄存器的UART_LSR_THRE_MASK是否置位(发送FIFO空),如果置位说明可写,此时写入THR寄存器就会传送给TX FIFO。

三、实战

        VScode打开工程并进入调试窗口,在

cd ~/workspace/work/hpm/hello_world
code .
uart0引脚配置

 

uart0串口寄存器配置

 

                以上就是uart的基本内容,包括功能说明、引脚配置、时钟配置、轮询读写。 

         

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1323519.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Pycharm enable IntelliBot #patched后,工程无法打开

#本地环境# Pycharm&#xff1a;2023.12 Pro 对应robot pkg版本&#xff1a; robotframework 6.1 robotframework-databaselibrary 1.2.4 robotframework-pythonlibcore 4.1.2 robotframework-requests 0.9.4 robotframework-seleniumlibrary 6.1.…

新增工具箱管理功能、重构网站证书管理功能,1Panel开源面板v1.9.0发布

2023年12月18日&#xff0c;现代化、开源的Linux服务器运维管理面板1Panel正式发布v1.9.0版本。 在这一版本中&#xff0c;1Panel引入了新的工具箱管理功能&#xff0c;包含Swap分区管理、Fail2Ban管理等功能。此外&#xff0c;1Panel针对网站证书管理功能进行了全面重构&…

移动云捐赠三款开源项目,加速新一代基础软件生态繁荣

随着云计算、大数据、人工智能等新领域新信息技术的发展&#xff0c;我国基础软件的自主可控极大程度地影响着产业链上下游的多样性和技术创新的发展空间。移动云作为中国移动涉云业务的主入口&#xff0c;一直坚持共享开源价值&#xff0c;积极推动中国开源软件生态的繁荣发展…

UE5 水材质注意要点

1、两个法线反向交替流动&#xff0c;可以去观感假的现象 2、水面延边的透明度低 3、增加水面延边的浪花 4、增加折射 折射要整体质量至少在High才有效果 改为半透明材质没有法线信息&#xff1f; 5、处理反射效果 勾选为true 找到这个放在水域 勾为false&#xff0c;即可有非…

基于ssm品牌手机销售信息系统论文

摘 要 随着科学技术的飞速发展&#xff0c;各行各业都在努力与现代先进技术接轨&#xff0c;通过科技手段提高自身的优势&#xff1b;对于品牌手机销售信息系统当然也不能排除在外&#xff0c;随着网络技术的不断成熟&#xff0c;带动了品牌手机销售信息系统&#xff0c;它彻底…

05_Web框架之Django二

Web框架之Django二 学习目标和内容 1、能够使用类视图的写法 2、能够使用模板语言的相关语法 3、能够理解过滤器的作用 4、能够理解并使用模板继承 一、类视图 1、类视图介绍 视图是一个可调用的对象&#xff0c;它接收一个请求然后返回一个响应&#xff0c;这个可调用对象可…

phpmyadmin4.8.1远程文件包含漏洞 [GWCTF 2019]我有一个数据库1

打开题目 我们用dirsearch扫描一下后台看看 扫描结果如下 我们访问一下robots.txt看看&#xff0c;提示有phpinfo.php 那我们访问一下phpinfo.php 发现没有任何信息后我们转去看看phpmyadmin看看 成功访问到页面 在这里我们看到phpmyadmin的版本号是4.8.1 我们百度搜索一下看…

Java版企业电子招投标系统源代码,支持二次开发,采用Spring cloud微服务架构

招投标管理系统是一个集门户管理、立项管理、采购项目管理、采购公告管理、考核管理、报表管理、评审管理、企业管理、采购管理和系统管理于一体的综合性应用平台。它适用于招标代理、政府采购、企业采购和工程交易等业务的企业&#xff0c;旨在提高项目管理的效率和质量。该系…

linux搭建gitlab

gitlab的介绍 区别于github&#xff0c;github是面向互联网基于git实现的代码托管平台&#xff0c;gitlab是基于Ruby语言实现的git管理平台软件&#xff0c;一般用于公司内部代码仓库。 gitlab组成 Nginx 静态Web服务器Gitlab-workhorse 轻量级的反向代理服务器Gitlab-shell 用…

spring MVC概述和土门案例(无配置文件开发)

SpringMVC 1&#xff0c;SpringMVC概述2&#xff0c;SpringMVC入门案例2.1 需求分析2.2 案例制作步骤1:创建Maven项目步骤2:补全目录结构步骤3:导入jar包步骤4:创建配置类步骤5:创建Controller类步骤6:使用配置类替换web.xml步骤7:配置Tomcat环境步骤8:启动运行项目步骤9:浏览器…

Android 大版本升级变更截图方法总结

Android 大版本升级变更截图方法总结 一、Android R (11) 平台二、Android S (12) 平台三、Android U (14) 平台 Android 原生的截屏功能是集成在 SystemUI 中&#xff0c;因此我们普通应用想要获取截图方法&#xff0c;就需要研读下 SystemUI 截屏部分的功能实现。 一、Androi…

RocketMQ系统性学习-SpringCloud Alibaba集成RocketMQ以及消费收发实战

文章目录 Spring Cloud Alibaba 集成 RocketMQ 最佳实践集成依赖DashBoard消息收发实战 Spring Cloud Alibaba 集成 RocketMQ 最佳实践 SpringBoot 相对于 SSM 来说已经很大程度上简化了开发&#xff0c;但是使用 SpringBoot 集成一些第三方的框架&#xff0c;还是需要花费一些…

Nginx快速入门:安装目录结构详解及核心配置解读(二)

0. 引言 上节我们讲解了nginx的应用场景和安装&#xff0c;本节继续针对nginx的各个目录文件进行讲解&#xff0c;让大家更加深入的认识nginx。并通过一个实操案例&#xff0c;带大家来实际认知nginx的核心配置 1. nginx安装目录结构 首先nginx的默认安装目录为&#xff1a;…

【一】FPGA实现SPI协议之SPI协议介绍

【一】FPGA实现SPI协议之SPI协议介绍 一、spi协议解析 spi协议有4根线&#xff0c;主机输出从机输入MOSI、主机输入从机输出MISO、时钟信号SCLK、片选信号SS\CS 。 一般用于主机和从机之间通信。由主机发起读请求和写请求&#xff0c;主机的权限是主动的&#xff0c;从机是被…

web打印技术方案

在B/S应用系统开发中常常遇到表单打印需求&#xff0c;尤其是OA、ERP类的企业运营管理系统&#xff0c;打印的需求很常见&#xff0c;但WEB应用的打印一直以来是一个难题&#xff0c;特别是在应用中完成标签打印&#xff08;如包裹面单、货运标签等&#xff09;、票据打印&…

AI降重工具

WEB版 体验一下 from docx import Document import requestsdef call_api_and_get_content(content, prompt):api_url "http://XXXXXXXX/api?content" content promptresponse requests.get(api_url)if response.status_code 200:api_result response.text.re…

搭建知识付费平台?明理信息科技为你提供全程解决方案

明理信息科技saas知识付费平台 在当今数字化时代&#xff0c;知识付费已经成为一种趋势&#xff0c;越来越多的人愿意为有价值的知识付费。然而&#xff0c;公共知识付费平台虽然内容丰富&#xff0c;但难以满足个人或企业个性化的需求和品牌打造。同时&#xff0c;开发和维护…

安装centos 7及配置网卡、连接Xshell

1.点击新建虚拟机 2.默认自定义 3.默认选择17版本的 4.选择稍后安装操作系统 5.选择Linux 6.选择安装目录和自定义名称&#xff0c;安装时尽量新建一个文件夹 7.根据电脑配置&#xff0c;自定义处理器大小&#xff0c;这里是建议配置 8.最少2个G 9.使用NAT 注&#xff1a; VMn…

智能优化算法应用:基于闪电连接过程算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于闪电连接过程算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于闪电连接过程算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.闪电连接过程算法4.实验参数设定…

pytorch中nn.Sequential详解

1 nn.Sequential概述 1.1 nn.Sequential介绍 nn.Sequential是一个序列容器&#xff0c;用于搭建神经网络的模块被按照被传入构造器的顺序添加到容器中。除此之外&#xff0c;一个包含神经网络模块的OrderedDict也可以被传入nn.Sequential()容器中。利用nn.Sequential()搭建好…