news 2026/6/11 21:46:29

数码管T0计数器设计(基于51单片机)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
数码管T0计数器设计(基于51单片机)

基于51单片机的T0计数器系统设计,使用定时器0作为计数器对外部脉冲进行计数,并通过数码管显示计数值。

一、系统设计

1.1 功能要求

  • T0作为计数器,对P3.4(T0)引脚的外部脉冲计数
  • 4位共阳数码管显示计数值(0-9999)
  • 支持加计数和减计数两种模式
  • 按键控制:清零、模式切换、暂停/继续
  • 计数溢出处理(0-9999循环)
  • 计数频率可达50kHz

1.2 硬件资源

资源型号/规格数量
单片机STC89C52/AT89C521
数码管4位共阳数码管1
按键轻触开关3
电阻220Ω(限流)8
电阻10kΩ(上拉)3
晶振11.0592MHz1
脉冲源按键/信号发生器1

二、硬件设计

2.1 电路原理图

+5V | +-+ 数码管显示 | 段选:P0.0-P0.7 (经220Ω电阻) | 位选:P2.0-P2.3 (经220Ω电阻) | +-+ 按键控制 | K1(清零) -> P3.0 -> GND | K2(模式) -> P3.1 -> GND | K3(暂停) -> P3.2 -> GND | (各接10kΩ上拉电阻到+5V) | +-+ 计数输入 | P3.4(T0) <- 外部脉冲输入 | +-+ 单片机最小系统 XTAL1/XTAL2 -> 11.0592MHz晶振 RST -> 10kΩ电阻+10μF电容 EA -> +5V VCC -> +5V GND -> GND

2.2 引脚分配表

单片机引脚连接设备功能说明
P0.0-P0.7数码管段选a,b,c,d,e,f,g,dp
P2.0-P2.3数码管位选千位、百位、十位、个位
P3.0按键K1清零
P3.1按键K2模式切换
P3.2按键K3暂停/继续
P3.4外部脉冲T0计数输入
P1.0LED指示计数状态指示

三、软件设计

3.1 主程序 (main.c)

#include<reg52.h>#include"display.h"#include"keyboard.h"#include"timer0_counter.h"// 全局变量unsignedintcount_value=0;// 当前计数值unsignedintmax_count=9999;// 最大计数值unsignedintmin_count=0;// 最小计数值bit count_mode=0;// 0:加计数 1:减计数bit count_enable=1;// 计数使能bit overflow_flag=0;// 溢出标志voidmain(void){System_Init();while(1){Key_Process();// 按键处理Display_Update();// 显示更新Count_Check();// 计数范围检查}}voidSystem_Init(void){// 初始化定时器0为计数器模式Timer0_Counter_Init();// 初始化数码管Display_Init();// 显示初始值Display_Number(count_value);// 开启总中断EA=1;// 启动计数TR0=1;}voidKey_Process(void){unsignedcharkey=Key_Scan();switch(key){caseKEY_CLEAR:// 清零count_value=0;Display_Number(count_value);break;caseKEY_MODE:// 切换模式count_mode=!count_mode;if(count_mode)Display_Show_Mode("DEC");// 显示减计数模式elseDisplay_Show_Mode("INC");// 显示加计数模式break;caseKEY_PAUSE:// 暂停/继续count_enable=!count_enable;if(count_enable){TR0=1;// 继续计数P1_0=0;// LED亮表示计数中}else{TR0=0;// 暂停计数P1_0=1;// LED灭表示暂停}break;default:break;}}voidCount_Check(void){// 检查溢出if(overflow_flag){overflow_flag=0;if(count_mode==0)// 加计数溢出{count_value=min_count;// 回到最小值}else// 减计数溢出{count_value=max_count;// 回到最大值}Display_Number(count_value);}// 检查是否达到极限if(count_value>=max_count&&count_mode==0){count_enable=0;// 禁止计数TR0=0;P1_0=1;// LED灭}if(count_value<=min_count&&count_mode==1){count_enable=0;// 禁止计数TR0=0;P1_0=1;// LED灭}}// 定时器0中断服务程序(计数器溢出中断)voidTimer0_ISR(void)interrupt1{overflow_flag=1;// 设置溢出标志// 根据计数模式更新计数值if(count_mode==0)// 加计数{count_value++;if(count_value>max_count)count_value=min_count;// 循环}else// 减计数{count_value--;if(count_value<min_count)count_value=max_count;// 循环}Display_Number(count_value);}

3.2 定时器0计数器 (timer0_counter.h)

#ifndef__TIMER0_COUNTER_H__#define__TIMER0_COUNTER_H__#include<reg52.h>// 函数声明voidTimer0_Counter_Init(void);voidTimer0_Start(void);voidTimer0_Stop(void);voidTimer0_Set_Value(unsignedintvalue);unsignedintTimer0_Get_Value(void);#endif

3.3 定时器0计数器 (timer0_counter.c)

#include"timer0_counter.h"voidTimer0_Counter_Init(void){// 设置T0为计数器模式,工作方式1(16位计数)TMOD&=0xF0;// 清除T0控制位TMOD|=0x05;// 0000 0101: T0为计数器,方式1(16位)// 设置计数初值(0)TH0=0x00;TL0=0x00;// 允许T0中断ET0=1;// 启动T0(由TR0控制)TR0=0;// 先不启动}voidTimer0_Start(void){TR0=1;// 启动计数器}voidTimer0_Stop(void){TR0=0;// 停止计数器}voidTimer0_Set_Value(unsignedintvalue){TH0=value>>8;// 高8位TL0=value&0xFF;// 低8位}unsignedintTimer0_Get_Value(void){unsignedintvalue;value=(TH0<<8)|TL0;returnvalue;}

3.4 数码管显示 (display.h)

#ifndef__DISPLAY_H__#define__DISPLAY_H__#include<reg52.h>// 数码管段码定义(共阳)#defineSEG_A0x01#defineSEG_B0x02#defineSEG_C0x04#defineSEG_D0x08#defineSEG_E0x10#defineSEG_F0x20#defineSEG_G0x40#defineSEG_DP0x80// 数字0-9段码表externunsignedcharcode SegCode[10];// 位选定义#defineDIGIT_1P2_0// 千位#defineDIGIT_2P2_1// 百位#defineDIGIT_3P2_2// 十位#defineDIGIT_4P2_3// 个位// 函数声明voidDisplay_Init(void);voidDisplay_Number(unsignedintnum);voidDisplay_Scan(unsignedcharpos);voidDisplay_Clear(void);voidDisplay_Show_Mode(char*mode);// 显示缓冲区externunsignedcharDisplay_Buffer[4];#endif

3.5 数码管显示 (display.c)

#include"display.h"// 共阳数码管段码表(0-9)unsignedcharcode SegCode[10]={0xC0,// 0: 1100 00000xF9,// 1: 1111 10010xA4,// 2: 1010 01000xB0,// 3: 1011 00000x99,// 4: 1001 10010x92,// 5: 1001 00100x82,// 6: 1000 00100xF8,// 7: 1111 10000x80,// 8: 1000 00000x90// 9: 1001 0000};// 字母段码表unsignedcharcode LetterCode[26]={0x88,// A0x83,// b0xC6,// C0xA1,// d0x86,// E0x8E,// F0xC2,// G0x89,// H0xF9,// I0xF1,// J0xC7,// L0xC8,// M0xC1,// n0xC0,// O0x8C,// P0x98,// q0x92,// r0x87,// S0x83,// t0xC1,// u0x91,// v0xD1,// w0x89,// X0x49,// y0x90// Z};unsignedcharDisplay_Buffer[4]={0xC0,0xC0,0xC0,0xC0};voidDisplay_Init(void){P0=0xFF;// 段选全灭P2=0x0F;// 位选全灭}voidDisplay_Number(unsignedintnum){// 分解各位数字unsignedcharthousand,hundred,ten,unit;thousand=num/1000;hundred=(num%1000)/100;ten=(num%100)/10;unit=num%10;// 存储显示缓冲区Display_Buffer[0]=SegCode[thousand];Display_Buffer[1]=SegCode[hundred];Display_Buffer[2]=SegCode[ten];Display_Buffer[3]=SegCode[unit];}voidDisplay_Scan(unsignedcharpos){// 关闭所有位选P2=0x0F;// 送段码switch(pos){case0:// 千位DIGIT_1=0;// 选中千位P0=Display_Buffer[0];break;case1:// 百位DIGIT_2=0;// 选中百位P0=Display_Buffer[1];break;case2:// 十位DIGIT_3=0;// 选中十位P0=Display_Buffer[2];break;case3:// 个位DIGIT_4=0;// 选中个位P0=Display_Buffer[3];break;}}voidDisplay_Clear(void){P0=0xFF;// 段选全灭P2=0x0F;// 位选全灭}voidDisplay_Show_Mode(char*mode){// 显示模式标识if(mode[0]=='I')// INC{Display_Buffer[0]=LetterCode['I'-'A'];Display_Buffer[1]=LetterCode['N'-'A'];Display_Buffer[2]=LetterCode['C'-'A'];Display_Buffer[3]=0xFF;// 熄灭}elseif(mode[0]=='D')// DEC{Display_Buffer[0]=LetterCode['D'-'A'];Display_Buffer[1]=LetterCode['E'-'A'];Display_Buffer[2]=LetterCode['C'-'A'];Display_Buffer[3]=0xFF;// 熄灭}}

3.6 键盘扫描 (keyboard.h)

#ifndef__KEYBOARD_H__#define__KEYBOARD_H__#include<reg52.h>// 按键定义#defineKEY_CLEAR0x01#defineKEY_MODE0x02#defineKEY_PAUSE0x03#defineKEY_NONE0xFF// 按键端口定义sbit KEY_CLR_PIN=P3^0;sbit KEY_MOD_PIN=P3^1;sbit KEY_PAU_PIN=P3^2;// 函数声明voidKey_Init(void);unsignedcharKey_Scan(void);#endif

3.7 键盘扫描 (keyboard.c)

#include"keyboard.h"#include"delay.h"voidKey_Init(void){// 按键端口初始化}unsignedcharKey_Scan(void){// 检测清零键if(KEY_CLR_PIN==0){Delay_Ms(10);// 消抖if(KEY_CLR_PIN==0){while(KEY_CLR_PIN==0);// 等待按键释放returnKEY_CLEAR;}}// 检测模式键if(KEY_MOD_PIN==0){Delay_Ms(10);if(KEY_MOD_PIN==0){while(KEY_MOD_PIN==0);returnKEY_MODE;}}// 检测暂停键if(KEY_PAU_PIN==0){Delay_Ms(10);if(KEY_PAU_PIN==0){while(KEY_PAU_PIN==0);returnKEY_PAUSE;}}returnKEY_NONE;}

3.8 延时函数 (delay.h)

#ifndef__DELAY_H__#define__DELAY_H__#include<reg52.h>// 函数声明voidDelay_Ms(unsignedintms);voidDelay_Us(unsignedintus);#endif

3.9 延时函数 (delay.c)

#include"delay.h"// 毫秒延时voidDelay_Ms(unsignedintms){unsignedinti,j;for(i=ms;i>0;i--)for(j=110;j>0;j--);}// 微秒延时voidDelay_Us(unsignedintus){while(us--){_nop_();_nop_();_nop_();_nop_();}}

四、Proteus仿真电路

4.1 Proteus元件清单

1. AT89C52 (单片机) 2. 7SEG-MPX4-CA (4位共阳数码管) 3. BUTTON (按键×3) 4. RES (电阻220Ω×8) 5. RES (电阻10kΩ×3) 6. CRYSTAL (11.0592MHz) 7. CAP (电容30pF×2) 8. POWER (电源) 9. GROUND (地) 10. SIGNAL_GENERATOR (信号发生器,用于产生脉冲)

4.2 仿真连接图

AT89C52: P0.0-P0.7 -> 数码管段选a-g,dp P2.0-P2.3 -> 数码管位选1-4 P3.0 -> 按键K1(清零) P3.1 -> 按键K2(模式) P3.2 -> 按键K3(暂停) P3.4 -> 信号发生器输出(T0计数输入) XTAL1/XTAL2 -> 11.0592MHz晶振 RST -> 10kΩ电阻+10μF电容 VCC -> +5V GND -> GND

五、功能扩展

5.1 增加计数频率测量

// 测量计数频率voidMeasure_Frequency(void){staticunsignedintlast_count=0;staticunsignedlonglast_time=0;unsignedintcurrent_count;unsignedlongcurrent_time;unsignedintfrequency;current_time=Get_System_Time();// 获取系统时间(ms)current_count=Timer0_Get_Value();if(current_time-last_time>=1000)// 每秒测量一次{frequency=current_count-last_count;last_count=current_count;last_time=current_time;// 显示频率Display_Frequency(frequency);}}

5.2 增加计数预置值

// 设置预置值voidSet_Preset_Value(unsignedintpreset){count_value=preset;Timer0_Set_Value(preset);Display_Number(count_value);}

5.3 增加串行通信

// 串口初始化voidUART_Init(void){TMOD&=0x0F;// 清除T1控制位TMOD|=0x20;// 设置T1为模式2(8位自动重载)TH1=0xFD;// 波特率9600TL1=0xFD;TR1=1;// 启动T1SM0=0;// 设置串口为模式1SM1=1;REN=1;// 允许接收EA=1;// 允许总中断ES=1;// 允许串口中断}// 串口中断服务程序voidUART_ISR(void)interrupt4{unsignedcharreceived_data;if(RI)// 接收中断{RI=0;// 清除接收中断标志received_data=SBUF;// 根据接收到的数据设置预置值if(received_data>='0'&&received_data<='9'){unsignedintdigit=received_data-'0';count_value=count_value*10+digit;if(count_value>9999)count_value=9999;Display_Number(count_value);}elseif(received_data=='C'||received_data=='c'){count_value=0;Display_Number(count_value);}}}

参考代码 数码管T0计数器设计www.youwenfan.com/contentcsv/118036.html

六、使用说明

6.1 操作步骤

  1. 接通5V电源
  2. 数码管显示初始值"0000"
  3. 将脉冲源连接到P3.4(T0)引脚
  4. 按"模式"键切换加/减计数模式
  5. 按"暂停"键暂停/继续计数
  6. 按"清零"键将计数值清零

6.2 注意事项

  1. 外部脉冲幅度需在0-5V之间
  2. 脉冲宽度需大于2个机器周期
  3. 最大计数频率不超过50kHz
  4. 计数溢出时会自动循环

6.3 调试技巧

  1. 先用按键模拟脉冲测试基本功能
  2. 再用信号发生器测试高频计数
  3. 观察LED指示灯判断计数状态
  4. 使用示波器观察T0引脚波形

七、性能指标

参数指标
计数范围0-9999
计数模式加计数/减计数
最大计数频率50kHz
显示方式4位静态显示
按键响应<50ms
功耗<50mA @5V
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/11 21:42:53

P89LPC93x1系列MCU的ADC与比较器电气特性深度解析与设计实践

1. 项目概述在嵌入式硬件开发&#xff0c;尤其是涉及传感器信号采集、电池电压监控或阈值检测的应用中&#xff0c;选对微控制器&#xff08;MCU&#xff09;的模拟外设&#xff0c;往往比写好代码更重要。很多项目初期功能跑得通&#xff0c;一到量产或者环境变化就出现测量漂…

作者头像 李华
网站建设 2026/6/11 21:35:26

如何通过Barlow字体家族的54种样式提升数字设计系统的一致性

如何通过Barlow字体家族的54种样式提升数字设计系统的一致性 【免费下载链接】barlow Barlow: a straight-sided sans-serif superfamily 项目地址: https://gitcode.com/gh_mirrors/ba/barlow 在当今多平台数字体验的时代&#xff0c;字体一致性已成为构建品牌识别度的…

作者头像 李华
网站建设 2026/6/11 21:35:25

3分钟解决网页乱码:Chrome-Charset终极编码修复指南

3分钟解决网页乱码&#xff1a;Chrome-Charset终极编码修复指南 【免费下载链接】Chrome-Charset An extension used to modify the page default encoding for Chromium 55 based browsers. 项目地址: https://gitcode.com/gh_mirrors/ch/Chrome-Charset 还在为网页上出…

作者头像 李华
网站建设 2026/6/11 21:35:24

ONNX Runtime 边缘部署:ARM 平台上的模型优化与推理加速全链路

ONNX Runtime 边缘部署&#xff1a;ARM 平台上的模型优化与推理加速全链路一、边缘推理的算力困境&#xff1a;模型跑不动&#xff0c;延迟等不起 在 ARM Cortex-A 系列的边缘 SoC 上部署 AI 模型&#xff0c;面临的核心矛盾是&#xff1a;模型计算需求远超芯片算力。一块典型的…

作者头像 李华
网站建设 2026/6/11 21:34:24

MSC8102 DSP信号引脚深度解析:从内存控制器到GPIO复用与调试接口

1. 项目概述&#xff1a;深入解析MSC8102 DSP的“神经末梢” 在嵌入式系统&#xff0c;尤其是通信基础设施和实时信号处理领域&#xff0c;飞思卡尔&#xff08;现恩智浦&#xff09;的MSC8102四核数字信号处理器&#xff08;DSP&#xff09;曾是一颗璀璨的明星。它集成了四个高…

作者头像 李华
网站建设 2026/6/11 21:34:23

终极文字转手写工具:5分钟让你的电子文档变身个性手写体

终极文字转手写工具&#xff1a;5分钟让你的电子文档变身个性手写体 【免费下载链接】text-to-handwriting So your teacher asked you to upload written assignments? Hate writing assigments? This tool will help you convert your text to handwriting xD 项目地址: …

作者头像 李华