找回密码
 立即注册
×

00:00:00

您有一张0.1元限时体验卡,马上领取获得VIP尊享特权。

数码管时钟,已经修改了昨天走时不精准的问题 | 走时很精准

2026-4-8 08:28 来自 xbq202 发布 @ 综合讨论

昨天帖子的数码管时钟,发现走时不准,误差很大,现在对定时器进行了修改,走时很精准,下载时选择12MHz频率。喜欢的朋友赶快复制拿走!!!


/*================================================================
  功能:STC32四位数码管时钟(带冒号2秒闪烁和简化按键设置)
  硬件连接:
    - MCU: STC32G12K128
    - 数码管: 4401AS(四位共阴时钟数码管)
    - 段码: P2.0-P2.7 -> 数码管a,b,c,d,e,f,g,DP
    - 位码: P3.0-P3.3 -> 数码管位选1-4
    - 按键: P0.0-P0.3 -> 功能/加/减/确认键
  注意:冒号通过第2位数码管的DP段以2秒周期闪烁
================================================================*/

#include "STC32G.h"        // STC32头文件
#include "intrins.h"

/*============ 引脚定义 ============*/
#define SEG_PORT P2        // 段码端口(P2.0-P2.7 -> a,b,c,d,e,f,g,DP)
#define BIT_PORT P3        // 位码端口(P3.0-P3.3 -> 位选1-4)

// 按键引脚定义
sbit KEY_MODE = P0^0;      // 功能/模式键
sbit KEY_ADD  = P0^1;      // 加键
sbit KEY_SUB  = P0^2;      // 减键
sbit KEY_OK   = P0^3;      // 确认键

/*============ 模式定义 ============*/
#define MODE_NORMAL      0     // 正常显示模式
#define MODE_SET_HOUR    1     // 设置小时模式
#define MODE_SET_MINUTE  2     // 设置分钟模式

/*============ 全局变量 ============*/
// 时间结构体
typedef struct {
    unsigned char hour;     // 小时 (0-23)
    unsigned char minute;   // 分钟 (0-59)
    unsigned char second;   // 秒钟 (0-59)
} TIME_TYPE;

TIME_TYPE time = {12, 0, 0};  // 初始时间 12:00:00

// 显示相关变量
unsigned char disp_buf = {0};       // 显示缓冲区
bit colon_flag = 0;                    // 冒号显示标志
bit sec_led_on = 0;                    // 秒LED点亮标志
unsigned char display_mode = MODE_NORMAL;  // 当前显示模式
bit blink_flag = 0;                    // 设置闪烁标志
unsigned int t1_counter = 0;           // 定时器1计数器
unsigned int ms_counter = 0;           // 毫秒计数器

// 按键相关
unsigned char key_state = 0;           // 按键状态
unsigned int key_press_time = 0;       // 按键按下时间
bit key_pressed = 0;                   // 按键按下标志
bit key_enable = 1;                    // 按键使能标志
unsigned int key_repeat_delay = 0;     // 按键重复延时

/*============ 数码管编码表 ============*/
// 共阴数码管段码表 (0-9)
// 段码顺序:a b c d e f g DP (对应P2.0-P2.7)
const unsigned char code SEG_CODE = {
    // 0     1     2     3     4     5     6     7     8     9
    0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F,
    // 不显示
    0x00
};

// 位选表
// 共阴数码管,位选低电平有效
// 假设P3.0-3.3分别控制第1-4位数码管
const unsigned char code BIT_CODE = {
    0xFE,  // 11111110 - 第1位数码管 (P3.0=0)
    0xFD,  // 11111101 - 第2位数码管 (P3.1=0)
    0xFB,  // 11111011 - 第3位数码管 (P3.2=0)
    0xF7   // 11110111 - 第4位数码管 (P3.3=0)
};

/*============ 函数声明 ============*/
void System_Init(void);
void GPIO_Init(void);
void Timer0_Init(void);
void Timer1_Init(void);
void Update_Display_Buffer(void);
void Key_Scan(void);
void Key_Process(unsigned char key_val);
void Delay_ms(unsigned int ms);

/*============ 主函数 ============*/
void main(void)
{
    // 系统初始化
    System_Init();
   
    // 主循环
    while(1)
    {
        Key_Scan();               // 按键扫描
        Delay_ms(10);             // 增加主循环延时
    }
}

/*============ 系统初始化 ============*/
void System_Init(void)
{
    GPIO_Init();      // GPIO初始化
    Timer0_Init();    // 定时器0初始化
    Timer1_Init();    // 定时器1初始化
   
    // 开全局中断
    EA = 1;
   
    // 初始化显示缓冲区
    Update_Display_Buffer();
}

/*============ GPIO初始化 ============*/
void GPIO_Init(void)
{
    // P2设置为准双向口(段码输出)
    P2M0 = 0x00;
    P2M1 = 0x00;
    P2 = 0x00;           // 初始输出低电平
   
    // P3设置为准双向口(位码输出)
    P3M0 = 0x00;
    P3M1 = 0x00;
    P3 = 0xFF;           // 初始输出高电平(关闭所有位)
   
    // P0设置为高阻输入(按键输入),启用内部上拉
    P0M0 = 0x00;
    P0M1 = 0x00;
    P0 = 0xFF;           // 初始化为高电平
}

/*============ 定时器0初始化 ============*/
// 用于数码管动态扫描,1ms定时
void Timer0_Init(void)
{
    // 设置定时器0为模式0(16位自动重

免责声明:

本平台旨在开源共享精神,请勿发布敏感信息,任何违法信息我们将移交公安机关;

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2026-5-1 07:47 , Processed in 0.080587 second(s), 29 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

返回顶部