基于小脚丫的ADC081S101 电压采集595数码管显示

RTL结构图

采集模块运用SPI 通讯 MISO方式收集数据

module ad_collect
(
input sddata,
input rst_n,
output reg cs,
output reg sclk,
input clk,
output [7:0]seg_data,
output done
);

reg [7:0]cnt;
reg[4:0]state;
reg[7:0]data;
reg rdone;

[email protected](posedge clk or negedge rst_n ) begin
if(cs==0)begin sclk<=!sclk; cnt<=cnt+1;end
if(!rst_n)begin cs<=1;state<=0;cnt<=0;sclk<=1;rdone=0;end
else
begin
case(state)
0:if(rst_n==1)begin cs<=0;state<=state+1;end
1:if(cnt==8) begin data[7]<=sddata;state<=state+1;rdone=0;end
2:if(cnt==10) begin data[6]<=sddata;state<=state+1;rdone=0;end
3:if(cnt==12) begin data[5]<=sddata;state<=state+1;rdone=0;end
4:if(cnt==14) begin data[4]<=sddata;state<=state+1;rdone=0;end
5:if(cnt==16) begin data[3]<=sddata;state<=state+1;rdone=0;end
6:if(cnt==18) begin data[2]<=sddata;state<=state+1;rdone=0;end
7:if(cnt==20) begin data[1]<=sddata;state<=state+1;rdone=0;end
8:if(cnt==22) begin data[0]<=sddata;;state<=state+1;rdone=0;end
9:if(cnt==32) begin cs<=1;state<=state+1;sclk<=0;rdone=1;end
10: begin cnt<=cnt+1;if(cnt==42)begin cnt<=0;state<=0;rdone=0;end end
endcase
end
end
assign done=rdone;
assign seg_data=rdone?data[7:0]:seg_data;

endmodule

将输出的8位255的BCD码对应成3.3V的显示,用输出的Q[7:0]去乘上13,给二进制转BCD模块,最后数码管显示控制小数点的位置相当于再除以1000。

//这是一个使用Verilog HDL编写的带使能端的8-bit二进制转BCD码程序,具有占用资源少、移植性好、扩展方便的特点。
/********************************************\
Filrst_nme : B_BCD.v Author : Medied.Lee
Description : a 8-bit binary-to-bcd module
Revision : 2010/11/20 Company :
\********************************************/
module bin_bcd(rst_n,binary,bcd);
//rst_n为使能端,binary为待转换的二进制数,bcd为转换后的BCD码
parameter B_SIZE=12;
//B_SIZE为二进制数所占的位数,可根据需要进行扩展
input binary,rst_n;//rst_n高电平有效,低电平时
output bcd;
wire rst_n;
wire [B_SIZE-1:0] binary;
reg [B_SIZE-1:0] bin;
reg [B_SIZE+3:0] bcd; // bcd的长度应根据实际情况进行修改
reg [B_SIZE+3:0] result; //result的长度=bcd的长度
[email protected](binary or rst_n)
begin
bin= binary;
result = 0;
if(rst_n == 0)
bcd <= 0;
else
begin
repeat(B_SIZE-1)//使用repeat语句进行循环计算
begin
result[0] = bin[B_SIZE-1];
if ( result[3:0] > 4 )
result[3:0]=result[3:0]+ 4‘d3;
if(result[7:4]> 4)
result[7:4]=result[7:4]+4‘d3;
if(result[11:8]>4)
result[11:8] = result[11:8]+4‘d3;
//扩展时应参照此三条if语句续写
if(result[15:12]>4)
result[15:12]= result[15:12]+ 4‘d3;
result=result<<1;
bin=bin<<1; end
result[0]= bin[B_SIZE-1];
bcd<=result;
end
end
endmodule

输出的结果经过数码管译码

module smg_encoder_module(clk,rst_n,num,smg_data);

input clk;
input rst_n;
input [3:0]num;
output [7:0]smg_data;

/*共阴极数码管: 位选为低电平(即0)选中数码管; 各段选为高电平(即1接+5V时)选中各数码段;*/

//由0到f的编码为

parameter
SEG_NUM0=8‘h3f,

SEG_NUM1=8‘h06,

SEG_NUM2=8‘h5b,

SEG_NUM3=8‘h4f,

SEG_NUM4=8‘h66,

SEG_NUM5=8‘h6d,

SEG_NUM6=8‘h7d,

SEG_NUM7=8‘h07,

SEG_NUM8=8‘h7f,

SEG_NUM9=8‘h6f,

SEG_NUMA=8‘h77,

SEG_NUMB=8‘h7c,

SEG_NUMC=8‘h39,

SEG_NUMD=8‘h5e,

SEG_NUME=8‘h79,

SEG_NUMF=8‘h71;

reg [7:0]smg_data_r;

always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
smg_data_r <= 8‘b00000000;
else
case (num)
4‘d0: smg_data_r <= SEG_NUM0;
4‘d1: smg_data_r <= SEG_NUM1;
4‘d2: smg_data_r <= SEG_NUM2;
4‘d3: smg_data_r <= SEG_NUM3;
4‘d4: smg_data_r <= SEG_NUM4;
4‘d5: smg_data_r <= SEG_NUM5;
4‘d6: smg_data_r <= SEG_NUM6;
4‘d7: smg_data_r <= SEG_NUM7;
4‘d8: smg_data_r <= SEG_NUM8;
4‘d9: smg_data_r <= SEG_NUM9;

default: smg_data_r <= 8‘b00000000;
endcase
end

assign smg_data=smg_data_r;

endmodule

最后经过串行数据发送数据给595输出

module seg_chg
(
input clk_in, //25mhz
input rst_n_in, //active with low
input [7:0] datah_f,
input [7:0] datal_f,
input [7:0] datah_m,
input [7:0] datal_m,
output reg rclk_out, //74HC595 RCK
output reg sclk_out, //74HC595 SCK
output reg sdio_out //74HC595 SER
);

parameter CLK_DIV_PERIOD=3900; //related with clk_div‘s frequency
parameter DELAY_PERIOD=10000; //related with delay time and refresh frequency
parameter CLK_DIV_PULSE_PERIOD=25000000; //related with clk_div_pulse_out‘s frequency
parameter CLK_L=2‘d0;
parameter CLK_H=2‘d1;
parameter CLK_RISING_DEGE=2‘d2;
parameter CLK_FALLING_DEGE=2‘d3;
parameter IDLE=3‘d0;
parameter WRITE=3‘d1;
parameter DELAY=3‘d2;
parameter LOW =1‘b0;
parameter HIGH =1‘b1;
//initial for memory register

reg[24:0] cnt;
reg clk_div_1Hz;
[email protected](posedge clk_in or negedge rst_n_in)
begin
if(!rst_n_in) begin
cnt<=0;
clk_div_1Hz<=0;
end else if(cnt==(CLK_DIV_PULSE_PERIOD-1)) begin
cnt<=0;
clk_div_1Hz<=1;
end else begin
cnt<=cnt+1;
clk_div_1Hz<=0;
end
end

//clk_div = clk_in/CLK_DIV_PERIOD
reg clk_div;
reg[11:0] clk_cnt=0;
[email protected](posedge clk_in or negedge rst_n_in) begin
if(!rst_n_in) clk_cnt<=0;
else begin
clk_cnt<=clk_cnt+1;
if(clk_cnt==(CLK_DIV_PERIOD-1)) clk_cnt<=0;
if(clk_cnt<(CLK_DIV_PERIOD/2)) clk_div<=0;
else clk_div<=1;
end
end

//Divide clk_div 4 state,
//RISING and FALLING state is keeped one cycle of clk_in, like a pulse.
reg[1:0] clk_div_state=CLK_L;
[email protected](posedge clk_in or negedge rst_n_in) begin
if(!rst_n_in) clk_div_state<=CLK_L;
else case(clk_div_state)
CLK_L: begin
if (clk_div) clk_div_state<=CLK_RISING_DEGE;
else clk_div_state<=CLK_L;
end
CLK_RISING_DEGE :clk_div_state<=CLK_H;
CLK_H:begin
if (!clk_div) clk_div_state<=CLK_FALLING_DEGE;
else clk_div_state<=CLK_H;
end
CLK_FALLING_DEGE:clk_div_state<=CLK_L;
default;
endcase
end

//Finite State Machine,
reg shift_flag = 0;
reg[15:0] data_reg;
reg[2:0] data_state=IDLE;
reg[2:0] data_state_back;
reg[3:0] data_state_cnt=0;
reg[5:0] shift_cnt=0;
reg[25:0] delay_cnt=0;
[email protected](posedge clk_in or negedge rst_n_in) begin
if(!rst_n_in) begin
data_state<=IDLE;
data_state_cnt<=0;
end else begin
case (data_state)
IDLE: begin
data_state_cnt<=data_state_cnt+1;
case(data_state_cnt)
0: begin
data_reg<={{1‘b1,datah_f[6:0]}, 8‘h0e};
data_state<=WRITE;data_state_back<=IDLE;
end
1: begin
data_reg<={datal_f,8‘h0d};
data_state<=WRITE;data_state_back<=IDLE;
end
2: begin
data_reg<={datah_m,8‘h0b};
data_state<=WRITE;data_state_back<=IDLE;
end
3: begin
data_reg<={datal_m,8‘h07};
data_state<=WRITE;data_state_back<=IDLE;
end
4: begin data_state_cnt<=0; end
default;
endcase
end
WRITE: begin
if(!shift_flag) begin
if (clk_div_state==CLK_FALLING_DEGE) begin
if (shift_cnt==10) rclk_out<=LOW;
if (shift_cnt==16) begin
shift_cnt<=0;
rclk_out<=HIGH;
data_state<=data_state_back;
end else begin
sclk_out<=LOW;
sdio_out<=data_reg[15];
shift_flag <= 1;
end
end
end else begin
if (clk_div_state==CLK_RISING_DEGE) begin
data_reg<={data_reg[14:0], data_reg[15]};
shift_cnt<=shift_cnt+1;
sclk_out<=HIGH;
shift_flag <= 0;
end
end
end
DELAY: begin
if(delay_cnt==DELAY_PERIOD) begin
data_state<=IDLE;
delay_cnt<=0;
end else delay_cnt<=delay_cnt+1;
end

default;
endcase
end
end

endmodule

管脚分配

http://stepfpga.ecbcamp.com/doc/%E7%9B%B4%E6%B5%81%E7%94%B5%E5%8E%8B%E6%B5%8B%E9%87%8F 相关资料

时间: 2024-08-26 01:52:09

基于小脚丫的ADC081S101 电压采集595数码管显示的相关文章

单片机 &amp; 4&#215;4矩阵键盘 &amp; 4位串行595数码管显示

1 #include ? <reg52.h> 2 #define uchar unsigned char 3 #define uint unsigned int 4 //Led数码管数 5 sbit DIO = P2^0;//串行数据输入 6 sbit LRCLK = P2^1;//时钟脉冲信号——上升沿有效 7 sbit LSCLK = P2^2;//打入信号————上升沿有效 8 unsigned char code LED_0F[] = 9 {// 0 1 2 34 5 6 78 9 A

【应用笔记】【AN003】VC++环境下基于以太网的4-20mA电流采集

简介 4-20mA电流环具有广泛的应用前景,在许多行业中都发挥着重要作用.本文主要介绍了以太网接口的4-20mA电流采集模块在VC++环境下进行温度采集,实现WINDOWS平台对数据的采集.分析及显示. 系统组成及工作原理 系统组成主要包括PT100铂电阻.SBWZ温度变送器.4-20mA电流采集模块(GM4008)以及上位机软件组成,如图1所示. PT100铂电阻温度传感器:利用铂金属阻值随温度的变化而变化的特性制成的一种温度传感器,主要用来测量温度的变化量. SBWZ温度变送器:一种现场安装

【应用笔记】【AN004】VB环境下基于RS-485的4-20mA电流采集

版本:第一版作者:周新稳 杨帅 日期:20160226 =========================== 本资料高清PDF 下载: http://pan.baidu.com/s/1c1uuhLQ 源代码包下载: http://pan.baidu.com/s/1LSuXw =========================== 简介 本应用笔记主要说明如何在VB开发环境下基于RS485实现4-20mA电流采集. 系统组成及工作原理 系统组成如图1所示,主要包括 PT100铂电阻温度传感器.S

第3讲 数码管显示

一. 数码管显示原理 我们最经常使用的是七段式和八段式LED数码管,八段比七段多了一个小数点,其它的基本同样.所谓的八段就是指数码管里有八个小LED发光二极管,通过控制不同的LED的亮灭来显示出不同的字形.数码管又分为共阴极和共阳极两种类型,事实上共阴极就是将八个LED的阴极连在一起,让其接地,这样给不论什么一个LED的还有一端高电平,它便能点亮.而共阳极就是将八个LED的阳极连在一起.其原理图例如以下. 当中引脚图的两个COM端连在一起,是公共端,共阴数码管要将其接地,共阳数码管将其接正5伏电

7段数码管显示驱动代码

数码管显示进行简单的介绍,数码管显示原理在数电中已经给出了比较详细的介绍,我就不赘述了,因为我们用的是至芯的开发板,其上的数码管显示模块采用的是共阳极的数码管,为低电平有效,0-F的显示码依次为:    数码管的输入有3个位选和8个段选给出,位选信号sel来控制哪个数码管先亮,段选信号seg来控制数码管显示什么,位选本来应该是有6个的但是为了节约资源,采用了3-8译码器将6根线减少到3根,节约了FPGA的引脚资源. 因为人眼有一个视觉载留,所以60HZ来扫描的时候,数码管会让人眼觉得是同时点亮,

51单片机第三弹---数码管显示

先把定义拉过来: LED数码管是由多个发光二极管封装在一起组成"8"字型的器件,引线已在内部连接完成,只需引出它们的各个笔划,公共电极.LED数码管常用的段数一般为7段,有的另加一个小数点 .LED数码管根据LED的接法不同,分为共阴和共阳两类 . 贴原理图 其实就两点 :由于板子上有8个数码管,而每个数码管有8段,称选择显示哪一个数码管的东西为位选,称单个数码管显示数字几的东西为段选,位选由P2.2  p2.3 p2.4 控制 数码管IO口为P0 对于每一个数码管,显示数字几只要控制

单片机与控制实验(1)——数码管显示

一.实验目的和要求 初步学习和掌握MCS-51的体系结构和汇编语言,了解Keil编程环境和程序下载工具的使用方法.了解数码管输出的原理及编程方式. 二.实验设备 单片机测控实验系统 STC-ISP程序下载工具 Keil开发环境 三.实验内容 使用MCS-51汇编语言编写程序,完成如下功能: 1. 使用三个数码管显示十进制数值(001~999,可任意设置): 2. 每隔1秒,该数值自动减一,直到归零; 3. 归零后的下一秒,显示一个新的十进制数值(001~999,可任意设置): 4. 每隔1秒,新

单片机编程:让led数码管显示数字0到9

led数码管在单片机系统中应用非常普遍,是由发光二极管构成的.数码管由7个发光二极管组成的一个"日"字形,如果需要显示小数点,那么就再加上一个点,就是8段数码管. 数码管显示亮度高,相应速度快,分共阴极和共阳极两种形式,常用的有单个的和4联的,还有两联的和专门用来显示时间的. /*************************************************** *程序功能:点亮一个led数码管,让它显示数字从0到9 * *日期:2015.5.11 * *******

一天:51单片机从入门到一个动态数码管显示数字控制

最近进的公司是一个做路由器的..很多嵌入式工程师.有个项目( 智能空调控制)是跟嵌入式工程师对接,我做APP+PHP..他做服务器.我们用MQTT(由于emqtt是用erlang写的,所以我也学了点erlang,后期有时间分享一下,这个语言很好,很强大.特别抽象).这个项目激发了我对嵌入式的兴趣,于是乎.开始从51单片机搞起了..所以就有了这篇文章...今天搞得东西挺多.我最近都是笔记形式,不想以前写的那么详细...因为学的东西太多,白天在公司搞项目,没时间写太具体... 今天学了什么呢? >k