目录
一、题目
二、题目分析
2.1 按键功能分析
(1) 密码调整功能,按键刚上电显示界面的密码值为 @,按下 B1 , B2 , B3 三位密码值分别加 1
(2) 密码确认功能 B4 ,密码正确就跳转到输出状态页面,不正确就停留在输入界面,同时三位密码值重置为@
2.2 脉冲输出功能分析
(1) 无正确密码提交时,PA1 输出 1KHz 的方波信号
(2) 输入正确密码时,PA1 输出 2KHz 10% 占空比的脉冲信号持续 5 秒,之后切换回原始密码输入界面
2.3 串口通信功能分析
发送指定格式:当前密码 - 新密码,可修改密码,如果当前密码不正确就无法修改
2.4 LED 指示功能分析
(1) 密码验证成功,LD1 亮 5 秒之后熄灭
(2) 连续三次及以上的密码输入错误,LD2 以 0.1 秒闪烁 5 秒熄灭
三、CubeMX 配置
3.1 系统时钟配置
主频设置为80MHz,确保TIM、USART等外设时钟正确。
3.2 GPIO配置
按键(B1-B4):配置为输入模式,并写出相应名称。
LED(LD1-LD8):配置为输出模式,且初始电平设置为Low。
PA1(PWM输出):配置为TIM2_CH2的PWM模式。
3.3 定时器(TIM2)配置
3.4 串口(USART)配置
USART1:波特率9600,8位数据位,无校验位,1位停止位。
四、相关代码实现
4.1 按键扫描功能
(1)按键读取函数-->uint8_t KEY_Read(void)
uint8_t KEY_Read(void)
{
ucVal = 0;
if (HAL_GPIO_ReadPin(B1_GPIO_Port, B1_Pin) == 0)
{
HAL_Delay(10);
if (HAL_GPIO_ReadPin(B1_GPIO_Port, B1_Pin) == 0)
{
ucVal = 1;
}
}
if (HAL_GPIO_ReadPin(B2_GPIO_Port, B2_Pin) == 0)
{
HAL_Delay(10);
if (HAL_GPIO_ReadPin(B2_GPIO_Port, B2_Pin) == 0)
{
ucVal = 2;
}
}
if (HAL_GPIO_ReadPin(B3_GPIO_Port, B3_Pin) == 0)
{
HAL_Delay(10);
if (HAL_GPIO_ReadPin(B3_GPIO_Port, B3_Pin) == 0)
{
ucVal = 3;
}
}
if (HAL_GPIO_ReadPin(B4_GPIO_Port, B4_Pin) == 0)
{
HAL_Delay(10);
if (HAL_GPIO_ReadPin(B4_GPIO_Port, B4_Pin) == 0)
{
ucVal = 4;
}
}
return ucVal;
}
(2)B1/B2/B3:每次按下对应密码位+1(0-9循环)。
B4:验证密码,正确则切换PWM输出并跳转界面,错误则重置密码显示并计数。
void Key_Proc(void)
{
static uint8_t Key_old = 0,couter_error = 0;
uint8_t key;
if(ui == 0)
{
key = KEY_Read();
if(key != Key_old)
{
Key_old = key;
switch(key)
{
case 3:
if((psd[2]=='@')||(psd[2]=='9'))
{
psd[2]='0';
}
else
{
++psd[2];
}
break;
case 4:
if(psd[2]==psd_defualt[0])
{
ui = 1;
couter_error = 0;
led_5s = 5000;
}
else
{
psd[0] = '@';
psd[1] = '@';
psd[2] = '@';
++couter_error;
if(couter_error >= 3)
{
led_5s = 5000;
}
}
break;
default:
break;
}
}
}
}
4.2 LCD显示
(1)密码输入界面(PSD):
void Lcd_Proc(void)
{
uint8_t uclcd[21];//lcd display ram
if(lcd_100ms<100) return;
lcd_100ms = 0; //reset
if(ui == 0)
{
sprintf((char *)uclcd, " PSD");
LCD_DisplayStringLine(Line2, uclcd);
sprintf((char *)uclcd, " B1:%c ",psd[0]);
LCD_DisplayStringLine(Line4, uclcd);
sprintf((char *)uclcd, " B2:%c ",psd[1]);
LCD_DisplayStringLine(Line5, uclcd);
sprintf((char *)uclcd, " B3:%c ",psd[2]);
LCD_DisplayStringLine(Line6, uclcd);
}
else
{
//...
}
}
(2)输出状态界面(STA):
void Lcd_Proc(void)
{
uint8_t uclcd[21];
if(lcd_100ms<100) return;
lcd_100ms = 0;
if(ui == 0)
{
//...
}
else
{
sprintf((char *)uclcd, " STA");
LCD_DisplayStringLine(Line2, uclcd);
sprintf((char *)uclcd, " F:2000Hz ");
LCD_DisplayStringLine(Line4, uclcd);
sprintf((char *)uclcd, " D:10%% ");
LCD_DisplayStringLine(Line5, uclcd);
sprintf((char *)uclcd, " ");
LCD_DisplayStringLine(Line6, uclcd);
}
}
!!!由于代码较长,故不一一展示,有需要可联系我获取完整代码
4.3 PWM输出控制
默认状态:1KHz方波(ARR=999, Pulse=500)。
密码正确时:2KHz 10%占空比(ARR=499, Pulse=50),持续5秒后恢复默认。
4.4 串口通信
接收格式:当前密码-新密码(如123-789)。校验当前密码是否正确。若正确,更新密码并返回Success;否则返回Fail。
4.5 LED指示灯控制
密码正确时LD1点亮5秒,连续3次错误后LD2闪烁。
五、测试结果
(1)上电默认显示PSD界面,密码位显示@。
(2)输入正确密码(默认123)后:切换界面,显示F:2000Hz, D:10%。PA1输出2KHz 10%占空比脉冲,持续5秒后恢复1KHz方波。LD1点亮5秒。
(3)连续3次输入错误密码:LD2以0.1秒间隔闪烁5秒。
(4)串口通信:发送123-789修改密码---->密码正确时更新,错误时提示。