智能门禁的计划

项目需求

  1. 矩阵键盘输入密码,正确开锁,错误提示,三次错误后蜂鸣器响三秒;
  2. 按下#号确认输入,按下*号修改密码;
  3. 密码保存在W25Q128里;
  4. OLED屏幕显示信息。

硬件清单

矩阵键盘OLED显示屏继电器蜂鸣器W25Q128存储器
开发板ST-LinkUSB转TTL杜邦线------

其中,OLED显示器利用的是I2C的通信协议,W25Q128用的是SPI的通信协议 ;

矩阵键盘这节课进行介绍。

硬件接线

 简图:

模块:矩阵键盘(原理+驱动) 

         学了了独立按键之后,发现使用一个按键就要浪费一个IO口。那有没有一种节约GPIO的方法,比如要用16个按键,怎么样才能节省IO口?那我们就可以用矩阵键盘。16个按键,只需8IO口。

矩阵键盘介绍

我们矩阵键盘的型号多种多样,有 1x43x33x44x4,甚至是 8x8 的;有薄膜的,有按键的

矩阵键盘常见用途:

1. 电子密码锁

2. ATM 的键盘

3. POS机 的键盘

4. 家用电器的控制面板(微波炉、洗衣机等)

工作参数及引脚介绍 

引脚介绍:

  • 按键式的有的有引脚标识,R 是行,C 是列。有的没有引脚标识,可以找商家问下,或者自己看原理图。

  • 薄膜式的都没有引脚标识。键盘正对自己,引脚是先行后列,从小到大。

 矩阵键盘工作原理

 这是矩阵键盘(4x4)内部电路示意图:

矩阵键盘识别常用——逐行逐列扫描法 

  1. 使列线连接的I/O引脚输出低电平,四条行线所连接的I/O引脚输出高电平,当没有按键按下时,四条行线所连接的I/O引脚读取的将全部是高电平;当按键按下时,由于按键所在的行线与列线相通,行线将被下拉到低电阻。此时读取行线所连接的引脚,将不再是高电平。
  2. 逐列将列线依次置低电平,读取行线,如果某一条行线为低电平,则说明该行线与当前的行线为低电平的列线交叉点处的按键被按下,从判断按键按下。

中断来实现识别

  1. 把所有行引脚设成中断引脚,默认是上拉输入,下降沿触发,GPIO引脚输出高电平。
  2. 把所有列引脚连接的GPIO引脚设成输入内部下拉。(GPIO引脚输入,默认是下拉)
  3. 当有中断触发的时候就可以知道哪一行有按键按下,再逐列看哪一列变成高电平,就是哪个按键被触发了。

小实验:串口输出矩阵键盘按下的按键 

硬件清单:

STM32F103C8T6、矩阵键盘(3x4,薄膜)、USB转TTL、ST-Link

硬件接线: 

文件代码:

  • keyboard.c
#include "keyboard.h"#include "delay.h" uint8_t key_value; void keyboard_init(void){        //打开时钟    __HAL_RCC_GPIOB_CLK_ENABLE();    //调用GPIO的初始化函数    GPIO_InitTypeDef GPIO_Initstruct;        GPIO_Initstruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_10;    GPIO_Initstruct.Mode = GPIO_MODE_IT_FALLING;    GPIO_Initstruct.Pull = GPIO_PULLUP;    GPIO_Initstruct.Speed = GPIO_SPEED_FREQ_HIGH;    HAL_GPIO_Init(GPIOB, &GPIO_Initstruct);        GPIO_Initstruct.Pin = GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14;    GPIO_Initstruct.Mode = GPIO_MODE_INPUT;    GPIO_Initstruct.Pull = GPIO_PULLDOWN;    //配置成下拉模式,当导通时,会变成高电平    GPIO_Initstruct.Speed = GPIO_SPEED_FREQ_HIGH;    HAL_GPIO_Init(GPIOB, &GPIO_Initstruct);         HAL_NVIC_SetPriority(EXTI0_IRQn,2,2);    HAL_NVIC_EnableIRQ(EXTI0_IRQn);        HAL_NVIC_SetPriority(EXTI1_IRQn,2,2);    HAL_NVIC_EnableIRQ(EXTI1_IRQn);        HAL_NVIC_SetPriority(EXTI2_IRQn,2,2);    HAL_NVIC_EnableIRQ(EXTI2_IRQn);        HAL_NVIC_SetPriority(EXTI15_10_IRQn,2,2);    HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);    } void EXTI0_IRQHandler(void){        HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);    } void EXTI1_IRQHandler(void){        HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_1);    }void EXTI2_IRQHandler(void){        HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_2); }void EXTI15_10_IRQHandler(void){        HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_10);    } void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){    uint8_t row = 0,column = 0;    if(key_value != 0) return;    //防止手速过快,只读取第一次按下时的按键值        //确定行    if(GPIO_Pin == GPIO_PIN_0)        row  = 0x10;    else if(GPIO_Pin == GPIO_PIN_1)        row = 0x20;    else if(GPIO_Pin == GPIO_PIN_2)        row = 0x30;    else if(GPIO_Pin == GPIO_PIN_10)        row = 0x40;        //确定列    if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_11) == GPIO_PIN_SET){        delay_ms(10);        while(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_11) == GPIO_PIN_SET);        column = 0x01;    }    else if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_12) == GPIO_PIN_SET){        delay_ms(10);        while(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_12) == GPIO_PIN_SET);        column = 0x02;    }     else if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_13) == GPIO_PIN_SET){        delay_ms(10);        while(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_13) == GPIO_PIN_SET);        column = 0x03;    }     else if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_14) == GPIO_PIN_SET){        delay_ms(10);        while(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_14) == GPIO_PIN_SET);        column = 0x04;    }         if(row != 0 && column != 0)        key_value = row | column;    //按位与进行拼接} uint8_t keyboard_get_value(void){    uint8_t ch = 0;    if(key_value != 0)    {        if(key_value == 0x11) ch = '1';        else if(key_value == 0x12) ch = '2';        else if(key_value == 0x13) ch = '3';        else if(key_value == 0x14) ch = 'A';                else if(key_value == 0x21) ch = '4';        else if(key_value == 0x22) ch = '5';        else if(key_value == 0x23) ch = '6';        else if(key_value == 0x24) ch = 'B';                else if(key_value == 0x31) ch = '7';        else if(key_value == 0x32) ch = '8';        else if(key_value == 0x33) ch = '9';        else if(key_value == 0x34) ch = 'C';                else if(key_value == 0x41) ch = '*';        else if(key_value == 0x42) ch = '0';        else if(key_value == 0x43) ch = '#';        else if(key_value == 0x44) ch = 'D';        delay_ms(400);        key_value = 0x00;    }    return ch;}
  •  keyboard.h
#ifndef __KEYBOARD_H__#define __KEYBOARD_H__#include "stm32f1xx.h" void keyboard_init(void);uint8_t keyboard_get_value(void); #endif
  • main.c文件代码 
#include "sys.h"#include "led.h"#include "delay.h"#include "uart1.h"#include "keyboard.h"  int main(void){    HAL_Init();                         /* 初始化HAL库 */    stm32_clock_init(RCC_PLL_MUL9);     /* 设置时钟, 72Mhz */    led_init();                         /* LED初始化 */    uart1_init(115200);    printf("hello,world");    keyboard_init();        uint8_t key_value = 0;        while(1)    {         key_value = keyboard_get_value();        if(key_value != 0){            printf("按下了:%c \r\n",key_value);            key_value = 0;        }    }}

注意:这个代码采用的是配置中断来实现,要回顾关于中断的配置流程。 

 项目框图

(要养成习惯,在做项目的时候一定要配置流程图)

项目代码

输出设备

  • OLED

oled.c文件代码:

#include "oled.h"#include "delay.h"#include "font.h" void oled_gpio_init(void){    GPIO_InitTypeDef gpio_initstruct;    OLED_I2C_SCL_CLK();    OLED_I2C_SDA_CLK();        gpio_initstruct.Pin = OLED_I2C_SCL_PIN;    gpio_initstruct.Mode = GPIO_MODE_OUTPUT_OD;    gpio_initstruct.Pull = GPIO_PULLUP;    gpio_initstruct.Speed = GPIO_SPEED_FREQ_HIGH;    HAL_GPIO_Init(OLED_I2C_SCL_PORT,&gpio_initstruct);        gpio_initstruct.Pin = OLED_I2C_SDA_PIN;    HAL_GPIO_Init(OLED_I2C_SDA_PORT,&gpio_initstruct);    } /*** @breif 配置I2C协议的时序图:开始,读写,应答,结束。* @note     在配置读写时序的时候,要注意。。。。。**/void oled_i2c_start(void){    OLED_SCL_SET();    OLED_SDA_SET();    OLED_SDA_RESET();    OLED_SCL_RESET();} void oled_i2c_stop(void){    OLED_SCL_RESET();    OLED_SDA_RESET();    OLED_SCL_SET();    OLED_SDA_SET();}void oled_i2c_ack(void){    OLED_SCL_SET();    OLED_SCL_RESET();} void oled_i2c_write_byte(uint8_t data){    uint8_t i,temp;    temp = data;    for(i = 0;i > 4) | 0x10);  //取高位}  /*** @breif    设置oled显示屏清屏函数* @note     */void oled_fill(uint8_t data){    uint8_t i,j;    for (i = 0;i < 8 ;i++){        oled_set_cursor(i,0);        for(j = 0;j < 128;j++)            oled_write_date(data);    } } /*** @breif    封装oled显示屏显示字符、字符串、汉字、图像的函数* @note     */ void oled_show_char(uint8_t x ,uint8_t y,uint8_t number ,uint8_t size){         //size代表的是高度        number = number - ' ';    uint8_t i,j,page;                       //page:表示输入的字符总共需要的PAGE        page = size / 8;    if(size % 8 != 0)        page ++;     for (i = 0;i < page; i++)    {        oled_set_cursor(x+i,y);        for (j = size / 2 * i;j < size / 2 * (i + 1); j++){              //size/2:高度的一半是宽度            if(size == 16)                oled_write_date(ascii_8X16[number][j]);                           }    }} //显示字符串void oled_show_string(uint8_t x,uint8_t y,char *p ,uint8_t size){        while(*p != '\0'){        oled_show_char(x,y,*p,size);      //*p:取出数组中的首元素        y += size / 2;        p++;                               //p++:代表的是数组指针递增,指向下一个元素地址。    }} //void oled_show_chinese(uint8_t x,uint8_t y, uint8_t N ,uint8_t size){ //    uint8_t i,j;//    for (i = 0 ; i < size / 8 ;i++){//        oled_set_cursor(x+i,y);//        for(j = size * i;j < size * (i + 1);j++){//            if(size == 16)//                oled_write_date(chinese_16X16[N][j]);            if(size == 24)                oled_write_date(chinese_24X24[N][j]);//        }//    }//} //显示汉字的函数void oled_show_chinese(uint8_t x,uint8_t y, uint8_t N ,uint8_t message_type){     uint8_t i,j;    for (i = 0 ; i < 2 ;i++){        oled_set_cursor(x+i,y);        for(j = 16 * i;j < 16 * (i + 1);j++){            switch (message_type){                case SHOW_INPUT_PWD:                    oled_write_date(chinese_enter_password[N][j]);                    break;                                case SHOW_PWD_RIGHT:                    oled_write_date(chinese_password_right[N][j]);                    break;                                case SHOW_PWD_ERROR:                    oled_write_date(chinese_password_error[N][j]);                    break;                                case SHOW_INPUT_OLD_PWD:                    oled_write_date(chinese_enter_oldPassword[N][j]);                    break;                                case SHOW_INPUT_NEW_PWD:                    oled_write_date(chinese_enter_newPassword[N][j]);                    break;                                case SHOW_PWD_CHANGE:                    oled_write_date(modify_passWord_complete[N][j]);                    break;                                case SHOW_SET_PWD:                    oled_write_date(set_passWord[N][j]);                    break;                                default:                    break;              }        }    }} //请输入密码void oled_show_input(void){    oled_fill(0x00);    oled_show_chinese(1,10,0,SHOW_INPUT_PWD);    oled_show_chinese(1,30,1,SHOW_INPUT_PWD);    oled_show_chinese(1,50,2,SHOW_INPUT_PWD);    oled_show_chinese(1,70,3,SHOW_INPUT_PWD);    oled_show_chinese(1,90,4,SHOW_INPUT_PWD);    oled_show_char(1,110,':',16);}//密码正确void oled_pwd_right(void){    oled_fill(0x00);    oled_show_chinese(1,10,0,SHOW_PWD_RIGHT);    oled_show_chinese(1,30,1,SHOW_PWD_RIGHT);    oled_show_chinese(1,50,2,SHOW_PWD_RIGHT);    oled_show_chinese(1,70,3,SHOW_PWD_RIGHT);    oled_show_char(1,90,':',16);}//密码错误void oled_pwd_error(void){    oled_fill(0x00);    oled_show_chinese(1,10,0,SHOW_PWD_ERROR);    oled_show_chinese(1,30,1,SHOW_PWD_ERROR);    oled_show_chinese(1,50,2,SHOW_PWD_ERROR);    oled_show_chinese(1,70,3,SHOW_PWD_ERROR);    oled_show_char(1,110,':',16);}//请输入旧密码void oled_input_old_pwd(void){    oled_fill(0x00);    oled_show_chinese(1,10,0,SHOW_INPUT_OLD_PWD);    oled_show_chinese(1,26,1,SHOW_INPUT_OLD_PWD);    oled_show_chinese(1,42,2,SHOW_INPUT_OLD_PWD);    oled_show_chinese(1,58,3,SHOW_INPUT_OLD_PWD);    oled_show_chinese(1,74,4,SHOW_INPUT_OLD_PWD);    oled_show_chinese(1,90,5,SHOW_INPUT_OLD_PWD);    oled_show_char(1,106,':',16);}//请输入新密码void oled_input_new_pwd(void){    oled_fill(0x00);    oled_show_chinese(1,10,0,SHOW_INPUT_NEW_PWD);    oled_show_chinese(1,26,1,SHOW_INPUT_NEW_PWD);    oled_show_chinese(1,42,2,SHOW_INPUT_NEW_PWD);    oled_show_chinese(1,58,3,SHOW_INPUT_NEW_PWD);    oled_show_chinese(1,74,4,SHOW_INPUT_NEW_PWD);    oled_show_chinese(1,90,4,SHOW_INPUT_NEW_PWD);    oled_show_char(1,106,':',16);}//密码修改完成void oled_modif_pwd_complete(void){    oled_fill(0x00);    oled_show_chinese(1,10,0,SHOW_PWD_CHANGE);    oled_show_chinese(1,26,1,SHOW_PWD_CHANGE);    oled_show_chinese(1,42,2,SHOW_PWD_CHANGE);    oled_show_chinese(1,58,3,SHOW_PWD_CHANGE);    oled_show_chinese(1,74,4,SHOW_PWD_CHANGE);    oled_show_chinese(1,90,5,SHOW_PWD_CHANGE);    oled_show_char(1,106,':',16);}//请设置密码void oled_set_pwd(void){    oled_fill(0x00);    oled_show_chinese(1,10,0,SHOW_SET_PWD);    oled_show_chinese(1,30,1,SHOW_SET_PWD);    oled_show_chinese(1,50,2,SHOW_SET_PWD);    oled_show_chinese(1,70,3,SHOW_SET_PWD);    oled_show_chinese(1,90,4,SHOW_SET_PWD);    oled_show_char(1,110,':',16);} //显示图像 void oled_show_image(uint8_t x,uint8_t y, uint8_t width ,uint8_t highth ,uint8_t * bpm){     uint8_t i,j;     for(i = 0; i < highth ;i++)     {         oled_set_cursor(x+i,j);         for(j = 0;j < width;j++)            oled_write_date(bpm[ width * i + j ]);     } }

 oled.h文件代码:

#ifndef __OLED_H__#define __OLED_H__#include "stm32f1xx.h" enum message{    SHOW_INPUT_PWD = 0,    SHOW_PWD_RIGHT,    SHOW_PWD_ERROR,    SHOW_INPUT_OLD_PWD,    SHOW_INPUT_NEW_PWD,    SHOW_PWD_CHANGE,    SHOW_SET_PWD    };  #define OLED_I2C_SCL_CLK()       __HAL_RCC_GPIOB_CLK_ENABLE()#define OLED_I2C_SCL_PORT       GPIOB#define OLED_I2C_SCL_PIN        GPIO_PIN_8 #define OLED_I2C_SDA_CLK()      __HAL_RCC_GPIOB_CLK_ENABLE()#define OLED_I2C_SDA_PORT       GPIOB#define OLED_I2C_SDA_PIN        GPIO_PIN_9 #define OLED_SCL_RESET()          HAL_GPIO_WritePin(OLED_I2C_SCL_PORT,OLED_I2C_SCL_PIN,GPIO_PIN_RESET)#define OLED_SCL_SET()            HAL_GPIO_WritePin(OLED_I2C_SCL_PORT,OLED_I2C_SCL_PIN,GPIO_PIN_SET) #define OLED_SDA_RESET()          HAL_GPIO_WritePin(OLED_I2C_SDA_PORT,OLED_I2C_SDA_PIN,GPIO_PIN_RESET)#define OLED_SDA_SET()            HAL_GPIO_WritePin(OLED_I2C_SDA_PORT,OLED_I2C_SDA_PIN,GPIO_PIN_SET)  void oled_init(void);void oled_set_cursor(uint8_t x,uint8_t y);void oled_fill(uint8_t data);void oled_write_date(uint8_t data);void oled_show_char(uint8_t x ,uint8_t y,uint8_t number ,uint8_t size);void oled_show_string(uint8_t x,uint8_t y,char *p ,uint8_t size);void oled_show_chinese(uint8_t x, uint8_t y, uint8_t N, uint8_t size);void oled_show_image(uint8_t x,uint8_t y, uint8_t width ,uint8_t highth,uint8_t * bpm); void oled_show_input(void);void oled_pwd_right(void);void oled_pwd_error(void);void oled_input_old_pwd(void);void oled_input_new_pwd(void);void oled_modif_pwd_complete(void);void oled_set_pwd(void);  #endif

font.h文件代码 

#ifndef __FONT_H__#define __FONT_H__ //请输入密码;const unsigned char chinese_enter_password[][32] = {    0x40,0x42,0xCC,0x00,0x00,0x44,0x54,0x54,0x54,0x7F,0x54,0x54,0x54,0x44,0x40,0x00,    0x00,0x00,0x7F,0x20,0x10,0x00,0xFF,0x15,0x15,0x15,0x55,0x95,0x7F,0x00,0x00,0x00,/*"请",0*/            0x88,0x68,0x1F,0xC8,0x08,0x10,0xC8,0x54,0x52,0xD1,0x12,0x94,0x08,0xD0,0x10,0x00,    0x09,0x19,0x09,0xFF,0x05,0x00,0xFF,0x12,0x92,0xFF,0x00,0x5F,0x80,0x7F,0x00,0x00,/*"输",1*/            0x00,0x00,0x00,0x00,0x00,0x01,0xE2,0x1C,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,    0x80,0x40,0x20,0x10,0x0C,0x03,0x00,0x00,0x00,0x03,0x0C,0x30,0x40,0x80,0x80,0x00,/*"入",2*/            0x10,0x8C,0x44,0x04,0xE4,0x04,0x95,0xA6,0x44,0x24,0x14,0x84,0x44,0x94,0x0C,0x00,    0x02,0x02,0x7A,0x41,0x41,0x43,0x42,0x7E,0x42,0x42,0x42,0x43,0xF8,0x00,0x00,0x00,/*"密",3*/            0x04,0x84,0xE4,0x5C,0x44,0xC4,0x00,0x02,0xF2,0x82,0x82,0x82,0xFE,0x80,0x80,0x00,    0x02,0x01,0x7F,0x10,0x10,0x3F,0x00,0x08,0x08,0x08,0x08,0x48,0x88,0x40,0x3F,0x00,/*"码",4*/}; //密码正确;const unsigned char chinese_password_right[][32] = {    0x10,0x8C,0x44,0x04,0xE4,0x04,0x95,0xA6,0x44,0x24,0x14,0x84,0x44,0x94,0x0C,0x00,    0x02,0x02,0x7A,0x41,0x41,0x43,0x42,0x7E,0x42,0x42,0x42,0x43,0xF8,0x00,0x00,0x00,/*"密",0*/        0x04,0x84,0xE4,0x5C,0x44,0xC4,0x00,0x02,0xF2,0x82,0x82,0x82,0xFE,0x80,0x80,0x00,    0x02,0x01,0x7F,0x10,0x10,0x3F,0x00,0x08,0x08,0x08,0x08,0x48,0x88,0x40,0x3F,0x00,/*"码",1*/        0x00,0x02,0x02,0xC2,0x02,0x02,0x02,0xFE,0x82,0x82,0x82,0x82,0x82,0x02,0x00,0x00,    0x40,0x40,0x40,0x7F,0x40,0x40,0x40,0x7F,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,/*"正",2*/        0x04,0x84,0xE4,0x5C,0x44,0xC4,0x20,0x10,0xE8,0x27,0x24,0xE4,0x34,0x2C,0xE0,0x00,    0x02,0x01,0x7F,0x10,0x10,0x3F,0x80,0x60,0x1F,0x09,0x09,0x3F,0x49,0x89,0x7F,0x00,/*"确",3*/};//密码错误;const unsigned char chinese_password_error[][32] = {    0x10,0x8C,0x44,0x04,0xE4,0x04,0x95,0xA6,0x44,0x24,0x14,0x84,0x44,0x94,0x0C,0x00,    0x02,0x02,0x7A,0x41,0x41,0x43,0x42,0x7E,0x42,0x42,0x42,0x43,0xF8,0x00,0x00,0x00,/*"密",0*/        0x04,0x84,0xE4,0x5C,0x44,0xC4,0x00,0x02,0xF2,0x82,0x82,0x82,0xFE,0x80,0x80,0x00,    0x02,0x01,0x7F,0x10,0x10,0x3F,0x00,0x08,0x08,0x08,0x08,0x48,0x88,0x40,0x3F,0x00,/*"码",1*/        0x40,0x30,0xEF,0x24,0x64,0x48,0x48,0x7F,0x48,0x48,0x48,0x7F,0x48,0x48,0x40,0x00,    0x01,0x01,0x7F,0x21,0x11,0x00,0xFF,0x49,0x49,0x49,0x49,0x49,0xFF,0x00,0x00,0x00,/*"错",2*/        0x40,0x42,0xCC,0x00,0x00,0x80,0x9E,0x92,0x92,0x92,0x92,0x92,0x9E,0x80,0x00,0x00,    0x00,0x00,0x7F,0x20,0x94,0x84,0x44,0x24,0x14,0x0F,0x14,0x24,0x44,0x84,0x84,0x00,/*"误",3*/}; //请输入旧密码;const unsigned char chinese_enter_oldPassword[][32] = {    0x40,0x42,0xCC,0x00,0x00,0x44,0x54,0x54,0x54,0x7F,0x54,0x54,0x54,0x44,0x40,0x00,    0x00,0x00,0x7F,0x20,0x10,0x00,0xFF,0x15,0x15,0x15,0x55,0x95,0x7F,0x00,0x00,0x00,/*"请",0*/        0x88,0x68,0x1F,0xC8,0x08,0x10,0xC8,0x54,0x52,0xD1,0x12,0x94,0x08,0xD0,0x10,0x00,    0x09,0x19,0x09,0xFF,0x05,0x00,0xFF,0x12,0x92,0xFF,0x00,0x5F,0x80,0x7F,0x00,0x00,/*"输",1*/        0x00,0x00,0x00,0x00,0x00,0x01,0xE2,0x1C,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,    0x80,0x40,0x20,0x10,0x0C,0x03,0x00,0x00,0x00,0x03,0x0C,0x30,0x40,0x80,0x80,0x00,/*"入",2*/        0x00,0x00,0xFF,0x00,0x00,0x00,0xFE,0x82,0x82,0x82,0x82,0x82,0x82,0xFE,0x00,0x00,    0x00,0x00,0xFF,0x00,0x00,0x00,0x7F,0x20,0x20,0x20,0x20,0x20,0x20,0x7F,0x00,0x00,/*"旧",3*/        0x10,0x8C,0x44,0x04,0xE4,0x04,0x95,0xA6,0x44,0x24,0x14,0x84,0x44,0x94,0x0C,0x00,    0x02,0x02,0x7A,0x41,0x41,0x43,0x42,0x7E,0x42,0x42,0x42,0x43,0xF8,0x00,0x00,0x00,/*"密",4*/        0x04,0x84,0xE4,0x5C,0x44,0xC4,0x00,0x02,0xF2,0x82,0x82,0x82,0xFE,0x80,0x80,0x00,    0x02,0x01,0x7F,0x10,0x10,0x3F,0x00,0x08,0x08,0x08,0x08,0x48,0x88,0x40,0x3F,0x00,/*"码",5*/}; //请输入新密码const unsigned char chinese_enter_newPassword[][32] = {    0x40,0x42,0xCC,0x00,0x00,0x44,0x54,0x54,0x54,0x7F,0x54,0x54,0x54,0x44,0x40,0x00,    0x00,0x00,0x7F,0x20,0x10,0x00,0xFF,0x15,0x15,0x15,0x55,0x95,0x7F,0x00,0x00,0x00,/*"请",0*/    0x88,0x68,0x1F,0xC8,0x08,0x10,0xC8,0x54,0x52,0xD1,0x12,0x94,0x08,0xD0,0x10,0x00,    0x09,0x19,0x09,0xFF,0x05,0x00,0xFF,0x12,0x92,0xFF,0x00,0x5F,0x80,0x7F,0x00,0x00,/*"输",1*/    0x00,0x00,0x00,0x00,0x00,0x01,0xE2,0x1C,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,    0x80,0x40,0x20,0x10,0x0C,0x03,0x00,0x00,0x00,0x03,0x0C,0x30,0x40,0x80,0x80,0x00,/*"入",2*/    0x40,0x44,0x54,0x65,0xC6,0x64,0x54,0x44,0x00,0xFC,0x44,0x44,0xC4,0x42,0x40,0x00,    0x20,0x12,0x4A,0x82,0x7F,0x02,0x0A,0x92,0x60,0x1F,0x00,0x00,0xFF,0x00,0x00,0x00,/*"新",3*/    0x10,0x8C,0x44,0x04,0xE4,0x04,0x95,0xA6,0x44,0x24,0x14,0x84,0x44,0x94,0x0C,0x00,    0x02,0x02,0x7A,0x41,0x41,0x43,0x42,0x7E,0x42,0x42,0x42,0x43,0xF8,0x00,0x00,0x00,/*"密",4*/    0x04,0x84,0xE4,0x5C,0x44,0xC4,0x00,0x02,0xF2,0x82,0x82,0x82,0xFE,0x80,0x80,0x00,    0x02,0x01,0x7F,0x10,0x10,0x3F,0x00,0x08,0x08,0x08,0x08,0x48,0x88,0x40,0x3F,0x00,/*"码",5*/};//密码修改成功const unsigned char modify_passWord_complete[][32] = {   0x10,0x8C,0x44,0x04,0xE4,0x04,0x95,0xA6,0x44,0x24,0x14,0x84,0x44,0x94,0x0C,0x00,    0x02,0x02,0x7A,0x41,0x41,0x43,0x42,0x7E,0x42,0x42,0x42,0x43,0xF8,0x00,0x00,0x00,/*"密",0*/    0x04,0x84,0xE4,0x5C,0x44,0xC4,0x00,0x02,0xF2,0x82,0x82,0x82,0xFE,0x80,0x80,0x00,    0x02,0x01,0x7F,0x10,0x10,0x3F,0x00,0x08,0x08,0x08,0x08,0x48,0x88,0x40,0x3F,0x00,/*"码",1*/    0x40,0x20,0xF8,0x07,0xF0,0xA0,0x90,0x4C,0x57,0x24,0xA4,0x54,0x4C,0x80,0x80,0x00,    0x00,0x00,0xFF,0x00,0x1F,0x80,0x92,0x52,0x49,0x29,0x24,0x12,0x08,0x00,0x00,0x00,/*"修",2*/    0x04,0x84,0x84,0x84,0x84,0xFC,0x40,0x30,0xCC,0x0B,0x08,0x08,0xF8,0x08,0x08,0x00,    0x00,0x7F,0x20,0x10,0x10,0x08,0x80,0x40,0x21,0x16,0x08,0x16,0x21,0x40,0x80,0x00,/*"改",3*/    0x00,0x00,0xF8,0x88,0x88,0x88,0x88,0x08,0x08,0xFF,0x08,0x09,0x0A,0xC8,0x08,0x00,    0x80,0x60,0x1F,0x00,0x10,0x20,0x1F,0x80,0x40,0x21,0x16,0x18,0x26,0x41,0xF8,0x00,/*"成",4*/    0x08,0x08,0x08,0xF8,0x08,0x08,0x08,0x10,0x10,0xFF,0x10,0x10,0x10,0xF0,0x00,0x00,    0x10,0x30,0x10,0x1F,0x08,0x88,0x48,0x30,0x0E,0x01,0x40,0x80,0x40,0x3F,0x00,0x00,/*"功",5*/ };//请设定密码const unsigned char set_passWord[][32] = {    0x40,0x42,0xCC,0x00,0x00,0x44,0x54,0x54,0x54,0x7F,0x54,0x54,0x54,0x44,0x40,0x00,    0x00,0x00,0x7F,0x20,0x10,0x00,0xFF,0x15,0x15,0x15,0x55,0x95,0x7F,0x00,0x00,0x00,/*"请",0*/    0x40,0x40,0x42,0xCC,0x00,0x40,0xA0,0x9E,0x82,0x82,0x82,0x9E,0xA0,0x20,0x20,0x00,    0x00,0x00,0x00,0x3F,0x90,0x88,0x40,0x43,0x2C,0x10,0x28,0x46,0x41,0x80,0x80,0x00,/*"设",1*/    0x10,0x0C,0x44,0x44,0x44,0x44,0x45,0xC6,0x44,0x44,0x44,0x44,0x44,0x14,0x0C,0x00,    0x80,0x40,0x20,0x1E,0x20,0x40,0x40,0x7F,0x44,0x44,0x44,0x44,0x44,0x40,0x40,0x00,/*"定",2*/    0x10,0x8C,0x44,0x04,0xE4,0x04,0x95,0xA6,0x44,0x24,0x14,0x84,0x44,0x94,0x0C,0x00,    0x02,0x02,0x7A,0x41,0x41,0x43,0x42,0x7E,0x42,0x42,0x42,0x43,0xF8,0x00,0x00,0x00,/*"密",3*/    0x04,0x84,0xE4,0x5C,0x44,0xC4,0x00,0x02,0xF2,0x82,0x82,0x82,0xFE,0x80,0x80,0x00,    0x02,0x01,0x7F,0x10,0x10,0x3F,0x00,0x08,0x08,0x08,0x08,0x48,0x88,0x40,0x3F,0x00,/*"码",4*/};
  • BEEP (蜂鸣器)

beep.c文件代码

#include "stm32f1xx.h"#include "beep.h" //初始化GPIO口void beep_init(void){    //打开时钟    __HAL_RCC_GPIOC_CLK_ENABLE();    //打开GPIO口    GPIO_InitTypeDef GPIO_Initstruct;    GPIO_Initstruct.Mode = GPIO_MODE_OUTPUT_PP;    GPIO_Initstruct.Pin = GPIO_PIN_13;    GPIO_Initstruct.Pull = GPIO_NOPULL;    GPIO_Initstruct.Speed = GPIO_SPEED_FREQ_HIGH;    HAL_GPIO_Init(GPIOC,&GPIO_Initstruct);    //关闭蜂鸣器    beep_off();}//打开蜂鸣器函数void beep_on(void){    HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,GPIO_PIN_RESET);}//关闭蜂鸣器void beep_off(void){    HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,GPIO_PIN_SET);}//反转蜂鸣器void beep_toggle(void){    HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_13);  }
  • SWITCH(开关) 

 switch.h文件代码

#include "alarm.h"#include "stm32f1xx.h"                  // 外设的驱动函数  //初始化GPIO口 void alarm_init(void){        //打开时钟    __HAL_RCC_GPIOB_CLK_ENABLE();    //调用GPIO的初始化函数    GPIO_InitTypeDef GPIO_Initstruct;    GPIO_Initstruct.Mode = GPIO_MODE_OUTPUT_PP;    GPIO_Initstruct.Pin = GPIO_PIN_7;    GPIO_Initstruct.Pull = GPIO_PULLUP;    GPIO_Initstruct.Speed = GPIO_SPEED_FREQ_HIGH;    HAL_GPIO_Init(GPIOB, &GPIO_Initstruct);    //关闭继电器    alarm_off();}//接通继电器的函数void alarm_on(void){           HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_RESET);   } //断开继电器的函数void alarm_off(void){        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_SET);    } //获取继电器的状态uint8_t alarm_status_get(void){        return (uint8_t)HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_7);}
  • W25Q128(FLASH存储器) 

w25q128.c文件代码

#include "w25q128.h" SPI_HandleTypeDef spi_handle = {0};void w25q128_spi_init(void){        spi_handle.Instance = SPI1;    spi_handle.Init.Mode = SPI_MODE_MASTER;    //配置成主模式还是从模式    spi_handle.Init.Direction = SPI_DIRECTION_2LINES;                 //配置全双工还是半双工    spi_handle.Init.DataSize = SPI_DATASIZE_8BIT;      //数据的长度:8bit    spi_handle.Init.CLKPolarity = SPI_POLARITY_LOW;      //CPOL = 0    spi_handle.Init.CLKPhase = SPI_PHASE_1EDGE;          //CPHA = 奇数边沿检测    spi_handle.Init.NSS = SPI_NSS_SOFT;               //软件控制SS引脚配置    spi_handle.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256;    //波特率分频 :256    spi_handle.Init.FirstBit = SPI_FIRSTBIT_MSB;             //高位先行还是低位先行:高位先行      //下面这三个先不需要考虑    spi_handle.Init.TIMode = SPI_TIMODE_DISABLE;    spi_handle.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;    spi_handle.Init.CRCPolynomial = 7;        HAL_SPI_Init(&spi_handle);}  void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi){    if(hspi->Instance == SPI1){        __HAL_RCC_GPIOA_CLK_ENABLE();        __HAL_RCC_SPI1_CLK_ENABLE();                GPIO_InitTypeDef gpio_initstruct;                //NSS引脚        gpio_initstruct.Pin = GPIO_PIN_4;        gpio_initstruct.Mode = GPIO_MODE_OUTPUT_PP;        gpio_initstruct.Pull = GPIO_PULLUP;        gpio_initstruct.Speed  = GPIO_SPEED_FREQ_HIGH;        HAL_GPIO_Init(GPIOA,&gpio_initstruct);                //SCL引脚和输出引脚        gpio_initstruct.Pin = GPIO_PIN_5 |GPIO_PIN_7;        gpio_initstruct.Mode = GPIO_MODE_AF_PP;        HAL_GPIO_Init(GPIOA,&gpio_initstruct);                //输入引脚        gpio_initstruct.Pin = GPIO_PIN_6;        gpio_initstruct.Mode = GPIO_MODE_INPUT;        HAL_GPIO_Init(GPIOA,&gpio_initstruct);            } } uint8_t w25q128_spi_swap_byte(uint8_t data){        uint8_t recv_data = 0;    HAL_SPI_TransmitReceive(&spi_handle,&data, &recv_data,1,1000);  ///size:尺寸代表是多少个字节    return recv_data;} //初始化w25q128模块void w25q128_init(void){    w25q128_spi_init();} //测试:读IDuint16_t w25q128_read_id(void){    uint16_t device_id = 0;        W25Q128_CS(0);        w25q128_spi_swap_byte(FLASH_ManufactDeviceID);    w25q128_spi_swap_byte(0x00);    w25q128_spi_swap_byte(0x00);    w25q128_spi_swap_byte(0x00);        device_id = w25q128_spi_swap_byte(FLASH_DummyBtye) > 16);//高位    w25q128_spi_swap_byte(address >> 8);  //中位:由于函数是一个8位的,因此,移动后数据后,高位自动去掉。    w25q128_spi_swap_byte(address);} //忙等待的函数void w25q128_wait_busy(void){        while ((w25q128_read_sr1() & 0x01) == 0x01);  //判断最后一位是不是1} //读数据void w25q128_read_data(uint32_t address,uint8_t *data,uint32_t size){        uint32_t i = 0;        W25Q128_CS(0);    w25q128_spi_swap_byte(FLASH_ReadDate);    w25q128_send_address(address);        for(i = 0;i< size; i++)       data[i] =  w25q128_spi_swap_byte(FLASH_DummyBtye);    W25Q128_CS(1);    }//页写:写的是256个字节,void w25q128_write_page(uint32_t address,uint8_t *data,uint16_t size){   //代表的是字节数量        uint16_t i = 0;        w25q128_write_enable();    W25Q128_CS(0);    w25q128_spi_swap_byte(FLASH_PageProgram);    w25q128_send_address(address);        for(i = 0;i < size; i++)       w25q128_spi_swap_byte(data[i]);    W25Q128_CS(1);        //忙等待,写入数据是需要花费时间的;看状态寄存器的最后一位是0还是1    w25q128_wait_busy();}//扇区擦除void w25q128_erase_sector(uint32_t address){    w25q128_write_enable();    w25q128_wait_busy();    W25Q128_CS(0);    w25q128_spi_swap_byte(FLASH_SectorErase);    w25q128_send_address(address);    W25Q128_CS(1);    w25q128_wait_busy();}//如何指定变量的数据类型是多少

 w25q128.h文件代码

#ifndef __W25Q128_H__#define __W25Q128_H__#include "stm32f1xx.h" #define W25Q128_CS(x)  do{x ? \                            HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_SET): \                            HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_RESET);\                       }while(0) /* 指令表 */#define FLASH_ManufactDeviceID          0x90#define FLASH_WriteEable                0x06#define FLASH_ReadStatusReg1            0x05#define FLASH_ReadDate                  0x03#define FLASH_PageProgram               0x02#define FLASH_SectorErase               0x20#define FLASH_DummyBtye                 0xFF                        void w25q128_init(void);uint16_t w25q128_read_id(void);void w25q128_read_data(uint32_t address,uint8_t *data,uint32_t size);void w25q128_write_page(uint32_t address,uint8_t *data,uint16_t size);void w25q128_erase_sector(uint32_t address);                       #endif

输入设备 

  • KEYBOARD(矩阵键盘

keyboard.c文件代码:

#include "keyboard.h"#include "delay.h" static uint8_t key_value; void keyboard_init(void){        //打开时钟    __HAL_RCC_GPIOB_CLK_ENABLE();    //调用GPIO的初始化函数    GPIO_InitTypeDef GPIO_Initstruct;        GPIO_Initstruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_10;    GPIO_Initstruct.Mode = GPIO_MODE_IT_FALLING;    GPIO_Initstruct.Pull = GPIO_PULLUP;    GPIO_Initstruct.Speed = GPIO_SPEED_FREQ_HIGH;    HAL_GPIO_Init(GPIOB, &GPIO_Initstruct);        GPIO_Initstruct.Pin = GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14;    GPIO_Initstruct.Mode = GPIO_MODE_INPUT;    GPIO_Initstruct.Pull = GPIO_PULLDOWN;    //配置成下拉模式,当导通时,会变成高电平    GPIO_Initstruct.Speed = GPIO_SPEED_FREQ_HIGH;    HAL_GPIO_Init(GPIOB, &GPIO_Initstruct);         HAL_NVIC_SetPriority(EXTI0_IRQn,2,2);    HAL_NVIC_EnableIRQ(EXTI0_IRQn);        HAL_NVIC_SetPriority(EXTI1_IRQn,2,2);    HAL_NVIC_EnableIRQ(EXTI1_IRQn);        HAL_NVIC_SetPriority(EXTI2_IRQn,2,2);    HAL_NVIC_EnableIRQ(EXTI2_IRQn);        HAL_NVIC_SetPriority(EXTI15_10_IRQn,2,2);    HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);    } void EXTI0_IRQHandler(void){        HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);    } void EXTI1_IRQHandler(void){        HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_1);    }void EXTI2_IRQHandler(void){        HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_2); }void EXTI15_10_IRQHandler(void){        HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_10);    } void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){    uint8_t row = 0,column = 0;    if(key_value != 0) return;    //防止手速过快,只读取第一次按下时的按键值        //确定行    if(GPIO_Pin == GPIO_PIN_0)        row  = 0x10;    else if(GPIO_Pin == GPIO_PIN_1)        row = 0x20;    else if(GPIO_Pin == GPIO_PIN_2)        row = 0x30;    else if(GPIO_Pin == GPIO_PIN_10)        row = 0x40;        //确定列    if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_11) == GPIO_PIN_SET){        delay_ms(10);        while(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_11) == GPIO_PIN_SET);        column = 0x01;    }    else if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_12) == GPIO_PIN_SET){        delay_ms(10);        while(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_12) == GPIO_PIN_SET);        column = 0x02;    }     else if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_13) == GPIO_PIN_SET){        delay_ms(10);        while(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_13) == GPIO_PIN_SET);        column = 0x03;    }     else if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_14) == GPIO_PIN_SET){        delay_ms(10);        while(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_14) == GPIO_PIN_SET);        column = 0x04;    }         if(row != 0 && column != 0)        key_value = row | column;    //按位与进行拼接} uint8_t keyboard_get_value(void){    uint8_t ch = 0;    if(key_value != 0)    {        if(key_value == 0x11) ch = '1';        else if(key_value == 0x12) ch = '2';        else if(key_value == 0x13) ch = '3';        else if(key_value == 0x14) ch = 'A';                else if(key_value == 0x21) ch = '4';        else if(key_value == 0x22) ch = '5';        else if(key_value == 0x23) ch = '6';        else if(key_value == 0x24) ch = 'B';                else if(key_value == 0x31) ch = '7';        else if(key_value == 0x32) ch = '8';        else if(key_value == 0x33) ch = '9';        else if(key_value == 0x34) ch = 'C';                else if(key_value == 0x41) ch = '*';        else if(key_value == 0x42) ch = '0';        else if(key_value == 0x43) ch = '#';        else if(key_value == 0x44) ch = 'D';        delay_ms(400);        key_value = 0x00;    }    return ch;}

 PASSWORD(配置密码)

password.c文件代码:

#include "password.h"#include "w25q128.h"#include "oled.h"#include "keyboard.h"#include "string.h"#include "stdio.h"#include "alarm.h"#include "beep.h"#include "delay.h" #define PASSWORD_SIZE       10  uint8_t pwd_input[PASSWORD_SIZE] = {0};uint8_t pwd_read[PASSWORD_SIZE] = {0};uint8_t i = 0,key_value = 0,try_times = 0;                     /********** 1 *********/ //初始化函数void password_init(void){    w25q128_init();   }//读取密码:读取的是w25Q128_read_data(); //保存密码void password_save(void){    w25q128_erase_sector(0x000000);    w25q128_write_page(0x000000,pwd_input,PASSWORD_SIZE);    oled_modif_pwd_complete();}//清空输入缓存void password_input_clear(void){    memset(pwd_input, 0 ,PASSWORD_SIZE);    i = 0;} //获取键盘输入:将按键输入(数字、字母)存到一个字符串数组当中,而“#”,“*”则进行返回。uint8_t password_get_input(void){   password_input_clear();                                  /*清除 字符数组 中的值 */       while(1){      key_value =  keyboard_get_value();       if(key_value == '#'){           printf("按下了 %c 键 \r\n", key_value);           return POUND_KEY;       }       else if(key_value == '*'){           printf("按下了 %c 键 \r\n", key_value);           return STAR_KEY;       }       else if(key_value != 0){           printf("按下了 %c 键 \r\n", key_value);           oled_show_char(3,i * 10,key_value,16);  //字符的尺寸。           pwd_input[i++] = key_value;       }   }    }                    /********** 2 *********///密码比对:长度和元素。返回值:TURE和FLASEuint8_t password_compare(void){    uint8_t i = 0;    w25q128_read_data(0x000000,pwd_read,PASSWORD_SIZE);    //先检查两个字符串的长度    if(strlen((char *)pwd_input) != strlen((char *)pwd_read))        return FALSE;    for (i = 0;i = 3){        beep_on();        delay_ms(1000);        beep_off();        try_times = 0;    }    delay_s(1);} //旧密码输入正确的操作void password_old_right_action(void){    oled_input_new_pwd();    password_get_input();    password_save();    beep_on();    delay_ms(300);    beep_off();    delay_ms(700);} //旧密码输入错误的操作void password_old_error_action(void){    oled_pwd_error();    delay_ms(1000);} //检查密码是否存在void password_check(void){    w25q128_read_data(0x000000,pwd_read,PASSWORD_SIZE);    printf("读出密码:%s\r\n",pwd_read);    if(pwd_read[0] == '\0' || pwd_read[0] == 0xFF){        oled_set_pwd();        password_get_input();        password_save();    }}

password.h文件代码

#ifndef __PASSWORD_H__#define __PASSWPRD_H__#include "stm32f1xx.h" #define FALSE               0#define TRUE                1 #define POUND_KEY   '#'#define STAR_KEY    '*' void password_init(void); void password_check(void);void password_save(void);uint8_t password_get_input(void);uint8_t password_compare(void); void password_input_right_action(void);void password_input_error_action(void); void password_old_right_action(void);void password_old_error_action(void);  #endif

 主函数

main.c文件代码:

#include "sys.h"#include "led.h"#include "delay.h"#include "uart1.h"#include "oled.h"#include "beep.h"#include "alarm.h"#include "w25q128.h"#include "keyboard.h"#include "password.h"  int main(void){    HAL_Init();                         /* 初始化HAL库 */    stm32_clock_init(RCC_PLL_MUL9);     /* 设置时钟, 72Mhz */    uart1_init(115200);    printf("hello,world!!!\r\n");        beep_init();    alarm_init();    oled_init();    keyboard_init();    password_init();//    w25q128_init();        password_check();    uint8_t key_last = 0;    while(1)    {        oled_show_input();       key_last = password_get_input();       if(key_last == POUND_KEY){           if(password_compare() == TRUE)               password_input_right_action();           else               password_input_error_action();       }       else if(key_last == STAR_KEY){           oled_input_old_pwd();           password_get_input();           if(password_compare() == TRUE)               password_old_right_action();           else               password_old_error_action();       }    }}

posted on 2025-10-05 15:00  slgkaifa  阅读(14)  评论(0)    收藏  举报

导航