
正文
基于FPGA的电压表与串口通信(上)
提示:扫一扫查出行【扫一扫了解最新限行尾号】
复制提示
实验原理
该实验主要为利用TLC549采集模拟信号,然后将模拟信号的数字量通过串口发送到PC上上位机进行显示,使用到的TLC549驱动模块在进阶实验已经使用到了,串口模块在基础实验也已经使用到了,本实验主要是做一个综合,将数据流进行一个整合。
硬件原理图
实验代码
顶层文件
TLC549驱动
|
/******************************************************************************* **----------------------------文件信息-------------------------- ** 文件名称:ADC_TLC549.v ** 功能描述:使用AD芯片TLC549采集模拟信号 ** 操作过程:将模拟信号接到TLC549的输入管脚上 *******************************************************************************/ module ADC_TLC549 ( clk , //系统50MHZ时钟 reset_n , //复位 ioclk , //AD TLC549的时钟 data , //AD TLC549的数据口 cs , //AD TLC549的片选择 segcs , //数码管的为选择 段码 send_finish , //发送完成标志 start , //开始采集信号 data_cnt , //数据位标志 voltage_data1 , //采集的电压数据 voltage_data2 , //采集的电压数据 voltage_data3 , //采集的电压数据 voltage_data4 //采集的电压数据 ); input clk ; //系统50MHZ时钟 input reset_n ; //复位 input data ; //AD TLC549的数据口 input send_finish ; //发送完成标志 output cs ; //AD TLC549的数据口 output ioclk ; //AD TLC549的时钟 output start ; //开始采集信号 ] voltage_data1 ; //采集的电压数据 ] voltage_data2 ; //采集的电压数据 ] voltage_data3 ; //采集的电压数据 ] voltage_data4 ; //采集的电压数据 ] data_cnt ; //数据位标志 ] segdata ; ] segcs ; ] voltage_data1 ; //采集的电压数据 ] voltage_data2 ; //采集的电压数据 ] voltage_data3 ; //采集的电压数据 ] voltage_data4 ; //采集的电压数据 ] data_cnt ; // reg[7:0] voltage_data; ] segcs ; ] segdata ; reg start ; reg cs , ioclk , clk1k , clk1ms ; ] count ; ] count1ms ; ] cnt ; ] number ; ] state ; ] dataout ; ] tenvalue ; parameter sample = 2'b00 , display = 2'b01 ; /**********产生100k的采集时钟信号*********/ always@(posedge clk ) begin ) count <= count + 1'b1 ; else begin ; ioclk <=~ ioclk ; end end /*******产生周期为1ms即1kHz的信号*********/ always@(posedge clk ) begin if( count1ms > 25'd25000 ) begin clk1ms <=~ clk1ms ; ; end else count1ms <= count1ms + 1'b1 ; end /*********AD采样程序**************/ always@(negedge ioclk or negedge reset_n ) begin if( reset_n == 1'b0 ) begin start <= 1'b0 ; state <= sample ; ; //关AD片选 ; ; ; end else begin case( state ) sample : begin ; start <= 1'b0 ; ], data }; if( cnt > 4'd7 ) begin ; state <= display ; end else begin cnt <= cnt + 1'b1 ; state <= sample ; end end display : begin ; //关AD片选 ; // //得到采集的数据 start <= 1'b1 ; )+ 8'd48 ; //个位 )+ 8'd48 ; //十位 )+ 8'd48 ; //百位 )+ 8'd48 ; //千位 if( send_finish == 1'b1 ) state <= sample ; else state <= display ; end default: state <= display ; endcase end end /***********2进制转十进制函数*************/ 位的数字 ] datain ; begin case( datain ) 4'b00000000 : tendata = 4'd0 ; //0 4'b00000001 : tendata = 4'd1 ; //1 4'b00000010 : tendata = 4'd2 ; //2 4'b00000011 : tendata = 4'd3 ; //3 4'b00000100 : tendata = 4'd4 ; //4 4'b00000101 : tendata = 4'd5 ; //5 4'b00000110 : tendata = 4'd6 ; //6 4'b00000111 : tendata = 4'd7 ; //7 4'b00001000 : tendata = 4'd8 ; //8 4'b00001001 : tendata = 4'd9 ; //9 4'b00001010 : tendata = 4'd10 ; // 4'b00001011 : tendata = 4'd11 ; // 4'b00001100 : tendata = 4'd12 ; 4'b00001101 : tendata = 4'd13 ; 4'b00001110 : tendata = 4'd14 ; 4'b00001111 : tendata = 4'd15 ; default: tendata = 8'bzzzz_zzzz ; endcase end endfunction /*********十进制转LED段选函数*********/ 位的数字 ] datain ; begin case( datain ) 4'd0 : leddata = 8'b11000000 ; //0 4'd1 : leddata = 8'b11111001 ; //1 4'd2 : leddata = 8'b10100100 ; //2 4'd3 : leddata = 8'b10110000 ; //3 4'd4 : leddata = 8'b10011001 ; //4 4'd5 : leddata = 8'b10010010 ; //5 4'd6 : leddata = 8'b10000010 ; //6 4'd7 : leddata = 8'b11111000 ; //7 4'd8 : leddata = 8'b10000000 ; //8 4'd9 : leddata = 8'b10010000 ; //9 4'd10 : leddata = 8'b10111111 ; //- 4'd11 : leddata = 8'b01111111 ; //. default: leddata = 8'bzzzz_zzzz ; endcase end endfunction /********数码管扫描函数*************/ always@(posedge clk1ms ) begin ; else begin ; case( number ) 4'd0 : begin ); //个位 segcs <= 4'b1110 ; end 4'd1 : begin ); //十位 segcs <= 4'b1101 ; end 4'd2 : begin ); //百位 segcs <= 4'b1011 ; end 4'd3 : begin ); //千位 segcs <= 4'b0111 ; end 4'd4 : begin segdata <= leddata ( 4'd11 ); //. 显示小数点 segcs <= 4'b0111 ; end endcase end end endmodule |
UART通信
|
/******************************************************************************* ** 文件名称:uart.v 位起始位,8个数据位,1个结束) *******************************************************************************/ module uart ( clk , rst , rxd , txd , start , data_cnt , voltage_data1 , voltage_data2 , voltage_data3 , voltage_data4 , send_finish ); input clk ; //系统50MHZ时钟 input rst ; //复位 input rxd ; //串行数据接收端 output txd ; //串行数据发送端 input start ; //开始采集信号 ] data_cnt ; //数据位标志 ] voltage_data1 ; //采集的电压数据 ] voltage_data2 ; //采集的电压数据 ] voltage_data3 ; //采集的电压数据 ] voltage_data4 ; //采集的电压数据 output send_finish ; //发送完成标志 倍波特率的时钟 ] div8_tras_reg ; //该寄存器的计数值对应发送时当前位于的时隙数 ] state_tras ; //发送状态寄存器 reg clkbaud_tras ; //以波特率为频率的发送使能信号 倍波特率为频率的时钟,它的作用是将发送或接受一个bit的时钟周期分为8个时隙 reg trasstart ; //开始发送标志 reg send_finish ; reg txd_reg ; //发送寄存器 ] rxd_buf ; //接受数据缓存 ] txd_buf ; //发送数据缓存 ] send_state ; //发送状态寄存器 parameter div_par = 16'h145 ; //分频参数,其值由对应的波特率计算而得,按此参数分频的时钟频率是波倍特率的8 的波特率,即分频出的时钟频率是9600*8 (CLK50M) assign txd = txd_reg ; // assign send_state=data_cnt; 倍波特率的时钟*********/ always@(posedge clk ) begin if(! rst ) ; else begin if( div_reg == div_par - 1'b1 ) ; else div_reg <= div_reg + 1'b1 ; end end always@(posedge clk ) begin if(! rst ) ; else if( div_reg == div_par - 1'b1 ) 倍波特率的时钟:clkbaud8x end // *******************************/ always@(posedge clkbaud8x or negedge rst ) //clkbaud8x begin if(! rst ) ; else if( trasstart ) 倍波特率的时钟下加1循环 end always@( div8_tras_reg ) begin ) 个时隙,发送使能信号有效,将数据发出 else ; end // *********发送数据模块***************/ always@(posedge clkbaud8x or negedge rst ) //clkbaud8x begin if(! rst ) begin ; //发送寄存器置高 ; //开始发送标志置低 txd_buf <= 8'h00 ; //发送缓存器清零 ; //发送状态寄存器清零 send_finish <= 1'b0 ; send_state <= 4'd0 ; end else if( start == 1'b1 ) case( state_tras ) 4'b0000 : begin //发送起始位 send_finish <= 1'b0 ; if(! trasstart && send_state < 4'd7 ) ; else if( send_state < 4'd7 ) begin if( clkbaud_tras ) begin ; state_tras <= state_tras + 1'b1 ; end end else begin ; end end 位 if( clkbaud_tras ) begin ]; ]; state_tras <= state_tras + 1'b1 ; end end 位 if( clkbaud_tras ) begin ]; ]; state_tras <= state_tras + 1'b1 ; end end 位 if( clkbaud_tras ) begin ]; ]; state_tras <= state_tras + 1'b1 ; end end 位 if( clkbaud_tras ) begin ]; ]; state_tras <= state_tras + 1'b1 ; end end 位 if( clkbaud_tras ) begin ]; ]; state_tras <= state_tras + 1'b1 ; end end 位 if( clkbaud_tras ) begin ]; ]; state_tras <= state_tras + 1'b1 ; end end 位 if( clkbaud_tras ) begin ]; ]; state_tras <= state_tras + 1'b1 ; end end 位 if( clkbaud_tras ) begin ]; ]; state_tras <= state_tras + 1'b1 ; end end 4'b1001 : begin //发送停止位 if( clkbaud_tras ) begin ; txd_buf <= 8'h00 ; state_tras <= state_tras + 1'b1 ; end end 4'b1111 :begin if( clkbaud_tras ) begin state_tras <= state_tras + 1'b1 ; send_state <= send_state + 1'b1 ; ; case( send_state ) 4'b0000 : txd_buf <= voltage_data4 ; //个位 4'b0001 : txd_buf <= 8'd46 ; //小数点 4'b0010 : txd_buf <= voltage_data3 ; //十位 4'b0011 : txd_buf <= voltage_data2 ; //百位 4'b0100 : txd_buf <= voltage_data1 ; //千位 4'b0101 : txd_buf <= 8'd86 ; //"V" 4'b0110 : begin txd_buf <= 8'd10 ; //换行符 send_finish <= 1'b1 ; send_state <= 4'b0000 ; end default: txd_buf <= 8'd0 ; endcase end end default: begin if( clkbaud_tras ) begin state_tras <= state_tras + 1'b1 ; ; end end endcase end endmodule |
每日推送不同科技解读,原创深耕解读当下科技,敬请关注微信公众号“科乎”。






