简易电压表设计验证

news2024/9/29 7:17:54

前言

        电压表是测量电压的一种仪器。由永磁体、线圈等构成。电压表是个相当大的电阻器,理想的认为是断路。初中阶段实验室常用的电压表量程为0~3V和0~15V。

        传统的指针式电压表包括一个灵敏电流计,在灵敏电流计里面有一个永磁体,在电流计的两个接线柱之间串联一个由导线构成的线圈,线圈放置在永磁体的磁场中,并通过传动装置与表的指针相连。大部分电压表都分为两个量程。电压表有三个接线柱,一个负接线柱,两个正接线柱,电压表的正极与电路的正极连接,负极与电路的负极连接。

正文

一、简易电压表设计验证

        1.项目需求

        基于fpga设计一款电压表,显示数据误差不高于0.001V。

        2.技术介绍

        模数转换器即AD转换器,或简称ADC(Analog to DigitalConver),通常是指一个将模拟信号转变为数字信号的电子元件或电路。
        将经过与标准量比较处理后的模拟量转换为以二进制数值表示的离散信号。
模拟信号向数字信号的转换过程一般分为四个步骤:采样、保持、量化、编码。通常量化,编码在ADC芯片中进行,常用ADC芯片有积分型、逐次逼近型、闪烁型、流水线型

        本实验的数据采集需要借助于AD转换模块,该模块使用芯片AD9280,是一款并行8位宽,采样率32M,电压范围+5V,到-5V。

        da_in的数据范围为0000_0000到1111_1111,即0到255,表示-5到+5v,在0到127表示-5到0V,当前电压为= -精度*(127-测量值)。当前精度为10/(2^8);128到255表示0到+5V,当前电压为= 精度*(测量值-127)。当前精度为10/(2^8)。
这里测量方法选用中值法:系统上电后采集接口悬空,此时ad输入数据应为0V,对此时采集的数据取均值M,此时M对应0V,测量数据0到M即对应-5到0V,当前电压为= -精度*(M-测量值),当前精度为10/((M+1)*2);M到255表示0到+5V,当前电压为= 精度*(测量值-M)。当前精度为10/((255-M)*2)。

        3.顶层架构

        4.端口描述

clk时钟信号(50Mhz)
rst_n复位信号(低电平有效)
Clk_ad采样时钟
daAD模块接转换的数据
[2:0] sel位选信号
[7:0] seg段选信号

二、代码验证

数据计算模块

module div_volt(

	input 		  		clk			,
	input 		  		rst_n			,
	input[7:0]	  		da_in			,
					
	output 		  		da_clk		,
	output   [23:0]	data    		,
	output 				sign				//符号位

);

reg 			cnt		;//分频计数器
reg 			da_clk_o	;//四分频时钟
reg [12:0]	cnt_ad	;//数据计数器,基于采样时钟
reg [17:0] 	data_sum	;//数据累加器
reg 			sum_en	;//累加范围标准信号,1024个数据后拉高
reg [7:0] 	data_pj	;//数据M求平均

wire [27:0]	data_p	;//数据精度(-5——0V)
wire [27:0]	data_l	;//数据精度(-5——0V)

reg [27:0]	data_out	;//输出数据暂存
	
always@(posedge clk,negedge rst_n)//四分频计数器
begin
	if(rst_n == 0)
		cnt <= 1'b0;
	else
		cnt = cnt + 1'b1;
end

always@(posedge clk,negedge rst_n)//实现四分频
begin
	if(rst_n == 0)
		da_clk_o <= 1'b0;
	else
		if(cnt == 1'b1)
			da_clk_o <= ~da_clk_o;
		else
			da_clk_o <= da_clk_o;
end

assign da_clk = ~da_clk_o;//输出实现四分频,采样时钟

always@(posedge da_clk,negedge rst_n)//数据计数器
begin
	if(rst_n == 0)
		cnt_ad <= 13'd0;
	else
		if(sum_en == 1'b0)
			cnt_ad <= cnt_ad + 13'd1;
		else
			cnt_ad <= cnt_ad;
end

always@(posedge da_clk,negedge rst_n)//数据累加
begin
	if(rst_n == 0)
		data_sum <= 18'd0;
	else
		if(cnt_ad == 13'd1024)
			data_sum <= 18'd0;
		else
			data_sum <= data_sum + da_in;
end		

always@(posedge da_clk,negedge rst_n)//累加范围标志信号
begin
	if(rst_n == 0)
		sum_en <= 1'b0;
	else
		if(cnt_ad == 13'd1024)//0-1024为悬空状态下确定M的过程
			sum_en <= 1'b1;
		else
			sum_en <= sum_en ;
end

always@(posedge da_clk,negedge rst_n)//求M
begin
	if(rst_n == 0)
		data_pj <= 8'd0;
	else
		if(cnt_ad == 13'd1024)
			data_pj <= data_sum / 1024;
		else
			data_pj <= data_pj;
end

assign data_p = (sum_en == 1'b1)? 81920000/((data_pj +1)*2 ):0;//((10*2^13*1000)/(M+1)*2)

assign data_l = (sum_en == 1'b1)? 81920000/((255-data_pj +1)*2 ):0;//精度扩大2^13倍


always@(posedge da_clk,negedge rst_n)//求M
begin
	if(rst_n == 0)
		data_out <= 24'd0;
	else
		if(sum_en == 1'b1)
			if(da_in < data_pj)
				data_out <= (data_p * (data_pj - da_in)) >>13;
			else
				if(da_in > data_pj)
					data_out <= (data_l * (da_in - data_pj)) >>13;
		
end

assign sign = (da_in > data_pj)?1'b0:1'b1;

assign data = data_out;
			
endmodule

数码管驱动模块

module seg_driver(
 
	input 				clk		,
	input 				rst_n		,
	input [23:0] 		data_in	,//接收数字时钟信号
	
	output reg [2:0] 	sel		,//位选信号
	output reg [7:0]	seg			//段选信号
);
 
reg [18:0] cnt;//1MS
parameter MAX = 19'd50_000;
//20ns记50000次
//产生1ms的延时
//位选信号1ms变换一次
reg [3:0] temp;
always @(posedge clk,negedge rst_n)
begin
	if(rst_n == 0)
		cnt <= 19'd0;
	else
		if(cnt < MAX - 1)//产生1ms的延时
			cnt <= cnt + 19'd1;
		else
			cnt <= 19'd0;
end 
 
//数码管位选信号控制逻辑
always @(posedge clk,negedge rst_n)
begin
	if(rst_n == 0)
		sel <= 3'd0;
	else
		if(cnt == MAX - 1)//位选信号6位,1ms的延时到变化一次
			if(sel < 5)
				sel <= sel + 3'd1;
			else 
				sel <= 3'd0;
		else 
			sel <= sel;	
end 
always @(*) begin
	if(rst_n == 0)
		temp <= 4'd0;
	else
		case(sel)//位选信号到将数据输出到对应输出位上
			3'd0	:	temp <= data_in[23:20];
			3'd1	:	temp <= data_in[19:16];
			3'd2	:	temp <= data_in[15:12];
			3'd3	:	temp <= data_in[11:8];
			3'd4	:	temp <= data_in[7:4];
			3'd5	:	temp <= data_in[3:0];
			default	:	temp <= 4'd0;
		endcase
end 
always @(*) begin
	if(rst_n == 0)
		seg <= 8'hff;
	else
		case(temp)//段选信号,对应的数码管信号
			4'd0	:	seg <= 8'b1100_0000;//0
			4'd1	:	seg <= 8'b1111_1001;//1
			4'd2	:	seg <= 8'b1010_0100;//2
			4'd3	:	seg <= 8'b1011_0000;//3
			4'd4	:	seg <= 8'b1001_1001;//4
			4'd5	:	seg <= 8'b1001_0010;//5
			4'd6	:	seg <= 8'b1000_0010;//6
			4'd7	:	seg <= 8'b1111_1000;//7
			4'd8	:	seg <= 8'b1000_0000;//8
			4'd9	:	seg <= 8'b1001_0000;//9
			4'd10	:	seg <= 8'b1000_1000;//A
			4'd11	:	seg <= 8'b1000_0011;//b
			4'd12	:	seg <= 8'b1100_0110;//C
			4'd13	:	seg <= 8'b1010_0001;//d
			4'd14	:	seg <= 8'b1000_0110;//E
			4'd15	:	seg <= 8'b1000_1110;//F
			default	:	seg <= 8'hff;
		endcase 
end 
endmodule 

顶层连线

module div_volt_top(

	input 		  		clk			,
	input 		  		rst_n			,
	input[7:0]	  		da_in			,
					
	output 		  		da_clk		,
	output  [2:0] 		sel			,//位选信号
	output  [7:0]		seg			//段选信号

);

wire [23:0]data;

div_volt div_volt_inst(

	.clk		(clk	),
	.rst_n	(rst_n),
	.da_in	(da_in),
   
	.da_clk	(da_clk),
	.data    (data  ),
	.sign 	(      )

);

seg_driver seg_driver_inst(
 
	.clk		(clk		),
	.rst_n	(rst_n	),
	.data_in	(data 	),//接收数字时钟信号
    
	.sel		(sel		),//位选信号
	.seg		(seg		)	//段选信号
);
 

endmodule

仿真代码

`timescale 1ns/1ps
module div_volt_top_tb;
	
	reg 			clk	;
	reg 			rst_n	;
	reg[7:0]		da_in	;
	reg			da_en	;
	reg[7:0]		da_reg;
	
	wire [7:0]	seg	;
	wire [2:0]	sel	;
	wire 			da_clk;
	
div_volt_top div_volt_top_inst(

	.clk		(clk		),
	.rst_n	(rst_n	),
	.da_in	(da_in	),

	.da_clk	(da_clk	),
	.sel		(sel		),//位选信号
	.seg		(seg		)	//段选信号
);


initial clk =1;
always #10 clk = ~clk;


initial begin
	rst_n = 0;
	#20
	rst_n = 1;
	#100
	da_en = 0;
	#499990
	da_en = 1;
	#20000
	$stop;
end

always@(posedge clk,negedge rst_n)
begin
	if(rst_n == 0)
		da_reg <= 8'b0;
	else
		if(da_en == 1)
			da_reg <= da_reg + 1;
		else
			da_reg <= 8'b0;
end

always@(posedge clk,negedge rst_n)
begin
	if(rst_n == 0)
		da_in <= 8'b0;
	else
		if(da_en == 0)
			da_in <= 8'd125;
		else
			if(da_en == 1)
				da_in <= da_reg;
			else
				da_in <= da_in;
end


endmodule

三、仿真验证

运行仿真,这里可以看到在500818665ps后开始有数据输出。

调出中间数据,放大波形图进行观察

数据输出4920,在精度计数块,对数据进行了1000倍的放大,所以这里输出数据为4.92V,sign为高电平,表示该数据为负数,即-4.92V。此时输入数据为1,0V时对应输入124,输入范围为0-255,通过对比计算得到输出电压。

数据输出1249,在精度计数块,对数据进行了1000倍的放大,所以这里输出数据为1.249V,sign为低电平,表示该数据为正数,即1.249V。数据输出正确,实验成功

参考资料

等精度测量

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2066666.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

GenAI 的产品:快速行动,但失败

2022 年秋季&#xff0c;我正在做一个很酷的项目。是的&#xff0c;你猜对了——使用公司特定的数据对预先训练的 LLM&#xff08;Bert&#xff09;进行微调。 然而&#xff0c;很快 ChatGPT 就发布了&#xff0c;并席卷了全世界。既然已经有一门非常强大的 LLM 了&#xff0c…

支持AI智能搜索的知识库管理系统有哪些?分享4个软件

引言 在数字化时代&#xff0c;知识的获取、管理和利用已成为企业竞争力的重要组成部分。随着信息量的爆炸性增长&#xff0c;如何快速、准确地从海量数据中检索出有价值的知识&#xff0c;成为企业面临的一大挑战。支持AI智能搜索的知识库管理系统能够快速准确地检索信息&…

【前端】vue监视属性和计算属性对比

首先分开讲解各个属性的作用。 1.计算属性 作用&#xff1a;用来计算出来一个值&#xff0c;这个值调用的时候不需要加括号&#xff0c;会根据依赖进行缓存&#xff0c;依赖不变&#xff0c;computed的值不会重新计算。 const vm new Vue({el:#root,data:{lastName:张,firstNa…

严重腰椎滑脱、无法走路,江山邦尔骨科医院机器人辅助手术为患者完美复位

8月8日上午&#xff0c;53岁的李清&#xff08;化名&#xff09;扶着腰、跛脚走进江山邦尔骨科医院。接诊他的&#xff0c;是江山邦尔骨科医院脊柱科的林科院长。 李清和林院长说&#xff0c;自己已有长达两年的腰痛史&#xff0c;最近还伴随右腿麻木及跛行的症状&#xff0c;严…

深度解析上海我店 三年突破一百亿销售额!

在当今数字化时代的大潮中&#xff0c;消费模式正经历着翻天覆地的变革。上海我店网络科技有限公司&#xff08;简称“我店”&#xff09;&#xff0c;凭借其创新的“互联网实体终端”融合商业模式与独特的绿色积分体系&#xff0c;在消费市场中异军突起&#xff0c;成为引领行…

ClkLog常见问题-埋点集成篇Sec. 1

本篇主要解答ClkLog使用过程中【埋点集成】阶段的常见问题。 1.【指标项数据统计】 问&#xff1a;数据概览无法看到数据。 答&#xff1a;如果数据概览所有指标项都没有数据&#xff0c;则需要先检查埋点数据是否接收成功&#xff1b;如果只是会话相关数据&#xff08;访问次数…

缺陷检测之Anomalib

缺陷检测的现状 工业缺陷数据有一个比较显著的特征&#xff1a;样本不平衡。绝大部分采集得到的工业数据都是没有缺陷的&#xff0c;这样一来&#xff0c;正样本的数据在模型训练中根本没有起到作用&#xff0c;负样本又太少&#xff0c;很难训练得到有效的模型。使用有监督学…

六西格玛与5S管理体系并行落地,实现生产事件精益管理

在现代制造业中&#xff0c;六西格玛管理和5S管理体系是提升生产效率和质量控制的重要工具。六西格玛以其严格的数据分析方法帮助企业减少过程中的变异和缺陷&#xff0c;而5S管理则通过优化工作环境和流程&#xff0c;确保生产线的整洁、有序和高效。如何将这两大管理体系成功…

wpf livechart 绘制笛卡尔曲线

先上图&#xff1a; 代码部分&#xff1a; <GroupBox Header"各生产线生产量趋势"><Grid><Grid.RowDefinitions><RowDefinition Height"45"/><RowDefinition Height"auto"/><RowDefinition/></Grid.RowD…

第R1周: RNN-心脏病预测

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 一、什么是RNN RNN&#xff08;Recurrent Neural Network&#xff09;是一种特殊的神经网络&#xff0c;它能够处理序列数据&#xff0c;如时间序列、文本序列…

MedGraphRAG:医学版 GraphRAG

MedGraphRAG&#xff1a;医学版 GraphRAG 提出我的解法思路 MedGraphRAG 大纲解法大纲 解法拆解U-retrieve 双向检索 分析性关联图创意视角MedGraphRAG 对比 传统知识图谱大模型现在医疗知识图谱的问题MedGraphRAG的三层层级图结构&#xff0c;能不能让普通的医疗知识图谱&…

线程——函数式创建线程threading模块,继承式创建线程,Lock对象解决多线程不安全问题,线程模型中的生产者消费者模式

调度程序内的多任务使用多进程&#xff0c;调度一个进程内的多任务使用多线程 函数式创建线程的方式threading模块 在Python中&#xff0c;创建线程主要依赖于threading模块。 使用threading模块中的Thread类&#xff0c;你可以很容易地基于函数模式创建线程。基本步骤包括&…

Linux | 文件描述符fd详解及重定向技术的应用

多谢梅花&#xff0c;伴我微吟。 - 《高阳台除夜》(韩疁) 2024.8.23 目录 1、文件描述符fd 文件操作符概念(简单带过) 重点&#xff1a;如何理解文件操作符使得系统实现了设备无关性&#xff1f;&#xff08;使得操作系统无需关心具体的硬件细节&#xff09; 示例代码:标准输入…

SAP BW:QUERY数据结果写入ADSO

作者 idan lian 如需转载备注出处 如果对你有帮助&#xff0c;请点赞收藏~~~ 需求背景 客户基于QUERY进行报表展示&#xff0c;现需迁移到永洪报表平台&#xff0c;query中的变量参数&#xff0c;公式等无法直接生成视图&#xff0c;query相对复杂&#xff0c;不想直接在视图…

流动会场:便捷、经济与声学效果的理想融合—轻空间

在现代活动策划中&#xff0c;选择合适的场地至关重要。流动会场作为一种新型移动空间&#xff0c;不仅具备便捷性和高性价比&#xff0c;还以其优异的声学效果&#xff0c;成为各类会议、展览、演出等活动的理想选择。 便捷安装&#xff0c;快速搭建 流动会场的模块化设计使其…

P-One如何测试一个场景集包含多个接口

P-One是泽众软件自主研发的一站式性能测试平台&#xff0c;集管理、设计、压测、监控以及分析于一体的全方位性能测试解决方案&#xff0c;适用于各种非功能测试场景&#xff1a;压力测试、负载测试、稳定性测试、可靠性测试、容量测试等。 在实际业务场景中&#xff0c;如电商…

springsecurity 在web中如何获取用户信息(后端/前端)

一、SecurityContextHolder 是什么 是一个安全的上下文对象&#xff0c;用于获取经过身份验证的用户。 二、SecurityContextHolder 是何时被创建的 当我们经过表单UsernamePasswordAuthenticationFilter 过滤器后&#xff0c;会回调父类的AbstractAuthenticationProcessingFilt…

华为自研仓颉编程语言测试版上线,计划持续到10月21号

现如今&#xff0c;编程语言作为构建软件世界的基石&#xff0c;其重要性不言而喻。 而华为&#xff0c;作为全球领先的信息与通信技术&#xff08;ICT&#xff09;解决方案提供商&#xff0c;其在技术创新上的每一步都备受瞩目。最近&#xff0c;华为再次成为焦点&#xff0c…

OpenCompass 评测 InternLM-1.8B 实践

1. 环境安装 conda create -n opencompass python3.10 conda activate opencompass conda install pytorch2.1.2 torchvision0.16.2 torchaudio2.1.2 pytorch-cuda12.1 -c pytorch -c nvidia -y# 注意&#xff1a;一定要先 cd /root cd /root git clone -b 0.2.4 https://gith…

系统编程-lvgl

带界面的MP3播放器 -- lvgl 目录 带界面的MP3播放器 -- lvgl 一、什么是lvgl&#xff1f; 二、简单使用lvgl 在工程中编写代码 实现带界面的mp3播放器 main.c events_init.c events_init.h 补充1&#xff1a;glob函数 补充2&#xff1a;atexit函数 一、什么是lvgl&a…