色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

如何實現串口數據的接收呢?

冬至子 ? 來源:兩猿社 ? 作者:IC猿 ? 2023-06-05 15:24 ? 次閱讀

00 簡介

UART接收數據部分是接收另一個串口設備發送的數據,緩存到接收FIFO中。FIFO快要寫滿時,產生中斷通知CPU拿取數據,實現串口數據的接收。

模塊涉及到兩個時鐘域,ARM時鐘和26MHz功能時鐘。其中 接收FIFO讀寫邏輯是ARM時鐘域,接收數據狀態機和同步邏輯等是功能時鐘域

01 模塊接口與描述

1.jpg

2.jpg

02 實現

UART_RX模塊主要由三部分組成: 配置信息同步接收狀態機接收數據FIFO控制

配置信息是reg_if模塊由APB總線配置寄存器產生,功能時鐘域做兩級同步處理。

接收狀態機是根據串口協議劃分,分為IDLE、START、RX_DATA、CHECK_DATA、STOP和SEND六種狀態。

接收數據FIFO控制部分將接收完成的數據寫入到FIFO,在CPU讀取RX_FIFO寄存器時將FIFO數據讀出送到RX_FIFO寄存器。

  • 配置信息同步

由于配置信息是由ARM時鐘產生,到接收模塊的功能時鐘域需要做同步處理。配置信息是電平信號,通常不會像數據一樣變化快,所以只需要兩級同步。

  • 接收狀態產生

接收數據停止位狀態指示st_error和接收數據校驗位狀態指示p_error是串口校驗位和停止位檢測狀態指示。前者為1表示停止位錯誤;后者為1表示校驗位錯誤。兩個狀態位都會傳到reg_if模塊,指示URAT當前狀態,供CPU查詢。當CPU發現停止位或者校驗位錯誤時,會決定當前數據的處理方式(丟棄或者接受),清除狀態位(即寫1清0)。reg_if模塊發現該狀態位清除后,會回送一個ack到接收模塊,即st_error_ack和p_error_ack。接收模塊接收到ack后釋放狀態指示st_error和p_error,繼續接收數據。

這個過程就是狀態位的握手,本模塊設計方式是握手期間,即發現校驗位或者停止位錯誤后停止接收數據,直到CPU清除狀態后才開始正常接收。讀者可以根據自己的需要判斷錯誤后是否繼續接收數據。

  • 接收狀態機

使用典型的三段式狀態機設計,包含六種狀態,IDLE、START、RX_DATA、CHECK_DATA、STOP和SEND。

圖片

uart接收狀態轉移圖

IDLE:狀態機從IDLE狀態開始,檢測到uart_i的下降沿,進入START狀態。

START:START狀態起始位是否為低(避免毛刺觸發狀態機),起始位正常即進入RX_DATA開始接收數據。RX_DATA:接收滿8bit后判斷是否使能校驗位,如使能,進入CHECK_DATA狀態進行奇偶校驗的判斷;如不使能,直接進入停止狀態STOP。

CHECK_DATA:CHECK_DATA狀態判斷奇偶校驗是否正確,不正確則發出p_error信號,在狀態寄存器指示校驗錯誤,待CPU處理返回p_error_ack后回到IDLE狀態。如果正確,判斷是否使能停止位檢查;使能停止位檢查則跳轉到STOP狀態;不使能則跳轉到SEND狀態。

STOP:同樣的,在STOP狀態檢測停止位是否是高電平。如果是,表示停止位正確,跳轉到SEND狀態;如果不是,則發出st_error信號,在狀態寄存器指示停止位錯誤,待CPU處理返回st_error_ack后回到IDLE狀態。

SEND:SEND狀態主要是產生rx_start信號表示8bits數據接收正確,可以將數據寫到接收FIFO。

前兩段狀態機,狀態跳轉:

// state to nextstate with clk in this block.
always@(posedge clk26m ornegedge rst26m_)begin
    if(!rst26m_) begin
        state <= IDLE;
    end
    elsebegin
        state <= nextstate;
    end
end

// nextstate transform
always@(*) begin
    case(state)
    IDLE: begin
        if(neg_urxd_i) begin
            nextstate = START;
        end
        elsebegin
            nextstate = IDLE;
        end
    end
    START: begin
        if(start_right) begin// start bit is right,then reserve data
            nextstate = RX_DATA;
        end
        elsebegin
            nextstate = IDLE;
        end
    end
    RX_DATA: begin
        if(data_cnt < 4'd8) begin// reserve 8 datas
            nextstate = RX_DATA;
        end
        elsebegin
            if(rx_bpsclk) begin
                if(check_syn2) begin
                    nextstate = CHECK_DATA;
                end
                elsebegin
                    nextstate = STOP;
                end
            end
            elsebegin
                nextstate = RX_DATA;
            end
        end
    end
    CHECK_DATA: begin
        if(p_error_ack_delay2) begin
            nextstate = IDLE;
        end
        elsebegin
            if(rx_bpsclk) begin
		            // p_error:1:parity bit error,0:parity bit error
		            if(p_error) begin
		                nextstate = CHECK_DATA;
		            end
		            elsebegin
		                // st_check:1:check stop bit,0:don't check stop bit
		                if(st_check_syn2) begin
		                    nextstate = STOP;
		                end
		                elsebegin
		                    nextstate = SEND;
		                end
		            end
		        end
		        elsebegin
		            nextstate = CHECK_DATA;
		        end
        end
    end
    STOP: begin
        if(st_error_ack_delay2) begin
            nextstate = IDLE;
        end
        elsebegin
            if(rx_bpsclk) begin
		            // st_error:1:stop bit error,0:stop bit error
		            if(st_error) begin
		                nextstate = STOP;
		            end
		            elsebegin
		                nextstate = SEND;
		            end
		        end
		        elsebegin
		            nextstate = STOP;
		        end
        end
    end
    SEND: begin
        if(rx_ack_delay2) begin
            nextstate = IDLE;
        end
        elsebegin
            nextstate = SEND;
        end
    end
    default: begin
        nextstate = IDLE;
    end
    endcase
end

第三段狀態機,信號賦值:

// output signal state
always@(posedge clk26m ornegedge rst26m_) begin
    if(!rst26m_) begin
        rx_bpsen <= 1'b0;
        data_rx  <= 8'd0;
        data_cnt <= 4'd0;
        p_error  <= 1'b0;
        st_error <= 1'b0;
        rx_start <= 1'b0;
        start_right <= 1'b0;
    end
    elsebegin
        case(nextstate)
        IDLE: begin
            rx_bpsen    <= 1'b0;
            data_cnt    <= 4'd0;
            st_error    <= 1'b0;
            p_error     <= 1'b0;
            rx_start    <= 1'b0;
            start_right <= 1'b0;
        end
        START: begin
            rx_bpsen    <= 1'b1;
            if(rx_bpsclk) begin
                if(urxd_i == 1'b0) begin
                    start_right <= 1'b1;
                end
                elsebegin
                    start_right <= 1'b0;
                end
            end
        end
        RX_DATA: begin
            if(rx_bpsclk) begin
                data_rx[data_cnt] <= urxd_i;
                data_cnt <= data_cnt + 1'b1;
            end
        end
        CHECK_DATA: begin
            if(rx_bpsclk) begin
                // odd check
                if(parity_syn2) begin
                    if(^data_rx == urxd_i) begin// odd check is wrong
                        p_error  <= 1'b1;
                        rx_bpsen <= 1'b0;
                    end
                end
                // even check
                elsebegin
                    if(^data_rx == !urxd_i) begin// even check is wrong
                        p_error  <= 1'b1;
                        rx_bpsen <= 1'b0;
                    end
                end
            end
        end
        STOP: begin
            if(rx_bpsclk) begin
                if(urxd_i == 1'b0) begin// stop bit is wrong
                    st_error <= 1'b1;
                    rx_bpsen <= 1'b0;
                end
            end
        end
        SEND: begin
            rx_start <= 1'b1;
        end
        endcase
    end
end
  • 接收數據FIFO控制

接收狀態機的SEND狀態表示1Byte數據接收完成,此狀態會產生一個rx_start信號。

FIFO寫控制部分通過監控此信號產生寫使能rx_fifo_winc(1個ARM時鐘周期)和接收響應rx_ack,SEND狀態發現rx_ack后釋放rx_start,回到IDLE狀態。由于FIFO寫控制是在ARM時鐘域進行,握手的時間很短,不會對接收下一Byte數據產生影響。

// this state machine to send data to RX FIFO
always@(posedge clk ornegedge rst_) begin
    if(!rst_) begin
        rx_ack       <= 1'b0;
        rx_fifo_winc <= 1'b0;
        wdata_state  <= 2'b0;
    end
    elsebegin
        case(wdata_state)
        2'b00: begin
            if(!rx_fifo_wfull && rx_start_delay2) begin
                rx_ack       <= 1'b1;
                rx_fifo_winc <= 1'b1;
                wdata_state  <= 2'b01;
            end
        end
        2'b01: begin
            rx_fifo_winc    <= 1'b0;
            if(!rx_start_delay2) begin
                rx_ack      <= 1'b0;
                wdata_state <= 2'b10;
            end
        end
        2'b10: begin
            wdata_state <= 2'b0;
        end
        endcase
    end
end

FIFO讀邏輯放在reg_if模塊,APB讀RX_DATA寄存器時,產生讀使能信號,FIFO將數據放到寄存器中。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 狀態機
    +關注

    關注

    2

    文章

    492

    瀏覽量

    27544
  • FIFO存儲
    +關注

    關注

    0

    文章

    103

    瀏覽量

    5988
  • UART接口
    +關注

    關注

    0

    文章

    124

    瀏覽量

    15296
  • 時鐘域
    +關注

    關注

    0

    文章

    52

    瀏覽量

    9536
  • 狀態寄存器
    +關注

    關注

    0

    文章

    39

    瀏覽量

    7091
收藏 人收藏

    評論

    相關推薦

    stm32串口是如何實現接收不定長度數據

    1.不定長度數據為什么會存在串口接收不定長度數據?首先,在通信雙方進行數據傳輸的時候,由于不同
    發表于 08-11 08:18

    如何去實現STM32串口發送數據接收數據

    串口發送數據最直接的方式是什么?如何去實現STM32串口發送數據接收
    發表于 12-07 06:03

    如何去實現STM32的USART串口接收數據處理

    如何去實現STM32的USART串口接收數據處理?其代碼程序該如何去實現
    發表于 12-09 07:30

    如何實現串口USART2的發送和接收功能

    如何實現串口USART2的發送和接收功能?如何實現USART2中斷接收任意長度和任意格式的
    發表于 01-20 06:16

    net2.0實現串口GPS數據接收設計應用

    net2.0實現串口GPS數據接收設計應用
    發表于 02-08 16:42 ?25次下載

    python串口接收數據

    本文主要介紹了python串口接收數據。其中涉及了Python使用線程來接收串口數據,以及pyt
    發表于 01-15 09:52 ?4.6w次閱讀
    python<b class='flag-5'>串口</b><b class='flag-5'>接收</b><b class='flag-5'>數據</b>

    labview串口接收數據_labview串口被動接收數據

    字節的數據。最后,用一個狀態機來實現相鄰兩個字符串的判斷。如果串口在相鄰兩個字符串之間接收時間大于50ms,則判斷為兩個獨立的字符串;如果小于50ms,則自動拼接前后兩個字符串。
    發表于 01-15 15:49 ?6.7w次閱讀
    labview<b class='flag-5'>串口</b><b class='flag-5'>接收</b><b class='flag-5'>數據</b>_labview<b class='flag-5'>串口</b>被動<b class='flag-5'>接收</b><b class='flag-5'>數據</b>

    MCU-串口接收實現

    MCU-串口接收實現例程倉庫:https://gitee.com/ll0_0ll/MCU-UART1.串口接收中斷+空閑中斷空閑中斷是接受
    發表于 10-25 10:36 ?12次下載
    MCU-<b class='flag-5'>串口</b><b class='flag-5'>接收</b><b class='flag-5'>實現</b>

    stm32 串口接收不定長度數據及黏包處理 + 串口DMA接收

    1.不定長度數據 為什么會存在串口接收不定長度數據?首先,在通信雙方進行數據傳輸的時候,由于不
    發表于 12-23 19:09 ?27次下載
    stm32 <b class='flag-5'>串口</b><b class='flag-5'>接收</b>不定長度<b class='flag-5'>數據</b>及黏包處理 + <b class='flag-5'>串口</b>DMA<b class='flag-5'>接收</b>

    STM32—無需中斷來實現使用DMA接收串口數據

    如何來優化?比如四軸飛行器,當在不停地獲取姿態控制方向時,又要去接收串口數據.答:使用DMA,無需CPU中斷便能實現接收
    發表于 12-24 19:01 ?8次下載
    STM32—無需中斷來<b class='flag-5'>實現</b>使用DMA<b class='flag-5'>接收</b><b class='flag-5'>串口</b><b class='flag-5'>數據</b>

    STM32之串口DMA接收不定長數據

    目錄STM32之串口DMA接收不定長數據引言DMA簡介什么是DMA在STM32的DMA資源DMA接收數據判斷
    發表于 12-24 19:03 ?30次下載
    STM32之<b class='flag-5'>串口</b>DMA<b class='flag-5'>接收</b>不定長<b class='flag-5'>數據</b>

    stm32 發送完數據串口繼續發送_STM32之串口DMA接收不定長數據

    引言在使用stm32或者其他單片機的時候,會經常使用到串口通訊,那么如何有效地接收數據?假如這段數據是不定長的有如何高效
    發表于 12-24 19:17 ?8次下載
    stm32 發送完<b class='flag-5'>數據</b>后 <b class='flag-5'>串口</b>繼續發送_STM32之<b class='flag-5'>串口</b>DMA<b class='flag-5'>接收</b>不定長<b class='flag-5'>數據</b>

    如何有效地使用串口通訊接收數據

    在使用stm32或者其他單片機的時候,會經常使用到串口通訊,那么如何有效地接收數據?假如這段數據是不定長的有如何高效
    的頭像 發表于 02-14 09:50 ?2774次閱讀
    如何有效地使用<b class='flag-5'>串口</b>通訊<b class='flag-5'>接收</b><b class='flag-5'>數據</b>

    串口接收數據的兩種方式是什么

    上方是發送數據的例子,那么串口接收又該如何配置,又要在串口發送的例子上做哪些更改? 這里我們可以通過查詢或者中斷的方式來進行
    的頭像 發表于 11-10 16:20 ?2369次閱讀
    <b class='flag-5'>串口</b><b class='flag-5'>接收</b><b class='flag-5'>數據</b>的兩種方式是什么

    基于RA2L1實現串口DTC數據接收

    基于RA2L1實現串口DTC數據接收
    的頭像 發表于 10-10 09:34 ?549次閱讀
    基于RA2L1<b class='flag-5'>實現</b><b class='flag-5'>串口</b>DTC<b class='flag-5'>數據</b><b class='flag-5'>接收</b>
    主站蜘蛛池模板: 男人J放进女人P全黄网站| 好姑娘BD高清在线观看免费| 成年免费三级视频| 久久中文字幕人妻熟AV女蜜柚M| 日韩精品特黄毛片免费看 | 99re 这里只有精品| 久久亚洲精品AV成人无| 曰曰夜夜在线影院视| 久久精品亚洲精品国产欧美| 亚洲综合免费视频| 久久国产露脸老熟女熟69| 一二三四高清中文版视频| 九九免费的视频| 亚洲视频精选| 久久ZYZ资源站无码中文动漫| 亚洲欧美另类无码专区| 国语精彩对白2021| 一边吃奶一边啪啪真舒服| 久久成人免费观看全部免费| 一个人的免费高清影院| 久久综合丁香激情久久| 67194成网页发布在线观看| 男插女高潮一区二区| FREECHINESE东北群交| 欧美性爱 先锋影音| 富婆找黑人老外泻火在线播放| 王晶三级作品| 黄色三级网络| 最新无码国产在线视频| 琪琪午夜福利免费院| 国产成人高清视频| 亚洲乱码国产乱码精品精98| 伦理片天堂eeuss影院| 99久久久无码国产精品不卡按摩| 人妻互换免费中文字幕| 国产精品久久人妻无码蜜| 亚洲熟少妇在线播放999| 蜜桃传媒在线播放| 国产激情视频在线观看| 伊人久久大香线蕉综合电影| 男人大臿蕉香蕉大视频|