基于FPGA的智能电子秤设计_第1页
基于FPGA的智能电子秤设计_第2页
基于FPGA的智能电子秤设计_第3页
基于FPGA的智能电子秤设计_第4页
基于FPGA的智能电子秤设计_第5页
已阅读5页,还剩55页未读 继续免费阅读

付费下载

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

[26]在按键抖动时,会产生数个脉冲,这会影响FPGA对按键的检测,导致按键功能异常。为了不产生这种现象而作的措施就是按键消抖。在按键消抖后,消抖后的按键并不一定需要低电平有效,也可以检测按键变化来实现按键功能,例如检测按键上升沿或下降沿。图3.11展示了拨码开关原理图。图3.11拨码开关原理图拨码开关是通过改变引脚连接关系实现控制功能,在FPGA板上,当拨码开关向下拨动时,引脚与地连接,处于低电平;当向上波时,处于高电平。设计采用了5个拨码开关来控制物体重量与价格,两个拨码开关控制复位与去皮功能。图3.12展示了相应的控制模块硬件设计对应功能。图3.12控制模块硬件设计3.3本章小结本章基于模块化思想搭建硬件系统,涵盖数据采集、显示、蜂鸣器报警及控制模块。数据采集采用HX711芯片连接称重传感器,实现高精度模数转换;显示模块选用LCD1602液晶,支持字符信息实时呈现;蜂鸣器模块通过三极管驱动实现报警功能;控制模块基于板载按键,结合硬件消抖电容与软件延时算法提升输入可靠性。设计中重点解析了HX711的时序逻辑,通过SCK时钟与DOUT数据引脚的协同实现24位数据稳定读取,并通过逻辑分析仪得出了HX711的数据传输速率;深入研究LCD1602指令集与时序逻辑,列举出了LCD1602实现字符输出的大致框架。该章重点基于硬件设计与原理介绍,为后续软件设计提供思路。第4章智能电子秤的软件设计4.1系统程序总流程软件程序设计利用Verilog硬件描述语言编程,其主要用于数字电路的设计、建模和验证,能够描述从简单逻辑门到复杂处理器系统的硬件行为。为了便于对系统进行模块化的分析,首先需要对总系统程序功能进行一个清晰的设计,理解运行逻辑。图4.1展示了系统程序功能总流程图。图4.1系统程序总流程图在系统流程图中,“是否”对应按键控制、价格和重量转换功能,于是可以在软件设计上把系统划分为数据采集模块、显示模块、蜂鸣器模块和控制转换模块,从而与第三章提及过的硬件模块相互对应。最后,再用顶层模块把这些模块例化整合起来,从而实现系统软件设计功能。4.2系统模块程序设计4.2.1顶层模块在XilinxVivado设计流程中,可以采用自上向下与自下向上的设计方法。简单来说,自上向下的设计方法就是先从系统级需求出发,逐层分解为可实现的硬件模块,最终完成底层RTL代码或IP集成。自下向上则是先分析子模块功能,在例化整合到顶层模块。相较于自下向上设计,自上向下设计可以明确输入输出接口、模块间交互逻辑,保证顶层集成时的兼容性。设计顶层模块时,首先要明确各例化模块的功能,将其与硬件模块设计功能对应起来,便于更好的分析和设计代码。表4.1展示了相应的软硬件模块对应功能。表4.1软硬件模块对应表硬件模块软件模块按键消抖模块key_filter模块数据采集模块hx711模块(集成时钟分频div模块)控制转换模块change模块(集成hex_to_ascii模块)显示数据模块lcd_1602模块蜂鸣器模块buzzer_ctrl模块另外,顶层模块的输入输出接口与硬件模块精密联系,是连接硬件实体与RTL设计的核心纽带,因此要确保接口定义的准确性与完整性,保证其与硬件模块的兼容性。表4.2展示了顶层模块的端口定义。表4.2顶层模块端口定义输入口(input)输出口(output)端口定义clk--系统时钟(50MHz)rst_n--系统复位key_in[0]-key_in[4]--按键key_in[5]--拨码开关din--HX711数据输出--sckHX711内置时钟--lcd_enLcd使能信号--lcd_rslcd数据/命令选择--lcd_rwlcd读/写选择--[7:0]lcd_datalcd双向数据--buzzer蜂鸣器从表可以看出,顶层模块的定义满足了硬件模块基本要求,资源匹配可以实现。4.2.2按键消抖模块在3.2.4关于硬件设计中的按键模块介绍中,我们已经提出了按键抖动的原理。一般情况下,按键抖动时间在20ms以下,正常按动时,抖动维持在10ms左右。因此,在处理中,我们会对按键按下和松开过程时进行一个20ms的消抖,从而实现按键的功能稳定。下面根据程序设计讲解功能的实现。首先是输入输出口的定义,代码如下:modulekey_filter#(parameterKEY_W=6,CNT_TIME=1_000_000)(inputclk,inputrst_n,input[KEY_W-1:0]key_in,outputreg[KEY_W-1:0]key_out);clk是系统时钟信号,rst_n是异步复位信号,key_in是按键输入信号,key_out是消抖后的按键输出信号。因为系统时钟频率为50MHz,一周期为20ns,所以需要把计数CNT_TIME设置为1000000,以达到延时20ms的功能。另外,由于按键键入信号时异步信号,为了避免亚稳态影响,需要设置寄存器key_r0与key_r来对异步信号进行同步处理,相关代码如下:always@(posedgeclkornegedgerst_n)beginif(!rst_n)beginkey_r0<=-1;//初始化为全1(假设按键低电平有效)key_r1<=-1;endelsebeginkey_r0<=key_in;//第一级寄存器:采样异步信号key_r1<=key_r0;//第二级寄存器:同步输出endend在软件层面中,由于信号不存在线路中的时间延迟,所以不存在亚稳态问题。但在硬件层面中,由于信号在寄存器之间传递需要时间,存在着先后顺序,所以从

key_in到

key_r1的值更新是有延迟的,需要经过两个寄存器的延迟时间,此时亚稳态会稳定,从而实现异步信号的同步处理。同时,需要定义4种状态进行逻辑转换,代码如下:parameterIDLE=4'b0001,F_D=4'b0010,H_D=4'b0100,F_U=4'b1000;定义了状态机的4种状态:IDLE:空闲状态,等待按键按下。F_D:消抖按下状态,检测到按键按下的下降沿后进入该状态,开始消抖计数。H_D:稳定按下状态,消抖计数完成后进入该状态,表示按键已稳定按下。F_U:消抖释放状态,检测到按键释放的上升沿后进入该状态,进行释放消抖计数。接下来是对按键进行边沿检测并实行计数延时功能,主要代码如下:always@(posedgeclkornegedgerst_n)beginif(!rst_n)begincnt<=0;endelseif(add_cnt)beginif(end_cnt||p_edge)begincnt<=0;endelsebegincnt<=cnt+1;endendelsebegincnt<=cnt;endendadd_cnt代表F_D(消抖按下)或F_U(消抖释放)状态,cnt为CNT_TIME-1,end_cnt代表add_cnt为高电平并且cnt计数已满。当检测到上升沿p_edge时,计数器也会清零,这是为了处理在计数过程中可能出现的新的边沿情况,比如抖动可能大于20ms。这样,当按键在按下时检测到第一个下降沿和上升时检测到第一个上升沿时,都会进行延时20ms的消抖功能。最后,是实现消抖后的按键输出:always@(posedgeclkornegedgerst_n)beginif(!rst_n)beginkey_out<={KEY_W{1'b0}};endelseif(state_c==H_D&&p_edge)beginkey_out<=~key_r1;endelsebeginkey_out<=0;endend上述代码主要是为了实现按键高电平有效,当状态处于按键按下并且检测到上升沿时(即按键松动),会进行按键输出。4.2.3数据采集模块数据采集要接收到正确的数据,就需要在程序设计中把数据采集速率与数据输出速率同步。数据输出速率已经在第三章用逻辑分析仪测出,其速率大约在1MHz左右。因此,需要采用clk时钟分频去达到数据采集速率,相关代码如下:always@(posedgeclk) if(rx_flag==0)begin cnt<='d0; clk_1hz<='d0; endelseif(cnt==time_1s_cnt)begin//分频25,得1mHZ cnt<=32'd0; clk_1hz<=~clk_1hz; end elsebegin cnt<=cnt+32'd1; clk_1hz<=clk_1hz; end此处,clk_1hz与sck相连,time_1s_cnt为24,从而使得sck输出频率为1MHz。根据图3.5的相关流程图,下面对相关程序代码进行讲解。 首先,din为异步信号,需要对其进行同步处理,方法在4.2.2中已经提及,具体的代码可见附录。在同步处理之后,需要设置信号接收标志。相关代码如下:if(start_flag)rx_flag<=1'b1;//检测到下降沿,启动接收elseif((bps_cnt==(i_BPS_CNT/2-10))&&(rx_cnt==5'd25))rx_flag<=1'b0;//接收完25个计数后停止elserx_flag<=rx_flag;start_flag为din的下降沿检测,rx_flag为接收数据使能标志,bps_cnt为数据采样点,i_BPS_CNT为50以实现采集速度为1MHz。当检测到din下降沿时,rx_flag置1开始接收数据。当接收完24个数据后,停止接受数据。因为AD数据传输信号在边沿处会有抖动,所以,采样点一般设置位周期的中间,在考虑传输延时的情况下,这里将采样点提前10个周期,确保采样数据稳定。 接收信号设置完成后,需要根据接收信号进行数据采样与存储,当rx_flag为1时,将接收到的数据依次存入24位数据输出tx_data的对应位中。根据图3.3的HX711时序图,第一位数据存入到最高位中,最后一位数据存入到最低位中,相关代码如下:if(rx_flag)begincase(rx_cnt)5'd1:tx_data[23]<=uart_rxd_d1;//第1位(MSB)5'd2:tx_data[22]<=uart_rxd_d1;//...中间省略...5'd24:tx_data[0]<=uart_rxd_d1;//第24位(LSB)default:tx_data<=tx_data;endcase 到此,就完成了数据采集模块的整个程序设计,实现数据采集功能。4.2.4数据显示模块要想实现数据显示,首先需要定义符合要求的数据输入,下列代码定义了模块输入输出:input clk input rst_n output wire lcd_en output wire lcd_rw output reg lcd_rs output reg [7:0] lcd_data input wire [127:0] row_1 input wire [127:0] row_2row_1与row_2表示lcd第一行与第二行显示内容,每行16个字符,每个字符8位宽,故row位宽定义为128。根据图3.7流程图,需要在功能设计前对LCD进行初始化。相关代码如下:always@(posedgeclkornegedgerst_n)beginif(!rst_n)cnt_20ms<=0;elseif(cnt_20ms==TIME_20MS-1)cnt_20ms<=cnt_20ms;elsecnt_20ms<=cnt_20ms+1;endTIME_20MS为1000000,目的是进行20ms的等待,保持LCD上电稳定。此外,LCD所需的使能信号需要低频脉冲,因此需要进行分频操作。相关代码如下:always@(posedgeclkornegedgerst_n)beginif(!rst_n)cnt_500hz<=0;elseif(delay_done)beginif(cnt_500hz==TIME_500HZ-1)cnt_500hz<=0;elsecnt_500hz<=cnt_500hz+1;endelsecnt_500hz<=0;endassignlcd_en=(cnt_500hz>(TIME_500HZ-1)/2)?1'b0:1'b1;//50%占空比assignwrite_flag=(cnt_500hz==TIME_500HZ-1);在分频之后,利用赋值操作生成500Hz方波作为使能信号,另外,每个周期末尾产生脉冲write_flag,驱动状态机转换。下面,需要设置LCD的状态,表4.3展示了模块设置中LCD的状态定义。表4.3LCD的状态定义状态名称状态定义SET_FUNCTION设置LCD工作模式DISP_OFF关闭显示DISP_CLEAR清屏ENTRY_MODE设置光标移动方向DISP_ON开启显示ROW1_ADDR设置LCD显示的第一行起始地址ROW1_0~ROW1_F设置第一行相应位置的显示字符ROW2_ADDR设置LCD显示的第二行起始地址ROW2_0~ROW2_F设置第二行相应位置的显示字符 接下来,对上述状态依次进行转换。部分代码如下:case(c_state)IDLE:n_state=SET_FUNCTION;SET_FUNCTION:n_state=DISP_OFF;DISP_OFF:n_state=DISP_CLEAR;DISP_CLEAR:n_state=ENTRY_MODE;ENTRY_MODE:n_state=DISP_ON;DISP_ON:n_state=ROW1_ADDR;//后续状态依次转换...endcase每个状态在

write_flag

有效时跳转(500Hz周期末尾触发)。接下来,需要根据不同指令实现不同功能,具体指令根据表3.2进行设置。首先是lcd_rw需要设置为0,表示LCD执行写功能。另外是控制信号lcd_rs的设置,相关代码如下:if(write_flag)begin//初始化状态和地址设置时为指令(RS=0)if(n_state为初始化或地址设置)lcd_rs<=0;elselcd_rs<=1;//数据模式(发送字符)end当要执行具体指令时,如清屏、关闭和开启显示等指令时,控制信号lcd_rs需设置为0,当要执行具体数据写入时,lcd_rs需设置为1。最后便是进行指令码映射,利用状态机实现,部分代码如下:if(write_flag)begincase(n_state)SET_FUNCTION:lcd_data<=8'h38;DISP_OFF:lcd_data<=8'h08;DISP_CLEAR:lcd_data<=8'h01;ENTRY_MODE:lcd_data<=8'h06;DISP_ON:lcd_data<=8'h0C;ROW1_ADDR: lcd_data<=8'h80;ROW2_ADDR:lcd_data<=8'hC0;ROW1_0:lcd_data<=row_1[127:120];//显示第一行第一个字符//...其他状态 ROW2_F:lcd_data<=row_2[7:0];//显示第二行最后一个字符endcaseend每个状态直接对应一个指令码,状态机的跳转顺序决定了指令的发送顺序,通过

write_flag(500Hz脉冲)控制状态切换和指令码发送的节奏。4.2.5控制转换模块 控制转换模块的端口定义需要把数据采集模块以及数据显示模块连接起来,下面是比较重要的端口定义相关代码:input[KEY_W-1:0]key_out,input[23:0]tx_data,outputwire[127:0]row_1,outputwire[127:0]row_2,其中,key_out与按键消抖模块端口相连,实现按键消抖;tx_data与数据采集模块端口相连,对tx_data进行处理,进而控制重量与价格转换;row_1与row_2与数据显示模块端口相连,进而进行相关显示。在进行重量称量时,首先要进行去皮以获得正确的数据显示,去皮与重量计算相关代码如下:always@(posedgeclkornegedgerst_n)if(!rst_n)beginkey_tare_prev<=1'b0;tare_value<=24'd0;endelsebeginkey_tare_prev<=key_out[5];if(key_out[5]&&!key_tare_prev)begintare_value<=tx_data;endendwire[33:0]net_weight_raw=(tx_data>=tare_value)?(tx_data-tare_value):34'd0;assignnet_weight=(net_weight_raw*1000)/weight_div; 通过检测

key_out[5]

的上升沿,从而将原始储存ad值tx_data赋给

tare_value,net_weight_raw则为净ad值,将ad值放大1000除以校正参数weight_div后即可得到净重。这里将采集的原始数据tx_data放大一千倍是为了方便之后对小数部分的处理,满足精度要求。获得正确重量后,需设置状态转换与功能使能,相关代码如下:always@(posedgeclkornegedgerst_n)beginif(!rst_n)state<=1'b1;elseif(key_out[0])state<=~state;//按一次切换一次endalways@(posedgeclkornegedgerst_n)beginif(!rst_n)weight_state<=1'b0;elseif(key_out[1])weight_state<=~weight_state;endalways@(posedgeclkornegedgerst_n)beginif(!rst_n)price_state<=1'b0;elseif(key_out[2])price_state<=~weight_state;end第一个always块功能为显示状态切换,当按键key_out[0]按下时,执行重量与价格的切换。第二个always块功能为重量单位设置使能,当按键key_out[1]按下时,执行启用/禁用单位调整设置。第三个always块功能为重量单位设置使能,当按键key_out[2]按下时,执行启用/禁用价格调整设置。得到实际重量后,为了得到不同重量单位显示,需要进行重量转换,主要代码如下:if(key_out[3])weight_div<=19'd194816;elseif(key_out[4])weight_div<=19'd214748;根据2.2.4中提及的单位转换,可知,在重量模式下,按下相关按键,可以将重量单位变换为斤与磅。 在获得重量数据后,进行价格计算,代码如下:data_prise<=net_weight*price;单价price可以通过按键进行加减,范围在0~99之间,主要代码如下:if(key_out[3]&&(price<99))beginprice<=price+1;endelseif(key_out[4]&&(price>0))beginprice<=price-1;end为了满足电子秤0.1%的精度要求(即精确到克),需要进行小数计算,这里展示部分重量的处理代码:assigndata_weight_d0=net_weight/1000;assigndata_weight_y1=net_weight%1000;assign data_weight_d1 =data_weight_y1/100;data_weight_d0表示实际重量的整数部分,data_weight_d1表示第一位小数,之后按照相同逻辑处理两次,即可得到三位小数。到此,已经完成了模块的重量和价格设计,之后便是实现数据正常显示。首先是ASCII码的转换,主要代码如下:if(din_vld)beginif(din<4'ha)dout<=din+48;//hex((4))->dec(asccii(4))elsedout<=din+55;在转换规则中,当字符din为数字时,自身加48即为对应ASCII码;当为字母时,自身加55即为对应ASCII码。最后是显示数据部分代码:row_2_d0<={48'h30_30_30_30_30_30,asc_data_weight_d0,8'h2e,asc_data_weight_d1,asc_data_weight_d2,asc_data_weight_d3,40'h30_30_30_30_30};这里的asc_data_weight_d0到asc_data_weight_d3都是处理后的ASCII码,48'h30_30_30_30_30_30表示5个0,8'h2e表示小数点。可以通过三元运算符来设置不同状态下的显示数据,代码如下:assign row_1 = state?row_1_d0:row_1_d1;assign row_2 = state?row_2_d0:row_2_d1;:row_1_d0

row_1_d1

分别存储了两种模式下的显示内容,在不同状态下,row_1得到不同的赋值,从而进行显示界面的转换。另外,可以根据不同的weight_div值设置状态机,在显示界面显示不同重量单位。单价部分也可以通过ASCII码转换在第一行显示出来,相关代码可见附录。4.2.6蜂鸣器模块 首先是模块端口定义: inputclk, inputrst_n, input[13:0]net_weight, outputregbuzzer net_weight为控制转换模块对应的净重,buzzer与顶层模块相应端口相连。 下面进行超重检测,主要代码如下: if(!rst_n)begin weight_over_flag<=2'b00; endelsebeginweight_over_flag<={weight_over_flag[0],(net_weight>THRESHOLD)}; endweight_over_flag2位寄存器,用于记录连续超重状态,THRESHOLD为超重阈值5000。每个时钟周期,weight_over_flag

左移一位,最低位更新为当前是否超重。这样,可以通过延时滤波避免重量瞬间波动导致的误触发。蜂鸣器的驱动信号一般为PWM信号,下面是生成PWM波的代码设计:wirepwm_wave=(pwm_cnt<16'd12500);always@(posedgeclkornegedgerst_n)beginif(!rst_n)beginpwm_cnt<=16'd0;//复位时计数器归零endelsebeginpwm_cnt<=(pwm_cnt>=16'd24999)?16'd0:pwm_cnt+1;endendpwm_cnt最大计数为24999,即将50MHz信号分频为2KHz。pwm_wave赋值判段条件为pwm_cnt是否小于最大计数的一半,表明该程序设计可以产生占空比50%、频率2KHz的方波。最后是蜂鸣器控制输出,代码设计如下:if(!rst_n)beginbuzzer<=1'b0;endelsebeginbuzzer<=(weight_over_flag==2'b11)?pwm_wave:1'b0;end在连续两周期检测到超重时,buzzer则输出PWM波,此时,蜂鸣器发声,否则,蜂鸣器置低电平,保持静音模式。4.3本章小结本章采用VerilogHDL实现状态机控制,开发了数据采集、单位转换、LCD显示及超重报警等子模块。通过分层设计优化代码结构,利用分频技术匹配传感器时序,并完成ASCII码转换与动态界面刷新,验证了系统的实时性与可扩展性。第5章智能电子秤系统功能验证5.1智能电子称功能仿真验证在智能电子秤开发工作里,功能仿真验证属于保证设计正确无误、提高系统可靠性能的关键步骤,它作为硬件实现之前的最后一道验证关卡,仿真测试借助构建虚拟测试环境,针对电子秤的核心功能模块展开全面评估,和传统硬件测试相比较,功能仿真有低成本、高效率以及可重复性强等优点,可在设计阶段的早期就发现并修复潜在的缺陷,防止后期硬件迭代所带来的时间与经济成本。功能仿真验证的关键作用在于借助一套系统的测试策略,来保证电子秤功能和设计规格精确相符,这个过程包含对单个模块的单元测试,还得开展跨模块的集成验证,经由设计覆盖各类使用场景的测试用例,再结合专业仿真工具VivadoSimulator的波形分析,就可透彻了解系统行为,对设计性能进行量化评估,为最终的硬件实现给予可靠的质量保障。5.1.1按键消抖模块在进行模块仿真时,因为目的是检验按键按下时是否有20ms消抖延时产生,所以,为了方便观察,在testbench是设置中,只设置了按键key_in[0]的消抖测试。仿真目的是观察按键key_in[0]按下、抬起时cnt和key_out的变化,检验延时是否达标。图4.1展示了按键按下时的仿真图。图4.1按键下降沿检测key_in[0]按下时,key_in从111111变为111110,异步信号会经过两个寄存器同步,此时cnt等待计数,在下一个clk上升沿到达时,cnt达成条件开始计数,消抖延时开始。图4.2展示了按键抬起时的仿真图图4.2按键上升沿沿检测在cnt计数999999后,也就是20ms后,cnt归零。根据4.2.2中的程序设计,此时key_out[0]会等待按下状态下的按键上升沿,即图中state_c为0100和key_r1变为111111时,开始输出,此时cnt准备计数。当下一个clk上升沿到达后,cnt开始计数,进行按键恢复时的延时消抖。可以看出,按键消抖模块符合软硬件功能设计,符合要求。5.1.2数据采集模块模块的主要功能是在检测到din的下降沿后,启动数据接收过程,通过sck时钟读取24位数据,并存储在tx_data中。因此,测试平台需要模拟HX711的行为,生成din信号,并检查tx_data是否正确接收。图4.3给出了数据采集模块整体仿真波形图。图4.3数据采集模块整体仿真波形图在整体图中,首先可以看出,din的每次变化都是建立在sck上升沿到来时,当sck上升沿到来时,将test_data数据对应位传给din,这是符合协议规则的。一个数据完整周期内,产生了25个sck时钟,rx_cnt计数24次,这些都与图3.3的时序图相对应,符和数据采集功能。但可以发现,test_data与tx_data的数据最后并不一样,这是由于异步信号同步处理的结果。图5.4展示了造成这种现象的原因。图5.4同步处理延迟影响uart_rxd_d1比起din会延迟两个时钟周期变化,这导致了tx_data对应储存数据并非与din严格一致。但是,由于同步引入2个主时钟周期延迟(40ns),而HX711的SCK周期为1μs(1000ns),延迟占比仅4%,远小于数据稳定窗口,这种在实际硬件测试中基本不会带来影响。综上所述,数据采集模块功能仿真正确,符合设计要求。5.1.3数据显示模块模块基于LCD的使用规则,仿真中需要观察状态机、指令发送和数据显示,验证各个状态是否正确转换,指令是否按顺序发送,数据显示是否正确。由于所展示字符要由ASCII码表示,这使得在16进制条件下,仿真图形每一行字符显示需要32个16进制数,在状态机的转换中,难以在一个仿真界面清楚分析两行字符的完整输入,于是在下面仿真图分析中,利用两幅图来分别分析两行字符输入是否正确。仿真图图5.5展示了LCD第一行的数据接收与显示。图5.5LCD第一行数据接收与显示首先是初始化过程,lcd_rw置0,表示执行写操作,lcd_rs置0,表示向LCD发送指令,在进行了系统稳定延时cnt_20ms后(图中黄线位置),lcd_en开始作用,n_state与c_state的状态转换与lcd_data指令输入开始执行。在执行完初始化过程后(即图中lcd_data=48时),lcd_rs置1,开始向LCD发送数据。从lcd_data=48到lcd_data=20(及图中蓝线位置),row_1每个字符的ASCII码都被准确的发送到了lcd_data中,表明第一行数据输入正确。lcd_data为c0时,表示开始向第二行写入数据。图5.6展示了LCD第二行的数据接收与显示。图5.6LCD第二行数据接收与显示 同样,可以看出,在黄线(lcd_data=20时)和蓝线(lcd_data=80时)之间,row_2每个字符的ASCII码都被准确的发送到了lcd_data中,表明第二行数据输入正确。之后,便是执行循环输入,以及为显示页面刷新做准备。 可见,数据显示模块功能仿真正确,符合设计要求。5.1.4控制转换模块控制转换模块仿真主要是为了验证不同按键按下时,对应的重量、价格是否正确改变,以及显示字符的ASCII码是否正确。首先是去皮,图5.7为去皮功能的仿真验证图。图5.7去皮功能的仿真验证 这里主要观察key_out、tx_data、tare_value与net_weight(图中标红部分)信号。在key_out为8’h00时,即控制去皮功能的的拨码开关未拨动时,net_weight为152,这正是ad值扩大1000后除以校正参数weight_div得到的皮重,此时row_2展示了net_weight缩小1000后的真实皮重。当key_out为8’h20时,即key_out[5]对应的拨码开关拨动时,去皮功能准备,在下一个时钟上升沿到达后,tare_value得到对应ad值,net_weight变为零,实现去皮功能。 去皮之后,开始验证按键控制价格与重量的转换功能,图5.8展示了按键控制价格转换的仿真波形。图5.8价格转换的仿真验证 首先看tx_data的转变,增大了一倍,用来模拟与皮重相同重物被称量时的情况。在图中黄线部分,标记的正是key_out[0]按下时row_1的转换,此时重量显示变为价格显示,该按键功能正确。当单价未转换时,单价默认为1,row_2显示正是重量与单价相乘的结果。当key_out为8’h04时,即key_out[2]对应的按键按动时,进入单价配置模式;key_out为8’h08时,即key_out[3]对应的按键按动时,单价加一,row_2显示翻倍;key_out为8’h10时,即key_out[4]对应的按键按动时,单价减一,row_2显示减半。可见,价格设置功能正确。接下来时重量功能验证,图5.9展示了按键控制重量转换的仿真波形。图5.9重量转换的仿真验证当key_out为8’h01时,即key_out[0]对应的按键按动时,row_1进入重量显示模式,在未进行重量单位转换后,默认kg;key_out为8’h02时,即key_out[1]对应的按键按动时,进入重量单位转换;key_out为8’h08时,即key_out[3]对应的按键按动时,row_2显示数据kg与2.20相乘结果,正好对应重量单位磅;key_out为8’h10时,即key_out[4]对应的按键按动时,row_2显示数据kg与2相乘结果,正好对应重量单位斤。综上,价格控制模块功能仿真正确,符合设计要求。5.1.5蜂鸣器模块蜂鸣器模块验证相对简单,主要观察buzzer波形是否在超重状态下与PWM波形一致。首先我们先验证buzzer的逻辑转变是否正确。图5.10为buzzer的逻辑仿真验证图。图5.10buzzer的逻辑仿真验证可以明显看到,weight_over_flag的数值随着net_weight是否超重而变化,当weight_over_flag数值等于3时,即连续两周期超重后,buzzer的值会在下次上升沿到来后更新为pwm_wave的值。同样,当没有超重时,buzzer会变为0,保持低电平。接下来看整体波形,观察buzzer在超重时是否输出PWM方波,图5.11展示buzzer与PWM的关系。图5.11buzzer与PWM仿真关系图可以清楚的看到,在超重情况下,buzzer的值与pwm_wave一直保持一致,buzzer成功输出了2KHzPWM方波。综上,价格控制模块功能仿真正确,符合设计要求。5.2智能电子称实物功能验证5.2.1实物连接图实物连接作为硬件系统功能验证的基石,其正确性直接决定了系统能否稳定运行。错误的接线方式不仅会导致数据传输异常、功能逻辑错乱等问题,更可能因短路、电压不匹配等情况引发硬件模块烧毁,造成不可修复的损坏,严重影响研发进度与成本控制。因此,在进行实物连接时,需严格遵循既定设计规范与技术要求。本次实物连接严格参照图3.1所示的系统架构示意图,以及2.2.3节中关于传感器与数据采集模块的连接说明、2.2.4节中显示模块与主控芯片的接口定义,确保各模块间电气连接的准确性与兼容性。为便于直观理解与操作,现将完整的实物连接图呈现如图5.12所示,该图详细展示了各模块接口引脚、信号流向以及电源连接方式,为硬件系统的顺利搭建与功能验证提供清晰指引。5.12实物连接图LCD采用排针连接,HX711采用杜邦线连接,秤架分为托盘和底盘,托盘需正面朝上,否则重物重量会出现错误。5.2.2去皮与复位 系统接上电源开机后,复位开关SW0置低电平,系统进入复位模式,LCD显示屏将默认显示重量称重,第一行显示重量weight,第二行为复位时重量显示,此时重量置0,说明系统复位功能正确,实物图如图5.13所示。图5.13复位界面 将复位按钮SW0置高电平,进入重量称重模式,再不放重物情况下,LCD显示皮重weight,默认kg,第二行显示2.195,表明此时皮重2.195kg。获得皮重后,开始去皮,将去皮开关SW1由低电平拨动置高电平,进行去皮,LCD显示净重weight(kg)TARE,第二行显示为0,表明未放重物时净重为0,去皮功能成功运行,实物图如图5.14与图5.15所示。图5.14称重界面(未去皮)图5.15净重显示(去皮) 综上,可见去皮功能正确运行,实物功能验证正确。5.2.3重量称量和单位转换 实现去皮后,开始放置重物,系统测试重物采用砝码,重量分为100g、50g、20g、10g和5g,图5.16为砝码展示。图5.16测试砝码重量 放置100g砝码置秤架上,观察LCD显示,在重量单位为kg的情况下,LCD第二行显示0.100,表明重物为0.100kg,即100g,满足0.1%的精度要求。如图5.17所示。图5.17100g砝码重量显示 为检验电子秤在小重物时的称量准确性,继续向秤架上添加5g砝码。观察LCD显示,可见,重量单位保持kg,LCD第二行显示为0.105,即105g,系统称量正确,图5.18所示。图5.18100g+5g砝码重量显示 实际上,重物称量时重量显示会有微笑的跳动,具体体现在小数千分位上会出现微小跳动,跳动范围在实际重物重量的±1g上下。通过软件方面采集速率的调节,跳动仍然不会消失,可能原因有两个,第一是HX711模块自身信号输出并达不到24位精度,即可能会在低位信号输出时产生波动;第二是HX711与FPGA接口采用杜邦线连接,这种方法可能会导致数据传输的不稳定。总体来说,该微小跳动对电子秤称重功能的影响很小,属于可接受范围。 实现重量称重功能后,进行重量单位转换功能验证,按下按键S1,进入重量单位转换模式,分别按下S3与S4,LCD第一行依次变为weight(lb)TARE和weight(jin)TAREW,即重量单位依次变为磅和斤,并且第二行价格依次变为0.232与0.211,符合kg与磅和斤的比例转换,表明重量转换功能正确运行,如图5.19所示。(a)磅显示(b)斤显示图5.19重量单位转换 综上,称量和转换功能正确运行,实物功能验证成功。5.2.4价格计算与单价转换 以100g砝码为例,按下按键S0,进行价格计算,LCD第一行显示价格Price(1),表明此时是重物单价为1时的总价显示;LCD第二行显示0.100,在数值上与实际重物重量一致,总价正好为单价与重物重量的乘积,说明价格功能正确运行,实物图如5.20所示。图5.20100g砝码价格计算 按下按键S1,进入单价增减模式,连续按下两次S3,观察单价与价格变化,LCD第一行显示从Price(1)依次变为Price(2)和Price(3),说明每次按下S1,单价均会加1,说明价格增加功能正确运行。价格增加后,进行价格减少功能验证,连续按下两次S4,观察单价与价格变化,LCD第一行显示从Price(3)依次变为Price(2)和Price(1),说明每次按下S1,单价均会减1,说明价格减少功能正确运行。实物图如图5.21与5.22所示。图5.21单价依次增加图5.22单价依次减少综上,价格计算与单价转换功能正确运行,实物功能验证成功。5.3本章小结本章采用仿真与实物测试相结合的方式,对系统各功能模块进行全面验证。在仿真阶段,通过构建testbench跑仿真波形,对按键消抖模块、AD数据采集模块、LCD显示模块以及超重报警模块的运行逻辑进行细致验证,确保各模块在理论层面的可行性与稳定性。在实物测试阶段,利用高精度砝码,对系统进行称量和计价测试。LCD显示模块不仅能够实时、较为稳定地显示测量数据,还支持克(g)、千克(kg)、磅(lb)等多种单位的动态切换,切换响应迅速且显示无闪烁。实验数据完整记录并对比了各项功能指标与设计要求,结果表明系统在精度、稳定性和功能性方面均达预期目标,具备良好的实用性,可满足实际应用场景中的多样化需求。第6章总结与展望6.1工作总结本文围绕高精度智能电子秤的设计需求,以FPGA为核心技术载体,构建了一套完整的硬件-软件协同解决方案。通过理论分析、模块化设计及实验验证,完成了以下设计目标:并行处理能力:基于FPGA的并行架构使数据采集速率达到1MHz,较传统单片机方案处理数据更快,实时性显著增强。精度优化:通过HX711传感器的高分辨率(24位AD)与动态校准算法,以及在程序设计方面对采集数据速率的调整,系统在0-5kg量程内实现±0.1%误差,满足设计所需精度需求。功能扩展性:开发多模式状态机支持动态单位转换(kg/lb/jin)、单价实时计价(0-99元范围)、超重报警(阈值5kg)及去皮功能,功能扩展性与复杂度较高较传统方案右明显提高。总体来说,本文设计方案能够得到软、硬件层面验证,成功实现了基于FPGA的电子秤设计所需要求。另外,就此次设计中所遇到的相关问题与解决方案,在此进行相关经验总结。HX711模块数据输出速率与采集速率不匹配问题。设计之初,由于HX711用户手册提供的AD模块数据输出速率有误,导致程序设计中设置的数据采集速率与实际数据输出速率不匹配,在实际硬件平台上验证中无法检测到重物重量。后通过相关资料查询与老师指导,采用逻辑分析仪对AD模块的sck与din进行时序分析,通过检验sck上升沿或din下降沿的方式,测试得出真实的数据输出频率1MHz。通过程序设计匹配采集速率与输出速率,最终成功得到重量数据。称重显示与实际值相差过大在实物称重检验时,LCD上显示重量与实际值相差大,并且没有相关规律,即并不是显示重量均小于或大于实际重量,这说明问题并不是动态校准参数导致。后通过学习关于AD模块数据采集相关知识,通过在程序设计方面尝试调慢数据采集速度的方式,称重结果准确度明显提高。确定调试大方向后,通过 人机交互页面观察和软件层面改写的协同配合,使重物称量结果的精度精确到0.1%(即g)。上述问题是设计过程中遇到最经典的问题,故做出解决经验的总结,供相关学习人员参考。6.3后续研究工作展望对于此次设计,就FPGA的可扩展性而言,提出以下几方面的研究展望:外设矩阵键盘:本次设计只采用了板载的有限按键进行系统的状态转换,对于功能指令更多的电子秤,例如增添单价的小数调整或设置更多国际重量单位转换等,则需要更多的状态转换。对于板载有限按键,要想实现更多功能则需要更复杂的按键调用,严重影响了电子秤的操作简便性。在此,可添加外设矩阵键盘进行多状态的控制,相比起前者,逻辑简单,操作容易。外设语音模块:通过外接语音识别模块,例如ASR01、ASRPRO、LD3320等低成本语音识别模块,经过程序编程,将声音信号从采集(ADC转换)、预处理(降噪、端点检测)、特征提取算法(MFCC)到识别的全流程集成在芯片上,实时生成控制信号驱动外设。其核心优势是适合实时交互的设备,实现“声音输入-指令执行”的便捷控制,解放操作人员双手。HX711AD模块接口优化:本次设计中的AD模块采用杜邦线与FPGA相应I/O口进行连接,当AD模块精度要求更高时,可能会由于数据传输不稳定导致数据传输错误。对此,在之后研究中,可进行版图设计来制定特定的AD模块,通过采用排针与FPGA板实现连接,以实现更稳定的数据传输。综上所述,在后续研究工作中,可按照上述方面进行智能电子秤的功能优化。参考文献黄风杰.电子秤系统的高精度设计实现与智能化检测[D].电子科技大学,2016.左兰.单

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论