第一章:按键系统
1.1 按键底层原理
- 矩阵按键(先扫描行,再扫描列)
- 独立按键(4个独立按键)
独立按键读取函数
unsigned char Key_Read() {
unsigned char temp = 0;
// 按优先级判断按键(P3.3优先级最高)
if (P33 == 0) temp = 4; // 第4个按键按下
if (P32 == 0) temp = 3; // 第3个按键按下
if (P31 == 0) temp = 2; // 第2个按键按下
if (P30 == 0) temp = 1; // 第1个按键按下
return temp; // 返回0表示无按键,1-4表示按键编号
}
1.2 按键应用层(三行代码消抖)
Key_Val = Key_Read();
Key_Down = Key_Val & (Key_old ^ Key_Val);
Key_Up = ~Key_Val & (Key_old ^ Key_Val);
Key_old = Key_Val; // 保存当前状态供下次比较
状态变化表
| Key_Old | Key_Val | 对应的按键过程 | Key_Old ^ Key_Val | Key_Down |
|---|---|---|---|---|
| 0 | 0 | 未按下 | 0 | 0 |
| 0 | 4 | 按下过程中 | 4 | 4 |
| 4 | 4 | 按下稳定期间 | 0 | 0 |
| 4 | 0 | 抬起过程中 | 4 | 0 |
1.3 考点解析
考点1:模式切换
- S4:定义为“界面”按键,按下S4切换温度显示、参数设置和DAC输出界面。
unsigned char Seg_show_mode; // 0:温度显示 1:参数设置 2:DAC输出
void Key_Proc() {
static unsigned char Key_Val, Key_Down, Key_Up, Key_Old;
if (Key_Slow_Down) return;
Key_Slow_Down = 1;
Key_Val = Key_Read();
Key_Down = Key_Val & (Key_Old ^ key_Val);
Key_Up = ~Key_Val & (Key_Old ^ key_Val);
Key_Old = Key_Val;
if (Key_Down == 4)
Seg_show_mode = (++Seg_show_mode) % 3; // 循环0-2
}
考点2:参数设置
- S8:参数界面下,温度参数值加1。
- S9:参数界面下,温度参数值减1;时间回显子界面下,长按S9超过2秒后松开,清除所有记录数据,触发次数重置为0。
考点3:参数保存
通过S4按键从参数设置界面退出时,需检查参数合理性(Tmax ≥ Tmin);若合理则生效,否则恢复原参数。
unsigned char Tmax_Control, Tmin_Control; // 参数设置值
unsigned char Tmax, Tmin; // 参数保存值
void Key_Proc() {
static uchar Key_val, Key_Down, Key_Up, Key_Old;
if (Key_Slow_Down) return;
Key_Slow_Down = 1;
Key_val = Key_Read();
Key_Down = Key_val & (Key_Old ^ Key_val);
Key_Up = ~Key_val & (Key_Old ^ Key_val);
Key_Old = Key_val;
if (Key_Down == 8) Tmax_Control++;
if (Key_Down == 9) Tmin_Control++;
if (Key_Down == 4) {
if (Tmax_Control >= Tmin_Control) {
Tmax = Tmax_Control;
Tmin = Tmin_Control;
} else {
Tmax_Control = Tmax;
Tmin_Control = Tmin;
}
}
}
1.4 按键多击
bit key_click_flag; // 按键触发标志
unsigned char time_100ms;
unsigned char key_click_count;
void Key_Proc() {
static unsigned char Key_val, Key_Down, Key_Up, Key_Old;
unsigned char i;
if (Key_Slow_Down) return;
Key_Slow_Down = 1;
Key_val = Key_Read();
Key_Down = Key_Val & (Key_Old ^ key_val);
Key_Up = ~Key_Val & (Key_Old ^ key_val);
Key_Old = Key_Val;
if (Key_Down == 4) {
Time_100ms = 0;
Key_Click_Flag = 1;
Key_Click_Count++;
}
if (Time_100ms >= 100) {
switch (Key_Click_Count) {
case 1: // 单击
break;
case 2: // 双击
break;
case 3: // 三击
break;
}
Key_Click_Count = 0;
Key_Click_Flag = 0;
Time_100ms = 0;
}
}
定时器支持
void Timer1_Isr(void) interrupt 3 {
if (Key_Click_Flag) {
if (++Time_100ms >= 100)
Time_100ms = 101;
} else {
Time_100ms = 0;
}
}