恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
基于AT89C51与32768Hz晶振的多量程数字频率计设计
首页
资讯中心
/
基于AT89C51与32768Hz晶振的多量程数字频率计设计
基于AT89C51与32768Hz晶振的多量程数字频率计设计
发布时间:2026/9/17 21:55:26
简介这是一份面向计算机、电子信息类专业学生的51单片机课程设计资料主题为基于AT89C51单片机的数字频率计设计适合正在做课设、单片机入门实践或需要参考完整设计方案的学习者。压缩包内共1个pdf文件约602KB以课程设计报告形式呈现便于打印与逐节阅读。内容从数字频率计概述、频率测量思路与基本设计原理讲起依次展开硬件结构设计系统构成、AT89C51引脚说明、信号调理及放大整形模块、时基信号产生电路、显示模块与软件设计定时计数、量程转换、BCD转换、LCD显示并附有结束语、参考文献和汇编源程序代码主体采用1602A LCD动态显示6位数测量范围1Hz至10kHz时基宽度可选1us、10us、100us、1ms兼具频率测量误差分析等知识点。目前已有480人学习适合作为课设选题参考与单片机系统开发流程的入门范例。1. 低频段为什么不能共用一把闸门数脉冲数字频率计最容易翻车的地方不在程序在量程。1s 闸门直接数脉冲10kHz 信号能数到 10000 个数±1 的量化误差只有 0.01%同一把闸门拿去测 1Hz 信号就只剩 1 个数误差直接飙到 100%。所以一份基于 AT89C51 的课程设计不可能用一种方法吃下 1Hz—10kHz。它必须把时基切成 1us、10us、100us、1ms 四档用 32768Hz 晶振经 CD4060 与 CD4013 分出秒信号做高频段的测频闸门用单片机 T1 定时器派生标准时基做低频段的测周基准再让 LM311 把正弦、方波、三角波整形成同频方波最后由 1602A 显示六位十进制读数。适合正在做单片机课程设计、要交硬件原理图和汇编源码的人也适合想把测频这件事的原理补扎实的电子、自动化方向从业者。2. 从正弦波到TTL方波信号调理、放大与施密特整形链路被测信号不会乖乖按 TTL 电平送进来。它可能是几十毫伏的传感器输出也可能是几十伏的功放输出直接怼到单片机引脚上轻则读不到数重则烧口。调理链路的任务就是把这堆不确定的模拟波形统一成一路幅度固定、边沿陡峭、频率不变的方波。2.1 四级结构各自解决什么问题放大整形系统由衰减器、跟随器、放大器、施密特触发器串联而成缺一级都会出问题级典型器件作用关键参数分压衰减电阻分压网络 二极管钳位把 30Vpp 大信号压进安全区分压比起步 15:1钳位到 VCC0.7V阻抗变换LF353 射极跟随器提高输入阻抗不拉垮前级输入阻抗 1M同相放大LF353 另一半把 mV 级小信号抬到伏级A 1 R2/R1上限约 40整形LM311 比较器 正反馈变方波输出 TTL 电平迟滞 ±0.45V上拉 1k分压器放在最前面是因为大信号先在电阻上分掉不会进到运放的输入级造成削顶失真。射极跟随器摆在分压和放大之间把分压网络的输出阻抗从几十千欧降到几十欧后级放大倍数才不会随信号源内阻漂。放大器负责把小信号抬起来整形级负责给单片机一个干净的数字沿。2.2 分压比和放大倍数怎么算输入范围没法定死常见做法是按最小 50mVpp、最大 30Vpp这种量级先估一个覆盖区间再倒推两级参数# 输入 50mVpp ~ 30Vpp希望进入比较器前落在 2Vpp 左右 vin_min, vin_max 0.05, 30.0 v_target 2.0 atten vin_max / v_target # 最大输入所需的总衰减比 gain_max v_target / vin_min # 最小输入所需的净增益 print(round(atten, 1), round(gain_max, 1)) # 15.0 40.0分压网络先按 15:1 打底同相放大器再接一个 40 倍以内可调的增益整条链路就能覆盖 50mVpp 到 30Vpp。注意这两级是串联关系总增益等于分压比乘放大倍数调其中一个必须回头看另一个是否还落在比较器的线性区里。同相放大器的倍数由 A 1 R2/R1 决定改变 R1 就能改倍数做课程设计时通常用 10k 电位器串一个固定电阻避免调到 1 倍以下失去放大意义。2.3 LM311 施密特整形的阈值与迟滞电阻整形级用施密特触发器而不是普通过零比较器原因是输入信号上常带毛刺。普通比较器在阈值附近会被噪声反复触发输出一串假脉冲计数器读数直接偏大。正反馈引入迟滞后上下阈值拉开噪声落在窗口里就不会翻转。vcc 5.0 rin, rf 10e3, 100e3 # 输入电阻 10k正反馈电阻 100k vh vcc * rin / (rin rf) # 迟滞半宽 print(round(vh, 3)) # 0.455 V以 2.5V 为参考中点上阈值约 2.95V下阈值约 2.05V。迟滞窗口太小抗不住噪声太大对小信号不敏感100mV 以下的信号必须先在放大级抬起来再进比较器。LM311 的输出是集电极开路结构必须外接 1k 到 4.7k 的上拉电阻拉到 5V才能给单片机 T0 引脚一个像样的 TTL 高电平——这一步漏掉后面程序怎么调都是零读数。注意整形后的方波占空比不一定是 50%。测频法只数脉冲个数占空比无所谓但如果改用测周法测一个完整周期占空比失真会直接带进结果。3. 32768Hz晶振到秒闸门CD4060分频链与CD4051档位切换时基的稳定度就是频率计的精度上限。用单片机的 RC 振荡或内部定时器做闸门温漂随随便便几百 ppm换成 32768Hz 石英晶振再经数字分频闸门误差直接落到晶振本身的量级这是一份课程设计里最划算的一次器件升级。3.1 CD4060 十四级分频的抽头频率CD4060 内部是振荡器加 14 级二进制串行计数器振荡器既可以接 RC也可以接晶振。本设计用 32768Hz 表晶再从各级抽头取出不同频率输出分频比频率32768Hz 输入Q4162048 HzQ5321024 HzQ664512 HzQ7128256 HzQ8256128 HzQ951264 HzQ10102432 HzQ1240968 HzQ1381924 HzQ14163842 HzCR 引脚为高电平时计数器清零振荡器停振所以上电时必须给一个复位脉冲。常见做法是 CR 上接 100k 电阻到 VCC、再并 0.1uF 到地上电瞬间电容电压为零、CR 被拉高完成清零RC 时间常数约 10ms足够覆盖单片机和 LCD 的上电时间。晶振回路的负载电容是最容易被抄错的地方。CD4060 的振荡器引脚之间要接 1M 反馈电阻原理图里的 R7两只负载电容按 CL C1·C2/(C1C2) Cstray 计算。32768Hz 表晶的标称负载电容一般是 12.5pFC1C210pF 时算出来只有 5pF 加杂散实际偏小频率会走快。原理图里那只 0.1uF 应该老老实实待在 VDD 和 GND 之间做去耦不能挪到振荡器引脚上冒充负载电容否则起振都起不来。3.2 CD4013 二分频与秒闸门的对应关系Q14 输出 2Hz接到 CD4013 的一个触发器上把 Q 非接回 D 端就构成二分频得到 1Hz 方波——周期 1s高电平持续 0.5s。要让高电平持续 1 秒作为闸门还得再级联一级分频到 0.5Hz周期 2s或者干脆在软件里把 0.5s 闸门的计数值乘 2。这里有个必须捋清的账闸门宽度决定读数的换算系数。1s 闸门时 f N0.5s 闸门时 f 2N。硬件秒脉冲和软件闸门必须配套不能一个给 0.5s、另一个按 1s 去算。源码里 T1 定时器用 50ms 溢出二十次凑出 1s等于把闸门定义完全交给了软件硬件那边只提供稳定参考这种分工在调试阶段反而更好改。3.3 CD4051 通道选择与 P1.6/P1.7 档位读取量程切换靠 CD4051 八选一做模拟开关A、B、C 三位地址线选通道INH 接地使能。原理图里用两位拨码开关接在 P1.6、P1.7 上程序直接把这两位读进来当档位号; 读 P1.6 / P1.7 两位拨码开关组合成 0~3 档位存到 17H CLR C MOV C,P1.6 ; P1 口有内部上拉开关另一端接地即读到 0 MOV 27H.0,C CLR C MOV C,P1.7 MOV 27H.1,C MOV A,27H ANL A,#03H ; 屏蔽未用到的 6 位 MOV 17H,A ; 17H 0/1/2/3供换档和显示使用P1 口内部有上拉电阻拨码开关一端接 P1.6、另一端接 GND闭合读到 0断开靠上拉读到 1不需要外部上拉。CLR C 是为了保证进位位干净避免后面传送时混入杂散值ANL A,#03H 只保留低两位因为 27H 的高六位在复位后没有明确赋值带着它们去做比较会随机跳档。17H 这个单元在后面同时管两件事决定时基档位决定 1602 显示缓冲区的右对齐方式。4. AT89C51定时器/计数器测频TMOD15H配置与移位加倍BCD转换整套程序的核心就两条线T0 负责数被测脉冲T1 负责掐闸门时间。两行寄存器配置写错一个位读数就会差一倍或者干脆不动。4.1 TMOD15H 拆开看0x15 0001 0101B高四位归 T1低四位归 T0位归属值含义TMOD.7GATE10不用 INT1 门控T1 由 TR1 软件启停TMOD.6C/T10定时方式对内部机器周期计数TMOD.5-4M1M001方式 116 位定时器TMOD.3GATE00不用 INT0 门控T0 由 TR0 软件启停TMOD.2C/T01计数方式对 T0P3.4外部脉冲计数TMOD.1-0M1M001方式 116 位计数器文档第 3 节花了不少篇幅讲 GATE1 时用 INT0 电平控制定时器启停的门控原理但源码里 GATE 填的是 0实际用 TR0 软件开关闸门。两种做法都对区别在于硬件门控能让闸门和被测信号边沿严格同步减少 ±1 计数误差软件门控省一根线代价是闸门起停和信号异步量化误差就出在这里。4.2 50ms×20 的一秒闸门12MHz 晶振下机器周期是 1usT1 方式 1 装 65536-50000溢出周期正好 50ms累计 20 次就是 1sMAIN: MOV TMOD,#15H ; T1 方式1定时T0 方式1计数 MOV TH1,#HIGH(65536-50000) MOV TL1,#LOW(65536-50000) ; 50ms 12MHz MOV TH0,#00H MOV TL0,#00H MOV R3,#00H ; 闸门计数单元 SETB TR0 ; 开被测脉冲计数 SETB TR1 ; 开 50ms 定时 WAIT: JBC TF1,RELOAD ; 查询溢出并清标志 JMP WAIT RELOAD: MOV TH1,#HIGH(65536-50000) MOV TL1,#LOW(65536-50000) ; 重装初值 INC R3 MOV A,R3 CJNE A,#20,WAIT ; 未满 1s 继续 CLR TR0 ; 关闸门停止计数 CLR TR1 MOV R2,TH0 ; 高字节 MOV R6,TL0 ; 低字节 MOV TL0,#00H MOV TH0,#00H ; 清零准备下一轮 LCALL ZHUAN LCALL WRITE1 JMP MAIN查询方式写法简单代价是溢出标志被检测到之前有几十个机器周期的延迟二十次累积下来误差在几十微秒量级对 1s 闸门是 0.00x%可以忽略。要再准一点就在 001BH 中断入口里重装初值ORG 001BH LJMP IT1 IT1: MOV TH1,#HIGH(65536-50000) ; 中断里立即重装补偿响应延迟 MOV TL1,#LOW(65536-50000) INC R3 RETI中断重装的确定性更好但要注意中断服务程序本身耗时也会进入累计误差所以里面不要放显示这类慢操作。另外 10kHz、1s 闸门下计数值最多 1000016 位计数器不会溢出不用担心 TF0。4.3 ZHUAN 子程序的移位加倍BCD算法TH0:TL0 里是二进制计数值1602 要的是十进制。ZHUAN 用的是一套移位加倍算法本质是把二进制数从高位开始逐位送进十进制累加器; 入口: R2高字节(TH0)R6低字节(TL0) ; 出口: 30H~35H 六位十进制30H 为最高位 ZHUAN: MOV A,R2 CLR C MOV 20H,#00H MOV 21H,#00H MOV 22H,#00H ; 3 字节 BCD 累加器初值 0 MOV R3,#10H ; 16 次循环 NEXT: RLC A ; 最高位移入 C MOV R2,A MOV A,20H ADDC A,20H ; 自身加自身再加 C等价于 ×2 移出位 DA A ; 十进制调整只对 A 生效 MOV 20H,A MOV A,21H ADDC A,21H DA A MOV 21H,A MOV A,22H ADDC A,22H DA A MOV 22H,A MOV A,R2 DJNZ R3,NEXT ; TL0 部分同样处理 8 次结果并入 24H、25H最后两段相加关键在 DA A 只对累加器做十进制调整所以三个字节必须逐个 ADDC 后紧跟 DA不能只调一次。另外 16 次循环不是白给的R2 只有 8 位8 次左移后 A 里全是 0后面 8 次循环继续做 ×2等于把 TH0 的权重放大到 256 倍正好对上它在 16 位计数值里的位置。低字节做 8 次循环得到的就是它本身两段相加才是完整的计数值。拆位时用 ANL A,#0F0H 加 SWAP A 取高半字节ANL A,#0FH 取低半字节依次填进 30H 到 35H。这里要特别小心顺序30H 是最高位、45H 是最低位填反了读数会整体倒过来。4.4 1602 显示缓冲与前导零消隐初始化序列固定四步0x38 设 8 位总线两行显示0x0C 开显示关光标0x06 写入后地址自动加一0x01 清屏。清屏指令执行时间长连续发三次再进主循环是源码里防止上电时序不够的土办法。ENABLE: CLR RS ; RS0 写指令寄存器 CLR RW ; RW0 写模式 CLR E ACALL DELAY ; 保证建立时间 SETB E ; 产生上升沿 RET源码里 E 拉高后没有主动拉低靠下一次调用开头的 CLR E 补下降沿。1602 是在 E 下降沿锁存数据的这样写能跑但时序余量很小换一块响应慢的屏就容易出乱码。稳妥写法是在 SETB E 之后加几个 NOP 再 CLR E。如果不想等固定延时也可以读忙标志 BFRS0、RW1BF 为 1 表示内部操作未完成此时不能写指令。换档逻辑在 WRITE1 里体现为显示缓冲区的右对齐规则按 17H 的值决定前几位是否填 00H17H 档位40H—45H 前导位填 00H 的数量有效数字位数0306 位0233 位0124 位0015 位显示循环从 40H 开始逐个取数遇到 00H 就跳过直到碰到第一个非零数字才把标志位 10H 置 0FFH之后即使数字是 0 也照常显示——这就是前导零消隐的标准实现少了标志位读数中间和末尾的 0 都会被吃掉。5. 测频与测周法的误差边界、切换点和实物排错量化误差 ±1 是数字测量的天花板没有哪种方法能绕过它只能靠换方法把它压到整个频段都看不见。5.1 两条误差曲线在哪里相交测频法的相对误差是 δ 1/(f·T)闸门 T1s 时10kHz 只有 0.01%1Hz 却高达 100%。测周法是 f 1/(N·T0)误差 δ T0·f时基 T01ms、被测 1Hz 时误差 0.1%可到了 1kHz 就变成 100%彻底不能用了。两条曲线在 1/(fT) T0·f 处相交解得 f 1/√(T·T0)。T1s、T01ms 时交点约 31.6Hz。工程上不会贴着交点切换而是在误差都够小的重叠区换档于是四档时基正好落在四段测量方法标准时基适用频率计数值±1 误差测频法T 1s1kHz—10kHz1000—100000.1%—0.01%测周法T0 1us1kHz 附近约 1000约 0.1%测周法T0 10us100Hz 附近约 1000约 0.1%测周法T0 100us10Hz 附近约 1000约 0.1%测周法T0 1ms1Hz 附近约 1000约 0.1%这份映射恰好把 1us、10us、100us、1ms 四个时基宽度全用上了也让 1Hz 到 10kHz 全频段误差压在 0.1% 上下。设计时基档位时只要保证每档的计数值落在 1000 到 10000 之间精度就有保障。5.2 上电不显示、读数跳变的排查顺序现象常见原因排查动作上电只显示一排方块初始化未完成或对比度电压不对确认 0x38 前延时足够调 VEE 电压到 VDD-4.5V 附近低频读数恒为 0施密特阈值太高小信号没整形出方波示波器看比较器输出必要时加大放大级增益读数总是实际值的一半闸门宽度和换算系数不匹配核对是 1s 还是 0.5s 闸门软件有没有乘 2高频读数偏大且随显示抖动整形输出有毛刺或闸门与被测信号异步增大迟滞窗口或改用 INT0 硬件门控拨档位开关无反应P1.6/P1.7 接地端虚焊万用表测引脚对地通断确认读到 0LCD 偶发乱码E 脉冲宽度不足或没等忙标志SETB E 后加 NOP 再拉低或改查 BF排查顺序建议从模拟端往前推先确认比较器输出是干净方波再确认 T0 引脚上确实有脉冲跳变最后才动程序。反着查很容易在完全正常的代码里改来改去。5.3 多周期同步等精度测量怎么改固定闸门的所有麻烦都来自闸门和被测信号不同步多周期同步法就是让闸门由被测信号自己开关// 等精度思路预置闸门 被测信号同步启停 uint16_t nx, ns; uint16_t Tpr 20000; // 预置闸门单位是标准时钟周期 while (1) { while (PIN_FX 0); // 等被测信号上升沿 TR0 1; TR1 1; // 两个计数器同时开 while (ns Tpr); // 标准时钟先计满预置闸门 while (PIN_FX 1); // 再等一个上升沿同步关闸门 while (PIN_FX 0); TR0 0; TR1 0; fx (uint32_t)nx * F0 / ns; // 实际闸门 ns 个标准时钟周期 nx 0; ns 0; }实际闸门时间不再是固定的 1s而是被测信号的整数个周期误差只剩 ±1/ns跟被测频率高低无关全频段误差一致。代价是 51 上只有两个定时器标准时钟侧得靠 T1 溢出中断累加得到 ns分辨率取溢出周期或者干脆用一片 CD4520 之类的计数器在片外数标准时钟单片机只负责读。实物验证时把两路计数器的启停脚接示波器双通道对齐看一眼JBC/JNB 的等待顺序有没有把边沿吃掉比盯着 LCD 上跳动的数字猜要快得多。本文还有配套的精品资源点击获取