用C语言写一个51单片机定时器秒表,要求使用两位数码管动态显示计时值,还要求复位键有效时,计时器清零后不能再计时,还要求复位键无效下,使能键有效开始计时,无效时暂停计时

时间: 2023-05-19 11:01:52 浏览: 56
非常感谢您的问题!以下是一个简单的C语言程序,可以实现您所需的功能: ``` #include <reg51.h> #define DISPLAY_PORT P0 // 数码管控制端口 #define RESET_BUTTON P1_0 // 复位键 #define ENABLE_BUTTON P1_1 // 使能键 unsigned char code DIGITS[] = { // 数码管显示表 0xC0, // 0 0xF9, // 1 0xA4, // 2 0xB0, // 3 0x99, // 4 0x92, // 5 0x82, // 6 0xF8, // 7 0x80, // 8 0x90 // 9 }; void delay(unsigned int ms) { // 延时函数 unsigned int i, j; for (i = 0; i < ms; i++) { for (j = 0; j < 125; j++); } } void display(unsigned char value) { // 数码管显示函数 unsigned char digit1, digit2; digit1 = value / 10; digit2 = value % 10; DISPLAY_PORT = DIGITS[digit1]; delay(5); DISPLAY_PORT = DIGITS[digit2]; delay(5); } void main() { unsigned char seconds = 0; // 秒数 bit reset_pressed = 0; // 复位键是否按下 bit enable_pressed = 0; // 使能键是否按下 while (1) { if (RESET_BUTTON == 0) { // 复位键按下 reset_pressed = 1; enable_pressed = 0; seconds = 0; display(seconds); while (RESET_BUTTON == 0); // 等待复位键释放 } else if (ENABLE_BUTTON == 0 && !reset_pressed) { // 使能键按下且复位键未按下 enable_pressed = !enable_pressed; while (ENABLE_BUTTON == 0); // 等待使能键释放 } if (enable_pressed) { // 计时器计时 seconds++; if (seconds >= 100) seconds = 0; display(seconds); } } } ``` 这个程序使用了一个循环来不断检测复位键和使能键的状态,根据状态来控制计时器的行为。当复位键按下时,计时器清零并停止计时;当使能键按下时,计时器开始计时并动态显示计时值。

相关推荐

可以使用C语言编写以下代码实现秒表计时器的设计: #include <reg51.h> #define uchar unsigned char #define uint unsigned int sbit en=P2^0; // 使能键 sbit rst=P2^1; // 复位键 sbit dula=P2^6; // 两位数码管段选1 sbit wela=P2^7; // 两位数码管段选2 uchar code table[]={ 0x3f, // 0 0x06, // 1 0x5b, // 2 0x4f, // 3 0x66, // 4 0x6d, // 5 0x7d, // 6 0x07, // 7 0x7f, // 8 0x6f // 9 }; // 数码管显示表 uint cnt=0; // 计数器 bit flag=0; // 标志位,表示计时器是否在计时 void delay(uint x) // 延时函数,x为延时时间 { uint i,j; for(i=x; i>0; i--) for(j=110; j>0; j--); } void display(uchar num) // 数码管显示函数,num为要显示的数字 { wela=1; // 打开第二位数码管的段选 P0=table[num/10]; // 显示十位 wela=0; dula=1; // 打开第一位数码管的段选 P0=table[num%10]; // 显示个位 dula=0; } void Timer0() interrupt 1 // 定时器0中断服务函数 { TH0=(65536-50000)/256; // 定时器0初值 TL0=(65536-50000)%256; cnt++; // 计数器加1 if(cnt==20) // 如果计数器达到20,表示1秒钟已经过去 { cnt=0; // 计数器清零 flag=1; // 标志位置1,表示计时器可以加一秒钟 } } void main() { TMOD=0x01; // 定时器0工作方式为模式1 TH0=(65536-50000)/256; // 定时器0初值 TL0=(65536-50000)%256; EA=1; // 打开总中断 ET0=1; // 打开定时器0中断 TR0=1; // 启动定时器0 while(1) { if(rst==0) // 复位键有效 { cnt=0; // 计数器清零 flag=0; // 标志位清零,表示计时器不能计时 display(cnt); // 数码管显示0 } if(en==0) // 使能键有效 { if(flag) // 标志位为1,表示计时器可以加一秒钟 { flag=0; // 标志位清零 cnt++; // 计数器加1 if(cnt>=60) // 如果计数器达到60,表示一分钟已经过去 cnt=0; // 计数器回到0,重新开始计时 display(cnt); // 数码管显示计时结果 delay(5); // 延时5毫秒,避免数码管显示闪烁 } } else // 使能键无效 flag=0; // 标志位清零,表示计时器不能计时 } } 在51单片机实验板上外接晶振频率为12MHz,使用单片机定时/计数器的工作方式1产生周期为50ms的方波,由此产生秒表计时器的1秒时钟信号,实现了秒表计时器在0~59秒范围内循环计时,每次增加1秒,当复位键有效时该计时器清零后停止计时,在复位键无效的前提下,当使能键有效时该计时器开始计时,当使能键无效时该计时器暂停计时,使用两位数码管动态显示计时值。
下面是C语言编程实现秒表计时器的设计: c #include <reg51.h> sbit SWITCH_EN = P3^0; // 使能键,低电平有效 sbit SWITCH_RST = P3^1; // 复位键,低电平有效 sbit LED_D1 = P2^4; // 数码管D1,低电平亮 sbit LED_D2 = P2^5; // 数码管D2,低电平亮 sbit LED_COM = P2^6; // 数码管公共端,高电平亮 unsigned char count = 0; // 计时器计数值,0-59 unsigned char second = 0; // 秒表计时器秒数,0-59 bit enable_flag = 0; // 使能标志位,1-启用计时器,0-暂停计时器 void delay_ms(unsigned int); // 延时函数 void display(unsigned char); // 数码管显示函数 void timer_init(); // 定时器初始化函数 void timer_interrupt() // 定时器中断服务函数 void main() { timer_init(); // 定时器初始化 while (1) { if (!SWITCH_RST) { // 复位键有效,清零计数器,停止计时 count = 0; enable_flag = 0; } else if (SWITCH_EN) { // 使能键有效,启用计时器 enable_flag = 1; } else { // 使能键无效,暂停计时器 enable_flag = 0; } if (count == 0) { // 计数值为0时,秒数+1 second++; if (second >= 60) second = 0; // 秒数循环计数 } display(second); // 显示秒数值 } } void delay_ms(unsigned int n) { unsigned int i, j; for (i = 0; i < n; i++) for (j = 0; j < 125; j++); } void display(unsigned char n) { unsigned char a, b; a = n / 10; // 十位数码管显示值 b = n % 10; // 个位数码管显示值 LED_COM = 1; // 点亮数码管公共端 LED_D1 = 1; // 点亮数码管D1 LED_D2 = 0; P0 = a; // 显示十位数码管值 delay_ms(2); // 延时2ms,进行动态扫描 LED_COM = 1; // 点亮数码管公共端 LED_D1 = 0; LED_D2 = 1; // 点亮数码管D2 P0 = b; // 显示个位数码管值 delay_ms(2); // 延时2ms,进行动态扫描 } void timer_init() { TMOD &= 0xF0; // 将定时器/计数器的控制模式寄存器低4位清0 TMOD |= 0x01; // 定时器模式1,16位自动重载计数器 TH0 = (65536 - 50000) >> 8; // 定时器初值,1秒钟(50ms*20) TL0 = (65536 - 50000) & 0xFF; TR0 = 1; // 启动定时器/计数器0 ET0 = 1; // 允许T0中断 EA = 1; // 打开总中断开关 } void timer_interrupt() interrupt 1 using 1 { TH0 = (65536 - 50000) >> 8; // 定时器1秒钟(50ms*20)自动重载初值 TL0 = (65536 - 50000) & 0xFF; if (enable_flag) { // 使能标志位为1,则计数器计数 count++; if (count >= 60) count = 0; // 计数值循环计数 } } 其中,delay_ms()函数为延时函数,用于动态扫描数码管时进行延时;display()函数为数码管显示函数,用于动态显示秒表计时器的值;timer_init()为定时器初始化函数,用于初始化定时器/计数器和中断服务函数,并开启总中断;timer_interrupt()为定时器中断服务函数,用于计数器计数、秒数累加等操作。注意:二位数码管的输出需要使用138译码器进行驱动,本文没有涉及到具体的连线方法。
以下是一个简单的C51单片机秒表程序: #include<reg52.h> #include<intrins.h> sbit k1=P3^1; sbit k2=P3^0; sbit k3=P3^2; unsigned char xdata disp[6]={0,0,0,0,0,0}; //定义计时器每位的值 unsigned char xdata time_count=0; //定义计时器中断次数 bit flag=0; //定义计时器开关 void delay(unsigned int i) //延时函数 { unsigned int j,k; for(j=i;j>0;j--) for(k=110;k>0;k--); } void init() //初始化函数 { TMOD=0x01; //设置定时器0为模式1 TH0=(65536-50000)/256; //设置定时器初值 TL0=(65536-50000)%256; TR0=1; //开启定时器0 ET0=1; //开启定时器0中断 EA=1; //开启总中断 } void main() { init(); while(1) { if(k1==0) //开始计时 { flag=1; delay(10); //消抖 if(k1==0) //再次判断按键是否按下 { flag=1; time_count=0; } } else if(k2==0) //停止计时 { flag=0; delay(10); if(k2==0) { flag=0; time_count=0; } } else if(k3==0) //复位计时 { flag=0; delay(10); if(k3==0) { flag=0; time_count=0; disp[0]=0; disp[1]=0; disp[2]=0; disp[3]=0; disp[4]=0; disp[5]=0; } } } } void timer0() interrupt 1 //定时器0中断服务函数 { TH0=(65536-50000)/256; //重新赋初值 TL0=(65536-50000)%256; time_count++; if(time_count==20) //20次中断为1秒 { time_count=0; if(flag==1) //判断计时器是否开启 { disp[5]++; if(disp[5]==10) { disp[5]=0; disp[4]++; if(disp[4]==10) { disp[4]=0; disp[3]++; if(disp[3]==6) { disp[3]=0; disp[2]++; if(disp[2]==10) { disp[2]=0; disp[1]++; if(disp[1]==6) { disp[1]=0; disp[0]++; if(disp[0]==10) { disp[0]=0; } } } } } } } } } 以上程序通过定时器0中断实现秒表计时,具体步骤如下: 1. 定义一个长度为6的数组disp,用于存储计时器每位的值,其中disp[0]为秒表的个位数,disp[1]为十位数,依次类推。 2. 定义一个计时器中断次数time_count,每次定时器中断后,time_count加1,当time_count等于20时,说明已经过去了1秒,将time_count清零。 3. 通过按键控制秒表的计时、停止和复位操作,其中按下k1键开始计时,按下k2键停止计时,按下k3键复位计时器。 4. 在定时器0中断服务函数中,判断计时器是否开启,如果开启,则每次中断将秒表的值加1,同时判断进位和显示。 最后,将程序下载到单片机上,连接按键和数码管,即可实现秒表计时功能。
以下是一个基于STC89C52单片机的秒表计时器的C语言代码: c #include <reg52.h> unsigned char code table[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f}; // 数码管显示0~9的编码 sbit KEY1 = P3^0; // 开始/停止键 sbit KEY2 = P3^1; // 复位键 unsigned char second = 0; // 秒数 unsigned char minute = 0; // 分钟数 unsigned char hour = 0; // 小时数 void delay(unsigned int t) // 延时函数 { unsigned int i, j; for (i = t; i > 0; i--) for (j = 110; j > 0; j--); } void display(unsigned char num, unsigned char position) // 数码管显示函数 { unsigned char i, j; for (i = 0; i < position; i++) { P0 = 0; P2 = ~(1 << i); delay(1); } P0 = table[num % 10]; P2 = ~(1 << i); delay(1); i++; for (j = 0; j < position; j++) { P0 = 0; P2 = ~(1 << i); delay(1); } P0 = table[num / 10]; P2 = ~(1 << i); delay(1); } void main() { TMOD = 0x01; // 定时器T0工作在模式1 TH0 = 0xFC; // 定时器初值 TL0 = 0x18; TR0 = 1; // 启动定时器T0 ET0 = 1; // 允许定时器T0中断 EA = 1; // 允许总中断 while (1) { if (!KEY1) // 开始/停止键按下 { delay(10); // 延时去抖动 if (!KEY1) // 确认按键按下 { TR0 = !TR0; // 启动/停止定时器T0 while (!KEY1); // 等待按键松开 } } if (!KEY2) // 复位键按下 { delay(10); // 延时去抖动 if (!KEY2) // 确认按键按下 { TR0 = 0; // 停止定时器T0 second = 0; // 清零计时器 minute = 0; hour = 0; display(second, 3); // 显示清零后的秒数 display(minute, 2); // 显示清零后的分钟数 display(hour, 1); // 显示清零后的小时数 TR0 = 1; // 启动定时器T0 while (!KEY2); // 等待按键松开 } } } } void timer0() interrupt 1 // 定时器T0中断服务程序 { static unsigned int cnt = 0; TH0 = 0xFC; // 重新赋初值 TL0 = 0x18; cnt++; // 计数器加1 if (cnt == 1000) // 1秒钟过去了 { cnt = 0; // 计数器清零 second++; // 秒数加1 if (second == 60) // 1分钟过去了 { second = 0; // 秒数清零 minute++; // 分钟数加1 if (minute == 60) // 1小时过去了 { minute = 0; // 分钟数清零 hour++; // 小时数加1 if (hour == 24) // 1天过去了 { hour = 0; // 小时数清零 } } } display(second, 3); // 显示秒数 display(minute, 2); // 显示分钟数 display(hour, 1); // 显示小时数 } } 该代码使用定时器T0来计时,每隔1秒钟产生一次中断,计时器加1,然后将计时器的值显示在三个数码管上。按下开始/停止键可以启动/停止计时器,按下复位键可以将计时器清零。

最新推荐

微信小程序源码企业展示

微信小程序源码企业展示本资源系百度网盘分享地址

Unity Webgl使用GET/POST获取服务器数据,对JSON数据进行解析

Unity Webgl使用GET/POST获取服务器数据,对JSON数据进行解析

Combination.java

Combination.java

异步通知-MX6U嵌入式linux驱动开发学习笔记基于正点原子阿尔法开发板

异步通知-MX6U嵌入式linux驱动开发学习笔记基于正点原子阿尔法开发板

vue面试题汇总 ,包含答案

vue面试题汇总,包含答案

市建设规划局gis基础地理信息系统可行性研究报告.doc

市建设规划局gis基础地理信息系统可行性研究报告.doc

"REGISTOR:SSD内部非结构化数据处理平台"

REGISTOR:SSD存储裴舒怡,杨静,杨青,罗德岛大学,深圳市大普微电子有限公司。公司本文介绍了一个用于在存储器内部进行规则表达的平台REGISTOR。Registor的主要思想是在存储大型数据集的存储中加速正则表达式(regex)搜索,消除I/O瓶颈问题。在闪存SSD内部设计并增强了一个用于regex搜索的特殊硬件引擎,该引擎在从NAND闪存到主机的数据传输期间动态处理数据为了使regex搜索的速度与现代SSD的内部总线速度相匹配,在Registor硬件中设计了一种深度流水线结构,该结构由文件语义提取器、匹配候选查找器、regex匹配单元(REMU)和结果组织器组成。此外,流水线的每个阶段使得可能使用最大等位性。为了使Registor易于被高级应用程序使用,我们在Linux中开发了一组API和库,允许Registor通过有效地将单独的数据块重组为文件来处理SSD中的文件Registor的工作原

要将Preference控件设置为不可用并变灰java完整代码

以下是将Preference控件设置为不可用并变灰的Java完整代码示例: ```java Preference preference = findPreference("preference_key"); // 获取Preference对象 preference.setEnabled(false); // 设置为不可用 preference.setSelectable(false); // 设置为不可选 preference.setSummary("已禁用"); // 设置摘要信息,提示用户该选项已被禁用 preference.setIcon(R.drawable.disabled_ico

基于改进蚁群算法的离散制造车间物料配送路径优化.pptx

基于改进蚁群算法的离散制造车间物料配送路径优化.pptx

海量3D模型的自适应传输

为了获得的目的图卢兹大学博士学位发布人:图卢兹国立理工学院(图卢兹INP)学科或专业:计算机与电信提交人和支持人:M. 托马斯·福吉奥尼2019年11月29日星期五标题:海量3D模型的自适应传输博士学校:图卢兹数学、计算机科学、电信(MITT)研究单位:图卢兹计算机科学研究所(IRIT)论文主任:M. 文森特·查维拉特M.阿克塞尔·卡里尔报告员:M. GWendal Simon,大西洋IMTSIDONIE CHRISTOPHE女士,国家地理研究所评审团成员:M. MAARTEN WIJNANTS,哈塞尔大学,校长M. AXEL CARLIER,图卢兹INP,成员M. GILLES GESQUIERE,里昂第二大学,成员Géraldine Morin女士,图卢兹INP,成员M. VINCENT CHARVILLAT,图卢兹INP,成员M. Wei Tsang Ooi,新加坡国立大学,研究员基于HTTP的动态自适应3D流媒体2019年11月29日星期五,图卢兹INP授予图卢兹大学博士学位,由ThomasForgione发表并答辩Gilles Gesquière�