FPGA 学习笔记(十二) 如何用串口发送32位数据?
2017-03-16 15:24
330 查看
在笔者之前所用的串口中,串口一次只能发送数据为8位,这跟串口通信的协议方式有关系。而最近笔者的项目中需要用到一次发送32位的数据。笔者最开始想到的是32位数据发送4次。
为了不改动原来的串口通信协议驱动,笔者设计了如下发送方式:
设计一个状态为state,每次发送使能信号txd_flag来之后state加一;(笔者前面还设计了一个不断发送脉冲信号的模块)
检测state变化,state的每个变化的状态代表串口输入的数据不同:
即 state为0发送32位数据的低8为,state为1发送32为数据的后8位,依次类推;
然后调用原来的串口驱动程序即可
以上程序笔者亲测可行。
为了不改动原来的串口通信协议驱动,笔者设计了如下发送方式:
设计一个状态为state,每次发送使能信号txd_flag来之后state加一;(笔者前面还设计了一个不断发送脉冲信号的模块)
always@(posedge clk or negedge rst_n) begin if(!rst_n) begin state<=0; end else if(txd_flag) if(state < 4'd9) state<=state+1; else state<=0; else state<=state; end
检测state变化,state的每个变化的状态代表串口输入的数据不同:
即 state为0发送32位数据的低8为,state为1发送32为数据的后8位,依次类推;
if(state==4'd1) data<=txd_data[7:0]; else if(state==4'd2) data<=txd_data[15:8]; else if(state==4'd3) data<=txd_data[23:16]; else if(state==4'd4) data<=txd_data[31:24]; else if(state==4'd5)
然后调用原来的串口驱动程序即可
/*----------------------------------------------------------------------- \\\|/// \\ - - // ( @ @ ) +-----------------------------oOOo-(_)-oOOo-----------------------------+ CONFIDENTIAL IN CONFIDENCE This confidential and proprietary software may be only used as authorized by a licensing agreement from CrazyBingo (Thereturnofbingo). In the event of publication, the following notice is applicable: Copyright (C) 2013-20xx CrazyBingo Corporation The entire notice above must be reproduced on all authorized copies. Author : CrazyBingo Technology blogs : http://blog.chinaaet.com/crazybingo Email Address : thereturnofbingo@gmail.com Filename : uart_receiver.v Data : 2012-01-28 Description : Data transfer for FPGA to PC. Modification History : Data By Version Change Description ========================================================================= 12/01/28 CrazyBingo 1.0 Original 12/12/04 CrazyBingo 2.0 Modification 13/06/25 CrazyBingo 3.0 Modification 14/04/11 CrazyBingo 3.1 Modification ------------------------------------------------------------------------- | Oooo | +-------------------------------oooO--( )-----------------------------+ ( ) ) / \ ( (_/ \_) -----------------------------------------------------------------------*/ `timescale 1ns/1ns module uart_transfer ( //gobal clock input clk, input rst_n, //uart interface input clken_16bps,//clk_bps * 16 output reg txd, //uart txd interface //user interface input txd_en, //uart data transfer enable input [7:0] txd_data, //uart transfer data output reg txd_flag //uart data transfer done ); /************************************************************************** ..IDLE...Start...............UART DATA........................End...IDLE... ________ ______________ |____< D0 >< D1 >< D2 >< D3 >< D4 >< D5 >< D6 >< D7 > Bit0 Bit1 Bit2 Bit3 Bit4 Bit5 Bit6 Bit7 Bit8 Bit9 **************************************************************************/ //--------------------------------------- //parameter of uart transfer localparam T_IDLE = 2'b0; //test the flag to transfer data localparam T_SEND = 2'b1; //uart transfer data reg [1:0] txd_state; //uart transfer state reg [3:0] smp_cnt; //16 * clk_bps, the center for sample reg [3:0] txd_cnt; //txd data counter localparam SMP_TOP = 4'd15; localparam SMP_CENTER = 4'd7; always@(posedge clk or negedge rst_n) begin if(!rst_n) begin smp_cnt <= 0; txd_cnt <= 0; txd_state <= T_IDLE; end else begin case(txd_state) T_IDLE: begin smp_cnt <= 0; txd_cnt <= 0; if(txd_en == 1) txd_state <= T_SEND; else txd_state <= T_IDLE; end T_SEND: begin if(clken_16bps == 1) begin smp_cnt <= smp_cnt + 1'b1; if(smp_cnt == SMP_TOP) begin if(txd_cnt < 4'd9) begin txd_cnt <= txd_cnt + 1'b1; txd_state <= T_SEND; end else begin txd_cnt <= 0; txd_state <= T_IDLE; end end else begin txd_cnt <= txd_cnt; txd_state <= txd_state; end end else begin txd_cnt <= txd_cnt; txd_state <= txd_state; end end endcase end end //-------------------------------------- //uart 8 bit data transfer always@(*) begin if(txd_state == T_SEND) case(txd_cnt) 4'd0: txd = 0; 4'd1: txd = txd_data[0]; 4'd2: txd = txd_data[1]; 4'd3: txd = txd_data[2]; 4'd4: txd = txd_data[3]; 4'd5: txd = txd_data[4]; 4'd6: txd = txd_data[5]; 4'd7: txd = txd_data[6]; 4'd8: txd = txd_data[7]; 4'd9: txd = 1; default:txd = 1; endcase else txd = 1'b1; //default state end //------------------------------------- //Capture the falling of data transfer over always@(posedge clk or negedge rst_n) begin if(!rst_n) txd_flag <= 0; else if(clken_16bps == 1 && txd_cnt == 4'd9 && smp_cnt == SMP_TOP) //Totally 8 data is done txd_flag <= 1; else txd_flag <= 0; end endmodule
以上程序笔者亲测可行。
相关文章推荐
- c#学习笔记三 如何访问另一个页面的控件数据
- Sharepoint学习笔记---如何在Sharepoint2010网站中整合Crystal Report水晶报表(显示数据 二)
- Kettle学习笔记一 :MySQL到Postgres导入数据且发送日志邮件
- Android(java)学习笔记80:UDP协议发送数据
- 32位汇编语言学习笔记(34)--一个数据的柱状图显示程序
- Excel学习笔记002-002:工作表内及工作表间、工作簿间单元格数据的复制、剪切、粘贴;如何进行成绩排序。
- linux如何清空串口接收缓冲区和发送缓冲区数据
- 【黑金原创教程】【FPGA那些事儿-驱动篇I 】实验十二:串口模块① — 发送
- Sharepoint学习笔记---如何在Sharepoint2010网站中整合Crystal Report水晶报表(显示数据 一)
- Asp.net控件开发学习笔记(十二)----数据绑定
- 我的OpenCV学习笔记(23):Mat中实际数据是如何保存的
- 32位汇编语言学习笔记(2)--数据传送指令
- 【QTP学习笔记 1 】下拉框数据随机选择,日期输入,如何获取动态的对话框
- TinyOS学习笔记8-简单发送接收数据
- 学习《Oracle 9i10g编程艺术》的笔记 (十二) redo 和undo 如何协作
- TinyOS学习笔记8-简单发送接收数据
- MySQL学习笔记十二:数据备份与恢复
- Cocos2d-x学习笔记(十二)-------->x引擎的数据保存
- C2000LaunchPad学习记录(4)——SIC串口发送数据