目录

1.题目

2.user.h中

3.user.c中

4.main中

5.超时跳转


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界面时要修改密码,等到修改完密码才会跳转页面,否则直接跳转    

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐