数码管时钟,已经修改了昨天走时不精准的问题 | 走时很精准
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位自动重
/*================================================================
功能: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位自动重
免责声明:
本平台旨在开源共享精神,请勿发布敏感信息,任何违法信息我们将移交公安机关;


