- 打卡等级:常住居民II
- 打卡总天数:83
- 最近打卡:2025-09-18 08:48:47
已绑定手机
中级会员
- 积分
- 236
|
发表于 2025-9-8 09:56:46
|
显示全部楼层
#include <STC8H.H>
#include <intrins.h>
// 数码管段引脚定义(共阳极)
sbit SEG_D = P1^5; // D段连接P1.5
sbit SEG_G = P1^3; // G段连接P1.3
sbit SEG_C = P1^4; // C段连接P1.4
sbit SEG_A = P5^4; // A段连接P5.4
sbit SEG_E = P1^6; // E段连接P1.6
sbit SEG_F = P1^7; // F段连接P1.7
sbit SEG_B = P1^2; // B段连接P1.2
// 数码管位选引脚(低电平有效)
sbit DIGIT_QIAN = P3^6; // 千位通过P3.6控制
sbit DIGIT_BAI = P3^7; // 百位通过P3.7控制
sbit DIGIT_SHI = P1^0; // 十位通过P1.0控制
sbit DIGIT_GE = P1^1; // 个位通过P1.1控制
// 共阳极数码管段码表(0-9)
unsigned char code SEG_TABLE[] = {
0x3F, // 0
0x06, // 1
0x5B, // 2
0x4F, // 3
0x66, // 4
0x6D, // 5
0x7D, // 6
0x07, // 7
0x7F, // 8
0x6F // 9
};
// 全局变量
unsigned char qian_num = 0; // 千位数字,初始为0
unsigned char bai_num = 0; // 百位数字,初始为0
unsigned char shi_num = 0; // 十位数字,初始为0
unsigned char ge_num = 0; // 个位数字,初始为0
unsigned int timer_count = 0; // 定时器计数(用于1秒更新)
unsigned char scan_count = 0; // 扫描计数(用于高频刷新)
bit update_flag = 0; // 更新标志
// 定时器0初始化(0.05ms中断)
void Timer0_Init(void) {
TMOD = 0x01; // 定时器0工作在方式1
TH0 = (65536 - 50) / 256; // 0.05ms中断初值(12MHz晶振)
TL0 = (65536 - 50) % 256;
ET0 = 1; // 允许定时器0中断
EA = 1; // 允许总中断
TR0 = 1; // 启动定时器0
}
// 端口初始化
void Port_Init(void) {
// 配置段选和位选引脚为推挽输出
P1M0 = 0xA7; // P1.0-P1.7推挽输出
P1M1 = 0x00;
P5M0 = 0x10; // P5.4推挽输出
P5M1 = 0x00;
// 配置百位和千位控制引脚为推挽输出
P3M0 = 0xC0; // P3.6(千位)和P3.7(百位)推挽输出
P3M1 = 0x00;
// 初始关闭所有数码管
DIGIT_QIAN = 1;
DIGIT_BAI = 1;
DIGIT_SHI = 1;
DIGIT_GE = 1;
}
// 设置数码管段码
void Set_Segment(unsigned char num) {
unsigned char seg_code = SEG_TABLE[num];
// 共阳极数码管:段码位为1时,对应引脚输出0点亮
SEG_A = (seg_code & 0x01) ? 0 : 1;
SEG_B = (seg_code & 0x02) ? 0 : 1;
SEG_C = (seg_code & 0x04) ? 0 : 1;
SEG_D = (seg_code & 0x08) ? 0 : 1;
SEG_E = (seg_code & 0x10) ? 0 : 1;
SEG_F = (seg_code & 0x20) ? 0 : 1;
SEG_G = (seg_code & 0x40) ? 0 : 1;
}
// 快速动态扫描显示四位数字
void Fast_Scan_Display(void) {
// 关闭所有位选,防止串扰
DIGIT_QIAN = 1;
DIGIT_BAI = 1;
DIGIT_SHI = 1;
DIGIT_GE = 1;
// 循环扫描千位、百位、十位、个位
switch(scan_count % 4) {
case 0: // 显示千位
Set_Segment(qian_num);
DIGIT_QIAN = 0;
break;
case 1: // 显示百位
Set_Segment(bai_num);
DIGIT_BAI = 0;
break;
case 2: // 显示十位
Set_Segment(shi_num);
DIGIT_SHI = 0;
break;
case 3: // 显示个位
Set_Segment(ge_num);
DIGIT_GE = 0;
break;
}
}
// 定时器0中断服务程序(高频刷新+计时)
void Timer0_ISR(void) interrupt 1 {
// 重装载初值(0.05ms)
TH0 = (65536 - 50) / 256;
TL0 = (65536 - 50) % 256;
// 每0.05ms执行一次快速扫描
scan_count++;
Fast_Scan_Display();
// 累计20000次中断为1秒(0.05ms * 20000 = 1000ms)
if (timer_count < 20000) {
timer_count++;
} else {
timer_count = 0;
update_flag = 1; // 置位更新标志
}
}
// 更新数字(从0000递增到9999后循环到0000继续)
void Update_Number(void) {
ge_num++; // 个位先加1
if (ge_num > 9) { // 个位满10
ge_num = 0; // 个位归零
shi_num++; // 十位加1
if (shi_num > 9) { // 十位满10
shi_num = 0; // 十位归零
bai_num++; // 百位加1
if (bai_num > 9) { // 百位满10
bai_num = 0; // 百位归零
qian_num++; // 千位加1
if (qian_num > 9) { // 千位满10(达到9999)
// 循环到0000重新开始
qian_num = 0;
bai_num = 0;
shi_num = 0;
ge_num = 0;
}
}
}
}
}
void main(void) {
Port_Init(); // 初始化端口
Timer0_Init(); // 初始化定时器
while (1) {
// 主循环处理数字更新,显示由定时器中断控制
if (update_flag) {
update_flag = 0;
Update_Number();
}
}
}
|
|