- 积分
- 41
- 在线时间
- 1124 小时
- 最后登录
- 2025-8-2
- 阅读权限
- 40
- 精华
- 0

- UID
- 258898
- 帖子
- 46
- 精华
- 0
- 经验
- 41 点
- 金钱
- 39 ¥
- 注册时间
- 2010-11-8
|

楼主 |
发表于 2025-7-26 22:50
|
显示全部楼层
#include <STC8H.H>
#include <intrins.h>
/*--- 函数声明 ---*/
void Init_GPIO(void);
void Init_Interrupt(void);
void HC595_Send4Digits(unsigned char d1, unsigned char d2, unsigned char d3, unsigned char d4);
void UpdateDisplay(void);
/*--- 全局变量定义 ---*/
volatile unsigned char count = 0x80; // count=0对应127.5,count=255对应0.0
volatile unsigned char current_output = 0x80;
volatile unsigned char delayed_bits = 0;
volatile bit delay_active = 0;
volatile unsigned char delay_counter = 0;
volatile bit output_enabled = 1;
/*--- 锁定机制相关变量 ---*/
volatile unsigned int lock_timer = 10000;
volatile bit keys_locked = 1;
/*--- 按键状态控制变量 ---*/
volatile unsigned char key1_state = 0, key2_state = 0, key3_state = 0;
volatile unsigned int key1_counter = 0, key2_counter = 0, key3_counter = 0;
/*--- 数码管驱动部分 ---*/
sbit DS = P3^0;
sbit STCP = P3^5;
sbit SHCP = P3^4;
code unsigned char SegCode[] = {
0xC0, 0xF9, 0xA4, 0xB0, 0x99, // 0-4
0x92, 0x82, 0xF8, 0x80, 0x90, // 5-9
0xBF // 横杠'-'
};
volatile bit display_refresh = 1;
/******************************
* GPIO初始化函数
******************************/
void Init_GPIO(void) {
P1M0 = 0xFF; // P1推挽输出
P1M1 = 0x00;
P1 = 0x80; // 初始值
P3M0 = 0x31; // P3.0,P3.4,P3.5推挽输出
P3M1 = 0x00;
P3PU = 0xCE; // P3.1,P3.6,P3.7上拉
}
/******************************
* 中断初始化函数
******************************/
void Init_Interrupt(void) {
IT0 = 1; // 下降沿触发
EX0 = 1; // 使能INT0
TMOD &= 0xF0;
TMOD |= 0x01; // 定时器0模式1
TH0 = (65536 - 1000) >> 8;
TL0 = (65536 - 1000) & 0xFF;
ET0 = 1;
EA = 1;
TR0 = 1;
}
/******************************
* 74HC595驱动函数
******************************/
void HC595_Send4Digits(unsigned char d1, unsigned char d2, unsigned char d3, unsigned char d4) {
unsigned char i;
unsigned long data_packet = ((unsigned long)d1 << 24) |
((unsigned long)d2 << 16) |
((unsigned long)d3 << 8) |
d4;
for(i = 0; i < 32; i++) {
DS = (data_packet & 0x80000000) ? 1 : 0;
data_packet <<= 1;
SHCP = 0;
_nop_();_nop_();
SHCP = 1;
}
STCP = 0;
_nop_();_nop_();
STCP = 1;
}
/******************************
* 显示更新函数(千位0显示为横杠)
******************************/
void UpdateDisplay(void) {
static unsigned int last_count = 0xFFFF;
static bit last_enabled = 2;
unsigned int value_x10;
unsigned char d1, d2, d3, d4;
unsigned char seg1, seg2, seg3, seg4;
if(last_count == count && last_enabled == output_enabled)
return;
last_count = count;
last_enabled = output_enabled;
if(!output_enabled) {
HC595_Send4Digits(0xBF, 0xBF, 0xBF, 0xBF);
return;
}
// 计算显示值:127.5 - count*0.5 → 格式XX.X
value_x10 = 1275 - 5 * count;
d1 = (value_x10 / 1000) % 10; // 千位
d2 = (value_x10 % 1000) / 100; // 百位
d3 = (value_x10 % 100) / 10; // 十位(带小数点)
d4 = value_x10 % 10; // 个位
// 千位0显示为横杠,数值0时完全消隐
if(value_x10 == 0) {
seg1 = 0xFF; // 千位消隐
seg2 = 0xFF; // 百位消隐
seg3 = SegCode[0] & 0x7F;
seg4 = SegCode[0];
} else {
seg1 = (d1 == 0) ? SegCode[10] : SegCode[d1]; // 千位0显示横杠
seg2 = (d1 == 0 && d2 == 0) ? 0xFF : SegCode[d2];
seg3 = SegCode[d3] & 0x7F;
seg4 = SegCode[d4];
}
HC595_Send4Digits(seg1, seg2, seg3, seg4);
}
/******************************
* 定时器0中断服务程序(完整逻辑)
******************************/
void timer0_isr(void) interrupt 1 {
TH0 = (65536 - 1000) >> 8;
TL0 = (65536 - 1000) & 0xFF;
// 锁定计时处理
if(keys_locked) {
if(lock_timer > 0) lock_timer--;
else keys_locked = 0;
}
// 消隐延迟处理
if(delay_active) {
if(delay_counter > 0) delay_counter--;
else {
current_output |= delayed_bits;
P1 = current_output;
delayed_bits = 0;
delay_active = 0;
}
}
// 按键扫描逻辑
if(!keys_locked) {
// 按键1(P3.6)增加count
if (!(P3 & 0x40)) {
if (key1_state == 0) {
if(++key1_counter >= 20) {
key1_state = 1;
key1_counter = 0;
if(count < 0xFF) count++;
display_refresh = 1; // 手动触发刷新
}
} else {
if(++key1_counter >= 500) {
if(count < 0xFF) count++;
display_refresh = 1; // 手动触发刷新
key1_counter = 400;
}
}
} else {
key1_state = 0;
key1_counter = 0;
}
// 按键2(P3.7)减少count
if (!(P3 & 0x80)) {
if (key2_state == 0) {
if(++key2_counter >= 20) {
key2_state = 1;
key2_counter = 0;
if(count > 0) count--;
display_refresh = 1; // 手动触发刷新
}
} else {
if(++key2_counter >= 500) {
if(count > 0) count--;
display_refresh = 1; // 手动触发刷新
key2_counter = 400;
}
}
} else {
key2_state = 0;
key2_counter = 0;
}
}
// 按键3(P3.1)
if (!(P3 & 0x02)) {
if (key3_state == 0) {
if(++key3_counter >= 20) {
key3_state = 1;
key3_counter = 0;
output_enabled = !output_enabled;
display_refresh = 1; // 手动触发刷新
if(!output_enabled) {
P1 = 0x00;
} else {
current_output = ~count;
}
}
}
} else {
key3_state = 0;
key3_counter = 0;
}
}
/******************************
* 外部中断0服务程序
******************************/
void exint0() interrupt 0 {
if (P3 & 0x08) { // 方向判断
if (count > 0) count--;
} else {
if (count < 0xFF) count++;
}
display_refresh = 1;
}
/******************************
* 主函数
******************************/
void main(void) {
Init_GPIO();
Init_Interrupt();
UpdateDisplay();
while(1) {
// 输出控制
if(output_enabled) {
if(current_output != count) {
unsigned char changed = current_output ^ count;
current_output = count;
P1 = current_output & ~(changed & count);
delayed_bits = changed & count;
delay_counter = 5;
delay_active = 1;
}
} else {
P1 = 0x00;
}
// 显示刷新处理
if(display_refresh) {
display_refresh = 0;
UpdateDisplay();
}
_nop_();
}
} |
|