基于stm32写一个密码锁功能,该密码锁具有修改密码,保存密码,将密码存进flash中,掉电会保存密码
时间: 2024-05-15 18:17:06 浏览: 15
1. 初始化
首先,我们需要初始化一些参数,如GPIO口,按键,LCD屏幕等。在这个例子中,我们使用STM32F103C8T6开发板和Keil uVision 5进行开发。以下是初始化代码的示例:
```c
#include "stm32f10x.h"
#include "lcd.h"
GPIO_InitTypeDef GPIO_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
void Init_GPIO(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE);
// 初始化按键
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 初始化LCD屏幕
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
}
void Init_EXTI(void)
{
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);
EXTI_InitStructure.EXTI_Line = EXTI_Line0;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void Init_LCD(void)
{
LCD_Init();
LCD_Clear();
}
```
2. 读取密码
我们将密码存储在STM32的Flash中,因此我们需要读取存储在Flash中的密码。以下是读取密码的示例代码:
```c
#include "stm32f10x_flash.h"
#define FLASH_START_ADDR 0x08000000
#define FLASH_PAGE_SIZE 0x400
uint32_t Read_Password(void)
{
uint32_t Password = 0;
uint32_t FlashAddr = FLASH_START_ADDR;
while (FlashAddr < (FLASH_START_ADDR + FLASH_PAGE_SIZE)) {
Password = *(uint32_t *)FlashAddr;
if (Password == 0xFFFFFFFF) {
break;
}
FlashAddr += 4;
}
return Password;
}
```
在Flash中,我们将密码存储为32位无符号整数。我们从Flash的起始地址开始读取,直到找到值为0xFFFFFFFF的密码为止。这意味着我们最多可以存储8个密码(每个密码占用4个字节)。
3. 保存密码
在我们修改或创建新密码后,我们需要将其保存在Flash中。以下是将密码保存到Flash中的示例代码:
```c
uint32_t Password = 123456;
void Save_Password(uint32_t Password)
{
FLASH_Status Status = FLASH_COMPLETE;
uint32_t FlashAddr = FLASH_START_ADDR;
// 擦除Flash页
FLASH_Unlock();
FLASH_ErasePage(FLASH_START_ADDR);
FLASH_Lock();
// 写入密码到Flash
while (FlashAddr < (FLASH_START_ADDR + FLASH_PAGE_SIZE)) {
Status = FLASH_ProgramWord(FlashAddr, Password);
if (Status != FLASH_COMPLETE) {
break;
}
FlashAddr += 4;
}
}
```
在保存密码之前,我们需要先擦除整个Flash页。然后,我们将密码写入Flash中。我们使用FLASH_ProgramWord函数将密码写入Flash。在写入过程中,我们需要检查写入是否成功。如果写入失败,则说明Flash已满。
4. 修改密码
当用户想要修改密码时,我们需要提供一个界面来输入新密码。以下是修改密码的示例代码:
```c
void Modify_Password(void)
{
uint32_t NewPassword = 0;
uint8_t Count = 0;
LCD_Clear();
LCD_Print("Enter new password:");
while (Count < 6) {
if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)) {
NewPassword = NewPassword * 10 + 1;
Count++;
while (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0));
}
LCD_Gotoxy(Count + 1, 1);
LCD_Print("*");
}
Save_Password(NewPassword);
LCD_Clear();
LCD_Print("Password saved");
}
```
在此示例中,我们使用LCD屏幕和按键来获取新密码。用户需要输入6位数的新密码。当用户按下按键时,我们将数字添加到新密码中,直到用户输入6位数的密码。然后,我们将新密码保存到Flash中。
5. 主函数
在主函数中,我们需要初始化GPIO、EXTI和LCD,然后读取现有密码。如果读取到的密码是0xFFFFFFFF,则说明Flash中没有保存的密码。在这种情况下,我们将要求用户创建新密码。否则,我们将要求用户输入现有密码。如果密码匹配,则允许访问锁定内容。否则,将拒绝访问。
以下是主函数的示例代码:
```c
int main(void)
{
uint32_t Password = 0;
uint32_t InputPassword = 0;
uint8_t Count = 0;
Init_GPIO();
Init_EXTI();
Init_LCD();
Password = Read_Password();
if (Password == 0xFFFFFFFF) {
Modify_Password();
Password = Read_Password();
}
LCD_Clear();
LCD_Print("Enter password:");
while (Count < 6) {
if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)) {
InputPassword = InputPassword * 10 + 1;
Count++;
while (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0));
}
LCD_Gotoxy(Count + 1, 1);
LCD_Print("*");
}
if (InputPassword == Password) {
// 访问锁定内容
LCD_Clear();
LCD_Print("Access granted");
} else {
// 拒绝访问
LCD_Clear();
LCD_Print("Access denied");
}
while (1);
}
```
在此示例中,我们首先尝试读取现有密码。如果没有现有密码,则要求用户创建新密码。然后,我们要求用户输入密码。如果密码匹配,则允许访问锁定内容。否则,将拒绝访问。