0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

UART系统配置步骤详解

冬至子 来源:两猿社 作者:IC猿 2023-06-05 16:05 次阅读

00 模块简介

CPU通过挂载到APB总线上的UART模块,实现其与外部设备的串行通信。系统配置部分将 实现UART模块与CPU的通信,APB总线的读写和模块的功能配置,中断信号的产生

AMBA总线中的APB总线由于功耗小,接口简单,适用于低带宽且不需要更高性能总线的中低速外设。UART是此类常见外设,通常使用APB总线与系统连接。

01 模块接口与描述

1.jpg

2.jpg

02 实现

REG_IF模块主要由 状态信息同步APB总线读写FIFO读写使能状态寄存器操作及中断产生这几部分构成。

APB总线读写:通过APB总线实现与CPU的通信,通过配置寄存器方式实现数据收发,控制UART模块功能,读取模块工作状态等。

FIFO读写使能:分别是RF_FIFO的读使能控制和TX_FIFO的写使能控制。

状态寄存器操作及中断产生:将TX、RX模块反馈的工作状态体现在状态寄存器中,供CPU查询,并产生中断信号通知CPU进行处理。

  • 状态信息同步

配置模块工作在系统时钟域,将收到来自接收模块和发送模块的状态指示信息,这部分信号需要在系统时钟域进行同步。

  • APB总线读写

前面我们讲过APB读写时序。

APB读:作为APB从设备,当APB总线发起读操作时,需要在合适的时间将对应地址的寄存器值送到总线(如下图T3),确保主机能收到数据。此时 PENABLE等于0,PSEL等于1,PWRITE等于0

图片

apb读

APB读实现如下:

//read reg value
always@(posedge clk ornegedge rst_) begin
    if(!rst_) begin
        prdata_o <= 32'h0;
    end
    elsebegin
        // APB read
        if(psel_i && (!penable_i) && (!pwrite_i)) begin
            case(paddr_i)
            4'h0:
                prdata_o <= uart_tx;
            4'h1:
                prdata_o <= uart_rx;
            4'h2:
                prdata_o <= uart_baud;
            4'h3:
                prdata_o <= uart_conf;
            4'h4:
                prdata_o <= uart_rxtrig;
            4'h5:
                prdata_o <= uart_txtrig;
            4'h6:
                prdata_o <= uart_delay;
            4'h7:
                prdata_o <= uart_status;
            4'h8:
                prdata_o <= uart_rxfifo_stat;
            4'h9:
                prdata_o <= uart_txfifo_stat;
            endcase
        end
    end
end

APB写:类似的,当APB总线上发起写操作时,从机需要在合适的时间接收总线上的数据(如下图T4),放到对应的寄存器地址。此时 PENABLE等于1,PSEL等于1,PWRITE等于1

图片

apb写

APB写实现如下:

//write reg value
always@(posedge clk ornegedge rst_) begin
    if(!rst_) begin
        uart_tx     <= 32'h0;
        uart_baud   <= 32'hf152;
        uart_conf   <= 32'h34;
        uart_rxtrig <= 32'h1;
        uart_txtrig <= 32'h0;
        uart_delay  <= 32'h2;
    end
    elsebegin
        // APB write
        if(psel_i && penable_i && pwrite_i) begin
            case(paddr_i)
            4'h0:
                uart_tx     <= pwdata_i;
            4'h2:
                uart_baud   <= pwdata_i;
            4'h3:
                uart_conf   <= pwdata_i;
            4'h4:
                uart_rxtrig <= pwdata_i;
            4'h5:
                uart_txtrig <= pwdata_i;
            4'h6:
                uart_delay  <= pwdata_i;
            endcase
        end
    end
end
  • FIFO读写使能

RX_FIFO读控制:

在cpu读uart状态寄存器(uart_status)时,如果rx中断有效(即状态位的第1bit位有效),且FIFO不为空,RX_FIFO读使能一个时钟周期。

或在cpu读接收数据寄存器(uart_rx)时,RX_FIFO读使能一个时钟周期。

注意由于读出FIFO数据需要1个时钟周期,为了使cpu能及时读到数据,在读状态寄存器时其实是一个预取动作。

// FIFO enable control
always@(posedge clk ornegedge rst_) begin
    if(!rst_) begin
        rx_fifo_rinc <= 1'b0;
        state        <= 1'b0;
    end
    elsebegin
        case(state)
        1'b0: begin
            // when ARM read uart_status, judge interrupt bit ,if rx_int is
            // active, or ARM read uart_rx ,rx_fifo_rinc enable 1 clk
            if(psel_i && (!penable_i)&&(!pwrite_i)&&(paddr_i==4'h7)) begin
                if(uart_status[1] && !rx_fifo_rempty) begin
                    rx_fifo_rinc <= 1'b1;
                    state        <= 1'b1;
                end
            end
            // when ARM read data,rx_fifo_rinc enable 1 clk
            if(psel_i &&(!penable_i)&&(!pwrite_i)&&(paddr_i==4'h1)) begin
                rx_fifo_rinc <= 1'b1;
                state        <= 1'b1;
            end
        end
        1'b1: begin
            rx_fifo_rinc <= 1'b0;
            state        <= 1'b0;
        end
        endcase
    end
end

TX_FIFO写控制:

在cpu写uart_tx时,说明需要UART模块发送数据,APB写数据到寄存器需要1个时钟周期,所以需要在1个时钟之后再写使能TX_FIFO。

always@(posedge clk ornegedge rst_) begin
    if(!rst_) begin
        tx_fifo_winc <= 1'b0;
        state_en     <= 2'b0;
    end
    elsebegin
        case(state_en)
        2'b0: begin
            // ARM write uart_tx,tx_fifo_winc enable 1 clk after 1 clk
            if(psel_i && penable_i && pwrite_i && (paddr_i==4'h0)) begin
                state_en <= 2'b01;
            end
        end
        2'b01: begin
            state_en     <= 2'b10;
            tx_fifo_winc <= 1'b1;
        end
        2'b10: begin
            tx_fifo_winc <= 1'b0;
            state_en     <= 2'b0;
        end
        endcase
    end
end
  • 状态寄存器操作及中断产生

状态寄存器指示4个状态:ST_ERROR,P_ERROR,RX_INT和TX_INT。由高到低在寄存器uart_status[3:0]。分别表示接收数据停止位出错、接收数据校验位出错、接收数据中断位和发送数据中断位。

其中接收数据中断位有效表示RX_FIFO中数据量增加到触发值,数据将满(触发值由cpu配置),通知cpu接收数据;发送数据中断位有效表示TX_FIFO中数据减少到触发值,数据将空(触发值由cpu配置),通知cpu数据将要发送完毕,需补充数据。

从接收模块接收到的ST_ERROR,P_ERROR信号响应也在此部分产生,表示已经收到此状态。

// uart_status register operate
always@(posedge clk ornegedge rst_) begin
    if(!rst_) begin
        p_error_ack  <= 1'b0;
        st_error_ack <= 1'b0;
        uart_status  <= 32'h0;
        rx_state     <= 1'b0;
        tx_state     <= 1'b0;
    end
    elsebegin
        if(st_error_syn) begin
            uart_status[3]   <= 1'b1;
        end
        elsebegin
            if(neg_uart_status3) begin
                st_error_ack <= 1'b1;
            end
            elsebegin
                if(!st_error_syn2) begin
                    st_error_ack <= 1'b0;
                end
            end
        end
        if(p_error_syn) begin
            uart_status[2]   <= 1'b1;
        end
        elsebegin
            if(neg_uart_status2) begin
                p_error_ack  <= 1'b1;
            end
            elsebegin
                if(!p_error_syn2) begin
                    p_error_ack  <= 1'b0;
                end
            end
        end
        // when rx_fifo_cnt from less than to equal the rxtrig,
        // rx_int is active
        case(rx_state)
        1'b0: begin
            if(rx_fifo_cnt == (uart_rxtrig[3:0] - 1'b1)) begin
                rx_state      <= 1'b1;
            end
            elsebegin
                rx_state      <= 1'b0;
            end
        end
        1'b1: begin
            if(rx_fifo_cnt == uart_rxtrig[3:0]) begin
                uart_status[1] <= 1'b1;
                rx_state       <= 1'b0;
            end
            elsebegin
                rx_state       <= 1'b1;
            end
        end
        endcase
        // when tx_fifo_cnt from greater than to equal the txtrig,
        // tx_int is active
        case(tx_state)
        1'b0: begin
            if(tx_fifo_cnt == (uart_txtrig[3:0] + 1'b1)) begin
                tx_state       <= 1'b1;
            end
            elsebegin
                tx_state       <= 1'b0;
            end
        end
        1'b1: begin
            if(tx_fifo_cnt == uart_txtrig[3:0]) begin
                uart_status[0] <= 1'b1;
                tx_state       <= 1'b0;
            end
            elsebegin
                tx_state       <= 1'b1;
            end
        end
        endcase
        // ARM write 1 clean 0  uart_status
        if(psel_i && penable_i && pwrite_i && (paddr_i==4'h7)) begin
            uart_status <= uart_status & (~pwdata_i);
        end
    end
end

// produce interrupt to CPU
always @(posedge clk ornegedge rst_) begin
    if(!rst_) begin
	      uart_int_o <= 1'b0;
		end
	  elsebegin
	      if(|uart_status[3:0]) begin
            uart_int_o <= 1'b1;
        end
		    elsebegin
            uart_int_o <= 1'b0;
        end
		end
end

当uart_status中任何一位状态位1中断信号将有效,cpu接收到中断后查询状态寄存器uart_status,处理后对uart_status寄存器写1清零,清掉状态位,即清除中断。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 触发器
    +关注

    关注

    14

    文章

    1677

    浏览量

    60402
  • FIFO存储
    +关注

    关注

    0

    文章

    102

    浏览量

    5894
  • UART接口
    +关注

    关注

    0

    文章

    123

    浏览量

    15067
  • 串口中断
    +关注

    关注

    0

    文章

    63

    浏览量

    13607
  • 状态寄存器
    +关注

    关注

    0

    文章

    37

    浏览量

    7001
收藏 人收藏

    评论

    相关推荐

    FPGA最小系统配置电路的设计资料

    FPGA最小系统配置电路的设计资料
    发表于 05-04 16:04

    NI MAX 系统配置问题

    NI MAX 系统配置出现问题显示不可用,请问该如何解决
    发表于 06-26 19:36

    单片机系统配置及接口相关介绍

    单片机原理及应用C语言版9ppt课件单片机原理及应用 (C语言版)第9章单片机系统配置及接口 第9章 单片机系统配置及接口 目录9.1键盘接口 9.2LED显示接口 9.3A/D转换接口 9.4D
    发表于 07-14 08:08

    硬实时RTlinux系统配置

    更多技术干货,欢迎扫码关注博主微信公众号:HowieXue,一起学习探讨软硬件技术知识经验,关注就有海量学习资料免费领哦:硬实时RTlinux系统配置1. Linux内核下载2. 下载与Linux
    发表于 09-14 06:43

    从I2C写入系统配置内存失败可能是什么原因?是否按照正确的程序写入系统配置

    我正在研究 ST25DV64KC NFC 芯片。我正在尝试从 i2c 写入系统配置内存。脚步:1) 我通过发送当前密码命令打开了 i2c 安全会话。我已经从动态寄存器内存中读取
    发表于 12-08 08:16

    借助USB来完成系统配置

    借助USB来完成系统配置 USB2.0规范凭借其较高的传送速率而使更加复杂和高度集成的外设设计得以实现许多USB设计都采用了现场可编程门阵列FPGA以便将定制逻辑
    发表于 03-18 10:41 35次下载

    阳能发电原理及系统配置设置说明

    阳能发电原理及系统配置设置说明 太阳能发电系统由太阳能电池组、太阳能控制器、蓄电池(组)组成。如输出电源为交流220V或 110V,还需要配置逆变器
    发表于 11-14 11:27 707次阅读

    MP4播放器系统配置

    MP4播放器系统配置              系统配
    发表于 12-21 16:29 2002次阅读

    LPC111x系统配置

    LPC111x系统配置,有需要的朋友下来看看。
    发表于 01-13 16:04 15次下载

    C语言教程之获取系统配置信息

    C语言教程之获取系统配置信息,很好的C语言资料,快来学习吧。
    发表于 04-25 17:07 0次下载

    FPGA最小系统配置电路的设计

    FPGA最小系统配置电路的设计,有兴趣的同学可以下载学习
    发表于 05-04 11:31 36次下载

    ABB机器人系统配置cclink课件下载

    ABB机器人系统配置cclink课件下载
    发表于 05-19 09:36 1次下载

    通信电源系统配置设计参数

    通信电源系统配置设计参数(安徽力普拉斯电源技术有限公司招聘)-该文档为通信电源系统配置设计参数总结文档,是一份不错的参考资料,感兴趣的可以下载看看,,,,,,,,,,,,,,,,,
    发表于 09-22 16:41 4次下载
    通信电源<b class='flag-5'>系统配置</b>设计参数

    服务器Linux系统配置IP地址的方法

    服务器Linux系统配置IP地址的方法。
    的头像 发表于 09-21 14:50 7972次阅读

    简单的菜单系统配置开源设计

    电子发烧友网站提供《简单的菜单系统配置开源设计.zip》资料免费下载
    发表于 06-09 10:31 0次下载
    简单的菜单<b class='flag-5'>系统配置</b>开源设计