IT技術互動交流平台

FPGA實現串口與iic控製器總結(1)

來源-|云顶平台是真是假:IT165收集  發布日期_-_武陟县公安局:2016-04-28 21:40:26

在剖析了《深入淺出玩轉FPGA》的串口代碼和IIC控製器代碼_-_芷江租房网、xilinx官方的xilinx的iic控製器(參見書《FPGACPLD設計工具──Xilinx ISE使用詳解》)|__全鹿大补胶囊、《片上係統設計思想與源代碼分析》一書中帶有wishbone接口的iic控製器後--|麦梓俊,本文嚐試對以上做一些總結_-_花冈实太,並分析不同的iic控製器的實現區別|_|106彩票官网。

1_|优胜彩票、串口

該章節代碼來源於《深入淺出玩轉FPGA》深入淺出的相關章節|青岛航空快线商务酒店。
改代碼實現的例子是串口以9600的波特率接受從電腦傳來的一個數據_--无氨显影液,然後立馬發回電腦||天天酷跑九月幸运星。根據頂層框圖可以發現rx的輸出數據接口是接在tx的輸入接口的--|绿酷高。所以這並不是一個完整的全功能的串口-|雅马哈r6报价,是一個閹割板的仿串口協議的收發|-_广东电大成绩查询平台,並且沒有用狀態機實現|-|阿福购物网。
整體框圖||大连开发区好望角:
頂層
4個文件|__诺基亚n79论坛:

speed_selectspeed_rx(
.clk(clk),//波特率選擇模塊
.rst_p(rst_p),
.bps_start(bps_start1),
.clk_bps(clk_bps1)
);

my_uart_rxmy_uart_rx(
.clk(clk),//接收數據模塊
.rst_p(rst_p),
.rs232_rx(rs232_rx),
.rx_data(rx_data),
.rx_int(rx_int),
.clk_bps(clk_bps1),
.bps_start(bps_start1)
);
///////////////////////////////////////////
speed_selectspeed_tx(
.clk(clk),//波特率選擇模塊
.rst_p(rst_p),
.bps_start(bps_start2),
.clk_bps(clk_bps2)
);
my_uart_txmy_uart_tx(
.clk(clk),//發送數據模塊
.rst_p(rst_p),
.rx_data(rx_data),
.rx_int(rx_int),
.rs232_tx(rs232_tx),
.clk_bps(clk_bps2),
.bps_start(bps_start2)
);

speed_select模塊中-108娱乐app:
一根輸入線受外部限製|众赢彩票计划软件手机,在if判斷中作為是否有必要啟動計時器的標誌___诺顿免费激活码。定義了一個計時器|长治日报,將在2603個計時周期處輸出改變clk_bps_r變量||_快播加速器,作為采樣脈衝-_-优衣库事件视频。同時已經計算好了在一個數據位的正中心采樣-_贴膜先撕1还是2。我們考慮為9600bps--亿彩彩票是骗局吗,這樣算下來每個數據位的時間是多少-||百事淘宝瓶盖兑奖,再結合自己板子的時鍾--|锐图拉斐,決定應該算多少個周期---218四柱彩测图。
speed模塊例化了2次--|永盛彩票里面是托吗,在接受和發送都可以設置選用不同的波特率|_-虚拟定位安卓。已經定義為變量---品箫,隻需選擇不同的值即可__-093彩票软件100。

my_uart_rx模塊中-|反间谍工作的主管单位是:

input clk;      // 50MHz主時鍾
input rst_p;    //高電平複位信號
input rs232_rx; // RS232接收數據信號
input clk_bps;  // clk_bps的高電平為接收或者發送數據位的中間采樣點|-cctv10怪兽之谜1,spped模塊就是專門產生這麼一個采樣脈衝的
output bps_start;       //接收到數據後|-若冬之颤,波特率時鍾啟動信號置位
output[7:0] rx_data;    //接收數據寄存器_-|国王皇后mv,保存直至下一個數據來到 
output rx_int;  //接收數據中斷信號,接收到數據期間始終為高電平

clk_bps即為speed模塊中傳來的采樣脈衝信號__众购彩票网首页,bps_start決定是否有必要啟動那個計時模塊||2019六开彩香港开奖结果。
進來首先可以看到是對rs232_rx信號的一個濾波_|_布朗司翻糖艺术蛋糕:

//----------------------------------------------------------------
reg rs232_rx0,rs232_rx1,rs232_rx2,rs232_rx3;    //接收數據寄存器_-|花城广场停车,濾波用
wire neg_rs232_rx;  //表示數據線接收到下降沿

always @ (posedge clk or posedge rst_p) begin
    if(rst_p) begin
            rs232_rx0 <= 1'b0;
            rs232_rx1 <= 1'b0;
            rs232_rx2 <= 1'b0;
            rs232_rx3 <= 1'b0;
        end
    else begin                          //打了4拍
            rs232_rx0 <= rs232_rx;
            rs232_rx1 <= rs232_rx0;
            rs232_rx2 <= rs232_rx1;
            rs232_rx3 <= rs232_rx2;
        end
end
    //因為串口的起始信號是一個下降沿
    //參考按鍵消抖-辽宁财政企业服务网,畫圖發現可以檢測到下降沿-_阿里旺旺2012买家版,如果正常的一個下降沿可以產生一個時長為20ns的瞬時高脈衝_|-248软件彩票靠谱吗,
    //但是如果是20ns-40ns的毛刺就無法產生這個了
    //下麵的下降沿檢測可以濾掉<20ns-40ns的毛刺(包括高脈衝和低脈衝毛刺)|369彩票官网注册,
    //這裏就是用資源換穩定(前提是我們對時間要求不是那麼苛刻_亿博平台安全吗,因為輸入信號打了好幾拍) 
    //(當然我們的有效低脈衝信號肯定是遠遠大於40ns的)
assign neg_rs232_rx = rs232_rx3 & rs232_rx2 & ~rs232_rx1 & ~rs232_rx0;    //接收到下降沿後neg_rs232_rx置高一個時鍾周期

可以看到實際上類似與按鍵去抖-|_火线闲聊,可以自己去畫畫隨著clk演變的圖-|新沂style,分析一下對什麼樣的噪聲有效|_-众博彩票平台。這是一種常見的處理方式_黑帮ceo的筹码情人。
根據串口的協議_|火瀑吧,起始位是一個低電平_|钻石夜总会主持人,所以我們要檢測下降沿||_玄魔神变。

always @ (posedge clk or posedge rst_p)
    if(rst_p) begin
            bps_start_r <= 1'bz;            //?
            rx_int <= 1'b0;
        end
    else if(neg_rs232_rx) begin     //接收到串口接收線rs232_rx的下降沿標誌信號
            bps_start_r <= 1'b1;    //啟動串口準備數據接收
            rx_int <= 1'b1;         //接收數據中斷信號使能
        end
    else if(num==4'd12) begin       //接收完有用數據信息
            bps_start_r <= 1'b0;    //數據接收完畢_-_全屏助手,釋放波特率啟動信號
            rx_int <= 1'b0;         //接收數據中斷信號關閉
        end

assign bps_start = bps_start_r;

檢測到rx上有效的低電平-裙地垫卫生巾,置位這2個信號|-35彩票官方,啟動計數器模塊開始準備技術采樣數據-_-长江电力商务网,同時表明正在接收數據-_中科彩票印务。當一幀數據完了(12位)_||航空证券保定营业部,則釋放--优衣库视频完整版下载。

//----------------------------------------------------------------
reg[7:0] rx_data_r;     //串口接收數據寄存器|||光明农场攻略,保存直至下一個數據來到
//----------------------------------------------------------------
reg[7:0] rx_temp_data;  //當前接收數據寄存器
always @ (posedge clk or posedge rst_p)
    if(rst_p) begin
            rx_temp_data <= 8'd0;
            num <= 4'd0;
            rx_data_r <= 8'd0;
        end
    else if(rx_int) begin   //接收數據處理        這個地方體現出對串口波特率的啟動
        if(clk_bps) begin       //這個地方顯然不能把clk_bps放到always的括號裏麵|-芳香假日,因為在speed模塊中分析了其實
        //讀取並保存數據,接收數據為一個起始位|-|船位船讯网,8bit數據-网点是什么,1或2個結束位     
                num <= num+1'b1;
                case (num)
                        4'd1: rx_temp_data[0] <= rs232_rx;  //鎖存第0bit
                        4'd2: rx_temp_data[1] <= rs232_rx;  //鎖存第1bit
                        4'd3: rx_temp_data[2] <= rs232_rx;  //鎖存第2bit
                        4'd4: rx_temp_data[3] <= rs232_rx;  //鎖存第3bit
                        4'd5: rx_temp_data[4] <= rs232_rx;  //鎖存第4bit
                        4'd6: rx_temp_data[5] <= rs232_rx;  //鎖存第5bit
                        4'd7: rx_temp_data[6] <= rs232_rx;  //鎖存第6bit
                        4'd8: rx_temp_data[7] <= rs232_rx;  //鎖存第7bit
                        default: ;
                    endcase
            end
        else if(num == 4'd12) begin     //我們的標準接收模式下隻有1+8+1(2)=11bit的有效數據
                num <= 4'd0;            //接收到STOP位後結束,num清零
                rx_data_r <= rx_temp_data;  //把數據鎖存到數據寄存器rx_data中
            end
        end
assign rx_data = rx_data_r; 

rx_int作為這個always中的if的啟動信號_-双升单机版,按照時鍾脈衝鎖存數據__|长城i7,當收滿一幀(包括奇偶校驗和停止位)||金螳螂 朱兴良,num清0__-云顶娱乐平台怎么样,傳出rx的值laichien。
記住整個過程都是多個並行的always塊||-2019最新白菜论坛,是如何實現流程控製的|_智多星77238?
即是通過if判斷中的是否滿足條件來實現的||_106福利版彩票苹果,如||-天星影院:
else if(neg_rs232_rx) begin //等到有效的下降沿啟動信號
if(num==4’d12) begin //相當與for循環
if(clk_bps) begin //等待speed模塊中的clk計數器到那一刻

tx模塊中--陈公博简介:

input clk;          // 50MHz主時鍾
input rst_p;        //高電平複位信號
input clk_bps;      // clk_bps_r高電平為接收數據位的中間采樣點,同時也作為發送數據的數據改變點
input[7:0] rx_data; //接收數據寄存器
input rx_int;       //接收數據中斷信號,接收到數據期間始終為高電平,在該模塊中利用它的下降沿來啟動串口發送數據(下降沿表示數據接受完了)
output rs232_tx;    // RS232發送數據信號
output bps_start;   //接收或者要發送數據-|_28彩票平台真的假的,波特率時鍾啟動信號置位

rx_int是在rx中定義的_||345彩票首页,還在接受數據則為1--_卡门 德洛雷菲切,接受完了即為0 --冷酷殿下判出局,這個地方即是通過這種信號的傳遞來實現是先收滿一個數據後再發出來一個數據
還是先是一個濾波||陈少游,可以分析下他是怎麼讓信號繼續保持一個時鍾周期的

//---------------------------------------------------------
reg rx_int0,rx_int1,rx_int2;    //rx_int信號寄存器_198彩app,捕捉下降沿濾波用
wire neg_rx_int;    // rx_int下降沿標誌位
//同樣是一個消抖
always @ (posedge clk or posedge rst_p) begin
    if(rst_p) begin
            rx_int0 <= 1'b0;
            rx_int1 <= 1'b0;
            rx_int2 <= 1'b0;
        end
    else begin
            rx_int0 <= rx_int;
            rx_int1 <= rx_int0;
            rx_int2 <= rx_int1;
        end
end
assign neg_rx_int =  ~rx_int1 & rx_int2;   //捕捉到下降沿後-金锣信息化平台,neg_rx_int拉高保持一個主時鍾周期

接下來是把數據從rx中傳到tx中去

//---------------------------------------------------------
reg[7:0] tx_data;   //待發送數據的寄存器
//---------------------------------------------------------
reg bps_start_r;
reg tx_en;  //發送數據使能信號_8万左右性价比高的车,高有效
reg[3:0] num;
always @ (posedge clk or posedge rst_p) begin
    if(rst_p) begin
            bps_start_r <= 1'bz;
            tx_en <= 1'b0;
            tx_data <= 8'd0;
        end
    else if(neg_rx_int) begin   //接收數據完畢--|沈远奎,準備把接收到的數據發回去
            bps_start_r <= 1'b1;
            tx_data <= rx_data; //把接收到的數據存入發送數據寄存器(整個寄存器一個周期就全部賦值過去了|--韩版恶作剧之吻收视率?)
            tx_en <= 1'b1;      //進入發送數據狀態中
        end
    else if(num==4'd11) begin   //數據發送完成|_爱唯侦查地址发布,複位
            bps_start_r <= 1'b0;
            tx_en <= 1'b0;
        end
end
assign bps_start = bps_start_r;

思路與rx一致__-我就要干,同樣也定義了一個tx_en信號來表征是否發完了_199反水05。注意這個時候num==11|__初中数学教案模板。
接下來吧數據發出去|_|斯丽,思路與rx一致__-零佣通:

//---------------------------------------------------------
reg rs232_tx_r;
always @ (posedge clk or posedge rst_p) begin
    if(rst_p) begin
            num <= 4'd0;
            rs232_tx_r <= 1'b1;
        end
    else if(tx_en) begin
            if(clk_bps) begin
                    num <= num+1'b1;
                    case (num)
                        4'd0: rs232_tx_r <= 1'b0;   //發送起始位
                        4'd1: rs232_tx_r <= tx_data[0]; //發送bit0
                        4'd2: rs232_tx_r <= tx_data[1]; //發送bit1
                        4'd3: rs232_tx_r <= tx_data[2]; //發送bit2
                        4'd4: rs232_tx_r <= tx_data[3]; //發送bit3
                        4'd5: rs232_tx_r <= tx_data[4]; //發送bit4
                        4'd6: rs232_tx_r <= tx_data[5]; //發送bit5
                        4'd7: rs232_tx_r <= tx_data[6]; //發送bit6
                        4'd8: rs232_tx_r <= tx_data[7]; //發送bit7
                        4'd9: rs232_tx_r <= 1'b1;   //發送結束位
                        default: rs232_tx_r <= 1'b1;
                        endcase
                end
            else if(num==4'd11) num <= 4'd0;    //複位
        end
end
assign rs232_tx = rs232_tx_r;

其實完整梳理下來思路很清晰|_评剧发源地,沒有用狀態機依舊實現了串口的功能|-夺宝传世法宝合成,後麵可以試試如何改為分部的-|_瓯江影城,連續接受後存到一個文件中-|。
或者把別的部分怎麼加進來-|-青春幻想曲。
因為不像軟件代碼的順序執行_-新上海滩郑少秋,這個是並發執行的|-汇家卡盟,所以還是有差別的|-|陈蓉图片。

下麵說說testbench-|成人奶妈网站,依舊是參見特權的例子_|觅风易语言教程:
關於仿真信號很多__-娱乐天地官方,所以需要弄懂整個設計思路_卤中仙官网,再來分析信號的變化-|优乐彩正规吗。自己之前犯了個低級錯誤-_众彩彩票网是真实的吗,ml605的板子是200MHZ的|||qq农牧餐偷匪三合一,但是自己的`timescale 1ns / 1ps在modelsim中根本產生不了200MHZ的時鍾-|_22选5开奖结果河南福彩,後麵分析計數器的計數值是對的-|传奇行会名称,但是算總的延時時間不對才定位到這裏--|laichien。所以一定要小心|_500g是多少斤,一點點排查---药酒是哪个朝代,有耐心聚焦_-1980平台登录,不要一下子看到這麼多信號懵逼了-|_全保定网独立团。
testbench的原理我就不講了|_众发彩票怎么提现,信號線應該怎麼接__苍井空ed2k,是reg還是wire型_||赢彩彩票苹果版。
特權的代碼裏麵封裝了一些常見的task__|106官网彩票可以提现吗:

    //-----------------------------------------
    //常用信息打印任務封裝
    //-----------------------------------------
        //警告信息打印任務
    task warning;
        input[2*8:1] msg;
        begin
            $write('WARNING at %t : %s 
',$time,msg);
        end
    endtask
        //錯誤信息打印任務
    task error;
        input[20*8:1] msg;
        begin
            $write('ERROR at %t:%s 
',$time,msg);
        end
    endtask 
        //致命錯誤打印並停止仿真任務
    task fatal;
        input[20*8:1] msg;
        begin
            $write('FATAL at %t : %s',$time,msg);
            $write('Simulation false
');
            $stop;
        end
    endtask 
      //完成仿真任務
    task terminate;
        begin
            $write('Simulation Successful
');
            $stop;
        end
    endtask

調用係統命令_|_长城彩票网站平台,最後會在modelsim串口打出來-_|进口摩托车市场。注意task的調用方法
這裏做了遍曆測試和隨機測試_-|怎么在淘宝网上开店:

        //遍曆測試      
        for(cnt=255;cnt>0;cnt=cnt-1)                //順次發送0-255
            begin                       
                tx_task(cnt);                               //發送數據
                @(negedge rx_flag);             //表示等到這個信號的下降沿再進行下一步|-|易旺彩票犯法吗。等待接收到的數據
                                                //這個地方是要等串口接收完|_|晋城五人。185行是一個always塊一直在檢
                                                //測是否收到數據_||单位性质有哪些,裏麵的rx_flag表示是否收完
                if(data_temp ==cnt)
                    $write('transmit:%d, receive:%d; ture
',cnt,data_temp);       //自收發數據正確
                else begin
                        $write('transmit:%d, receive:%d; error
',cnt,data_temp);      //自收發數據錯誤
                        error('false');
                        end
            end     
        #10_000;                                //10us延時

        //隨機測試
        for(cnt=1; cnt<255; cnt=cnt+1)              //順次發送0-255
            begin
                tx_data = {$random};                       
                tx_task(tx_data);                           //發送隨機數據
                @(negedge rx_flag);                     //等待接收到的數據
                if(data_temp ==tx_data)
                    $write('transmit:%d, receive:%d; ture
',cnt,data_temp);           //自收發數據正確
                else begin
                        $write('transmit:%d, receive:%d; error
',cnt,data_temp);  //自收發數據錯誤
                        error('false');
                        end
            end     
        terminate;
    end 

這裏調用了tx_task___106福利版苹果版下载。注意@(negedge rx_flag);的用法_娱乐彩票平台登录,因為是仿真語句-|_盐城一中吧,並不需要可綜合-智胜彩票app。這表示在此處一致等等到rx_flag的下降沿|_-掌上彩票投注下载,順序結構盈彩娱乐骗局。

    //串口發送任務-_寻找了解绝杀技,是主動的-2118最新118彩票手机版,所以隻需要一個task-|金螳螂朱兴良,我們主動去調用就可以了
    task tx_task;
        input[7:0] txdata;                          //發送數據輸入
        integer i;
        begin
            rs232_rx = 0;                               //起始位
            #tx_bps;
            for(i=0;i<8;i=i+1)                      //8位數據發送
                begin
                    rs232_rx = txdata[7-i];
                    #tx_bps;
                end
                rs232_rx = 1;                           //停止位
                #tx_bps;
        end
    endtask
    integer j;
        //串口接收_-|丁丁和杨坤后场接吻,是被動的_-易发彩票官网,所以一直要用always塊去檢測是否有數據發上來
    always @(negedge rs232_tx)                      //起始位檢測
        begin
            #(tx_bps/2);
            if(rs232_tx == 0)
                begin
                    rx_flag = 1;
                    #tx_bps;
                    for(j=0;j<8;j=j+1)
                        begin
                        data_temp[7-j] = rs232_tx;
                        #tx_bps;
                        end
                    rx_flag = 0;
                end
        end

其實整體思路還是比較清晰的||奇瑞b14。
與c語言差別很大___马云评价云联惠,如何實現各種結構--|iphone5香港官网,需要積累經驗|_17英里ktv团购。然後就是比較verilog要實現的東西一定要想清楚怎麼去實現-_|345彩票,劃分成那幾個功能模塊_||河南风味小吃,是否用狀態機-雷克斯警官,內部應定義那些信號來實現各模塊間的控製和數據傳遞|语文老师你的好紧嗯爽。這需要多去聯係來增強感覺|_兰州摸吧。

關於iic留到一下講|-_反间谍工作的主管单位是,更精彩_-_多彩宝石图纸!


lijiuyang
4-28夜於武昌藍巢逸品

延伸閱讀_|亿发彩票app:

Tag標簽_|_234天天彩票真假: 串口   控製器  
  • 專題推薦

  • Windows7係統入門 優化 技巧技術專題
  • Windows7係統專題 無論是升級操作係統--|魅力先生刘天宝、資料備份|-解方程计算器、加強資料的安全及管...... 詳細
About IT165 - 廣告服務 - 隱私聲明 - 版權申明 - 免責條款 - 網站地圖 - 網友投稿 - 聯係方式
本站內容來自於互聯網,僅供用於網絡技術學習,學習中請遵循相關法律法規
众购彩票K8彩票500万彩票天空彩票荣盛彩票盛世彩票

免责声明: 本站资料及图片来源互联网文章,本网不承担任何由内容信息所引起的争议和法律责任。所有作品版权归原创作者所有,与本站立场无关,如用户分享不慎侵犯了您的权益,请联系我们告知,我们将做删除处理!