文章目录
- 一、功能简介
- 二、软件设计
- 三、实验现象
- 联系作者
一、功能简介
本项目使用STM32F103C8T6单片机控制器,使用按键、IIC OLED模块、DS18B20温度传感器、SG90舵机、红外遥控、矩阵按键、EEPROM等。
主要功能:
系统运行后,OLED显示RTC日期时间和温度;
键盘解锁:可使用矩阵键盘S1-S10键输入数字
0-9,初始密码为012345,当密码输入有误可按下S11键撤回,输入完成后可按下S12键解锁,若密码正确则开锁,舵机启动。若密码错误,OLED显示错误信息,当错误次数超过3次则锁死一段时间后重新输入。当按下S13键可修改密码,进入密码修改界面首先需校验旧密码,当输入旧密码正确,才可进入新密码设置。可按下S16键返回主界面。密码支持掉电不丢失。
红外遥控解锁:使用红外遥控器,按下第一个键(该键对应HEX为A2),则一键解锁。
二、软件设计
/*
作者:嗨小易(QQ:3443792007)*///系统参数初始化
void sys_parm_init(void)
{u8 i=0;sys_ctrl.mode=0;sys_ctrl.err_cnt=0;sys_ctrl.psw_flag=0;sys_ctrl.psw_resive=0;sys_ctrl.psw_bit=0;//初始密码0-5if(AT24CXX_ReadOneByte(255)!=0x28){AT24CXX_WriteOneByte(255,0x28);//写入初始密码到EEPROMfor(i=0;i<PSW_BITNUM;i++){sys_ctrl.save_psw[i]=i;AT24CXX_WriteOneByte(i,sys_ctrl.save_psw[i]);} }else{//读取EEPROM内密码数据for(i=0;i<PSW_BITNUM;i++){sys_ctrl.save_psw[i]=AT24CXX_ReadOneByte(i); } }
}//系统时钟温度显示模块
void sys_rtc_temp_show(void)
{u8 buf[5];static u8 i=0;OLED_Clear();OLED_ShowString(0,0, "2023-08-22 Week5",16);OLED_ShowString(0,20, " 12:16:56",16);OLED_ShowString(0,40," Temp: C",16);while(sys_ctrl.mode==0){//温度获取i++;if(i%1==0)sys_ctrl.temp=DS18B20_GetTemperture()*10;//日期显示buf[0]=calendar.w_year/1000+0x30;buf[1]=calendar.w_year%1000/100+0x30;buf[2]=calendar.w_year%1000%100/10+0x30;buf[3]=calendar.w_year%1000%100%10+0x30;buf[4]='\0';OLED_ShowString(0,0,buf,16);buf[0]=calendar.w_month/10+0x30;buf[1]=calendar.w_month%10+0x30;buf[2]='\0';OLED_ShowString(5*8,0,buf,16);buf[0]=calendar.w_date/10+0x30;buf[1]=calendar.w_date%10+0x30;buf[2]='\0';OLED_ShowString(8*8,0,buf,16);buf[0]=calendar.week%7+0x30;buf[1]='\0';OLED_ShowString(15*8,0,buf,16);//时间显示buf[0]=calendar.hour/10+0x30;buf[1]=calendar.hour%10+0x30;buf[2]='\0';OLED_ShowString(3*8,20,buf,16);//时buf[0]=calendar.min/10+0x30;buf[1]=calendar.min%10+0x30;buf[2]='\0';OLED_ShowString(6*8,20,buf,16);//分buf[0]=calendar.sec/10+0x30;buf[1]=calendar.sec%10+0x30;buf[2]='\0';OLED_ShowString(9*8,20,buf,16);//秒//温度显示buf[0]=sys_ctrl.temp/100+0x30;buf[1]=sys_ctrl.temp%100/10+0x30;buf[2]='.';buf[3]=sys_ctrl.temp%100%10+0x30;buf[4]='\0';OLED_ShowString(7*8,40,buf,16);//检测是否按下键,进入密码输入界面if(KEY_Matrix_Scan()!=0){sys_ctrl.mode=1;break;}OLED_Refresh_Gram();//刷新显存}
}//密码输入界面显示
void psw_input_show(void)
{OLED_Clear();OLED_ShowString(0,0,"Password:",16);
}
//修改密码时输入校验密码界面显示
void adjust_input_show(void)
{OLED_Clear();OLED_ShowString(0,0,"Calib Psw:",16);
}
//设置新密码界面显示
void set_new_psw_show(void)
{OLED_Clear();OLED_ShowString(0,0,"New Psw:",16);
}
//一键解锁界面显示
void one_click_unlock_show(void)
{OLED_Clear();OLED_ShowString(0,0,"One click unlock",16);OLED_ShowString(0,20,"OK...",16);
}//修改密码时,密码校验
void sys_psw_resive(void)
{u8 key=0;//在密码设置有效if(sys_ctrl.psw_resive){//初始化参数值sys_ctrl.psw_bit=0;sys_ctrl.err_cnt=0;sys_ctrl.psw_flag=0;memset(sys_ctrl.psw,0,PSW_BITNUM);//清除输入数据adjust_input_show();//修改密码时输入校验密码界面显示while(sys_ctrl.psw_resive){//键盘扫描key=KEY_Matrix_Scan();if(key>0)//按键输入{BEEP_Alarm(100,100);//提示音if(key<=10)//数字键0-9{if(sys_ctrl.psw_bit<PSW_BITNUM)//最多输入密码位数{sys_ctrl.psw[sys_ctrl.psw_bit]=key-1;//记录输入密码sys_ctrl.psw_bit++;//输入位数累加//密码可见if(PASSWORD_SHOW_HIDE)//显示输入密码OLED_ShowNum((9+sys_ctrl.psw_bit)*8,0,sys_ctrl.psw[sys_ctrl.psw_bit-1],1,16);//密码不可见elseOLED_ShowString((9+sys_ctrl.psw_bit)*8,0,"*",16);} }else if(key==11)//撤回键{sys_ctrl.psw[sys_ctrl.psw_bit-1]=10;//将所需撤回的数据设置为无效数OLED_ShowString((9+sys_ctrl.psw_bit)*8,0," ",16);//将撤销位置显示空位sys_ctrl.psw_bit--;if(sys_ctrl.psw_bit<0)sys_ctrl.psw_bit=0;}else if(key==12)//确定键{sys_ctrl.psw_flag=0;sys_ctrl.psw_bit=0;//输入密码与存储密码比较if(memcmp(sys_ctrl.psw,sys_ctrl.save_psw,PSW_BITNUM)==0)sys_ctrl.psw_flag=1;//密码正确memset(sys_ctrl.psw,0,PSW_BITNUM);//清除输入数据 //密码正确,开锁if(sys_ctrl.psw_flag==1){sys_ctrl.err_cnt=0;OLED_ShowString(0,20,"Password OK! ",16);OLED_Refresh_Gram();//刷新显存delay_ms(1000);break;//进入新密码设置程序 }//如果密码错误else{sys_ctrl.err_cnt++;//错误次数累计OLED_ShowString(0,20,"Password Error!",16);OLED_Refresh_Gram();//刷新显存//密码输入错误次数超限if(sys_ctrl.err_cnt>=ERROR_PASSWORD_CNT){sys_ctrl.err_cnt=0;OLED_ShowString(0,0,"Too many errors!",16);OLED_ShowString(0,20,"Please wait...",16);OLED_Refresh_Gram();//刷新显存delay_ms(1000); delay_ms(1000);delay_ms(1000);}else delay_ms(1000);adjust_input_show();//修改密码时输入校验密码界面显示}}else if(key==16)//退出键{sys_ctrl.psw_resive=0;sys_ctrl.mode=0;//回到时钟温度显示模式 break; }}OLED_Refresh_Gram();//刷新显存} }
}//应用控制系统
void app_sys_ctrl_demo(void)
{u8 i=10;LED_Init();USART1_Init(115200);AT24CXX_Init();OLED_Init();KEY_Matrix_Init();BEEP_Init();DS18B20_Init();RTC_Init();Hwjs_Init();//获取稳定数据while(i--){sys_ctrl.temp=DS18B20_GetTemperture()*10;delay_ms(100);}TIM4_Init(200,36000-1); //定时100msTIM3_CH2_PWM_Init(20000-1,71); //周期20mssteer_control(0);sys_parm_init();//系统参数初始化while(1){sys_rtc_temp_show();//系统时钟温度显示模块sys_psw_unlock_show();//系统解锁显示模块sys_psw_resive();//修改密码时,密码校验sys_new_psw_set();//新密码设置}
}
三、实验现象
B站演示视频:https://space.bilibili.com/444388619
联系作者
专注于51单片机、STM32、国产32、DSP、Proteus、ardunio、ESP32、物联网软件开发,PCB设计,视频分享,技术交流。