蓝桥杯嵌入式第十六届模拟题
修改界面下,必须在3秒内确定第一位修改的密码,不然就会自动跳回第一个页面。没有设置输入一位密码后或者修改一位密码后才可以进行下一位的操作。
·
目录
1.题目




2.user.h中
#ifndef __USER_H
#define __USER_H
#include "main.h"
#include "stdio.h"
#include "i2c.h"
#include "math.h"
void key_scan(void);
void key_pro(void);
void ADC_R37pro(void);
void led_Disp(void);
void lcd_pro(void);
void eep_write(unsigned char addr,u8 dat);
uint8_t eep_read(u8 address);
void Password_Init(void);
#endif
3.user.c中
#include "user.h"
extern ADC_HandleTypeDef hadc2;
uint32_t adc_tick = 0;
double R37_volt = 0;
u16 time_ms = 0;
uint8_t page_index = 1; //页面
uint8_t is_voltage_changed = 0; // 标记电压是否变化超过阈值
void ADC_R37pro(void)
{
uint16_t ADC_Value;
static double prev_R37_volt = 0.0; // 静态变量保存前一次电压值
if(uwTick - adc_tick < 50)
return;
adc_tick = uwTick;
HAL_ADC_Start(&hadc2);
ADC_Value = HAL_ADC_GetValue(&hadc2);
double current_volt = (ADC_Value * 3.3f) / 4096.0f;
if(page_index == 2)
{
//在set页面中,检测电压变化超过正负0.25视为要改密码,不跳转页面
if (fabs(current_volt - prev_R37_volt) >= 0.25)
{
time_ms = 0; // 重置超时计时
is_voltage_changed = 1;
}
else is_voltage_changed = 0;
}
prev_R37_volt = current_volt; // 更新前次电压
R37_volt = current_volt; // 更新当前电压
}
uint8_t eep_read(u8 address)
{
I2CStart();
I2CSendByte (0xa0);
I2CWaitAck ();
I2CSendByte (address);
I2CWaitAck ();
I2CStop ();
I2CStart ();
I2CSendByte (0xa1);
I2CWaitAck ();
u8 data = I2CReceiveByte ();
I2CSendNotAck ();
I2CStop ();
return data;
}
void eep_write(unsigned char addr,u8 dat)
{
I2CStart();
I2CSendByte (0xa0);
I2CWaitAck();
I2CSendByte(addr);
I2CWaitAck();
I2CSendByte(dat);
I2CWaitAck();
I2CStop();
}
void Password_Init(void)
{
//第一次烧录,进行代码初始化
if(eep_read(123) != 123) //上电后,不等于,代表第一次写(初始化密码012)
{
eep_write(123,123);
HAL_Delay(5); //IIC通信速度慢,确保存入
eep_write(0x00,0);
HAL_Delay(5);
eep_write(0x01,1);
HAL_Delay(5);
eep_write(0x02,2);
}
}
uint8_t key_value,key_down,key_up,key_old = 0;
void key_scan(void)
{
if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0) == RESET)
key_value = 1;
else if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1) == RESET)
key_value = 2;
else if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2) == RESET)
key_value = 3;
else if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0) == RESET)
key_value = 4;
else key_value = 0;
key_down = key_value & (key_value ^ key_old);
key_up = ~key_value & (key_value ^ key_old);
key_old = key_value;
}
uint8_t a , b , c , e , f ,g; //前三位为输入密码,后三位为修改密码
uint8_t pass_bit = 1; //输入密码位数
uint8_t change_password_bit = 1; //修改密码位数
uint32_t key_tick = 0;
void key_pro(void)
{
if(uwTick - key_tick < 10)
return;
key_tick = uwTick;
key_scan();
if(page_index == 1)
{
change_password_bit = 1; //修改密码的第一位
if(key_down == 1) //输入密码位数加确定位
{
pass_bit ++;
if(pass_bit > 4)
{
pass_bit = 1;
}
}
//密码正确
if(a == eep_read(0x00) && b == eep_read(0x01) && c == eep_read(0x02) && pass_bit == 4)
{
page_index = 2;
LCD_Clear(Black);
}
}
else if(page_index == 2)
{
pass_bit = 1; //输入密码的第一位.无论对错都重置
if(key_down == 1) //修改密码位数加加(确定)
{
change_password_bit++;
time_ms = 0; // 重置超时计时
if(change_password_bit > 3)// 输入完成
{
change_password_bit = 1;
is_voltage_changed = 0; // 清除电压变化标记
page_index = 1;
LCD_Clear(Black);
eep_write(0x00,e); //存入修改密码
HAL_Delay(5);
eep_write(0x01,f);
HAL_Delay(5);
eep_write(0x02,g);
}
}
}
}
extern TIM_HandleTypeDef htim2;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if (htim->Instance == TIM2)
{
if (page_index == 2 && change_password_bit <= 3)
{
// 仅在未完成修改且电压未变化时累加超时
if (!is_voltage_changed) {
time_ms++;
}
if (time_ms >= 3000) // 超时跳转条件
{
page_index = 1;
time_ms = 0;
change_password_bit = 1;
e = f = g = 0; // 清空修改密码输入
LCD_Clear(Black);
}
}
}
}
void led_Disp(void)
{
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_All,GPIO_PIN_SET);
if(page_index == 1)
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_8,GPIO_PIN_RESET);
else if(page_index == 2)
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_9,GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
}
char buf[30];
uint32_t lcd_tick = 0;
void lcd_pro(void)
{
if(uwTick - lcd_tick < 200)
return;
lcd_tick = uwTick;
sprintf(buf," %.1lf ",R37_volt);
LCD_DisplayStringLine(Line7,(u8 *)buf);
if(page_index == 1)
{
LCD_DisplayStringLine(Line1,(u8 *)" Lock ");
LCD_DisplayStringLine(Line3,(u8 *)" Pass Word ");
if(pass_bit == 1)
{
if(R37_volt < 1.50)a = 0;
else if(R37_volt >= 1.50 && R37_volt <= 2.50)a = 1;
if(R37_volt > 2.50)a = 2;
sprintf(buf," %d * * ",a);
LCD_DisplayStringLine(Line4,(u8 *)buf);
}
else if(pass_bit == 2)
{
if(R37_volt < 1.50)b = 0;
else if(R37_volt >= 1.50 && R37_volt <= 2.50)b = 1;
if(R37_volt > 2.50)b = 2;
sprintf(buf," %d %d * ",a,b);
LCD_DisplayStringLine(Line4,(u8 *)buf);
}
else if(pass_bit == 3)
{
if(R37_volt < 1.50)c = 0;
else if(R37_volt >= 1.50 && R37_volt <= 2.50)c = 1;
else if(R37_volt > 2.50)c = 2;
sprintf(buf," %d %d %d ",a,b,c);
LCD_DisplayStringLine(Line4,(u8 *)buf);
}
}
else if(page_index == 2)
{
LCD_DisplayStringLine(Line1,(u8 *)" Set ");
LCD_DisplayStringLine(Line3,(u8 *)" Change ");
if(change_password_bit == 1)
{
if(R37_volt < 1.50)e = 0;
else if(R37_volt >= 1.50 && R37_volt <= 2.50)e = 1;
if(R37_volt > 2.50)e = 2;
sprintf(buf," %d * * ",e);
LCD_DisplayStringLine(Line4,(u8 *)buf);
}
else if(change_password_bit == 2)
{
if(R37_volt < 1.50)f = 0;
else if(R37_volt >= 1.50 && R37_volt <= 2.50)f = 1;
if(R37_volt > 2.50)f = 2;
sprintf(buf," %d %d * ",e,f);
LCD_DisplayStringLine(Line4,(u8 *)buf);
}
else if(change_password_bit == 3)
{
if(R37_volt < 1.50)g = 0;
else if(R37_volt >= 1.50 && R37_volt <= 2.50)g = 1;
else if(R37_volt > 2.50)g = 2;
sprintf(buf," %d %d %d ",e,f,g);
LCD_DisplayStringLine(Line4,(u8 *)buf);
}
}
}
4.main中
#include "user.h"
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_ADC2_Init();
MX_TIM2_Init();
I2CInit();
LCD_Init();
Password_Init();
LCD_Clear(Black);
LCD_SetBackColor(Black);
LCD_SetTextColor(White);
HAL_TIM_Base_Start_IT(&htim2); //3秒
while (1)
{
key_pro();
led_Disp();
ADC_R37pro();
lcd_pro();
}
}
5.超时跳转
在3s内扭动电位器导致电压变化超过正负0.25V时,视为在Set界面时要修改密码,等到修改完密码才会跳转页面,否则直接跳转
更多推荐



所有评论(0)