久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

基于verilog 的很基礎(chǔ)的RS232串口收發(fā)代碼

寫代碼,記筆記,,防忘記,,須牢記。
寫串口的Verilog代碼關(guān)鍵是要搞明白RS232串口的通信協(xié)議,,它并不像單片機,,直接讀寫SBUF就可實現(xiàn)串口的收發(fā)功能,收發(fā)整個字節(jié),。而FPGA要一位一位的收發(fā),,因此必須了解RS232的數(shù)據(jù)格式。
起始位:RS232約定一位起始位“0”。
停止位:約定停止位為“1”,??蛇x一位或兩位停止位。
奇偶校驗位:可選,。
通過串口發(fā)送數(shù)據(jù)時,,要嚴格遵守RS232的數(shù)據(jù)格式,先發(fā)送起始位,,然后是數(shù)據(jù),,最后是停止位(無奇偶校驗的情況)。
通過串口接收數(shù)據(jù)時,,若接收端無數(shù)據(jù)輸入,會一直處于高電平,,若開始接收數(shù)據(jù),,會首先收到來自串口的起始位“0”,然后是要接收的數(shù)據(jù),,最后為停止位(無奇偶校驗的情況),。所以對于接收模塊,可如此設(shè)計,,F(xiàn)PGA一直檢測接收端是否有下降沿到來,,直到檢測到下降沿,才開始接收數(shù)據(jù),。
波特率設(shè)置的重要性不言而喻,,毋庸贅述。
此設(shè)計為最基礎(chǔ)的串口收發(fā)代碼,,控制邏輯簡單,,適合編寫第一次編寫串口代碼的朋友。
此設(shè)計收發(fā)的數(shù)據(jù)格式為1位起始位,,1位停止位,,無奇偶校驗位,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 : 一個極為簡單的串口收發(fā)工程,,適于串口收發(fā)的入門,。只能收發(fā)單個字節(jié),沒有
//                奇偶校驗位。
//     工作流程為:串口發(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)輸入時鐘
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輸出時鐘
wire   clk_baud;   //波特率時鐘
PLL  u1(.inclk0(clk),.c0(clk2));                                               //PLL輸出低頻時鐘
clk_baud_gen  u2(.clk(clk2),.rst_n(rst_n),.clk_baud(clk_baud));                //產(chǎn)生波特率時鐘
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ā)出時,先發(fā)送起始位“0”,,即如果
//接收端出現(xiàn)由高到低的跳變,,說明串口有數(shù)據(jù)發(fā)出,應(yīng)開始接收
module  serial_rxd(rst_n,clk,rxd,data);
input   rst_n;          //全局復(fù)位
input   clk;            //接收時鐘
input   rxd;            //FPGA接收串口數(shù)據(jù)的接收端
output  [7:0] data;     //FPGA接收的來自串口的數(shù)據(jù),,輸出至LED顯示

reg     [3:0] cnt;      //接收數(shù)據(jù)計數(shù)器
reg     rec_reg1;       //起始位檢測寄存器1
reg     rec_reg2;       //起始位檢測寄存器2
reg     [7:0] data;     //FPGA接收的數(shù)據(jù)
always @(posedge clk or negedge rst_n)
      if(!rst_n)        
begin
rec_reg1<=1'b1;     //起始位檢測寄存器置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)   //檢測rxd下降沿,也即是否有低電平到來
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ù)接收完畢,,起始位檢測寄存器復(fù)位,, 
    rec_reg2<=1'b1;//以準備下次接收
    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; //檢測到起始位后,,接收數(shù)據(jù)計數(shù)器啟動
endmodule 
發(fā)送模塊
//此模塊的作用是FPGA控制模塊向串口發(fā)送數(shù)據(jù),,起始位為“0”,停止位為“1”
//延時電路的設(shè)計思想為按鍵按下彈起之后開始計時,,時長為1010/11920秒
//延時去抖結(jié)束后給出發(fā)送標志位,,直至FPGA向串口發(fā)送完畢
module  serial_txd(rst_n,clk,ena,data,txd);
input    rst_n;           //全局復(fù)位
input    clk;             //串口發(fā)送時鐘
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ù)計數(shù)器
reg      [9:0] cnt_delay; //延時去抖計數(shù)器,延時時間為1010/11920秒
reg      ena_reg1;        //按鍵狀態(tài)寄存器1
reg      ena_reg2;        //按鍵狀態(tài)寄存器2
wire     tx_flag;         //發(fā)送標志位,,高電平表示正在發(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)          //檢測按鍵按下后彈起,,即ena的上升沿(因為無動作時連接按鍵的pin處于高電平)
case (cnt_delay)            
10'd1011:begin
       cnt_delay<=10'd0;            //延時去抖結(jié)束,計數(shù)器清零
 ena_reg1<=1'b1;              //按鍵狀態(tài)寄存器置1,,等待下次ena上升沿的到來
       ena_reg2<=1'b1;
 end
default:cnt_delay<=cnt_delay+10'd1;  //檢測到上升沿,,延時去抖計數(shù)器啟動
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)&&   //延時去抖結(jié)束后給出發(fā)送忙標志,持續(xù)10
                 (cnt_delay<=10'd1010));   //個周期,,以等待FPGA向串口發(fā)送完畢
always @(posedge clk or negedge rst_n)
      if(!rst_n)
  cnt<=4'd0;                        //串口發(fā)送計數(shù)器復(fù)位
else if(!tx_flag)                    
  cnt<=4'd0;                        //若沒有檢測到串口發(fā)送標志位,,則計數(shù)器等待
      else
  cnt<=(cnt>=4'd10)?4'd11:cnt+4'd1; //檢測到串口發(fā)送標志位,啟動計數(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)生模塊(此模塊的輸入時鐘來自PLL,,頻率為12MHz,PLL模塊為宏功能函數(shù))
//此模塊為波特率生成模塊,,修改BAUDRATE的值可改變波特率
//串口波特率時鐘的高電平僅僅持續(xù)一個clk周期
module   clk_baud_gen(clk,rst_n,clk_baud);
input  clk;       //波特率基準時鐘,,此時鐘來自PLL
input  rst_n;     //全局復(fù)位
output clk_baud;  //串口波特率時鐘
wire   clk_baud;  
reg    [9:0] cnt; //波特率時鐘計數(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ù)器啟動
assign   clk_baud=(cnt==BAUDRATE-10'd2);
endmodule 

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點,。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,謹防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多