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

news2024/11/17 7:30:27

蓝桥杯 小蜜蜂   单元训练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, // 0
        0xf9, // 1
        0xa4, // 2
        0xb0, // 3
        0x99, // 4
        0x92, // 5
        0x82, // 6
        0xf8, // 7
        0x80, // 8
        0x90, // 9
        0xBF  // 符号"-"
};

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;
        }
        else
            keyStatus = 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); // 关闭LED
    COM(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.coloradmin.cn/o/2046553.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

火语言RPA--手机对象元素库使用方法

使用自动选取工具获得手机中元素的xpath路径。 工具标识 手机 分组下组件若有此标识,则包含选择元素工具,点击此标识会可以选择手机中的元素进行操作。 元素库介绍 ① 根据元素名称筛选元素库中保存的元素 ② 元素库,显示已经保存的元素名称…

算法的学习笔记—链表中倒数第 K 个结点(牛客JZ22)

😀前言 在编程过程中,链表是一种常见的数据结构,它能够高效地进行插入和删除操作。然而,遍历链表并找到特定节点是一个典型的挑战,尤其是当我们需要找到链表中倒数第 K 个节点时。本文将详细介绍如何使用双指针技术来解…

48天笔试训练错题——day47

目录 选择题 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 编程题 1. 合唱团 2. 马戏团 选择题 1. 子网掩码是 255.255.255.0,前三个字节都是 1,则表示有 24 位网络号和子网号。又是 B 类 IP 地址,只有 16 位网络号,所有第三个…

聊聊JS中的WebSocket

你好,我是沐爸,欢迎点赞、收藏和关注。个人知乎 在JavaScript中,使用WebSocket非常简单直观。通过几行代码,你就可以轻松创建一个WebSocket连接,并监听来自服务器的消息。无论是开发实时聊天应用、在线游戏、实时数据分…

高效录制新选择:2024年Windows录屏软件

录屏能帮助我们捕捉屏幕上的精彩瞬间,作为老师可以用来录制课程,作为会议记录员可以用来录制远程会议。那么有什么软件是适合windows录屏的呢?这次我们一起来探讨一下吧。 1.福昕录屏大师 链接:www.foxitsoftware.cn/REC/ 这款软…

【数据结构】 顺序表的应用 - 通讯录的实现

0. 前言 上一期博客中,我们已经学习了顺序表是什么,以及顺序表相关接口的实现,了解了如何实现顺序表的插入和删除等功能,那么在这期博客,我们可以基于顺序表来实现一个通讯录,在通讯录当中能实现联系人的增…

【代码随想录训练营第42期 Day27打卡 贪心Part1 - LeetCode 455.分发饼干 376. 摆动序列 53. 最大子序和

目录 一、贪心 二、题目与题解 题目一:455.分发饼干 题目链接 题解:排序双指针贪心 题目二:376. 摆动序列 题目链接 题解:贪心 题目三:53. 最大子序和 题目链接 题解1:暴力(失败&…

解决生产环境服务启动失败:一次远程Bug排查与修复历程

一、问题现象 同事没事一直给服务器断电(直接拔插头那种!!!!) 二、初步排查 首先,我登录到生产服务器,查看服务启动日志。在日志中,我发现了一些异常信息,…

全网独家梳理:数字病理图像的常用存储格式以及格式转换的方法|24-08-17

小罗碎碎念 这一期推文,跟你们分享一些比较底层,并且顶刊中不会涉及但是又至关重要的内容。 我们在做任何一个病理AI的项目前,有两样东西是一定会拿到手的——切片&对应的临床基线表。(如果做多组学/多模态的项目,…

宠物空气净化器推荐购买吗?真的能除毛去味吗?

自从做了猫咖店老板,我这生活真的是美滋滋,每天都可以摸到不同品种的可爱的小猫咪,在赚钱养家的同时还能肆意和猫咪贴贴,连朋友都说想和我干一样的工作了。每天接待的顾客也不少,店里面的空气质量也还不错,…

模块一(任务2):SDH系统原理解读

一、PDH与SDH标准速率介绍 OTN网络技术是基于SDH系统和WDM系统设计的,所以学习OTN系统原理必须要掌握SDH和WDM量大系统原理 1、PDH与SDH概念及特点 二、SDH的帧结构 目前通信常见的数据结构有两种: 报文:基于以太网通信的数据结构 帧&am…

真诚巨作:全文一万字教你快速熟悉项目|文心快码帮你快速熟悉~

写在前面 : 上了好多年的学,终于毕业进入职场啦~在公司也有一段时间了,慢慢地也变成了纯正的社畜了。近来开始熟悉部门的项目代码,说实话公司的代码真跟以前接触的不一样,内部各种自建框架,让人看得眼花缭乱…

ARCGIS PRO 要素标注背景色透明度的设置

使用ArcGIS Pro 设置标注背景色的透明度 一、点击标注属性 二、点击符号、注释 三、下拉框选择背景 四、背景符号 五、点击颜色 六、编辑颜色 七、应用

Java语言程序设计基础篇_编程练习题**16.26(模拟:升旗并播放国歌)

目录 题目:**16.26(模拟:升旗并播放国歌) 习题思路: 代码示例 结果展示 音频来源 题目:**16.26(模拟:升旗并播放国歌) 创建一个显示升国旗的程序,如图15-14…

还在使用百度翻译?这4款翻译工具也能帮你打破语言壁垒!

是谁像我一样,一提到翻译工具第一想到的就是百度翻译。它可以是用了好久的翻译工具,可是随着学习的深入, 我还是发觉了一些其他的实用翻译工具。比如下面这四款: 1、365翻译工具 直达链接:https://fanyi.pdf365.cn/ …

NLP之transformer:transformer-explainer的简介、安装和使用方法、案例应用之详细攻略

NLP之transformer:transformer-explainer的简介、安装和使用方法、案例应用之详细攻略 目录 相关论文 《Transformer Explainer: Interactive Learning of Text-Generative Models》翻译与解读 transformer-explainer的简介 transformer-explainer的安装和使用方…

尚硅谷MYSQL(12-13章)

第十二章数据类型 比如说tinyint(4)这个四表示的是那个取值范围的位数 他只是一个显示 比如说int后面应该是int(11)这是有符号的 无符号int是int(10) 如果写成int(3)但是存的数据是…

论文写作新神器!10款可以写论文的人工智能软件

在当今快速发展的数字时代,人工智能(AI)技术已经渗透到各个领域,包括学术研究和论文写作。为了帮助学者和学生提高写作效率和质量,市场上涌现了许多优秀的AI写作工具。本文将详细介绍10款可以写论文的人工智能软件&…

STM32F103C8T6单片机原理图设计(PCB板)

先了解了以下stm32f103c8t6的引脚使用: 对比过一些原理图,我发现除了特定协议的引脚功能,只要功能正确,可以自己选择连接对应的引脚。可以根据使用的LED/BEEP/DHT11/BH1750/ESP8266等模块的功能对应相应的引脚: WIFI(…

[开源] 安卓系统发送modbus协议到硬件设备下位机

最近是在研究安卓板子上的modbus通信,于是写了这个maven依赖。 项目中主要用到的功能是读写寄存器,所以依赖中重点测试了读写多个寄存器的协议。 另外你可以自定义协议pdu交给程序进行封装及发送。 如果使用中发现了什么问题,可以到仓库添…