使用8H1K08单片机点亮两位数码管
使用8H1K08单片机点亮两位数码管,写了一个代码,让数码管显示00-99,且使用STC官方的烧录器方便多了使用STC8H1K08单片机点亮两位数码管,实现00-99的循环显示,是一种常见的嵌入式应用。STC8H1K08作为一款高性能、低功耗的8位单片机,具备丰富的外设资源和灵活的编程能力,非常适合用于此类基础显示控制任务。
在本项目中,我们采用共阴极数码管,通过单片机的I/O口控制段选与位选,实现动态扫描显示。代码逻辑清晰,结构合理,能够稳定地完成从00到99的数字递增显示,并且配合STC官方烧录器进行程序下载,极大提升了开发效率和可靠性。
以下为实现该功能的核心代码及说明:
c
include
// 定义数码管段选端口(P1)
sbit SEGA = P1^0;
sbit SEGB = P1^1;
sbit SEGC = P1^2;
sbit SEGD = P1^3;
sbit SEGE = P1^4;
sbit SEGF = P1^5;
sbit SEGG = P1^6;
// 定义数码管位选端口(P2)
sbit DIGIT1 = P2^0;
sbit DIGIT2 = P2^1;
// 数码管显示字符对应的段码(共阴极)
unsigned char code segcode = {
0x3F, // 0
0x06, // 1
0x5B, // 2
0x4F, // 3
0x66, // 4
0x6D, // 5
0x7D, // 6
0x07, // 7
0x7F, // 8
0x6F// 9
};
void delay(unsigned int ms) {
unsigned int i, j;
for (i = 0; i < ms; i++)
for (j = 0; j < 110; j++);
}
void display(unsigned char num) {
unsigned char digit1 = num / 10;
unsigned char digit2 = num % 10;
// 显示十位
P1 = segcode;
DIGIT1 = 0;
DIGIT2 = 1;
delay(5);
// 显示个位
P1 = segcode;
DIGIT1 = 1;
DIGIT2 = 0;
delay(5);
}
void main() {
unsigned char count = 0;
while (1) {
display(count);
if (++count > 99)
count = 0;
}
}
代码说明:
段选控制:通过P1口控制数码管的各个段(a~g),每个数字对应一个段码。
位选控制:通过P2口控制两个数码管的显示位置,实现动态扫描。
动态显示:通过快速切换两个数码管的显示内容,利用人眼的视觉暂留效应,实现稳定的显示效果。
延时函数:用于控制数码管刷新频率,确保显示稳定。
主循环:不断更新显示数值,实现从00到99的循环显示。
烧录方式:
使用STC官方烧录器(如STC-ISP)进行程序下载,操作简便,支持多种通信接口(如USB、串口等),兼容性强,适合初学者和专业开发者。
综上所述,基于STC8H1K08单片机的两位数码管显示系统设计简单、运行稳定,适用于教学实验、简易仪表、状态指示等多种应用场景。通过合理配置I/O端口和优化显示算法,可进一步提升系统的性能与可靠性。
[本文内容由国芯人工智能辅助生成,仅供参考] 原理图 PCB 设计的时候带了5个按键和一个输出,后续可以附加功能 #include <STC8H.H>
#include <intrins.h>
// 数码管段引脚定义
sbit SEG_A = P1^5;
sbit SEG_B = P1^3;
sbit SEG_C = P1^4;
sbit SEG_D = P5^4;
sbit SEG_E = P1^6;
sbit SEG_F = P1^7;
sbit SEG_G = P1^2;
// 数码管位选引脚(十位和个位)
sbit DIGIT_SHI = P1^1;// 十位公共端(左位)
sbit DIGIT_GE = P1^0; // 个位公共端(右位)
// 共阳极数码管段码表(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 shiwei_num = 0; // 十位数字(0-9)
unsigned char gewei_num = 0; // 个位数字(0-9)
unsigned intdelay_cnt = 0; // 延时计数器(1ms单位)
bit update_flag = 0;// 更新标志
// 定时器0初始化(1ms中断,12MHz晶振)
void Timer0_Init(void) {
TMOD = 0x01;
TH0 = 0xFC;
TL0 = 0x66;
ET0 = 1;
EA = 1;
TR0 = 1;
}
// 端口初始化(推挽输出)
void Port_Init(void) {
P1M0 = 0xFF;// P1口全推挽输出
P1M1 = 0x00;
P5M0 = 0x10;// P5.4推挽输出
P5M1 = 0x00;
// 初始消隐
DIGIT_SHI = 1;
DIGIT_GE = 1;
}
// 设置段码
void Set_Segment(unsigned char num) {
unsigned char seg_code = SEG_TABLE;
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 Display_Number(void) {
// 显示十位
Set_Segment(shiwei_num);
DIGIT_SHI = 0;// 点亮十位
DIGIT_GE = 1;// 消隐个位
_nop_();_nop_();_nop_();_nop_();// 短暂延时
DIGIT_SHI = 1;// 关闭十位
// 显示个位
Set_Segment(gewei_num);
DIGIT_GE = 0;// 点亮个位
DIGIT_SHI = 1;// 消隐十位
_nop_();_nop_();_nop_();_nop_();// 短暂延时
DIGIT_GE = 1;// 关闭个位
}
// 定时器0中断服务程序(1秒触发一次)
void Timer0_ISR(void) interrupt 1 {
TH0 = 0xFC;
TL0 = 0x66;
// 累计1000ms(1秒)
if (delay_cnt < 1000) {
delay_cnt++;
} else {
delay_cnt = 0;
update_flag = 1;// 1秒到,置位更新标志
}
}
// 更新数字(实现00-99循环)
void Update_Number(void) {
gewei_num++; // 个位先加1
if (gewei_num > 9) {// 个位满10进1
gewei_num = 0;
shiwei_num++; // 十位加1
if (shiwei_num > 9) {// 十位满10重置
shiwei_num = 0;
}
}
}
void main(void) {
Port_Init();
Timer0_Init();
while (1) {
Display_Number();// 持续动态扫描,确保显示稳定
if (update_flag) {// 到时间更新数字
update_flag = 0;
Update_Number();
}
}
}
烧录文件
页:
[1]