当前位置: 首页 > news >正文

单元训练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; // 数码管显示的分的数值}}}}
}

http://www.lryc.cn/news/426024.html

相关文章:

  • 国外项目管理软件最佳实践:选型与应用
  • Angular组件概念
  • 嵌入式人工智能ESP32(4-PWM呼吸灯)
  • 继承 (上)【C++】
  • WPF打印控件内容
  • [C++][opencv]基于opencv实现photoshop算法图像剪切
  • 四十、大数据技术之Kafka3.x(3)
  • redis——基本命令
  • pytorch实现单层线性回归模型
  • 智能小家电能否利用亚马逊VC搭上跨境快车?——WAYLI威利跨境助力商家
  • 顺丰科技25届秋季校园招聘常见问题答疑及校招网申测评笔试题型分析SHL题库Verify测评
  • 深入理解 Kibana 配置文件:一份详尽的指南
  • 算法的学习笔记—链表中倒数第 K 个结点(牛客JZ22)
  • 聊聊场景及场景测试
  • Spring Web MVC入门(中)
  • Django后端架构开发:后台管理与会话技术详解
  • 挑战Infiniband, 爆改Ethernet(2)
  • Postman文件上传接口测试
  • stm32入门学习14-电源控制
  • [C++][opencv]基于opencv实现photoshop算法色相和饱和度调整
  • Github 2024-08-16Java开源项目日报 Top10
  • AI学习记录 - torch 的 matmul和dot的关联,也就是点乘和点积的联系
  • leetcode 885. Spiral Matrix III
  • mysql windows安装与远程连接配置
  • 子网掩码是什么以及子网掩码相关计算
  • 仿RabbitMQ实现消息队列
  • SpringBoot教程(二十三) | SpringBoot实现分布式定时任务之xxl-job
  • 微前端架构的数据持久化策略与实践
  • 讲解 狼人杀中的买单双是什么意思
  • 回归分析系列5-贝叶斯回归