设计内容:
1、密码存储在I2C器件中,实现密码掉电不丢失。
2、电路板一上电四个数码管显示“-“
3、实现数字键0-9和功能键的设计:
4、四个功能键:
(1)密码输入
(2)退出
(3)密码修改:当密码密码修改键按下,若输入密码正确后,按下此键时,将修改的密码进行存储。输入密码正确显示”8888“
输入失败显示”HHHH“
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
- #include <reg51.h>
- #include <intrins.h>
- #include <string.h>
- typedef unsigned char u8;
- typedef unsigned int u16;
- #define SMG_PORT P0
- #define KEY_MATRIX_PORT P1
- #define AT24C02_ADDRESS 0xA0
- u8 gsmg_code[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f,0x40,0x76};//0-9 "-" "H"
- u8 e_mima[4] = {1, 2, 3, 4}; // 初始密码是1234
- u8 read_mima[4];
- u8 entered_password[4]; // 存储用户输入的密码
- u8 input_index = 0;
- u8 key = 0;
- u8 wei=0;
- u8 panduan=0;//判断密码是否正确
- u8 state=0;
- u8 xiugai=0;
- u8 wdata=0;
- u8 show_h=0;
- sbit led=P2^7;
- sbit LSA = P2^2;
- sbit LSB = P2^3;
- sbit LSC = P2^4;
- sbit sda=P2^0;
- sbit scl=P2^1;
- u8 chushi = 1;
- //@11.0592MHz
- void Delay10ms()
- {
- unsigned char i, j;
- i = 108;
- j = 145;
- do
- {
- while (--j);
- } while (--i);
- }
- //@11.0592MHz
- void delay_us(unsigned int us)
- {
- unsigned int i;
- while(us--)
- {
- i = 11; // 11 是根据 11.0592MHz 晶振频率调整的数值
- while (--i);
- }
- }
- void delayms(u16 x)
- {
- u8 i;
- while(x--)
- {
- for(i=150;i>0;i--);
- }
- }
- void nop()
- {
- _nop_();
- _nop_();
- }
- /////////24C02读写驱动程序////////////////////
- void delay1(unsigned int m)
- { unsigned int n;
- for(n=0;n<m;n++);
- }
- void init() //24c02初始化子程序
- {
- scl=1;
- nop();
- sda=1;
- nop();
- }
- void start() //启动I2C总线
- {
- sda=1;
- nop();
- scl=1;
- nop();
- sda=0;
- nop();
- scl=0;
- nop();
- }
- void stop() //停止I2C总线
- {
- sda=0;
- nop();
- scl=1;
- nop();
- sda=1;
- nop();
- }
- void writebyte(unsigned char j) //写一个字节
- {
- unsigned char i,temp;
- temp=j;
- for (i=0;i<8;i++)
- {
- temp=temp<<1;
- scl=0;
- nop();
- sda=CY; //temp左移时,移出的值放入了CY中
- nop();
- scl=1; //待sda线上的数据稳定后,将scl拉高
- nop();
- }
- scl=0;
- nop();
- sda=1;
- nop();
- }
- unsigned char readbyte() //读一个字节
- {
- unsigned char i,j,k=0;
- scl=0; nop(); sda=1;
- for (i=0;i<8;i++)
- {
- nop(); scl=1; nop();
- if(sda==1)
- j=1;
- else
- j=0;
- k=(k<<1)|j;
- scl=0;
- }
- nop();
- return(k);
- }
- void clock() //I2C总线时钟
- {
- unsigned char i=0;
- scl=1;
- nop();
- while((sda==1)&&(i<255))
- i++;
- scl=0;
- nop();
- }
- ////////从24c02的地址address中读取一个字节数据/////
- unsigned char read24c02(unsigned char address)
- {
- unsigned char i;
- start();
- writebyte(0xa0);
- clock();
- writebyte(address);
- clock();
- start();
- writebyte(0xa1);
- clock();
- i=readbyte();
- stop();
- delay1(10);
- return(i);
- }
- //////向24c02的address地址中写入一字节数据info/////
- void write24c02(unsigned char address,unsigned char info)
- {
- start();
- writebyte(0xa0);
- clock();
- writebyte(address);
- clock();
- writebyte(info);
- clock();
- stop();
- delay1(50);
- }
- u8 key_matrix_ranks_scan(void)
- {
- u8 key_value = 0;
- KEY_MATRIX_PORT = 0xf7; //第一列为低电平
- if (KEY_MATRIX_PORT!= 0xf7) //有按键按下
- {
- Delay10ms();
- switch(KEY_MATRIX_PORT)
- {
- case 0x77: key_value = 1; break; //S1按下时
- case 0xb7: key_value = 4; break;
- case 0xd7: key_value = 7; break;
- case 0xe7: key_value = 10; break;
- }
- }
- while(KEY_MATRIX_PORT!= 0xf7); //等待释放,当按键按下时KEY值不等于0xf7,一直循环,当按键释放时,KEY等于0xf7,跳出循环
- KEY_MATRIX_PORT = 0xfb; //第二列为低电平
- if (KEY_MATRIX_PORT!= 0xfb) //有按键按下
- {
- Delay10ms();
- switch(KEY_MATRIX_PORT)
- {
- case 0x7b: key_value = 2; break;
- case 0xbb: key_value = 5; break;
- case 0xdb: key_value = 8; break;
- case 0xeb:/* key_value = 11;*/ break;
- }
- }
- while(KEY_MATRIX_PORT!= 0xfb);
- KEY_MATRIX_PORT = 0xfd; //第三列为低电平
- if (KEY_MATRIX_PORT!= 0xfd) //有按键按下
- {
- Delay10ms();
- switch(KEY_MATRIX_PORT)
- {
- case 0x7d: key_value = 3; break;
- case 0xbd: key_value = 6; break;
- case 0xdd: key_value = 9; break;
- case 0xed:/* key_value = 12; */break;
- }
- }
- while(KEY_MATRIX_PORT!= 0xfd);
- KEY_MATRIX_PORT = 0xfe; //第四列为低电平
- if (KEY_MATRIX_PORT!= 0xfe)
- {
- Delay10ms();
- switch(KEY_MATRIX_PORT)
- {
- case 0x7e: key_value = 13; break; //S1按键按下时
- case 0xbe: key_value = 14; break;
- case 0xde: key_value = 15; break;
- case 0xee: key_value = 16; break;
- }
- }
- while(KEY_MATRIX_PORT!= 0xfe);
- return key_value;
- }
- // 显示单个数字到指定的数码管位
- void display_on_smg(u8 num, u8 pos)
- {
- switch (pos)
- {
- case 1: LSC = 1; LSB = 1; LSA = 1; break; // 第1位
- case 2: LSC = 1; LSB = 1; LSA = 0; break; // 第2位
- case 3: LSC = 1; LSB = 0; LSA = 1; break; // 第3位
- case 4: LSC = 1; LSB = 0; LSA = 0; break; // 第4位
- }
- SMG_PORT = 0x00;
- SMG_PORT = gsmg_code[num];
- delay_us(5);
- SMG_PORT = 0x00;
- }
- void clear_display(void)
- {
- LSC = 1; LSB = 0; LSA = 0;
- SMG_PORT = 0x00; // 清空显示
- }
- void show_8888(void)
- {
- display_on_smg(8,1);
- display_on_smg(8,2);
- display_on_smg(8,3);
- display_on_smg(8,4);
- }
- void show_HHHH(void)
- {
- display_on_smg(11,1);
- display_on_smg(11,2);
- display_on_smg(11,3);
- display_on_smg(11,4);
- }
- void show____(void)
- {
- display_on_smg(10,1);
- display_on_smg(10,2);
- display_on_smg(10,3);
- display_on_smg(10,4);
- }
- //输入密码
- void import_ss()
- {
- u8 i;
- for (i = 0; i < 4; i++)
- {
- e_mima[i] = read_mima[i];
- }
- if (key!= 0 && key!=13 && key!=14 && key!=15 && key!=16)
- {
- wei++;
- entered_password[input_index] = key-1;
- input_index++;
- if (input_index >= 4)
- {
- input_index = 0;
- }
- }
- if(wei==1)
- {
- display_on_smg(10, 1);
- }
- else if(wei==2)
- {
- display_on_smg(10, 1);
- display_on_smg(10, 2);
- }
- else if(wei==3)
- {
- display_on_smg(10, 1);
- display_on_smg(10, 2);
- display_on_smg(10, 3);
- }
- else if(wei==4)
- {
- display_on_smg(10, 1);
- display_on_smg(10, 2);
- display_on_smg(10, 3);
- display_on_smg(10, 4);
- panduan=1;
- wei=0;
- }
- if(panduan==1)
- {
- if(panduan==1)
- {
- // 比较密码
- if (entered_password[0] == e_mima[0] && entered_password[1] == e_mima[1] && entered_password[2] == e_mima[2] && entered_password[3] == e_mima[3])
- {
- show_8888();
- led=0;
- }
- else
- {
- show_HHHH();
- led=1;
- }
- }
- }
- }
- // 密码修改
- void xiugai_ss(void)
- {
- u8 i,j;
-
- for (i = 0; i < 4; i++)
- {
- e_mima[i] = read_mima[i];
- }
- if (key!= 0 && key!= 13 && key!= 14 && key!= 15 && key!= 16)
- {
- entered_password[input_index] = key - 1;
- input_index++;
- if (input_index >= 4)
- {
- if (state == 0)
- {
- // 输入原密码阶段
- if (entered_password[0] == e_mima[0] && entered_password[1] == e_mima[1] && entered_password[2] == e_mima[2] && entered_password[3] == e_mima[3])
- {
- state = 1; // 原密码正确,进入输入新密码状态
- input_index = 0;
- clear_display();
- led=0;
- show_h=0;
- }
- else
- {
- show_h=1;
- state = 0;
- input_index = 0;
- }
- }
- else if (state == 1)
- {
- // 输入新密码阶段
- if (input_index == 4 )
- {
- // 输入新密码阶段
- if (input_index == 4)
- {
- state = 2; // 输入新密码完成,进入确认状态
- input_index = 0;
- }
- }
- }
- }
- }
- // 显示已输入的密码
- for (j = 0; j < input_index; j++)
- {
- display_on_smg(10, j + 1);
- }
- if (state == 2 && key == 16)
- {
- led=1;
- // 确认修改密码
- for (i = 0; i < 4; i++)
- {
- e_mima[i] = entered_password[i];
- }
- wdata=1;
- show_8888();
- state = 0;
- input_index = 0;
- chushi = 1;
- xiugai = 0;
- show____(); // 修改完成后返回初始界面显示
- }
- }
- void main()
- {
- u8 i;
- led=1;
- init(); //初始化24C02
- // 上电从 24C02 读取数据
- for (i = 0; i < 4; i++)
- {
- read_mima[i] = read24c02(i);
- delayms(3);
- }
- while(1)
- {
- // 上电从 24C02 读取数据
- for (i = 0; i < 4; i++)
- {
- read_mima[i] = read24c02(i);
- delayms(3);
- }
- if(wdata==1)
- {
- write24c02(0, entered_password[0]); // 将修改后的密码发送给 24C02
- delayms(3);
- write24c02(1, entered_password[1]);
- delayms(3);
- write24c02(2, entered_password[2]);
- delayms(3);
- write24c02(3, entered_password[3]);
- delayms(3);
- wdata=0;
- }
- if(show_h==1)
- {
- show_HHHH();
- }
-
- key = key_matrix_ranks_scan();
- if (key == 13)//输入键
- {
- chushi = 0;
- panduan=0;
- clear_display();
- }
- if(key==14)//退出键
- {
- chushi=1;
- }
- if(key==15)//密码修改
- {
- show_h=0;
- chushi=2;
- panduan=0;
- clear_display();
- }
- if(key==16)
- {
- xiugai=1;
- }
-
- if(chushi==1)
- {
- show____();
- led=1;
- }
- else if (chushi == 0)
- {
- import_ss();
- }
- else if(chushi==2)
- {
- xiugai_ss();
- }
- }
- }
复制代码
仿真程序.7z
(222.12 KB, 下载次数: 0)
|