代码中的问题在于,当输入的密码少于4位时,AudioOff 被设置为 0(关闭语音转发),但是没有在输入结束后将其重新设置为 1(打开语音转发)。这导致了当密码输入少于4位时,语音转发不会自动打开。
密码可以少于4位数,并且需要在输入结束后自动恢复语音转发。问题在于,当输入少于4位的密码时,语音转发没有被正确恢复。我们需要在每次输入结束后检查 N 的值,并在适当的时候将 AudioOff 设置回 1。
为了实现不定长密码输入,并且以时间或特定结束符表示输入完成,你可以修改代码以添加一个计时器或检测特定按键(例如长按某个键或输入特定字符)。这里,我将提供一个示例,使用特定按键(例如长按'#'键)作为结束输入的标志。
以下是修改后的代码:
```c
#include <reg52.h>
#include <intrins.h>
#define LCD_WriteCommand(x) LcdWrite(x, 0)
#define LCD_WriteData(x) LcdWrite(x, 1)
unsigned char InputData[10]; // 增加数组大小以存储更多密码
unsigned char N = 0; // 初始化数据输入位数
bit AudioOff = 1; // 初始化音频转发状态为打开
void Delay_ms(unsigned int ms);
void LCD_Init(void);
void LcdWrite(unsigned char cmd, bit data);
void UART_InitConfig(void);
void Timer0_Init(void);
unsigned char MatrixKey(void);
void main(void)
{
unsigned char keynum, NUM;
unsigned char i, j;
P1M0 &= 0x00;
P1M1 &= 0x00;
P3M0 &= ~0x0c; // P3^2-3准双向
P3M1 &= ~0x0c;
P3M0 |= 0xf0; // P3^4-7推挽输入
P3M1 &= ~0xf0;
P3 = 0x0f; // 初始化信道转换P3^4 5 6 7为低电平
Delay_ms(400); // 启动等待,等LCM讲入工作状态
LCD_Init(); // LCD初始化
UART_InitConfig();
Timer0_Init();
LCD_WriteCommand(0x80); // 设置光标位置
LCD_WriteData('W'); // 写入开机画面
LCD_WriteData('e');
LCD_WriteData('l');
LCD_WriteData('c');
LCD_WriteData('o');
LCD_WriteData('m');
LCD_WriteData('e');
LCD_WriteData('!');
while (1) // 进入循环
{
keynum = MatrixKey(); // 读按键的位置码
if (keynum) // 当有按键按下时
{
NUM = keynum; // 根据按键的位置将其编码,编码值赋值给NUM
switch (NUM) // 判断按键值
{
case ('A'): ; break;
case ('B'): ; break;
case ('C'): ; break; // ABC是无意义按键
case ('D'): ; break; // 可以添加重新设置密码的函数
case ('*'): ; break; // 可以添加取消当前输入的函数
case ('#'): // 长按'#'键结束输入
if (N > 0) // 确保有输入
{
AudioOff = 1; // 打开音频转发
LCD_WriteCommand(0x80 + 4 + N); // 移动光标到密码输入结束位置
LCD_WriteData('\n'); // 显示换行符表示输入结束
N = 0; // 重置密码位数
}
break;
default: // 如果不是功能键按下时,就是数字键按下
{
if (N < 10) // 限制密码最大长度为10位
{
AudioOff = 0; // 在有按键输入时,关闭发射机音频输入
LCD_WriteCommand(0x80 + 4 + N); // 显示位数随输入增加而增加
LCD_WriteData('*'); // 但不显示实际数字,用*代替
InputData[N] = NUM; // 将数字键的码赋值给InputData[]数组暂存
N++; // 密码位数加
}
}
}
}
else if (AudioOff == 1) // 当没有按键按下时,确保音频转发是打开的
{
Delay_ms(100); // 简单的防抖延时
if (!AudioOff) AudioOff = 1; // 再次检查并确保音频转发是打开的
}
}
}
void Delay_ms(unsigned int ms)
{
// 延时函数实现
}
void LCD_Init(void)
{
// LCD初始化函数实现
}
void LcdWrite(unsigned char cmd, bit data)
{
// LCD写入函数实现
}
void UART_InitConfig(void)
{
// UART初始化配置函数实现
}
void Timer0_Init(void)
{
// 定时器初始化函数实现
}
unsigned char MatrixKey(void)
{
// 矩阵键盘扫描函数实现
return 0; // 示例返回值
}
```
在这个修改中,我添加了一个长按'#'键作为结束输入的标志。当用户长按'#'键时,密码输入结束,音频转发自动打开,并在LCD上显示一个换行符表示输入结束。同时,我增加了一个简单的防抖延时,以确保在没有按键按下时,音频转发是打开的。
|