首页
📁归档
⏳时光机
🚩友链
📫留言
📧订阅
推荐
📕考研课程
🏜️ 免费壁纸
❤ 捐助本站
💰资助名单
🎵音乐实验
Search
1
【NPN/PNP三极管】放大电路饱和失真和截止失真的区别
20,099 阅读
2
论文写作中如何把word里面所有数字和字母替换为新罗马字体
10,655 阅读
3
【高数】形心计算公式讲解大全
9,052 阅读
4
Vivado-FPGA Verilog烧写固化教程
7,957 阅读
5
【概论】一阶矩、二阶矩原点矩,中心矩区别与概念
7,822 阅读
🪶微语&随笔
励志美文
我的随笔
工作办公
📡电子&通信
嵌入式&系统
通信&信息处理
编程&脚本笔记
⌨️IC&系统
FPGA&ASIC
VLSI&IC验证
EDA&虚拟机
💻电子&计算机
IP&SOC设计
机器学习
软硬件算法
登录
/
注册
物联网(共3篇)
找到
3
篇与
物联网
相关的结果
在FPGA上部署轻量BP神经网络-Python与Verilog:信号检测实战
目录 储备知识: 一、背景:为什么要在FPGA上跑神经网络? 二、系统整体架构 三、神经网络模型设计:极致轻量 四、FPGA硬件实现详解4.1 串并转换模块(Serial-to-Parallel 4.2 数据归一化模块 4.3 隐藏层神经元模块(核心计算单元) 4.4 ReLU激活函数模块 4.5 输出层神经元模块 4.6 阈值判断模块 五、关键优化技巧5.1 归一化的"逆向"处理 5.2 权值二值化(BWN)降低功耗 5.3 亚稳态消除 六、实验结果:功耗与性能 七、总结与思考 python和verilog源程序下载 储备知识: 我们在前文讲了BP神经网络算法和激活函数 BP神经网络算法 https://ee.ac.cn/index.php/archives/612.html 激活函数讲解 https://ee.ac.cn/index.php/archives/617.html 一、背景:为什么要在FPGA上跑神经网络? 在无源物联网(Battery-free IoT)和反向散射通信(Backscatter)场景中,传统的信号检测方法(如能量检测)虽然电路简单,但无法区分同频段的多种信号,且受噪声影响大;而基于PC或GPU的深度学习方案虽然精度高,但功耗动辄数十瓦,显然无法部署在依赖能量采集的微瓦级标签上。 核心矛盾在于:缺乏一种检测精度高、功耗极低(毫瓦级)、且能实时处理的解决方案。 答案是将轻量级的BP神经网络部署到低功耗FPGA上,在边缘端完成信号推理。 二、系统整体架构 整个检测系统的链路如下: 目标信号 → 天线 → 阻抗匹配 → LNA放大 → 包络检波(ENV) → ADC采样(1MSPS, 12bit) → FPGA(BP神经网络推理) → 调制控制信号在FPGA内部,BP神经网络负责识别当前输入的512点采样数据是否为目标信号的前导码(Preamble)。一旦识别成功,输出控制信号,开启后端的Backscatter调制模块。 FPGA选型:Actel IGLOO/e系列 AGLE600V5-FG484。选择它的原因是: Flash架构:上电即运行,无需外部配置芯片,适合无源系统; 超低功耗:静态功耗仅0.046mW,适合能量采集场景; 资源适中:13824个逻辑单元,足以容纳轻量级网络。 三、神经网络模型设计:极致轻量 为了在FPGA上高效部署,网络结构必须足够"轻"。本文设计的网络结构如下: pasted_1785558315326_lc6zyp.png图片 层级神经元数说明输入层512对应ADC采集的一条信号的512个采样点隐藏层2仅2个神经元,大幅降低计算量输出层1二分类:是目标信号(1) / 非目标信号(0)激活函数:隐藏层和输出层均采用 ReLU。 $$f(x) = \max(0, x)$$ 选择ReLU的原因不仅是训练效果好,更重要的是硬件实现极其简单——只需一个比较器判断正负,无需计算指数或乘法,这对FPGA非常友好。 pasted_1785561816152_bsny25.png图片 训练环境:TensorFlow/Keras,使用Adam优化器和MSE损失函数。在真实环境数据集上训练后,测试集识别准确率可达 95.76%。 pasted_1785561967835_yy5zgm.png图片 四、FPGA硬件实现详解 FPGA内部的神经网络是一个纯推理引擎。本节按数据流方向,逐个拆解每个模块的设计思路和Verilog实现要点。 pasted_1785562098406_gf64mu.png图片 整体RTL结构如下: pasted_1785563631508_f74j4w.png图片 4.1 串并转换模块(Serial-to-Parallel pasted_1785563649652_chqrj8.png图片 ADC(ADS7042)在片选信号CS拉低后,先输出2个前导0,再输出12位有效数据(D11→D0),每个数据位占用一个CLK周期。 设计要点: CS和CLK由FPGA内部产生,CS每16个CLK周期拉低一次; 在CS下降沿开始,用计数器对串行数据移位寄存; 凑齐12位有效数据后,输出一组并行数据 adc_data[11:0]。 波形图 pmhbofe.png图片 module serial_p(input data0_in,input cs,input clk,output[12:0] data0_out,input rst); reg[11:0] temp; reg[12:0] save; integer count; integer cnt; always @(negedge clk or negedge rst) begin if(!rst) begin//reset temp<=12'b000000000000; count<=-1; save<=12'b111111111111; cnt<=-1; end else if(cs&&count%16==0) begin save<={1'b0,temp}; count<=1; cnt<=cnt+1; if(cnt==512) begin cnt<=1; end end else if(cs) begin temp<=12'b0; count<=1; end else if(count<3) count<=count+1; else begin temp<={temp,data0_in}; count<=count+1; end end assign data0_out=save; endmodule 4.2 数据归一化模块 问题:训练时,输入数据被归一化到 [0, 1.8](对应ADC参考电压1.8V)。如果在FPGA中直接用除法做 Vin = adc_data / 4095 * 1.8,会消耗大量逻辑资源(FPGA做除法器代价极高)。 解决方案:在软件端完成归一化,FPGA端只做整数运算。 具体做法: 在Python/Keras训练时,将输入数据 x 归一化为 x_norm = x / 4095 * 1.8; 在提取权值时,将第一层权值 w 除以 1.8 并放大 1024 倍取整; 这样FPGA输入的原始ADC值 adc_data(范围0~4095)直接与预处理后的权值相乘,等效于完成了归一化+加权。 # 创建一个自定义的回调对象 cb = MyCallback() # 以只读方式打开训练数据文件 with open('/content/work/data/data.txt') as traindata: # 读取文件内容 data = traindata.read() # 将文件内容转换为numpy数组,并将数据类型转换为float,并将数组形状调整为(47100, 2) data = np.array(list(data.split()), dtype=float).reshape((47100, 2)) # 创建一个最大最小归一化对象 min_max_scaler = preprocessing.MinMaxScaler() # 归一化 data = data * (1/65535) # 以只读方式打开训练标签文件 with open('/content/work/data/label.txt') as labda: # 读取文件内容 labels = labda.read() # 将文件内容转换为numpy数组,并将数据类型转换为float,并将数组形状调整为(47100, 2) labels = np.array(list(labels.split()), dtype=float).reshape((47100, 2)) # 对data和labels进行乱序,保持它们的对应关系 # 为了保持对应关系,需要先将data和labels沿着第二个维度拼接起来,形成一个(100, 4)的数组 # 然后对这个数组进行乱序,再将它们沿着第二个维度分开,还原成data和labels data_labels = np.concatenate((data, labels), axis=1) np.random.shuffle(data_labels) data = data_labels[:, :2] labels = data_labels[:, 2:]FPGA端实现: 实际上,归一化模块在FPGA中被合并到了权值预处理阶段,硬件上不需要额外的归一化电路。但为了模块化清晰,也可以显式设计一个"电压映射"模块,将12bit ADC码值转换为定点数格式: 工程建议:永远不要在FPGA里做除法。所有线性变换(归一化、缩放)都应在软件端合并到权值中,FPGA只做整数乘加。 4.3 隐藏层神经元模块(核心计算单元) 隐藏层的数学表达式: $$y = \text{ReLU}\left( \sum_{i=1}^{512} x_i \cdot w_i + b \right)$$ , i = 1..512 工程难点: 512次乘累加如果在一个时钟周期完成,需要512个乘法器,资源爆炸; 如果纯串行完成,需要512个时钟周期,一条chirp要512×512=262144个周期,太慢。 解决方案:采用 串行MAC流水线 + 双缓冲FIFO 架构。 设计思路: 权值存储:512个权值和1个偏置在编译时以 reg [31:0] w[0:511] 形式固化在FPGA中; FIFO缓存:ADC每输出一个采样点,立即写入FIFO。FIFO深度设为16即可(只要保证不溢出),因为读出速度(MAC运算)和写入速度(ADC采样)基本匹配; 串行MAC:每个时钟周期从FIFO读出一个数据 xi,与对应的 wi 相乘,累加到累加器 acc; 512个周期后:累加器结果加上偏置 b,送入ReLU模块。 pasted_1785563798085_32317i.png图片 FIFO波形图 pmhqDBt.png图片 关键设计细节: 位宽设计:输入22bit × 权值32bit = 乘法结果54bit,累加512次需要额外9bit,因此累加器至少需要 63bit。如果位宽不够,累加会溢出,导致结果完全错误。 时序约束:乘法器和加法器要满足16MHz时钟的建立保持时间。如果组合逻辑延迟太大,需要插入流水线寄存器(将乘法器和加法器分两级完成)。 双神经元并行:隐藏层有2个神经元,需要例化两个上述模块,各自独立的权值存储和累加器,但共享同一个FIFO输入。 4.4 ReLU激活函数模块 ReLU的硬件实现是整个网络中最简单的部分: pmhqWcj.png图片 module relu ( input wire clk, input wire rst_n, input wire [31:0] x_in, // MAC+bias结果 input wire x_valid, output reg [31:0] y_out, output reg y_valid ); always @(posedge clk or negedge rst_n) begin if (!rst_n) begin y_out <= 32'd0; y_valid <= 1'b0; end else begin y_valid <= x_valid; if ($signed(x_in) >= 0) y_out <= x_in; else y_out <= 32'd0; end end endmodule4.5 输出层神经元模块 输出层只有1个神经元,输入是隐藏层2个神经元的输出: $$\text{output} = \text{ReLU}\left( h_1 \cdot w'_1 + h_2 \cdot w'_2 + b' \right)$$ 这个模块与隐藏层类似,但逻辑资源消耗极小。 pmhq7NT.png图片 module nerual_out( clk, rst,x1,x2,data_out ); input clk, rst; input signed[0:49] x1,x2; output signed[79:0] data_out; //<statements> //reg signed[0:28] weight[0:1]; reg signed[0:7] save,save1,save2; localparam bais=-50'd214979034352654; //localparam bais = -26'd6406874; localparam weight0 = 29'd22506522; localparam weight1 =-29'd341584992; //integer bais; integer count; always @(negedge clk or negedge rst) begin if(!rst) //reset,set values and bias begin // bais<=-50'd214979034352654; // weight[0]<=29'd22506522; // weight[1]<=-29'd341584992; save<=0; save1<=0; save2<=0; count<=0; end else begin save1<=x1*weight0; save2<=x2*weight1; count<=count+1; if(count>518) save<=save1+save2+bais;//Multiply the input by the weights and add up the results end end assign data_out=save; endmodule4.6 阈值判断模块 为什么需要阈值判断? 前面提到,我们在保存权值时将所有参数扩大了 1024 倍(即 $2^{10}$)。这意味着: 隐藏层的输出值也被放大了约1024倍; 输出层的计算结果同样被放大; 原本训练时,输出层ReLU后大于0即判定为目标信号; 现在由于数值被放大,不能简单以0为界,需要设定一个等效的阈值。 阈值推导: 原始判定边界:输出 > 0.5(二分类常用阈值); 放大后等效边界:threshold = 0.5 × 1024 × 1024 = 524288; 实际上,由于隐藏层和输出层都放大了1024倍,总放大倍数为 $1024^2 = 1048576$,因此: threshold = 0.5 × 1048576 = 524288。 波形图 pmhqXv9.png图片 五、关键优化技巧 5.1 归一化的"逆向"处理 再次强调这个最重要的优化: 处理方式FPGA资源消耗推荐度FPGA内做除法(adc/4095)极高,需除法器IP❌FPGA内用移位近似除法中等,精度损失大△权值预处理(本文方法)零额外消耗✅具体做法: 训练时归一化:$V_{\text{in}} = \frac{\text{adc_data}}{4095} \times 1.8$; 提取权值时:$w' = \frac{w}{1.8} \times 1024$,取整; FPGA输入:直接使用原始ADC值 $x$(0~4095); 等效运算。 5.2 权值二值化(BWN)降低功耗 为了进一步压缩模型、降低功耗,本文采用了 Binary-Weight-Networks (BWN) 对权值进行二值化: 权值只取 +1 或 -1; 引入缩放因子 α 保证量化后的权值尽可能接近原始浮点权值。 二值化后,乘法运算退化为加减法或符号位判断,FPGA资源占用和动态功耗大幅下降。虽然精度略有损失,但在本场景中仍能保持97%以上的识别率。 二值化乘法器的Verilog实现: // 二值化权值乘法:只需判断符号 wire signed [31:0] product; assign product = bin_weight ? x_in : -x_in; // bin_weight=1为正,0为负相比32bit×32bit的硬件乘法器,这个逻辑几乎不消耗DSP资源。 5.3 亚稳态消除 ADC数据输入和CS信号是异步信号(相对于16MHz系统时钟),必须做双级触发器同步,防止亚稳态传播: reg adc_dat_d1, adc_dat_d2; always @(posedge clk) begin adc_dat_d1 <= adc_dat; // 第一级 adc_dat_d2 <= adc_dat_d1; // 第二级(稳定后使用) end wire adc_dat_sync = adc_dat_d2;六、实验结果:功耗与性能 通过 Actel Libero SOC 对FPGA各模块进行功耗仿真,结果如下: 工作模式静态功耗动态功耗总功耗空闲态0.046 mW00.046 mW正常工作0.046 mW2.79 mW2.835 mWFlash*Freeze模式0.115 mW00.115 mW2.835 mW 的总功耗,对于低功耗设备来说是完全可以接受的。 各子模块动态功耗分解: 串并转换:0.01 mW 隐藏层神经元(含FIFO):0.083 mW ReLU激活:0.067 mW 输出层神经元:0.067 mW 七、总结与思考 本文介绍了一套完整的从算法到硬件的轻量化神经网络部署方案: 算法层:针对低功耗约束,设计了512-2-1极简BP网络,避免使用CNN/RNN等重算力模型; 数据层:在真实环境中采集目标信号,建立含噪样本库,并通过数据增强提升泛化能力; 硬件层:基于Actel低功耗FPGA,用FIFO流水、整数运算、ReLU硬判决、权值二值化等手段,实现了毫瓦级推理; 系统层:与射频前端(LNA、包络检波、ADC)紧密配合,形成完整的标签信号检测链路。 可扩展性:该FPGA神经网络框架不仅可用于目标信号检测,只需更换训练数据集和权值参数,即可用于FMCW、RFID等其他射频信号的识别,具备良好的通用性。 python和verilog源程序下载
FPGA&ASIC
通信&信息处理
机器学习
软硬件算法
# ASIC/FPGA
# 信号处理
# 机器学习
# 软件算法
# 物联网
# Python
刘航宇
8月1日
0
41
6
基于51/52单片机电容、电感、电阻参数测量系统设计与Proteus仿真
目录 一、设计任务和要求 二、方案设计与论证2.1 系统总设计框图 2.2 方案一:电桥平衡原理① 电阻的测量:直流电桥平衡原理 ② 电容的测量:交流电桥平衡原理 ③ 电感的测量:交流电桥平衡原理 2.3 方案二:频率转换法(本设计采用)① 电阻的测量:555 构成单稳态 ② 电容的测量:555 构成单稳态 ③ 电感的测量:电容三点式正弦波振荡 2.4 方案对比与选择 三、单元电路设计和参数计算3.1 电阻的检测单元电路设计 3.2 电容的检测单元电路设计 3.3 电感的检测单元电路设计 四、总原理图及元器件清单4.1 总原理图 4.2 元器件清单 五、程序设计5.1 程序流程图 5.2 核心代码中断函数(频率测量) 主函数 显示函数 键盘检测函数 5.3 完整程序清单及protues仿真文件(附录) 六、安装与调试6.1 仿真调试(1)电阻测量电路仿真 (2)电容测量电路仿真 (3)电感测量电路仿真 调试要点 液晶显示电路调试 仿真整体显示 6.2 实物调试电阻检测 电容检测 电感检测 八、参考文献 九、附录-完整软件程序与protues仿真文件 完整程序与仿真文件见文章末尾 一、设计任务和要求 设计并制作一个元器件参数测量仪 电阻阻值测量,范围:100Ω ~ 1MΩ 电容容值测量,范围:100pF ~ 10000pF 测量精度:±5% 电感参数的测量 扩大量程 提高测量精度 二、方案设计与论证 2.1 系统总设计框图 pasted_1784990858481_sxzptf.png图片 图1 系统总设计框图在测量各元件参数时,采用首先把电感、电容、电阻的参数转化为频率[1],再送至单片机检测,检测结束后,送至 LCD1602 进行显示。 2.2 方案一:电桥平衡原理 ① 电阻的测量:直流电桥平衡原理 pasted_1784990980814_5yavx3.png图片 图2 直流电桥平衡电路图根据电路平衡原理,不断调节电位器 R3,使得电表指针指向正中间,再测量电位器电阻值。 ② 电容的测量:交流电桥平衡原理 pasted_1784991076614_jito75.png图片 图3 交流电桥平衡电路图通过调节 Z1、Z2 使电桥平衡。这时电表的读数为零。通过读取 Z1、Z2、Zn 的值,即可得到被测电容的值。 ③ 电感的测量:交流电桥平衡原理 pasted_1784991402619_84r7tl.png图片 图4 交流电桥平衡电路图2.3 方案二:频率转换法(本设计采用) ① 电阻的测量:555 构成单稳态 pasted_1784991953296_lg44ir.png图片 图5 555 定时器构成单稳态电路图根据 555 定时器构成单稳态,产生脉冲波形,通过单片机读取高低电平得出频率,通过公式换算得到电阻阻值。 ② 电容的测量:555 构成单稳态 pasted_1785027612555_za97df.png图片 图6 555 定时器构成单稳态电路图** 根据 555 定时器构成单稳态,产生脉冲波形,通过单片机读取高低电平得出频率,通过公式换算得到电容值。 ③ 电感的测量:电容三点式正弦波振荡 pasted_1785027682239_4u3sw9.png图片 图7 电容三点式正弦波振荡电路图由电容三点式正弦波振荡电路得出频率,通过单片机读取高低电平得出频率,通过公式换算得到电感值。 2.4 方案对比与选择 对比项方案一(电桥法)方案二(频率法)测量精度受人为调节影响大单片机数字化,精度高操作难度调节麻烦,不易操作自动测量,一键显示电感测量不易测得准确值振荡电路,相对稳定数字化不易数字化便于单片机处理结论: 方案二通过单片机读取转化,精确度会明显提高,且便于数字化显示。故本设计选择方案二。 三、单元电路设计和参数计算 3.1 电阻的检测单元电路设计 pasted_1785027698225_mjicut.png图片 图8 555 定时器构成单稳态电路图由 555 单稳态触发公式: $$f=\frac{1}{\ln2(R_{1}+2R_x)C}$$ 得: $$R_x=\frac{1}{2}(\frac{1}{\ln2fC}-R_{1})$$ 从而,可以计算得出电阻值的大小。 3.2 电容的检测单元电路设计 pasted_1785028035648_x380cp.png图片 图9 555 定时器构成单稳态电路图根据 555 定时器构成单稳态,产生脉冲波形,通过单片机读取高低电平得出频率,通过公式换算得到电容值[2]。 由: $$f=\frac{1}{\ln2^*(R_1+2R_2)^*C_x}$$ 若 R1 = R2,得: $$C_x=\frac{1}{3\ln2^*f^*R_1}$$ 从而,可以计算得出电容值的大小。 3.3 电感的检测单元电路设计 pasted_1785028091408_lymeeb.png图片 图10 电容三点式正弦波振荡电路图由 LC 振荡频率公式: $$f=\frac{1}{2\pi\sqrt{\frac{C_1*C_2}{C_1+C_2}*L_x}}$$ 得: $$L_x=\frac{1}{\left(2\pi f\right)^2\frac{C_1*C_2}{C_1+C_2}}$$ 从而,可以计算得出电感值的大小。 四、总原理图及元器件清单 4.1 总原理图 pasted_1785028273962_o8rzuv.png图片 图11 电阻、电容、电感参数测试总原理图 pasted_1785028294514_u0wku4.png图片 图12 测量电阻、电容部分的原理图 pasted_1785028310991_mmmde2.png图片 图13 测量电感以及 ±5V 发生原理图4.2 元器件清单 元件序号型号数量备注U1STC89C52RC1单片机R3A103J1排阻R2, R3, R17, R1810KΩ4电位器X111.0592M1晶振C325V, 10uF1电解电容C1, C2, C11103 (0.01uF)3瓷片电容R1, R13, R1810KΩ3电阻J1, J2, J3, J4—4按键U216021液晶A1, A2NE5552555 定时器R4300Ω1电阻R5, R6510KΩ2电阻C4~C9104 (0.1uF)6瓷片电容R7, R9100KΩ2电阻C1050V, 22uF1电解电容Q1~Q3S9108 (NPN)3三极管R102KΩ1电阻R8, R11, R141KΩ3电阻C12, C1350V, 47uF2电解电容R12, R1939KΩ2电阻R15, R1651Ω2电阻C1425V, 470uF1电解电容U3NE555321运放五、程序设计 5.1 程序流程图 图14 中断程序流程图 pasted_1785028347463_kh1ui9.png图片 图15 主程序流程图 pasted_1785028417008_m02be6.png图片 初始化 (led_init, t_init, keyscan) ↓ 清屏 ↓ 循环: ├── 显示频率 display_f(f) └── 根据 a 值分支: ├── case 1: 计算电阻 R,显示 display_R(R) ├── case 2: 计算电容 C,显示 display_C(C) └── case 3: 计算电感 L,显示 display_L(L)5.2 核心代码 中断函数(频率测量) void T0_count() interrupt 1 { switch(a) { case 1: // 电阻测量 while(R_out); while(!R_out); TH0 = 0; TL0 = 0; while(R_out); while(!R_out); th0 = TH0; tl0 = TL0; TR0 = 0; break; case 2: // 电容测量 while(C_out); while(!C_out); TH0 = 0; TL0 = 0; while(C_out); while(!C_out); th0 = TH0; tl0 = TL0; TR0 = 0; break; case 3: // 电感测量 while(L_out); while(!L_out); TH0 = 0; TL0 = 0; while(L_out); while(!L_out); th0 = TH0; tl0 = TL0; TR0 = 0; break; } f = 1000000.0 / 1.085069 / (th0 * 256 + tl0) + 0.5; }主函数 void main() { led_init(); // 液晶初始化 t_init(); // 定时器初始化 keyscan(); // 按键检测 write_com(0x01); // 清屏 while(1) { display_f(f); switch(a) { case 1: // 电阻: R = (T/0.693 - 150) 换算 R = (ulong)(5000000.0 / 0.6931472 / f - 150 + 0.5); display_R(R); break; case 2: // 电容: C = 换算公式 C = (int)(100000000.0 / 153 / 0.6931472 / f + 0.5); display_C(C); break; case 3: // 电感: L = 1/(4π²f²C) 换算 L = (int)(1000000000000.0 / 0.1 / PI / PI / f / f + 0.5); display_L(L); break; } } }显示函数 // 频率显示 void display_f(ulong f) { uchar count = 0; ulong f0 = f; while(f) { f = f / 10; count++; } for(num = 5 + count; num > 5; num--) { table2[num] = f0 % 10 + 48; f0 = f0 / 10; } write_com(0x80); for(num = 0; num < 6 + count; num++) { write_data(table2[num]); delayms(5); } } // 电阻显示 void display_R(ulong R) { uchar count = 0; ulong R0 = R; while(R) { R = R / 10; count++; } for(num = 6 + count; num > 6; num--) { table3[num] = R0 % 10 + 48; R0 = R0 / 10; } write_com(0x80 + 0x40); for(num = 0; num < 7 + count; num++) { write_data(table3[num]); delayms(5); } } // 电容显示 void display_C(uint C) { uchar count = 0; uint C0 = C; while(C) { C = C / 10; count++; } for(num = 5 + count; num > 5; num--) { table4[num] = C0 % 10 + 48; C0 = C0 / 10; } write_com(0x80 + 0x40); for(num = 0; num < 6 + count; num++) { write_data(table4[num]); delayms(5); } } // 电感显示 void display_L(uint L) { uchar count = 0; uint L0 = L; while(L) { L = L / 10; count++; } for(num = 5 + count; num > 5; num--) { table5[num] = L0 % 10 + 48; L0 = L0 / 10; } write_com(0x80 + 0x40); for(num = 0; num < 6 + count; num++) { write_data(table5[num]); delayms(5); } }键盘检测函数 void keyscan() { if(key_R == 0) // 检测电阻按键 { delayms(10); // 消抖 if(key_R == 0) a = 1; } else if(key_C == 0) // 检测电容按键 { delayms(10); if(key_C == 0) a = 2; } else if(key_L == 0) // 检测电感按键 { delayms(10); if(key_L == 0) a = 3; } else while(key_R && key_C && key_L); // 等待按键按下 }5.3 完整程序清单及protues仿真文件(附录) 见文末附录部分。 六、安装与调试 6.1 仿真调试 (1)电阻测量电路仿真 图16 电阻测量的仿真电路图 pasted_1785028525830_e8xagf.png图片 图17 电阻测量的仿真输出波形 pasted_1785028553380_77yjdf.png图片(2)电容测量电路仿真 图18 电容测量的仿真电路图 pasted_1785028566386_213kgj.png图片 图19 电容测量的仿真输出波形 pasted_1785028577785_fn2fqc.png图片(3)电感测量电路仿真 图20 电感测量的仿真电路图 pasted_1785028588732_9bvoyx.png图片 图21 电感测量的仿真输出波形 pasted_1785028599631_39ilf2.png图片调试要点 接通电源,用示波器观察输出波形,若为方波,则电路焊接无误,否则检查电路[3] 在调试过程中发现,若改变电源电压,输出方波的频率会发生变化,计算出的数值存在一定误差 当 VCC 为 3.25V 左右时误差较小 液晶显示电路调试 将测量电路的输出分别与单片机的 P1^5、P1^6、P1^7 相接,观察液晶是否显示测量结果 在调试过程中发现,电阻、电容的测量误差较小 由于电容三点式震荡电路的频率不稳定,电感测量的误差较大 仿真整体显示 图22 电阻测量显示 pasted_1785028620741_10mwwy.png图片 图23 电容测量显示 pasted_1785028631102_motyub.png图片 图24 电感测量显示 pasted_1785028644198_twwyn4.png图片 图25 电源生成模块显示 pm2vEdK.png图片6.2 实物调试 实物按照仿真电路搭建,通电显示 "Welcome! RCL detector"。 图26 实物开机界面 pm2vmJe.png图片电阻检测 插入 2.7KΩ 电阻 若显示不准确,调节仿真中 R2 对应的电位器即可改变输出频率,使得检测精准 检测显示 2735Ω,可见调试准确 图27 电阻检测显示 pm2vnRH.png图片电容检测 插入 0.1uF 电容 若显示不准确,调节仿真中 R3 对应的电位器即可改变输出频率,使得检测精准 检测显示 101pF,可见调试准确[4] 图28 电容检测显示 pm2vuzd.png图片电感检测 插入 65mH 电感 若显示不准确,调节程序计算公式5,即可改显示结果,使得检测精准 检测显示 65535uH,可见调试准确 图29 电感检测显示 pm2vMQA.png图片八、参考文献 [1]杨沁佳.浅谈电感传感器微位移检测仪的原理与设计[J].数字通信世界,2019(09):143+159. [2]张璐雅,阮景.一种基于555时基电路的振荡器设计[J].集成电路应用,2019,36(12):12-13. [3]谢琪林.浅谈STC89S51单片机时序[J].电子测试,2020(24):139-140. [4]黄江.基于STM32的高精度电容测量仪设计[J].信息技术与信息化,2020(11):140-141. [5]王晓辉,王智永,韩智伟,胡帅可,谢印庆.基于三极管放大原理的电容三点式LC振荡器的设计[J].电子世界,2020(03):206. [6] E. L. Pankratov. An approach to model manufacturing of an enhanced swing differential Colpitts oscillator based on heterostructures to increase density of their elements with account mismatch-induced stress: on optimization of annealing. 2020, :1-19. 九、附录-完整软件程序与protues仿真文件 // ============================================ // RCL 测量仪程序 // 基于 STC89C52RC + NE555 + LCD1602 // ============================================ #include <reg52.h> #define uint unsigned int #define uchar unsigned char #define ulong unsigned long #define PI 3.1415926 // ========== 字符串常量 ========== uchar code table1[8] = "Welcome! RCL detector"; uchar table2[16] = "f(Hz)="; uchar table3[16] = "R(Ohm)="; uchar table4[16] = "C(pF)="; uchar table5[16] = "L(uH)=";
嵌入式&系统
通信&信息处理
软硬件算法
# 嵌入式
# 信号处理
# 软件算法
# 物联网
刘航宇
7月26日
0
35
5
2023-07-13
反向散射理论与ADG902电路实现
后向散射通信技术,是在天线对信号散射的基础上,采用标签后向散射的方式,通过改变发射端标签的反射系数来实现后向散射通信。无线电波在传输过程中,当通过不同介质时,因为介质阻抗的差异性,会产生反射作用,根据介质材料和阻抗的不同,会产生不同的反射量。因此通过调节天线端口的阻抗匹配度,入射的无线电波就可以产生不同反射量,导致入射信号和反射信号的差异性,也就是反射系数 Γ 。具体表示如下: $$\Gamma=\frac{Z_L-Z_0}{Z_L+Z_0}$$ 式中 Z0表示天线端的特征阻抗,一般是 50 Ω,ZL表示标签端口的输入阻抗,Γ表示入射信号振幅和反射信号振幅的复数比。当Γ=0 时,阻抗匹配,入射信号全部传递,无反射信号的产生;Γ = 1时,标签端的输入阻抗为开路,阻抗失配,入射信号被全部反射,产生幅值相同相位相同的反射信号;Γ = −1时,标签端的输入阻抗为短路状态,阻抗失配,入射信号被全部反射,产生幅值相同相位相反的反射信号。因此,通过改变标签的输入阻抗,产生不同的反射系数,就可以控制无线电波的入射和反射,实现有效信号的传递,这也就是后向散射通信的基本原理。为了实现上述后向散射通信,还需要加载天线端口的控制,结构如下图。通过射频开关来控制两个不同的负载阻抗与天线端口的连接,实现阻抗的匹配和失调,完成信号的入射和反射。当开关在负载 Z1和 Z2间转化时,由于负载阻抗的不同,载波信号在天线端的反射比例也不同,因此就产生了不同的调制载波。在实际通信中,为了达到最优传输质量,通常要使反射信号的差异最大,对应完全反射和完全吸收两种形式。对调制后的反射信号进行解调处理后,就可以得到所传递的基带信号,完成后向散射的通信。采用负载 50 Ω 的完全吸收和负载短路的完全反射两种信号传输差异,来实现后向散射的信息传输。 图片 使用后向散射开关 ADG 902 来实现基带信号对天线状态的控制,ADG 902 电路结构如图 4.12 所示。将数字基带信号的接入 ADG 902 的 CTRL 端,通过数字基带信号的“0”、“1”来控制 ADG 902 的关断和闭合,RF2 端连接射频天线。通过 ADG 902 中开关的关断,来控制天线对外界调制载波的反射和吸收。 注意:RF1接天线,RF2接地也可以,这里读者可自行证明 图片 当逻辑电平 CTRL=0时,S1关断,S2闭合,此时天线接收端口接地,由式可得,Z=0,T=1,载波信号被完全反射;当逻辑电平 CTRL=1 时,S1 闭合,S2 关断,此时天线接收端匹配,载波被完全吸收。
通信&信息处理
# 通信&射频
# 物联网
刘航宇
3年前
1
1,572
2