资讯动态

从数字逻辑到工业应用:编码器原理、Verilog实现与PLC读取实战

发布时间:2026/8/21 3:39:10 来源:尧图企业网站定制
在实际数字电路设计和嵌入式系统开发中编码器是一个既基础又核心的组件。无论是处理物理按键、读取电机转速还是将并行数据转换为串行格式都离不开编码器的身影。很多初学者在接触“编码器”时容易将其与软件中的“编码/解码”概念混淆或者只停留在“将2的N次方个输入转换为N位二进制输出”的抽象定义上却不知道如何用硬件描述语言实现更不清楚如何在实际项目中连接和调试一个旋转编码器或绝对值编码器。本文将从数字电路数电的视角出发带你彻底理解编码器的原理、分类和实现。我们将从最基础的8线-3线优先编码器开始用Verilog HDL编写代码并仿真然后深入到实际硬件中常见的旋转编码器和绝对值编码器解释它们的工作原理、接口类型如I2C、485以及如何用PLC如西门子S7-1200或单片机读取其信号。无论你是电子工程专业的学生还是从事FPGA开发或工业自动化如使用三菱FX系列PLC的工程师都能通过本文构建起从理论到实践的完整知识链路。1. 编码器到底是什么从抽象定义到具体信号在开始写代码和接线之前我们必须先统一对“编码器”这个概念的理解。在数字电路领域编码器特指一类组合逻辑电路它的功能是将一组输入信号通常其中只有一个有效转换成一组特定格式的输出代码。1.1 核心功能赋予输入信号一个“数字身份”你可以把编码器想象成一个高效的“报名处”。假设有8个人8个输入信号排队但每次只允许一个人进来登记。编码器的工作就是根据进来的是哪个人快速生成一个对应的3位号码牌3位二进制输出。这个“号码牌”就是输入信号的数字编码。最常见的例子是计算机键盘。一个标准键盘有上百个键但CPU并不直接识别哪个键被按下。键盘内部有一个编码器矩阵当某个键被按下时编码器会生成一个唯一的扫描码如ASCII码这个扫描码就是该按键的“数字身份”。1.2 关键特性输入有效性与优先级这里有两个关键点容易混淆输入有效性在经典的理论模型中通常假设同一时刻只有一个输入信号是有效的例如高电平“1”。如果多个输入同时有效输出就会产生混乱。为了解决这个问题引入了优先编码器。优先级优先编码器为所有输入信号设定了优先级通常是输入下标越大优先级越高。当多个输入同时有效时编码器只对优先级最高的那个输入进行编码并输出其对应的代码。这在处理中断请求等场景中至关重要。1.3 主要分类按功能与物理形态根据功能和形态编码器主要分为两大类用途截然不同类型功能描述典型应用输出特点数字逻辑编码器实现编码功能的集成电路或HDL模块。地址编码、中断控制器、键盘扫描电路。并行数字信号如3位二进制。物理传感器编码器将物理量位置、速度转换为电信号的传感器。伺服电机位置反馈、机器人关节角度测量、旋钮调节。脉冲序列增量式或绝对数字码绝对值式。我们常说的“8线-3线编码器”属于第一类。而搜索热词中的“旋转编码器”、“磁编码器AS5047P”、“旋变编码器”则属于第二类。本文前半部分聚焦第一类数字逻辑后半部分会自然过渡到第二类物理传感器的接口与读取。2. 动手实现一个8线-3线优先编码器理解了概念最好的巩固方式就是实现它。我们将使用硬件描述语言Verilog来设计一个带有使能端和优先级功能的8线-3线编码器并通过仿真验证其行为。2.1 设计规格与接口定义首先明确设计需求输入8个信号din[7:0]1个使能信号en高有效。输出3位二进制代码dout[2:0]1个输出有效标志valid当有任何输入有效且使能时置高。优先级din[7]优先级最高din[0]优先级最低。编码规则输出dout为有效输入中优先级最高者的下标二进制值。例如若din[5]为1且是当前最高优先级有效位则输出dout 3‘b1015的二进制。2.2 Verilog代码实现我们采用行为级描述代码更清晰易懂。创建一个名为priority_encoder_8to3.v的文件。module priority_encoder_8to3 ( input wire [7:0] din, // 8位输入高电平有效 input wire en, // 使能信号高电平有效 output reg [2:0] dout, // 3位二进制输出 output reg valid // 输出有效标志 ); always (*) begin // 默认值 dout 3b000; valid 1b0; if (en) begin // 使能有效时才工作 casex (din) // 使用 casex 处理多输入有效的情况x表示不关心位 8b1xxxxxxx: begin dout 3b111; valid 1b1; end // din[7] 有效 8b01xxxxxx: begin dout 3b110; valid 1b1; end // din[6] 有效 8b001xxxxx: begin dout 3b101; valid 1b1; end // din[5] 有效 8b0001xxxx: begin dout 3b100; valid 1b1; end // din[4] 有效 8b00001xxx: begin dout 3b011; valid 1b1; end // din[3] 有效 8b000001xx: begin dout 3b010; valid 1b1; end // din[2] 有效 8b0000001x: begin dout 3b001; valid 1b1; end // din[1] 有效 8b00000001: begin dout 3b000; valid 1b1; end // din[0] 有效 default: begin dout 3b000; valid 1b0; end // 无输入有效 endcase end end endmodule关键代码解释casex语句是实现优先级的关键。x代表“不关心”这意味着只要高位为1无论低位是什么都会匹配对应的分支。例如8‘b1xxxxxxx匹配所有din[7]1的情况无论din[6:0]是什么值从而实现了din[7]的最高优先级。valid信号这是一个非常重要的设计。它明确指示了当前的输出dout是否有效即是否有输入被编码。在实际系统中下游电路可以根据valid信号来决定是否采样dout数据避免了在无输入时误操作默认值。2.3 测试仿真与结果分析设计完成后必须通过仿真验证。编写测试文件tb_priority_encoder.v。timescale 1ns/1ps module tb_priority_encoder; reg [7:0] din; reg en; wire [2:0] dout; wire valid; // 实例化被测试模块 priority_encoder_8to3 uut ( .din(din), .en(en), .dout(dout), .valid(valid) ); initial begin // 初始化 en 0; din 8b00000000; #100; // 等待100个时间单位 // 测试1使能无效输入变化应无输出 $display(Test 1: Enable is LOW); din 8b10000000; #10; if (valid ! 1b0) $display(ERROR: valid should be 0 when en0); #100; // 测试2使能有效单一输入 en 1; $display(\nTest 2: Single active input); din 8b00000100; // din[2]有效 #10; $display(din%b, dout%b, valid%b (Expected dout010), din, dout, valid); #100; // 测试3使能有效多个输入测试优先级 $display(\nTest 3: Multiple active inputs, check priority); din 8b00010100; // din[4]和din[2]同时有效din[4]优先级高 #10; $display(din%b, dout%b, valid%b (Expected dout100 for din[4]), din, dout, valid); #100; // 测试4最高优先级输入有效 din 8b10000100; // din[7]有效优先级最高 #10; $display(din%b, dout%b, valid%b (Expected dout111 for din[7]), din, dout, valid); #100; // 测试5无输入有效 din 8b00000000; #10; $display(din%b, dout%b, valid%b (Expected valid0), din, dout, valid); #100; $display(\nAll tests completed.); $finish; end endmodule使用仿真工具如ModelSim、Vivado Simulator或开源工具Icarus Verilog运行测试观察波形和打印信息。预期输出应显示dout始终输出最高优先级有效输入的下标且仅在en1且有输入有效时valid为高。注意在真实的FPGA或ASIC设计中casex语句的综合结果可能与仿真行为存在细微差别并且有些代码规范禁止使用casex。另一种更严谨的实现方式是使用if-else if链其优先级特性更明确。这里使用casex是为了更直观地展示优先级编码的思维模型。3. 从数字电路到物理世界认识旋转与绝对值编码器掌握了数字逻辑编码器我们就能更好地理解作为传感器的物理编码器。它们本质上是将物理量“编码”成数字信号的装置核心区别在于“编码”的规则和输出形式。3.1 增量式旋转编码器测量相对变化这是最常见的一种结构简单成本较低。工作原理内部有一个光栅盘或磁栅盘旋转时会产生两路相位差90度的方波脉冲A相和B相以及一个每圈一个的索引脉冲Z相。输出信号A、B两路脉冲。如何“编码”方向判断通过检测A、B相的相位差。若A相超前B相90度通常定义为正转反之则为反转。位置计算对脉冲进行计数。每产生一个脉冲位置就增加或减少一个最小单位分辨率。速度计算单位时间内的脉冲数即代表转速。优点结构简单价格低可测量无限行程。缺点断电后位置信息丢失需上电回零抗干扰能力相对较弱高速时可能丢脉冲。典型接线与读取单片机为例 编码器输出通常接入MCU的定时器编码器接口或外部中断引脚。以下是一个概念性代码片段展示如何用STM32的HAL库配置// 使用TIM2的编码器模式 TIM_Encoder_InitTypeDef sConfig {0}; TIM_MasterConfigTypeDef sMasterConfig {0}; sConfig.EncoderMode TIM_ENCODERMODE_TI12; // 在TI1和TI2上计数 sConfig.IC1Polarity TIM_ICPOLARITY_RISING; sConfig.IC1Selection TIM_ICSELECTION_DIRECTTI; sConfig.IC1Prescaler TIM_ICPSC_DIV1; sConfig.IC1Filter 6; // 添加滤波防抖动 // ... 类似配置IC2 ... if (HAL_TIM_Encoder_Init(htim2, sConfig) ! HAL_OK) { Error_Handler(); } sMasterConfig.MasterOutputTrigger TIM_TRGO_RESET; sMasterConfig.MasterSlaveMode TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(htim2, sMasterConfig) ! HAL_OK) { Error_Handler(); } // 启动编码器接口 HAL_TIM_Encoder_Start(htim2, TIM_CHANNEL_ALL); // 随时读取计数器值获取位置 int32_t current_position __HAL_TIM_GET_COUNTER(htim2);3.2 绝对值编码器获取绝对位置这是搜索热词中“三菱FX1N读取伺服驱动绝对值编码器位置”和“磁编码器AS5047P”所涉及的类型。工作原理每个机械位置对应一个唯一的数字编码。常见技术有光学多圈格雷码、磁性如AS5047P、旋转变压器旋变编码器。输出信号并行格雷码、串行通信如SSI、BiSS、I2C、SPI或现场总线如PROFIBUS、EtherCAT。如何“编码”编码器内部已经完成了“位置到数字码”的编码过程。控制器只需通过特定接口读取这个数字码即可知道当前位置无需计数和回零。优点断电不丢位置抗干扰强数据可靠。缺点结构复杂成本高分辨率受位数限制如单圈12位多圈16位。接口类型详解并行输出直接输出多位格雷码速度快但线缆多易受干扰传输距离短。串行同步接口SSI时钟线数据线控制器发送时钟编码器同步返回数据。抗干扰好是工业主流。I2C/SPI常见于磁编码器等小型传感器。如AS5047P是一款通过SPI或I2C接口读取的12位磁旋转编码器芯片。// 示例通过SPI读取AS5047P角度值伪代码 uint16_t read_as5047p_angle(void) { uint8_t tx_data[2] {0xFF, 0xFF}; // 读取命令具体参考芯片手册 uint8_t rx_data[2] {0}; HAL_SPI_TransmitReceive(hspi1, tx_data, rx_data, 2, 100); // 处理数据去除校验位等 uint16_t angle_raw ((rx_data[0] 0x3F) 6) | (rx_data[1] 2); return angle_raw; }现场总线编码器作为从站接入PROFIBUS-DP、EtherCAT等网络位置数据在过程数据中循环更新。3.3 旋变编码器Resolver这是一种特殊的模拟式绝对值编码器极其坚固耐用常用于极端环境高温、高振动。工作原理基于电磁感应。转子绕组通激励信号定子输出两路相位差90度的正弦模拟信号SinCos。输出信号模拟正弦波。如何“编码”需要额外的RDC旋变数字转换器芯片将Sin/Cos模拟信号解算成数字角度值。这个过程本身就是一次复杂的“解码”。优点耐高温、振动、油污寿命极长。缺点系统复杂需RDC成本高。4. 工业实战PLC如何读取编码器信号在自动化领域PLC是控制核心编码器是反馈眼睛。它们的连接方式是工程实践的关键。4.1 西门子S7-1200读取高速脉冲对于增量式编码器S7-1200通过高速计数器HSC功能读取。硬件接线编码器的A、B相分别接到PLC的HSC输入点如I0.0 I0.1。注意NPN/PNP类型匹配和24V电源。软件配置在TIA Portal中在设备视图双击CPU进入“属性”-“高速计数器”。选择一个HSC如HSC1功能选择“计数”。操作模式选择“单相”或“正交A/B相”。设置初始值、复位选项等。程序读取使用CTRL_HSC工艺对象或直接读取ID1000HSC1的当前值等背景数据块地址。// 在SCL或梯形图中可以直接使用背景DB中的计数值 // 例如HSC1的计数值可能映射到 ID1000 (DINT) current_count : “背景DB”.HSC_1.COUNT;脉冲程序逻辑通常将HSC的计数值与预设值比较触发中断OB执行定位控制逻辑。4.2 三菱FX系列通过485读取伺服绝对值编码器这是搜索热词中的具体场景。三菱FX1N PLC通过RS-485通信通常使用内置的RS-485 BD板与伺服驱动器如三菱MR-JE系列连接驱动器再连接绝对值电机内含绝对值编码器。系统架构FX1N PLC--RS-485--伺服驱动器--专用电缆--伺服电机含绝对值编码器通信协议通常采用三菱的专用通信协议如MC协议或Modbus RTU如果驱动器支持。PLC作为主站向驱动器发送读取指令。关键步骤硬件连接正确连接PLC的485接口如DA、DB、SG到驱动器的通信端口终端电阻设置正确。驱动器参数设置在驱动器参数中设置站号、波特率、数据格式等与PLC程序匹配。并设置允许通过通信读取当前位置。PLC编程使用RS指令或ADPRW指令取决于PLC型号和协议编写通信程序。需要根据伺服驱动器的通信地址映射表找到“当前位置”对应的寄存器地址。// 伪代码以FX3U的ADPRW指令为例FX1N可能使用RS指令 // 假设驱动器站号1 位置数据存放在驱动器寄存器 D10032位 // 发送读取命令 ADPRW H1 // 站号1 H3 // 功能码读取保持寄存器 D100 // 起始地址 D2 // 读取2个寄存器32位 D200 // PLC中存储返回数据的起始地址D200, D201数据处理读取到的32位数据可能需要根据驱动器手册进行转换如转换为有符号双整数并乘以一个系数才能得到实际工程单位如毫米或度。重要提醒不同品牌、系列的伺服驱动器和PLC其通信协议、地址映射、参数设置差异巨大。务必以对应型号的官方技术手册为准。上述步骤仅为通用流程示意。5. 编码器应用中的常见问题与排查无论是数字编码器模块还是物理编码器传感器在实际部署中都会遇到各种问题。5.1 数字逻辑编码器仿真/综合问题问题现象可能原因检查与解决思路仿真时输出全是X未知态输入信号未初始化或case/if分支未覆盖所有情况。1. 检查测试平台中所有reg型输入是否赋初值。2. 检查设计代码确保所有可能的输入组合都有明确的输出赋值特别是default分支。综合后电路面积过大使用了优先级不明确的逻辑综合器生成了并行选择器而非级联结构。1. 对于优先编码器明确使用if-else if链或casex语句这能向综合工具清晰地传达优先级信息。2. 检查是否无意中引入了不必要的锁存器Latch。时序违例Setup/Hold Violation组合逻辑路径过长在高速时钟下无法稳定。1. 插入流水线寄存器将大段组合逻辑拆分为多个时钟周期完成。2. 优化逻辑表达式减少逻辑级数。5.2 物理编码器连接与读数问题问题现象可能原因排查步骤增量编码器计数不准、乱跳1. 电源噪声或接地不良。2. A/B相序接反。3. 机械振动导致信号抖动。4. 线缆过长或未用屏蔽线引入干扰。1.示波器检查观察A、B相信号波形是否干净、相位差是否稳定90度。2.交换测试交换A、B相接线看计数方向是否反向。3.软件滤波启用定时器或PLC高速计数器的输入滤波功能。4.硬件整改使用屏蔽双绞线单端接地电源端加磁珠或滤波电容缩短走线。绝对值编码器通信失败如I2C无应答1. 电源电压不符。2. I2C地址错误。3. 上拉电阻未接或阻值不对。4. 通信速率过快。5. 时序不满足芯片要求。1.查手册确认芯片供电电压如AS5047P是3.3V还是5V。2.查地址确认I2C从地址7位或8位格式注意地址引脚电平。3.查电路SCL和SDA线是否接了上拉电阻通常4.7kΩ。4.降速率先将I2C时钟频率降到最低如100kHz测试。5.逻辑分析仪抓取I2C波形对比时序与芯片手册要求。旋变编码器角度值漂移或不稳定1. RDC参考激励信号幅度/频率不稳。2. Sin/Cos信号线受干扰。3. RDC芯片解算参数配置错误。1.测激励用示波器检查激励信号EXC的幅值和频率是否稳定、符合要求。2.测输出检查Sin、Cos信号的幅值是否相等波形是否为正弦有无畸变。3.查配置检查RDC芯片的位数、速度等配置寄存器是否正确写入。PLC高速计数器不计数1. 输入点未正确配置为HSC模式。2. 输入信号电压等级不匹配如24V信号接入5V输入。3. 计数方向设置错误。4. 硬件滤波器设置过宽滤掉了脉冲。1.查配置确认PLC编程软件中该输入点的HSC功能已启用且模式正确。2.测电压用万用表测量编码器输出信号在PLC输入端的电压。3.查方向检查A、B相接线或尝试在软件中反转计数方向。4.调滤波适当减小输入滤波时间常数。6. 选型与最佳实践指南面对众多编码器类型和接口如何为项目做出正确选择以下是一份速查清单。6.1 编码器选型决策表考量维度增量式旋转编码器绝对值编码器串行旋变编码器核心需求测速、相对定位、低成本计数断电保持绝对位置、高可靠性定位极端环境高温、高振下的绝对位置系统成本低传感器本身中高传感器接口高传感器RDC芯片安装复杂度低中中高需考虑RDC安装抗干扰性中需做好屏蔽高数字通信极高模拟信号抗电磁干扰强维护性需定期回零免维护无电池多圈型或需更换电池免维护寿命极长典型分辨率高可达数万PPR中高单圈12-24位中通常12-16位推荐接口差分线驱动如RS422接入HSCSSI、BiSS、EtherCAT模拟Sin/Cos输出至专用RDC6.2 工程实践要点电源与接地是生命线编码器尤其是模拟和高速数字编码器对电源质量非常敏感。务必使用线性稳压或低噪声开关电源为编码器单独供电并采用星型单点接地避免地环路。信号传输要防护超过1米的传输距离必须使用屏蔽双绞线。屏蔽层在传感器端接外壳在控制器端单点接地。差分信号如RS422比单端信号如集电极开路抗干扰能力强得多。上电初始化顺序对于绝对值系统确保控制器PLC/单片机先于或同时与编码器上电。避免编码器已输出数据而控制器未准备好读取导致数据丢失或错误。软件层面的容错处理增量编码器设置计数溢出/下溢中断并设计软件限位和位置校正机制如利用Z相信号。绝对值编码器通信读取需增加超时和CRC校验。首次上电或通信异常恢复后应进行位置验证如果机械位置已知。旋变编码器监控RDC芯片的故障标志位如丢失信号LOS、超速VEL等。分辨率与机械匹配编码器的分辨率每转脉冲数PPR或位数必须与机械系统的精度要求匹配。过高的分辨率可能导致计数器溢出过快或通信负载过重过低则无法满足控制精度。计算时考虑机械减速比。从理解一个8输入、3输出的数字逻辑模块到连接一个能耐受车间油污震动的旋变编码器贯穿始终的核心思想是“将信息转换为可处理的数字形式”。数字逻辑编码器是理解编码思想的基石而物理编码器则是这一思想在测量领域的辉煌应用。在实际项目中不要孤立地看待编码器而要将其置于整个信号链中从机械连接、电气接口、信号调理到控制器读取、数据解析和软件处理每一步都影响着最终系统的稳定性和精度。建议先从软件仿真一个优先编码器开始再使用开发板连接一个简单的旋转编码器模块实践计数最后再去研究复杂的工业通信协议这样层层递进的学习路径最为扎实。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价