代码如下
- #include <reg51.h>
- // 数码管段码定义(共阴极,0-9)
- unsigned char code seg_code[] = {
- 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F // 0-9
- };
- // 数码管位选定义(低电平有效)
- sbit dig1 = P2^0; // 千位
- sbit dig2 = P2^1; // 百位
- sbit dig3 = P2^2; // 十位
- sbit dig4 = P2^3; // 个位
- // 按键与IO口定义
- sbit key_reset = P1^0; // 重置按键
- sbit key_high = P1^1; // 高水位按键
- sbit key_normal = P1^2; // 正常水位按键
- sbit key_low = P1^3; // 低水位按键
- sbit key_add = P1^4; // 加10圈按键
- sbit key_sub = P1^5; // 减10圈按键
- sbit motor = P1^7; // 电机控制(水泵)
- // LED与IO口定义(状态互斥)
- sbit led_reset = P3^0; // 重置状态灯
- sbit led_low = P3^1; // 低水位红灯
- sbit led_normal = P3^2; // 正常水位绿灯
- sbit led_high = P3^3; // 高水位黄灯
- sbit led_150 = P3^4; // 150圈提示灯
- sbit led_300 = P3^5; // 300圈提示灯
- sbit led_450 = P3^6; // 450圈提示灯
- sbit motor_pulse = P3^7; // 电机脉冲输入
- // 全局变量
- #define MAX_COUNT 9990 // 最大圈数(10的倍数,避免个位非0)
- #define DEFAULT_TARGET 450 // 默认目标圈数(抽满水)
- unsigned int target_count = DEFAULT_TARGET; // 目标圈数(10的倍数)
- unsigned int current_count = 0; // 当前已转圈数
- bit is_running = 0; // 水泵运行标志
- bit timer_flag = 0; // 0.5秒定时标志
- unsigned int timer_cnt = 0; // 定时器计数
- // 函数声明
- void update_leds(void);
- void timer0_init(void);
- void delay_ms(unsigned int ms);
- void display_scan(void);
- void key_scan(void);
- void motor_run_one_circle(void);
- void clear_status_leds(void);
- // 定时器0初始化(0.5秒定时)
- void timer0_init() {
- TMOD &= 0xF0;
- TMOD |= 0x01;
- TH0 = 0x4C;
- TL0 = 0x00;
- ET0 = 1;
- EA = 1;
- TR0 = 0;
- }
- // 定时器0中断服务函数
- void timer0_isr() interrupt 1 {
- TH0 = 0x4C;
- TL0 = 0x00;
- timer_cnt++;
- if (timer_cnt >= 10) { // 10*50ms=500ms(每圈时间)
- timer_cnt = 0;
- timer_flag = 1;
- }
- }
- // 毫秒级延时
- void delay_ms(unsigned int ms) {
- unsigned int i, j;
- for (i = 0; i < ms; i++)
- for (j = 0; j < 112; j++); // 11.0592MHz晶振下约1ms
- }
- // 数码管动态扫描
- void display_scan() {
- unsigned char units, tens, hundreds, thousands;
- unsigned int disp_num = current_count;
- if (disp_num > MAX_COUNT) disp_num = MAX_COUNT;
- // 提取各位数字
- units = disp_num % 10;
- tens = (disp_num / 10) % 10;
- hundreds = (disp_num / 100) % 10;
- thousands = (disp_num / 1000) % 10;
- // 个位显示
- dig1 = 1; dig2 = 1; dig3 = 1; dig4 = 1;
- P0 = seg_code[units];
- delay_ms(1);
- dig4 = 0;
- delay_ms(2);
- dig4 = 1;
- // 十位显示
- dig1 = 1; dig2 = 1; dig3 = 1; dig4 = 1;
- P0 = seg_code[tens];
- delay_ms(1);
- dig3 = 0;
- delay_ms(2);
- dig3 = 1;
- // 百位显示
- dig1 = 1; dig2 = 1; dig3 = 1; dig4 = 1;
- P0 = seg_code[hundreds];
- delay_ms(1);
- dig2 = 0;
- delay_ms(2);
- dig2 = 1;
- // 千位显示
- dig1 = 1; dig2 = 1; dig3 = 1; dig4 = 1;
- P0 = seg_code[thousands];
- delay_ms(1);
- dig1 = 0;
- delay_ms(2);
- dig1 = 1;
- }
- // 清除所有状态灯(P3.0-P3.3)
- void clear_status_leds(void) {
- led_reset = 0;
- led_low = 0;
- led_normal = 0;
- led_high = 0;
- }
- // 更新LED状态(圈数提示灯)
- void update_leds(void) {
- led_150 = (current_count >= 150) ? 1 : 0;
- led_300 = (current_count >= 300) ? 1 : 0;
- led_450 = (current_count >= 450) ? 1 : 0; // 450圈提示(默认满水)
- }
- // 按键扫描(核心:加/减10圈逻辑)
- void key_scan() {
- // 重置按键:恢复默认450圈目标,计数清零
- if (key_reset == 0) {
- delay_ms(10); // 消抖
- if (key_reset == 0) {
- current_count = 0;
- target_count = DEFAULT_TARGET; // 重置为默认450圈
- motor = 0;
- is_running = 0;
- TR0 = 0;
- clear_status_leds();
- led_reset = 1;
- update_leds();
- while (key_reset == 0) display_scan();
- }
- }
- // 低水位按键:启动水泵
- if (key_low == 0) {
- delay_ms(10);
- if (key_low == 0) {
- is_running = 1;
- motor = 1;
- TR0 = 1;
- clear_status_leds();
- led_low = 1;
- while (key_low == 0) display_scan();
- }
- }
- // 正常水位按键:停止水泵
- if (key_normal == 0) {
- delay_ms(10);
- if (key_normal == 0) {
- motor = 0;
- is_running = 0;
- TR0 = 0;
- clear_status_leds();
- led_normal = 1;
- while (key_normal == 0) display_scan();
- }
- }
- // 高水位按键:停止水泵
- if (key_high == 0) {
- delay_ms(10);
- if (key_high == 0) {
- motor = 0;
- is_running = 0;
- TR0 = 0;
- clear_status_leds();
- led_high = 1;
- while (key_high == 0) display_scan();
- }
- }
- // 加按键:每次增加10圈(限制不超过最大值)
- if (key_add == 0) {
- delay_ms(10);
- if (key_add == 0) {
- if (target_count + 10 <= MAX_COUNT) {
- target_count += 10; // 加10圈
- }
- while (key_add == 0) display_scan(); // 等待释放,避免连加
- }
- }
- // 减按键:每次减少10圈(限制不低于0)
- if (key_sub == 0) {
- delay_ms(10);
- if (key_sub == 0) {
- if (target_count >= 10) { // 确保不低于0
- target_count -= 10; // 减10圈
- }
- while (key_sub == 0) display_scan(); // 等待释放,避免连减
- }
- }
- }
- // 电机每转一圈处理
复制代码
|