欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 时评 > 单元训练10:定时器实现秒表功能-数组方式

单元训练10:定时器实现秒表功能-数组方式

2024/10/25 12:17:52 来源:https://blog.csdn.net/mouze2000/article/details/141267535  浏览:    关键词:单元训练10:定时器实现秒表功能-数组方式

蓝桥杯 小蜜蜂   单元训练10:定时器实现秒表功能-数组方式

/** @Description:* @Author: fdzhang* @Email: zfdc@qq.com* @Date: 2024-08-15 21:58:53* @LastEditTime: 2024-08-16 19:07:27* @LastEditors: fdzhang*/#include "stc15f2k60s2.h"#define LED(x)                 \{                          \P2 = P2 & 0x1f | 0x80; \P0 = x;                \P2 &= 0x1f;            \}
// y7c 111,0xE0
#define SEG(x)                 \{                          \P0 = x;                \P2 = P2 & 0x1f | 0xE0; \P2 &= 0x1f;            \}
// y6c 110,0xC0
#define COM(x)                 \{                          \P0 = x;                \P2 = P2 & 0x1f | 0xC0; \P2 &= 0x1f;            \}typedef unsigned char uint8_t;uint8_t *setStopWatch(uint8_t min10, uint8_t min1, uint8_t sec10, uint8_t sec1, uint8_t ms10, uint8_t ms1)
{uint8_t *stopWatchTimer[6];*stopWatchTimer[0] = min10;*stopWatchTimer[1] = min1;*stopWatchTimer[2] = sec10;*stopWatchTimer[3] = sec1;*stopWatchTimer[4] = ms10;*stopWatchTimer[5] = ms1;return stopWatchTimer;
}uint8_t com1 = 0x01; // 定义数码管的8个口
uint8_t com2 = 0x02;
uint8_t com3 = 0x04;
uint8_t com4 = 0x08;
uint8_t com5 = 0x10;
uint8_t com6 = 0x20;
uint8_t com7 = 0x40;
uint8_t com8 = 0x80;sbit s4 = P3 ^ 3; // 定义按键
sbit s5 = P3 ^ 2;code unsigned char Seg_Table[] ={0xc0, // 00xf9, // 10xa4, // 20xb0, // 30x99, // 40x92, // 50x82, // 60xf8, // 70x80, // 80x90, // 90xBF  // 符号"-"
};uint8_t timerCounter = 0;
uint8_t counter50ms = 0;
uint8_t counter1s = 0;
uint8_t counter1min = 0;
uint8_t counter1h = 0;void Timer0_Init(void) // 5毫秒@12MHz
{AUXR |= 0x80; // 定时器时钟1T模式TMOD &= 0xF0; // 设置定时器模式TL0 = 0xA0;   // 设置定时初始值TH0 = 0x15;   // 设置定时初始值TF0 = 0;      // 清除TF0标志// TR0 = 1;      // 定时器0开始计时 //因为题目要求可以暂停,所以一开始不要打开ET0 = 1; // 使能定时器0中断EA = 1;
}
// 使用STC - ISP中的延时计算器生成,
// 不想再使用定时器1生成时间间隔了,有些麻烦。
// 注意,延时500us会有重影
void Delay1ms() //@12.000MHz 使用STC-ISP中的延时计算器生成
{unsigned char i, j;i = 2;j = 239;do{while (--j);} while (--i);
}void oneSegShow(uint8_t comX, uint8_t showNum) // 单数码管显示
{COM(comX);SEG(Seg_Table[showNum]);
}
void min10Seg1(uint8_t min10) // 1管显示分10位
{oneSegShow(com1, min10);
}
void min1Seg2(uint8_t min1) // 2管显示分个位
{oneSegShow(com2, min1);
}
void dashSeg3() // 3管显示符号-
{oneSegShow(com3, 10);
}
void sec10Seg4(uint8_t sec10) // 4管显示秒10位
{oneSegShow(com4, sec10);
}
void sec1Seg5(uint8_t sec1) // 5管显示秒个位
{oneSegShow(com5, sec1);
}
void dashSeg6() // 6管显示符号-
{oneSegShow(com6, 10);
}
void ms10Seg7(uint8_t ms10) // 7管显示毫秒10位
{oneSegShow(com7, ms10);
}
void ms1Seg8(uint8_t ms1) // 8管显示毫秒个位
{oneSegShow(com8, ms1);
}uint8_t arrayStatus;                         // 状态机显示方式
void segsAllShowFSM(uint8_t *stopWatchTimer) // Finite state machine
{switch (arrayStatus){case 0:min10Seg1(stopWatchTimer[0]);Delay1ms();arrayStatus = 1;break;case 1:min1Seg2(stopWatchTimer[1]);Delay1ms();arrayStatus = 2;break;case 2:dashSeg3();Delay1ms();arrayStatus = 3;break;case 3:sec10Seg4(stopWatchTimer[3]);Delay1ms();arrayStatus = 4;break;case 4:sec1Seg5(stopWatchTimer[4]);Delay1ms();arrayStatus = 5;break;case 5:dashSeg6();Delay1ms();arrayStatus = 6;break;case 6:ms10Seg7(stopWatchTimer[5]);Delay1ms();arrayStatus = 7;break;case 7:ms1Seg8(stopWatchTimer[6]);Delay1ms();arrayStatus = 0;break;default:arrayStatus = 0;break;}
}uint8_t s4Status;
uint8_t falling;
uint8_t counterOnOff = 0;uint8_t keyStatus;
uint8_t keyValue;void readKey()
{switch (keyStatus){case 0:if ((s4 == 0) | (s5 == 0)){keyStatus = 1;falling = 1;keyStatus = 1;}break;case 1:if (s5 == 0){keyValue = 5;}else if (s4 == 0){keyValue = 4;}if (falling){counterOnOff = ~counterOnOff;}if ((s4 == 0) | (s5 == 0)) // 如果长按锁定在当前状态{falling = 0;keyStatus = 1;}elsekeyStatus = 2;break;case 2:if ((s4 == 1) && (s5 == 1))keyStatus = 0;default:keyStatus = 0;break;}
}
void keyScan()
{uint8_t *arrayTimer;uint8_t ms10;uint8_t ms1;uint8_t sec10;uint8_t sec1;uint8_t min10;uint8_t min1;readKey();if (keyValue == 5){timerCounter = 0; // 清零counter50ms = 0;counter1s = 0;counter1min = 0;counter1h = 0;ms10 = counter50ms / 10;ms1 = counter50ms % 10;sec10 = counter1s / 10;sec1 = counter1s % 10;min10 = counter1min / 10;min1 = counter1min % 10;arrayTimer = setStopWatch(min10, min1, sec10, sec1, ms10, ms1);segsAllShowFSM(arrayTimer);}else if (keyValue == 4){ms10 = counter50ms / 10;ms1 = counter50ms % 10;sec10 = counter1s / 10;sec1 = counter1s % 10;min10 = counter1min / 10;min1 = counter1min % 10;arrayTimer = setStopWatch(min10, min1, sec10, sec1, ms10, ms1);segsAllShowFSM(arrayTimer);if (counterOnOff){TR0 = 1; // open timer启动恢复}else{TR0 = 0; // pause timer//暂停}}
}
void main()
{LED(0xff); // 关闭LEDCOM(0xFF); // 关闭数码管// SEG(Seg_Table[0]);Timer0_Init();while (1){keyScan();}
}void Timer0_Isr(void) interrupt 1
{if (++timerCounter == 10) // 5毫秒为基本单位,50ms为一个计时单元{timerCounter = 0;if (++counter50ms == 20) // 1s{counter50ms = 0;       // 数码管显示的毫秒的数值if (++counter1s == 60) // 1min{counter1s = 0;           // 数码管显示的秒的数值if (++counter1min == 60) // 1h{counter1min = 0; // 数码管显示的分的数值}}}}
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com