资讯动态

基于51单片机的行车速度里程表设计与Proteus仿真验证

发布时间:2026/9/16 8:02:09 来源:尧图企业网站定制
简介面向单片机课程设计与毕业设计场景这份行车速度里程表资料包基于51单片机与Proteus仿真涵盖源程序、仿真工程、论文材料和配套技术手册。方案以51/52系列为主控结合1602液晶、DS1302时钟、24C02存储、蜂鸣器及按键可实时显示日期时间、累计里程和当前车速用户可通过按键设定车轮直径以校准测速结果设置超速报警阈值触发蜂鸣器提醒并由24C02实现参数掉电保存。资源共40个文件包括Keil工程文件、Proteus仿真7.5与8.10版本、设计说明文档、常见元件技术手册和操作视频压缩包仅8.4MB目录分类清晰便于快速定位与对照学习。目前已有50人浏览学习适合希望掌握霍尔测速原理、单片机外设综合应用及整机调试流程的读者参考完整工程和录屏演示亦可作为课程设计模板或毕业设计功能参考。1. 测速原理与系统组成从霍尔脉冲到速度里程车轮每转一圈霍尔传感器就输出一个脉冲速度是脉冲频率的函数里程是脉冲次数的累加。这套基于51单片机的行车速度里程表设计把这两句话落成了外部中断计数加定时器闸门的结构STC89C52负责运算1602显示日期时间和速度里程DS1302独立走时24C02保存轮径与超速阈值超速时蜂鸣器报警。整个资源包含Keil源程序、Proteus 7.5和8.10仿真工程、设计说明文档和配套芯片手册无需额外硬件就能跑通。仿真里用不同频率信号源模拟霍尔输出正好可以验证测速公式算得对不对。适合两类人做单片机课设/毕设需要完整可演示项目的学生以及想把定时器、外部中断、I2C、按键状态机串成完整系统来理解的人。下面按硬件协同、核心算法、存储与仿真验证的顺序展开。2. 硬件分工与接线51主控、1602与DS1302的协同2.1 系统硬件架构与选型理由这套设计在硬件上是一个很典型的51单片机最小系统加外围设备组合STC89C52作主控1602液晶做显示DS1302做独立时钟24C02做参数存储霍尔信号从外部中断口进入。芯片选型上51系列要的就是生态成熟和时序透明——中断、定时器、I2C这些知识点都能在代码里直接看到毕设答辩时每个模块都能讲清楚原理。DS1302和24C02都选串行接口是省引脚的正确做法。DS1302三根线SCLK、IO、RST就能读回完整日历24C02两根线SCL、SDA就能读写EEPROM把宝贵的I/O留给1602的数据口和按键。相比之下如果并行的时钟芯片或存储芯片51的引脚根本不够用。下面给出一套常见的引脚分配具体到仿真图和电路图可能略有差异但功能引脚不会变模块芯片/接口作用常见接法主控STC89C52 / AT89S52脉冲计数、逻辑运算、显示刷新11.0592MHz晶振速度输入霍尔传感器信号外部中断计数霍尔脉冲P3.2INT0下降沿触发显示LCD1602显示日期时间、速度、里程P0数据口RS/RW/EN接P2.0-P2.2时钟DS1302独立走时掉电保持SCLK/IO/RST接P1.0-P1.2存储24C02保存轮径、超速阈值SCL接P2.6SDA接P2.7报警蜂鸣器超速声音报警P1.3经三极管驱动按键轻触按键×4设置/加/减/确认P1.4-P1.7霍尔信号接P3.2是硬件决定的因为INT0外部中断只能从这脚进入。P0口作为数据总线时要接10k上拉排阻这是51硬件的固定要求。蜂鸣器不建议直接接在P1.3上驱动51的I/O灌电流能力有限实物上要用S8550三极管放大仿真里用SOUNDER模型倒是不挑驱动力能响就行。2.2 1602的初始化与显示刷新1602是典型的HD44780控制器8位模式下每次传输一个字节通过RS选择命令或数据EN引脚产生下降沿锁存数据。初始化时序必须严格按照数据手册来上电后要等15ms以上然后依次送0x38、0x0C、0x06、0x01四条命令。很多人显示乱码或白屏就是初始化时延时不满足要求。#define LCD_DATA P0 sbit LCD_RS P2^0; sbit LCD_RW P2^1; sbit LCD_EN P2^2; void lcd_write_cmd(unsigned char cmd) { LCD_RS 0; // 命令模式 LCD_RW 0; // 写操作 LCD_DATA cmd; LCD_EN 1; delay_us(5); LCD_EN 0; // 下降沿锁存数据 delay_ms(2); } void lcd_write_data(unsigned char dat) { LCD_RS 1; // 数据模式 LCD_RW 0; LCD_DATA dat; LCD_EN 1; delay_us(5); LCD_EN 0; delay_ms(2); } void lcd_init(void) { delay_ms(15); // 等待1602上电稳定 lcd_write_cmd(0x38); // 8位数据2行显示5x7点阵 lcd_write_cmd(0x0C); // 显示开光标关闭 lcd_write_cmd(0x06); // 写入后地址自动加1 lcd_write_cmd(0x01); // 清屏 }delay_ms(2)是给1602内部处理留时间。0x38之后要等几十微秒清屏指令要等1.64ms实际工程直接用2ms的延时把这些问题全盖住。RW引脚通常直接接地因为这里只做写入不读忙很多开发板也是这么接的能省一个I/O。显示刷新方面我一般不会在主循环里无脑刷1602。日期时间变化频率低200ms刷一次足够速度数值变化快单独每100ms刷新一次第二行。刷新过快时1602忙着执行命令反而挤压了主循环里按键扫描和里程计算的时间实际效果还会闪烁。这套设计的显示布局是第一行放日期时间格式如2025-06-18 14:30第二行放速度和里程格式如V:079.2 KM:12345这两行正好占满1602的32个字符。日期时间来自DS1302速度里程来自每秒结算的测速逻辑两部分互不干扰。2.3 DS1302的读写时序与BCD码换算DS1302是3线制同步串行接口SCLK上升沿写入下降沿读出。访问寄存器时先写地址字节地址bit0为0是写操作、为1是读操作。读秒寄存器时写0x81读分写0x83以此类推。这里最容易犯的错误是忘记bit0写0x80去读结果什么都读不回来。sbit DS1302_SCLK P1^0; sbit DS1302_IO P1^1; sbit DS1302_RST P1^2; void ds1302_write_byte(unsigned char dat) { unsigned char i; for (i 0; i 8; i) { DS1302_IO dat 0x01; // 低位在前 DS1302_SCLK 1; // 上升沿写入 DS1302_SCLK 0; dat 1; } } unsigned char ds1302_read_byte(void) { unsigned char i, dat 0; for (i 0; i 8; i) { dat 1; if (DS1302_IO) dat | 0x80; DS1302_SCLK 1; // 下降沿读数据 DS1302_SCLK 0; } return dat; } unsigned char ds1302_read(unsigned char addr) { unsigned char dat; DS1302_RST 1; ds1302_write_byte(addr | 0x01); // 最低位置1表示读 dat ds1302_read_byte(); DS1302_RST 0; return dat; }时序上还有一个细节RST拉高后至少等一个SCLK周期再操作通讯结束后拉低RST不能在SCLK为高时拉低RST。DS1302返回的是BCD码不是十六进制比如秒寄存器读到0x53代表53秒直接按十进制显示会变成83。转换公式是dec (bcd 4) * 10 (bcd 0x0F)反过来写入时用bcd (dec / 10) 4 | (dec % 10)。常用寄存器地址如下表注意这里列的是写地址读时按表加1功能写地址读地址数值范围秒0x800x8100-59分0x820x8300-59时0x840x8501-12或00-23日0x860x8701-31月0x880x8901-12年0x8C0x8D00-99上电后DS1302可能处于停振状态表现为秒寄存器不变。程序里要对秒寄存器做合法性判断如果读到0x00并且10秒后仍然是0x00就给DS1302写一次初始时间顺便开启时钟的充电功能让后备电池维持走时。第一次上电不初始化后面调时间也调不进去这个问题在做Proteus仿真时就会出现时间不走先查这个。3. 速度里程核心算法定时器闸门、外部中断与超速判断3.1 M法测速的公式推导测速在工程上有M法和T法两种主流思路。M法是在固定时间T内数脉冲个数N频率就是N/T适合中高速场景T法是测量相邻两个脉冲的时间间隔低速场景更精准。这套设计用的是M法定时器产生1秒闸门外部中断对霍尔脉冲计数1秒内的脉冲数就是频率值。传感器部分需要注意每转脉冲数的概念。轮轴上的霍尔传感器配合磁钢每转过一个磁钢输出一个脉冲磁钢数量就是每转脉冲数。多数轮速方案只在轮毂上贴一颗磁钢所以每转1个脉冲程序里固定按1处理。如果实际装了两颗磁钢速度和里程都要除以2不处理的话显示值会翻倍。从脉冲频率到线速度的换算核心公式是线速度等于圆周长乘以每秒转数。车轮直径D用毫米表示时速度的km/h值计算如下v_kmh 3.6 × π × (D / 1000) × f其中f是每秒脉冲数D/1000把毫米换成米π乘以D/1000得到一圈的周长米数乘以频率得到米/秒乘3.6转成km/h。里程稍微不同它是总脉冲数对周长的积分S_km π × (D / 1000) × total_pulses / 1000总脉冲数除以1000得到千转再乘以每转米数得到公里数。程序里全程用整数或float运算都行51的浮点库虽然慢但这个频率量级完全撑得住。以直径700mm、每转1个脉冲为例1Hz频率对应的速度为7.92km/h这个常数可以作为手工验算程序是否写对的基准。频率Hz速度km/h每秒行驶距离m17.922.20539.611.01079.222.020158.444.0这套换算关系也可以用在小车测速、传送带测速等场景把轮径换成对应直径公式不变。3.2 定时器闸门与外部中断的配合测速的核心矛盾在于既要采集脉冲又要计算时间两件事不能互相干扰。霍尔脉冲频率可能在几十Hz到几百Hz之间变化如果用主循环查询P3.2电平来数脉冲一旦主循环在刷1602或者处理按键一个上升沿就漏过去了。解决办法是外部中断。INT0配置为下降沿触发后脉冲跳变会由硬件锁存触发中断即使主循环在做别的事也不会丢。每个脉冲触发一次外部中断0中断服务程序里只需要做加法1秒的闸门时间由定时器0负责。定时器0配置为50ms中断一次累计20次得到1秒。unsigned long pulse_count; // 1秒内的脉冲数用于速度计算 unsigned long total_pulse; // 总脉冲数用于里程累加 bit second_flag 0; // 1秒闸门标志 void ex0_isr(void) interrupt 0 { pulse_count; // 霍尔每来一个脉冲加1 total_pulse; // 里程累加也用同一份计数 } void timer0_isr(void) interrupt 1 { static unsigned char t50ms 0; TH0 0x4C; // 11.0592MHz晶振50ms定时初值 TL0 0x00; if (t50ms 20) { t50ms 0; second_flag 1; // 凑够1秒通知主循环结算 } }定时器0的初值0x4C00不是随便写的。12T模式下机器周期是12/11.0592MHz约1.085微秒50ms需要46080个机器周期65536减46080等于19456换成十六进制就是0x4C00。这个数值换了晶振或换了1T单片机全部要重算仿真里如果速度整体偏大或偏小先检查时钟频率和初值是否匹配。中断里只做加法和置标志这是51中断服务程序的设计原则。如果中断里处理速度换算或者1602写数据一方面会拉长中断响应时间另一方面在中断里调用占用时间长的函数很容易把其他中断或者主循环卡死。真正的速度计算放在主循环检测到second_flag后再做。3.3 每秒结算速度、里程与超速报警的C实现主循环里检测到1秒标志后把pulse_count取走并清零然后计算这一秒的平均速度和累积里程。这里有个细节取走计数和清除标志的顺序不能反。先清标志再取计数可能丢掉下一秒第一个脉冲先取计数再清标志下一秒的脉冲又会累进被取走的变量里造成计数错位。正确顺序是先取pulse_count再清pulse_count最后清second_flag。void update_speed_odometer(void) { unsigned long pulses; float wheel_m; if (!second_flag) return; pulses pulse_count; pulse_count 0; second_flag 0; wheel_m wheel_d / 1000.0f; // 轮径mm换算为m speed_kmh 3.6f * 3.14159f * wheel_m * (float)pulses / pulses_per_rev; odometer_km 3.14159f * wheel_m * (float)pulses / pulses_per_rev / 1000.0f; if (speed_kmh (float)alarm_th) { alarm_cnt; if (alarm_cnt 3) { // 连续3秒超速才报警 buzzer_on 1; } } else { alarm_cnt 0; buzzer_on 0; } }pulses_per_rev是每转脉冲数默认1。wheel_d是按键设置的轮径值默认700mm。speed_kmh是float变量显示时转成整数部分和小数部分用取整和取余的方式拆开不要用sprintf51的printf库太占资源。超速报警这里做了一个防抖速度超过阈值之后不立即响而是连续3秒都超速才拉高蜂鸣器。否则速度在阈值附近抖动时蜂鸣器会频繁通断听起来就像接触不良。这个防抖计数和按键消抖的思路同源都是在真实信号上叠加一个时间窗口来滤除毛刺。蜂鸣器驱动分两种有源蜂鸣器内部有振荡电路I/O拉高就响无源蜂鸣器需要给2kHz到4kHz的方波才能发声。仿真工程里的蜂鸣器接法看仿真图最直观如果连的是SOUNDER模型通常走方波驱动在定时器中断里翻转蜂鸣器引脚就行。3.4 一个容易被忽略的误差来源闸门与脉冲的不同步M法测速有个系统性误差定时器闸门和脉冲边沿不同步。设想4Hz的脉冲信号第一个脉冲在闸门开启后0.1秒到达1秒闸门关闭前最后一个脉冲在0.9秒到达这一秒内实际只数到了4个脉冲速度算出31.7km/h没问题。但如果第一个脉冲在闸门开启前0.02秒就到了最后一个脉冲在1.02秒才来这一秒数到的可能只有3个脉冲速度显示就成了23.8km/h。这种±1个脉冲的量化误差在低频输入时尤其明显。仿真中把DCLOCK设成1Hz显示值会在7.9和0之间跳变不是程序写错了是M法本身的精度极限。分辨率由采样时间决定提高精度可以加长闸门时间或者改成T法测周期。本设计按每秒刷新是合理的速度显示本来就要有实时性不能为了平滑把响应拖慢。实际行车场景里这个误差影响不大因为正常车速对应脉冲频率远高于1Hz。但如果你要验证代码看到低速时速度跳动先别怀疑程序算一下当前频率对应的理论速度再连续观察几秒的平均值。4. 参数掉电保存24C02的I2C读写与按键设置流程4.1 24C02的I2C时序基础24C02是2Kbit串行EEPROM也就是256字节存储空间I2C从设备地址由硬件引脚A0、A1、A2决定全部接地时器件地址是0xA0写和0xA1读。I2C总线只需要SCL和SDA两根线两根线都要接上拉电阻到VCC硬件上用4.7k或10k都行。Proteus仿真里不加上拉也能跑但实物不加上拉数据读写的稳定性会很差。I2C时序的四个关键动作起始、停止、发送字节、接收应答。起始条件是SCL为高电平时SDA产生下降沿停止条件是SCL为高电平时SDA产生上升沿。数据线在SCL高电平期间必须保持稳定只能在SCL低电平时切换这是整个I2C协议的根本约束。每发送完一个字节从设备会拉低SDA作为应答主设备要释放SDA线才能读到这个应答位。void i2c_start(void) { SDA 1; SCL 1; // SCL高期间SDA拉低起始 SDA 0; SCL 0; } void i2c_stop(void) { SDA 0; SCL 1; // SCL高期间SDA拉高停止 SDA 1; } unsigned char i2c_write_byte(unsigned char dat) { unsigned char i, ack; for (i 0; i 8; i) { SDA (dat 0x80) ? 1 : 0; dat 1; SCL 1; // 数据在SCL高电平期间被采样 SCL 0; } SDA 1; // 释放SDA准备接收应答 SCL 1; ack SDA; // 拉低应答高无应答 SCL 0; return ack; }写24C02的完整过程是先发起始再发送器件地址0xA0发送字节地址最后发送数据字节。每一步都要检查应答如果在器件地址阶段收到无应答说明地址写错了或者芯片不在总线上如果在数据阶段无应答通常是上一次写操作还没完成EEPROM在内部擦写期间不响应任何指令。24C02每写入一个字节内部需要大约5ms完成擦写这段时间内不能对芯片发起任何操作。工程上的做法是写完一个字节后调用延时函数等5ms再写下一个。批量写入可以一页16字节连续写用页写方式减少等待时间但本设计只需保存几个参数单字节写入完全够用。4.2 存储布局与读写校验24C02有256字节本设计只用了前4个字节。存储布局要有规划直接写一个字节存一个参数看起来省事但后续如果增加参数或者改变数据类型地址全要调整。合理的方式是定义地址宏每个参数对应固定地址再留一个校验字节。上电读取时先读校验字节不等于约定值就说明EEPROM里没有有效数据需要初始化。地址内容长度存储格式0x00轮径高字节1wheel_d 80x01轮径低字节1wheel_d 0xFF0x02超速阈值1单位km/h范围0-2000x03校验标志1固定值0xAA表示有效轮径范围300-1500mm16位无符号数完全够用所以要拆成高低两个字节存。超速阈值最大200km/h8位够用。EEPROM空片状态下所有字节都是0xFF如果把0xFF当轮径读出来就是65535mm速度计算会得到一个荒谬的结果。校验字节0xAA可以识别空片但更稳妥的是同时做范围校验。void save_params(void) { i2c_write_byte(0xA0, 0x00, wheel_d 8); delay_ms(6); // 等待内部擦写完成 i2c_write_byte(0xA0, 0x01, wheel_d 0xFF); delay_ms(6); i2c_write_byte(0xA0, 0x02, alarm_th); delay_ms(6); i2c_write_byte(0xA0, 0x03, 0xAA); delay_ms(6); } void load_params(void) { unsigned char flag; wheel_d (unsigned int)(i2c_read_byte(0xA0, 0x00) 8) | i2c_read_byte(0xA0, 0x01); alarm_th i2c_read_byte(0xA0, 0x02); flag i2c_read_byte(0xA0, 0x03); if ((flag ! 0xAA) || (wheel_d 300) || (wheel_d 1500)) { wheel_d 700; // 默认轮径700mm alarm_th 80; // 默认限速80km/h save_params(); // 参数无效时写入默认值 } }这里i2c_read_byte封装了完整的三段式读操作发送器件地址0xA0和字节地址再发送0xA1和重复起始最后读取数据并发送非应答。单片地址读的细节是读操作前要重复一次起始信号这是I2C规范要求的地址变更方式不这样做读回来的数据可能是错的。参数保存的时机要选好。修改完成后在确认退出的那一刻写一次EEPROM即可不要在主循环里每秒都写。EEPROM的擦写寿命通常以10万次到100万次计算每秒写一次的话几个月就报废了。这也是为什么需要按键流程里做一个明确的确认动作把保存集中在用户的意图点上。4.3 按键设置流程一个典型的菜单状态机按键设置的本质是状态迁移这在51单片机项目里是一个很标准的写法。四个按键分别是设置、加、减、确认对应的状态有三个正常运行态、设置轮径态、设置超速阈值态。这个设计的时间修改逻辑可以并入同一个状态机在超速阈值态之后再增加一个时间设置态本文先按轮径和阈值的两种状态说明。状态机的驱动放在主循环的按键扫描函数里。每次按键按下都要处理消抖和松手检测按下后延时20ms再判断一次电平确认确实按下才进入状态处理处理完等待按键释放才退出。不检测松手的话一次长按会被当成多次触发参数会一路加到顶。#define KEY_SET P1_4 #define KEY_ADD P1_5 #define KEY_SUB P1_6 #define KEY_OK P1_7 #define STATE_RUN 0 #define STATE_SET_WHEEL 1 #define STATE_SET_ALARM 2 unsigned char menu_state STATE_RUN; void key_scan(void) { if (KEY_SET 0) { delay_ms(20); if (KEY_SET 0) { if (menu_state STATE_RUN) { menu_state STATE_SET_WHEEL; lcd_show_set_wheel(wheel_d); // 显示当前轮径 } else if (menu_state STATE_SET_WHEEL) { menu_state STATE_SET_ALARM; lcd_show_set_alarm(alarm_th); // 显示当前阈值 } else { save_params(); // 确认保存 menu_state STATE_RUN; // 回到运行态 lcd_show_home(); } while (KEY_SET 0); // 等待释放 } } if (menu_state STATE_SET_WHEEL) { if (KEY_ADD 0) { delay_ms(20); if (KEY_ADD 0) { if (wheel_d 1500) wheel_d 10; // 每次加10mm lcd_show_set_wheel(wheel_d); while (KEY_ADD 0); } } // 减键逻辑对称 } }加减键在运行态不做任何事只有进入设置态后才有响应这个约束是靠menu_state判断实现的。轮径步进10mm阈值步进1km/h步长选择的逻辑是有讲究的轮径修正幅度需要足够精细但步进太小的话从700mm调到1200mm要按50次10mm在显示和操作手感之间比较平衡。设置态下1602显示内容要从运行画面切换成参数编辑画面。运行态显示的是时间和速度设置态要让用户看到当前正在改什么值改到多少。退出设置态时恢复运行画面同时把新参数用于速度计算。这个切换也要在状态机里处理不能在按键扫描里直接改显示否则状态和显示会不同步。整个按键状态机设计对任何单片机项目都适用。改时间、改闹钟、改PID参数本质都是这套状态迁移逻辑只是状态多了之后要从if-else改成switch-case或者函数指针表。这个设计里只有三个状态if-else分支清晰足以维护。5. Proteus仿真验证与调试验证5.1 加载工程与烧录hex拿到资源后先打开Proteus 8.10目录下的仿真工程再打开Keil工程目录下的源程序。Keil工程要在Options for Target的Output选项卡里勾选Create HEX File编译通过后在工程目录下生成hex文件。回到Proteus双击原理图中的STC89C52芯片在Program File一栏选择生成的hex文件点运行按钮开始仿真。如果编译报错先用Keil4打开工程文件用Keil5打开的话要在Device选项里重新确认芯片型号。AT89C52和STC89C52在寄存器层面兼容但头文件选择不同STC系列的波特率配置和内部EEPROM操作有差异。资源里给的是STC89C52选型时保持一致可以避免很多奇怪的问题。5.2 用信号源模拟霍尔脉冲验证算法Proteus左侧工具栏的Generator模式里有DCLOCK信号源拖到原理图上一端接地一端接P3.2。双击DCLOCK可以改频率默认1Hz对应每秒1个脉冲。启动仿真后第一行显示DS1302的日期时间第二行速度应该显示7.9km/h左右。改频率到10Hz速度变成79.2km/h这个线性关系可以直接验证测速公式有没有写对。操作期望结果DCLOCK设4Hz轮径700mm速度约31.7km/h进入设置态轮径改为500mm4Hz时速度约22.6km/h阈值设为30km/h输入4Hz不报警输入7Hz速度约55.4km/h蜂鸣器响超过30km/h停止仿真重新启动轮径和阈值保持上次设置值蜂鸣器报警的验证要注意Proteus的蜂鸣器模型有SOUNDER和BUZZER两种SOUNDER在仿真时需要设置触发电压和频率如果程序按方波驱动可以给频率参数如果用的是低电平触发的有源蜂鸣器模型直接接高电平就会响。看仿真图里蜂鸣器旁边的连接方式再对照程序里的驱动语句前后对应起来就能判断接线和程序是否匹配。5.3 常见故障排查DS1302时间不走是仿真中最高频的问题。Proteus的DS1302模型在X1和X2引脚之间必须放置32.768kHz晶振并且晶振两端接30pF电容到地时间才能正常走动。有些版本的仿真图为了简洁省掉了晶振时间就会停在初始值。确认晶振存在后再看程序里有没有做上电初始化首次使用要给DS1302写入当前时间。1602白屏或显示乱码检查三处一是V0对比度引脚有没有接可调电阻到地仿真里直接接地也能显示但对比度过高会出方块二是初始化延时够不够proteus对时序的模拟比真实芯片更宽容但延时太短仍会失败三是P0口有没有加上拉电阻模型不加上拉偶尔能工作显示不稳定时先补上。最隐蔽的坑是晶振频率不一致。Keil工程里编译器知道单片机用11.0592MHz但Proteus原理图里STC89C52的时钟频率如果设置成了12MHz定时器0按11.0592MHz计算的50ms初值就会产生偏差1秒闸门变为约1.08秒速度整体放大8%。遇到速度计算和理论值对不上先检查原理图单片机属性里的Clock Frequency和Keil工程里是否一致。资源和仿真图通常保持一致但自己在Keil里新建工程时很容易忽略这一步。最后建议拿到资源后第一次运行不要改任何参数。按原始工程编译、烧录、运行用4Hz信号源输入确认第二行速度显示31.7km/h且里程每秒增加约8.8m再开始改轮径、阈值、时间等参数。把这一步作为基准点后面所有修改是否有影响都拿这个基准去对照。本文还有配套的精品资源点击获取

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

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

免费获取报价