當(dāng)前位置:首頁(yè) > 技術(shù)學(xué)院 > 熱搜器件
[導(dǎo)讀]寫串口的Verilog代碼關(guān)鍵是要搞明白R(shí)S232串口的通信協(xié)議,它并不像單片機(jī),直接讀寫SBUF就可實(shí)現(xiàn)串口的收發(fā)功能,收發(fā)整個(gè)字節(jié)。而FPGA要一位一位的收發(fā),因此必須了解RS232的數(shù)據(jù)格式。

寫串口的Verilog代碼關(guān)鍵是要搞明白R(shí)S232串口的通信協(xié)議,它并不像單片機(jī),直接讀寫SBUF就可實(shí)現(xiàn)串口的收發(fā)功能,收發(fā)整個(gè)字節(jié)。而FPGA要一位一位的收發(fā),因此必須了解RS232的數(shù)據(jù)格式。
起始位:RS232約定一位起始位“0”。
停止位:約定停止位為“1”。可選一位或兩位停止位。
奇偶校驗(yàn)位:可選。
通過串口發(fā)送數(shù)據(jù)時(shí),要嚴(yán)格遵守RS232的數(shù)據(jù)格式,先發(fā)送起始位,然后是數(shù)據(jù),最后是停止位(無(wú)奇偶校驗(yàn)的情況)。
通過串口接收數(shù)據(jù)時(shí),若接收端無(wú)數(shù)據(jù)輸入,會(huì)一直處于高電平,若開始接收數(shù)據(jù),會(huì)首先收到來(lái)自串口的起始位“0”,然后是要接收的數(shù)據(jù),最后為停止位(無(wú)奇偶校驗(yàn)的情況)。所以對(duì)于接收模塊,可如此設(shè)計(jì),F(xiàn)PGA一直檢測(cè)接收端是否有下降沿到來(lái),直到檢測(cè)到下降沿,才開始接收數(shù)據(jù)。
波特率設(shè)置的重要性不言而喻,毋庸贅述。
此設(shè)計(jì)為最基礎(chǔ)的串口收發(fā)代碼,控制邏輯簡(jiǎn)單,適合編寫第一次編寫串口代碼的朋友。
此設(shè)計(jì)收發(fā)的數(shù)據(jù)格式為1位起始位,1位停止位,無(wú)奇偶校驗(yàn)位,8位數(shù)據(jù)位。波特率為19200,代碼中可隨意更改。
具體Verilog代碼如下:
頂層模塊
`timescale 1ns / 1ps
////////////////////////////////////////////////////////////////////////////////
// Company  : 杭州電子科技大學(xué)
// Engineer  : 曉曉川
// Create Date : 2012.08.26
// Design Name : serial_test
// Module Name : serial_test
// Project Name: serial_test
// Target Device: CycloneII EP2C5T144C8
// Tool versions: Quartus II 11.0
// Revision  : V1.0
// Description  : 一個(gè)極為簡(jiǎn)單的串口收發(fā)工程,適于串口收發(fā)的入門。只能收發(fā)單個(gè)字節(jié),沒有
//                奇偶校驗(yàn)位。
//         工作流程為:串口發(fā)送數(shù)據(jù)給FPGA,以LED燈的亮滅直觀顯示接收到數(shù)據(jù),按下
//                         相應(yīng)按鍵并彈起后,F(xiàn)PGA又將接收到的串口數(shù)據(jù)發(fā)送出去。
// Additional Comments : 
//
////////////////////////////////////////////////////////////////////////////////
module serial_test(clk,rst_n,ena,txd,rxd,data);
input clk;         //系統(tǒng)輸入時(shí)鐘
input rst_n;       //異步復(fù)位
input ena;         //FPGA發(fā)送使能,即按鍵輸入端
input rxd;         //FPGA接收端
output txd;        //FPGA發(fā)送端
output [7:0] data; //至LED顯示的數(shù)據(jù)
wire   [7:0] data;
wire   txd;
wire   clk2;       //PLL輸出時(shí)鐘
wire   clk_baud;   //波特率時(shí)鐘
PLL  u1(.inclk0(clk),.c0(clk2));                                               //PLL輸出低頻時(shí)鐘
clk_baud_gen  u2(.clk(clk2),.rst_n(rst_n),.clk_baud(clk_baud));                //產(chǎn)生波特率時(shí)鐘
serial_txd  u3(.clk(clk_baud),.rst_n(rst_n),.ena(ena),.data(data),.txd(txd));  //FPGA發(fā)送模塊
serial_rxd  u4(.clk(clk_baud),.rst_n(rst_n),.rxd(rxd),.data(data));            //FPGA接收模塊
endmodule
接收模塊
//此模塊是FPGA控制模塊從串口接收數(shù)據(jù),不接收起始位“0”和停止位“1”
//在接收端,若串口沒有數(shù)據(jù)發(fā)出,則一直處于高電平,有數(shù)據(jù)發(fā)出時(shí),先發(fā)送起始位“0”,即如果
//接收端出現(xiàn)由高到低的跳變,說明串口有數(shù)據(jù)發(fā)出,應(yīng)開始接收
module  serial_rxd(rst_n,clk,rxd,data);
input   rst_n;          //全局復(fù)位
input   clk;            //接收時(shí)鐘
input   rxd;            //FPGA接收串口數(shù)據(jù)的接收端
output  [7:0] data;     //FPGA接收的來(lái)自串口的數(shù)據(jù),輸出至LED顯示

reg     [3:0] cnt;      //接收數(shù)據(jù)計(jì)數(shù)器
reg     rec_reg1;       //起始位檢測(cè)寄存器1
reg     rec_reg2;       //起始位檢測(cè)寄存器2
reg     [7:0] data;     //FPGA接收的數(shù)據(jù)
always @(posedge clk or negedge rst_n)
      if(!rst_n)       
  begin
  rec_reg1<=1'b1;     //起始位檢測(cè)寄存器置1,
  rec_reg2<=1'b1;     //處于等待接收狀態(tài)
  data<=8'hzz;        //輸出復(fù)位,LED全滅
  end
  else if(rec_reg1&&rec_reg2)
  begin
  rec_reg1<=rxd;      //rec_reg1寄存rxd當(dāng)前周期的值
  rec_reg2<=rec_reg1; //rec_reg2寄存rxd前一周期的值
  end
  else if(!rec_reg1&&rec_reg2)   //檢測(cè)rxd下降沿,也即是否有低電平到來(lái)
  case (cnt)
      4'd0:data[0]<=rxd;  //接收第一位數(shù)據(jù)
  4'd1:data[1]<=rxd;  //接收第二位數(shù)據(jù)
  4'd2:data[2]<=rxd;  //接收第三位數(shù)據(jù)
  4'd3:data[3]<=rxd;  //接收第四位數(shù)據(jù)
  4'd4:data[4]<=rxd;  //接收第五位數(shù)據(jù)
  4'd5:data[5]<=rxd;  //接收第六位數(shù)據(jù)
  4'd6:data[6]<=rxd;  //接收第七位數(shù)據(jù)
  4'd7:begin
       data[7]<=rxd;  //接收第八位數(shù)據(jù)
       rec_reg1<=1'b1;//數(shù)據(jù)接收完畢,起始位檢測(cè)寄存器復(fù)位,
       rec_reg2<=1'b1;//以準(zhǔn)備下次接收
       end
      default:begin
          data<=8'hzz;
            rec_reg1<=1'b1;
          rec_reg2<=1'b1;
          end
  endcase
always @(posedge clk or negedge rst_n)
      if(!rst_n)
  cnt<=4'd0;          //復(fù)位,接收數(shù)據(jù)技術(shù)器清零
  else if(!rec_reg1&&rec_reg2)
  cnt<=(cnt<4'd7)?cnt+4'd1:4'd0; //檢測(cè)到起始位后,接收數(shù)據(jù)計(jì)數(shù)器啟動(dòng)
endmodule
發(fā)送模塊
//此模塊的作用是FPGA控制模塊向串口發(fā)送數(shù)據(jù),起始位為“0”,停止位為“1”
//延時(shí)電路的設(shè)計(jì)思想為按鍵按下彈起之后開始計(jì)時(shí),時(shí)長(zhǎng)為1010/11920秒
//延時(shí)去抖結(jié)束后給出發(fā)送標(biāo)志位,直至FPGA向串口發(fā)送完畢
module  serial_txd(rst_n,clk,ena,data,txd);
input    rst_n;           //全局復(fù)位
input    clk;             //串口發(fā)送時(shí)鐘
input    ena;             //串口發(fā)送使能輸入端,即按鍵輸入端
input    [7:0] data;      //FPGA向串口發(fā)送的數(shù)據(jù)
output   txd;             //FPGA向串口發(fā)送數(shù)據(jù)的發(fā)送端

reg      txd;            
reg      [3:0] cnt;       //發(fā)送數(shù)據(jù)計(jì)數(shù)器
reg      [9:0] cnt_delay; //延時(shí)去抖計(jì)數(shù)器,延時(shí)時(shí)間為1010/11920秒
reg      ena_reg1;        //按鍵狀態(tài)寄存器1
reg      ena_reg2;        //按鍵狀態(tài)寄存器2
wire     tx_flag;         //發(fā)送標(biāo)志位,高電平表示正在發(fā)送串口數(shù)據(jù)
always @(posedge clk or negedge rst_n)
      if(!rst_n)
  begin
  ena_reg1<=1'b1;
  ena_reg2<=1'b1;
  cnt_delay<=10'd0;
  end
  else if(ena_reg1&!ena_reg2)          //檢測(cè)按鍵按下后彈起,即ena的上升沿(因?yàn)闊o(wú)動(dòng)作時(shí)連接按鍵的pin處于高電平)
  case (cnt_delay)           
  10'd1011:begin
          cnt_delay<=10'd0;            //延時(shí)去抖結(jié)束,計(jì)數(shù)器清零
      ena_reg1<=1'b1;              //按鍵狀態(tài)寄存器置1,等待下次ena上升沿的到來(lái)
          ena_reg2<=1'b1;
      end
  default:cnt_delay<=cnt_delay+10'd1;  //檢測(cè)到上升沿,延時(shí)去抖計(jì)數(shù)器啟動(dòng)
  endcase
  else
   begin
  ena_reg1<=ena;                       //ena_reg1寄存ena當(dāng)前周期的狀態(tài)
  ena_reg2<=ena_reg1;                  //ena_reg2寄存ena前一周期的狀態(tài)
  end
assign  tx_flag=((cnt_delay>=10'd1000)&&   //延時(shí)去抖結(jié)束后給出發(fā)送忙標(biāo)志,持續(xù)10
                 (cnt_delay<=10'd1010));   //個(gè)周期,以等待FPGA向串口發(fā)送完畢
always @(posedge clk or negedge rst_n)
      if(!rst_n)
     cnt<=4'd0;                        //串口發(fā)送計(jì)數(shù)器復(fù)位
  else if(!tx_flag)                   
     cnt<=4'd0;                        //若沒有檢測(cè)到串口發(fā)送標(biāo)志位,則計(jì)數(shù)器等待
      else
     cnt<=(cnt>=4'd10)?4'd11:cnt+4'd1; //檢測(cè)到串口發(fā)送標(biāo)志位,啟動(dòng)計(jì)數(shù)器
always @(posedge clk or negedge rst_n)
      if(!rst_n)
      txd<=1'bz;              //發(fā)送端復(fù)位,高阻態(tài)       
  else
        case (cnt)
    4'd0:txd<=1'bz;        
    4'd1:txd<=1'b0;         //發(fā)送起始位
    4'd2:txd<=data[0];      //發(fā)送第一位
    4'd3:txd<=data[1];      //發(fā)送第二位
    4'd4:txd<=data[2];      //發(fā)送第三位
    4'd5:txd<=data[3];      //發(fā)送第四位
    4'd6:txd<=data[4];      //發(fā)送第五位
    4'd7:txd<=data[5];      //發(fā)送第六位
    4'd8:txd<=data[6];      //發(fā)送第七位
    4'd9:txd<=data[7];      //發(fā)送第八位
    4'd10:txd<=1'b1;        //發(fā)送停止位
    default:txd<=1'bz;
  endcase
endmodule
波特率產(chǎn)生模塊(此模塊的輸入時(shí)鐘來(lái)自PLL,頻率為12MHz,PLL模塊為宏功能函數(shù))
//此模塊為波特率生成模塊,修改BAUDRATE的值可改變波特率
//串口波特率時(shí)鐘的高電平僅僅持續(xù)一個(gè)clk周期
module   clk_baud_gen(clk,rst_n,clk_baud);
input  clk;       //波特率基準(zhǔn)時(shí)鐘,此時(shí)鐘來(lái)自PLL
input  rst_n;     //全局復(fù)位
output clk_baud;  //串口波特率時(shí)鐘
wire   clk_baud; 
reg    [9:0] cnt; //波特率時(shí)鐘計(jì)數(shù)器

parameter  BAUDRATE=10'd625;

always @(posedge clk or negedge rst_n)
      if(!rst_n)
     cnt<=10'd0;
  else
     cnt<=(cnt==BAUDRATE-10'd2)?10'd0:cnt+1'b1;  //波特率時(shí)鐘計(jì)數(shù)器啟動(dòng)
assign   clk_baud=(cnt==BAUDRATE-10'd2);
endmodule

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

倫敦2024年8月29日 /美通社/ -- 英國(guó)汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來(lái)越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來(lái)越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對(duì)日本游戲市場(chǎng)的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)開幕式在貴陽(yáng)舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語(yǔ)權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對(duì)環(huán)境變化,經(jīng)營(yíng)業(yè)績(jī)穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤(rùn)率延續(xù)升勢(shì) 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長(zhǎng) 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競(jìng)爭(zhēng)力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競(jìng)爭(zhēng)優(yōu)勢(shì)...

關(guān)鍵字: 通信 BSP 電信運(yùn)營(yíng)商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺(tái)與中國(guó)電影電視技術(shù)學(xué)會(huì)聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會(huì)上宣布正式成立。 活動(dòng)現(xiàn)場(chǎng) NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長(zhǎng)三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會(huì)上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡(jiǎn)稱"軟通動(dòng)力")與長(zhǎng)三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉