找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2031|回复: 1
收起左侧

LCD1602乱码,单片机密码锁程序

[复制链接]
ID:416660 发表于 2018-11-3 14:39 来自手机 | 显示全部楼层 |阅读模式
乱码如图:
IMG_20181103_132852.jpg
  1. #include <reg52.h>                 //调用单片机头文件
  2. #define uchar unsigned char  //无符号字符型 宏定义        变量范围0~255
  3. #define uint  unsigned int         //无符号整型 宏定义        变量范围0~65535

  4. uchar value,i;                //变量

  5. sbit relay = P2^2;  //继电器定义
  6. sbit beep  = P3^3;  //蜂鸣器定义

  7. sbit beiguan = P2^3;  //背光

  8. uint flag_time;

  9. uint flag_guan;

  10. uchar smg_i;
  11. uchar dis_smg[7]={0};

  12. uchar password[7]={6,5,4,3,2,1};            //密码保存
  13. uchar password_bj[7]={1,2,3,4,5,6};        //密码比较
  14. uchar code password_r[6] = {1,2,3,1,2,3} ;
  15. uchar code password_gl[6] = {5,2,0,0,2,5} ;
  16. uchar password_xg[6];        //密码修改
  17. uchar flag_password;      //密码正确否
  18. uchar flag_password_cichu1;//密码错误次数

  19. bit flag_200ms=1;     //200ms标志位

  20. uchar key_can;

  21. uchar menu_1,menu_i;

  22. sbit scl = P2^1;        //24C02 IO口定义
  23. sbit sda = P2^0;        //24C02 IO口定义

  24. uchar code table_num[]="0123456789abcdefg";

  25. sbit rs=P2^5;         //寄存器选择信号 H:数据寄存器          L:指令寄存器
  26. sbit rw=P2^6;         //寄存器选择信号 H:数据寄存器          L:指令寄存器
  27. sbit e =P2^7;         //片选信号   下降沿触发

  28. /***********************延时函数************************/
  29. void delay_uint(uint q)
  30. {
  31.         while(q--);
  32. }

  33. /***********************lcd1602写命令函数************************/
  34. void write_com(uchar com)
  35. {
  36.         e=0;
  37.         rs=0;
  38.         rw=0;
  39.         P0=com;
  40.         delay_uint(3);
  41.         e=1;
  42.         delay_uint(25);
  43.         e=0;
  44. }

  45. /***********************lcd1602写数据函数************************/
  46. void write_data(uchar dat)
  47. {
  48.         e=0;
  49.         rs=1;
  50.         rw=0;
  51.         P0=dat;
  52.         delay_uint(3);
  53.         e=1;
  54.         delay_uint(25);
  55.         e=0;        
  56. }

  57. /*********************光标控制***********************/
  58. void lcd1602_guanbiao(uchar open_off,uchar add)
  59. {
  60.         if(open_off == 1)   //开光标
  61.         {
  62.                 write_com(0x80+add);              //将光标移动到秒个位
  63.                 write_com(0x0f);                //显示光标并且闪烁
  64.         }
  65.         else
  66.         {
  67.                 write_com(0x0c);   //关光标
  68.         }               
  69. }

  70. /***********************lcd1602上显示两位十进制数************************/
  71. void write_sfm2(uchar hang,uchar add,uchar date)
  72. {
  73.         uchar shi,ge;
  74.         if(hang==1)   
  75.                 write_com(0x80+add);
  76.         else
  77.                 write_com(0x80+0x40+add);
  78.         shi=date%100/10;
  79.         ge=date%10;                  
  80.         write_data(0x30+shi);
  81.         write_data(0x30+ge);        
  82. }

  83. /***********************lcd1602上显示这字符函数************************/
  84. void write_string(uchar hang,uchar add,uchar *p)
  85. {
  86.         if(hang==1)   
  87.                 write_com(0x80+add);
  88.         else
  89.                 write_com(0x80+0x40+add);
  90.                 while(1)                                                                                                                 
  91.                 {
  92.                         if(*p == '\0')  break;
  93.                         write_data(*p);
  94.                         p++;
  95.                         delay_uint(50);
  96.                 }        
  97. }


  98. /***********************lcd1602初始化设置************************/
  99. void init_1602()
  100. {
  101.         write_com(0x38);        //
  102.         write_com(0x0c);
  103.         write_com(0x06);
  104.         delay_uint(1000);
  105.         write_string(1,0," Password Lock  ");        
  106.         write_string(2,0," Input:         ");
  107.         lcd1602_guanbiao(1,7+0x40);  //开光标
  108. }


  109. /***************启始信号 ***************************/
  110. void start()
  111. {
  112.         sda = 1;
  113.         scl = 1;
  114.         sda = 0;
  115.         scl = 0;
  116. }

  117. /****************结束信号 **************************/
  118. void stop()
  119. {
  120.         sda = 0;
  121.         scl = 1;
  122.         sda = 1;
  123.         scl = 0;
  124. }

  125. /*****************检测应答*************************/
  126. void ack()
  127. {
  128.         uchar i;
  129.         sda = 1;   
  130.         scl = 1;        
  131.         while((i < 100) & (sda == 1))        i++;
  132.         scl =0;
  133. }


  134. void ack_zhuji()
  135. {
  136.         sda = 0;
  137.         scl = 1;
  138.         scl = 0;
  139.         sda = 1;
  140. }

  141. /*****************非应答*************************/
  142. void no_ack()
  143. {
  144.         sda = 1;
  145.         scl = 1;
  146.         scl = 0;
  147. }

  148. /*****************写一个字节*************************/
  149. void write_iic(uchar dat)
  150. {
  151.         uchar i;
  152.         for(i=0;i<8;i++)
  153.         {
  154.                 scl = 0;
  155.                 dat <<= 1 ;
  156.                 sda = CY;
  157.                 scl = 1;
  158.         }
  159.         scl = 0;
  160. }

  161. /*******************读一个字节***********************/
  162. uchar read_iic()
  163. {
  164.         uchar i,value;
  165.         for(i=0;i<8;i++)
  166.         {
  167.                 scl = 1;
  168.                 value <<= 1;
  169.                 if(sda == 1)
  170.                         value |= 0x01;
  171.                 scl = 0;
  172.         }
  173.         return value;
  174. }

  175. /*****************向24C02写一个字节进去*************************/
  176. void write_24c02(uchar add,uchar dat)
  177. {
  178.         start();
  179.         write_iic(0xa0);
  180.         ack();
  181.         write_iic(add);
  182.         ack();
  183.         write_iic(dat);
  184.         no_ack();
  185.         stop();
  186. }

  187. /******************从24C02读一个字节进去************************/
  188. uchar read_24c02(uchar add)
  189. {
  190.         uchar value;
  191.         start();
  192.         write_iic(0xa0);
  193.         ack();
  194.         write_iic(add);
  195.         ack();

  196.         start();
  197.         write_iic(0xa1);
  198.         ack();
  199.         value = read_iic();
  200.         no_ack();
  201.         stop();
  202.         return value;
  203. }

  204. /*****************向24C02写多个字节进去*************************/
  205. void write_24c02_8(uchar n,uchar add,uchar *p)
  206. {
  207.         uchar i;
  208.         EA = 0;
  209.         start();
  210.         write_iic(0xa0);
  211.         ack();
  212.         write_iic(add);        
  213.         for(i=0;i<n;i++)
  214.         {        
  215.                 ack();
  216.                 write_iic(*p);
  217.                 p++;                        
  218.         }  
  219.         no_ack();   
  220.         stop();        
  221.         EA = 1;
  222. }
  223. /******************从24C02读多个字节进去************************/
  224. void read_24c02_8(uchar n,uchar add,uchar *p)
  225. {
  226.         uchar i;
  227.         EA = 0;
  228.         start();
  229.         write_iic(0xa0);
  230.         ack();
  231.         write_iic(add);
  232.         ack();

  233.         start();
  234.         write_iic(0xa1);
  235.         ack();
  236.         for(i=0;i<n;i++)
  237.         {
  238.                 p[i] = read_iic();
  239.                 if(i == n-1)
  240.                 {
  241.                         ack();
  242.                         stop();
  243.                 }
  244.                 else
  245.                         ack_zhuji();
  246.         }
  247.         EA = 1;
  248. }


  249. /***********************1ms延时函数*****************************/
  250. void delay_1ms(uint q)
  251. {
  252.         uint i,j;
  253.         for(i=0;i<q;i++)
  254.                 for(j=0;j<120;j++);
  255. }


  256. void key()         //独立按键程序
  257. {
  258.         static uchar key_new = 0, key_l;
  259.         key_can = 20;                   //按键值还原
  260.         P1 = 0x0f;
  261.         if((P1 & 0x0f) != 0x0f)                //按键按下
  262.         {
  263.                 delay_1ms(1);                     //按键消抖动
  264.                 if(((P1 & 0x0f) != 0x0f) && (key_new == 1))
  265.                 {                                                //确认是按键按下
  266.                         key_new = 0;
  267.                         key_l = (P1 | 0xf0);   //矩阵键盘扫描
  268.                         P1 = key_l;
  269.                         switch(P1)
  270.                         {
  271.                                 case 0xee:  key_can = 1;  break;  //得到按键值
  272.                                 case 0xde:  key_can = 4;  break;   //得到按键值
  273.                                 case 0xbe:  key_can = 7;  break;   //得到按键值
  274.                                 case 0x7e:  key_can = 10;  break;   //得到按键值
  275.         
  276.                                 case 0xed:  key_can = 0;  break;  //得到按键值
  277.                                 case 0xdd:  key_can = 8;  break;   //得到按键值
  278.                                 case 0xbd:  key_can = 5;  break;   //得到按键值
  279.                                 case 0x7d:  key_can = 2;  break;   //得到按键值
  280.         
  281.                                 case 0xeb:  key_can = 3;  break;  //得到按键值
  282.                                 case 0xdb:  key_can = 6;  break;   //得到按键值
  283.                                 case 0xbb:  key_can = 9;  break;   //得到按键值
  284.                                 case 0x7b:  key_can = 11;  break;   //得到按键值
  285.         
  286.                                 case 0xe7:  key_can = 15;  break;  //得到按键值
  287.                                 case 0xd7:  key_can = 14;  break;  //得到按键值
  288.                                 case 0xb7:  key_can = 13;  break;   //得到按键值
  289.                                 case 0x77:  key_can = 12;  break;  //得到按键值  

  290.                         }        
  291.                 }                        
  292.         }
  293.         else
  294.         {
  295.                 key_new = 1;
  296.         }        
  297. }


  298. /***************把数组清空**********************/
  299. void clear_shuzu(uchar *p)
  300. {
  301.         for(i=0;i<7;i++)
  302.                 p[i] = 0;
  303. }

  304. /*************定时器0初始化程序***************/
  305. void time_init()         
  306. {
  307.         EA   = 1;                   //开总中断
  308.         TMOD = 0X01;          //定时器0、工作方式1
  309.         ET0  = 1;                  //开定时器0中断
  310.         TR0  = 1;                  //允许定时器0定时
  311. }

  312. /******************下载程序密码初始化**********************/           
  313. void password_chushifa()
  314. {
  315.         scl = 0;
  316.         value = read_24c02(10) ;
  317.         if(value != 75)
  318.         {
  319.                 value = 75;
  320.                 beep = 0;
  321.                 write_24c02(10,value);
  322.                 delay_1ms(200);
  323.                 write_24c02_8(6,0,password_r);
  324.                 delay_1ms(200);
  325.                 read_24c02_8(6,0,password);
  326.                 beep = 1;         
  327.         }
  328. }


  329. /****************按键功能处理********************/           
  330. void key_with()
  331. {
  332.         static uchar value;
  333.         if(key_can == 14)   //手动关闭密码锁
  334.                 relay = 1;
  335.         if(menu_1 == 0)
  336.         {
  337.                 if(key_can <= 9)
  338.                 if(menu_i < 6)   //密码输入
  339.                 {
  340.                         menu_i ++;
  341.                         if(menu_i > 6)
  342.                                 menu_i = 6;
  343.                         smg_i = menu_i;
  344.                         for(i=6;i>0;i--)
  345.                                 password_bj[i] = password_bj[i-1];        
  346.                         password_bj[0] = key_can;
  347.                         for(i=0;i<smg_i;i++)
  348.                                 dis_smg[i] ='*';//0x30 + password_bj[i];
  349.                         write_string(2,7,dis_smg);        
  350.                         lcd1602_guanbiao(1,7 + menu_i + 0x40);  //开光标
  351.                 }        
  352.                 if(key_can == 11)         //密码删除
  353.                 {
  354.                         for(i=0;i<menu_i;i++)
  355.                                 password_bj[i] = password_bj[i+1];         
  356.                         menu_i --;
  357.                         password_bj[menu_i] = ' ';        
  358.                         dis_smg[menu_i] = ' ';
  359.                         write_string(2,7,dis_smg);        
  360.                         lcd1602_guanbiao(1,7 + menu_i + 0x40);  //开光标
  361.                 }
  362.                 if(key_can == 15)  //确认键
  363.                 {
  364.                         value = 0;
  365.                         for(i=0;i<6;i++)
  366.                         {
  367.                                 if(password_bj[i] == password_gl[i]) //判断管理员密码
  368.                                 {
  369.                                          value ++;
  370.                                         if(value >= 6)  //密码正确
  371.                                         {
  372.                                                 write_string(2,0,"    return      ");
  373.                                                 beep = 0;
  374.                                                 delay_1ms(200);
  375.                                                 read_24c02_8(6,0,password);
  376.                                                 beep = 1;         
  377.                                                 delay_1ms(2000);
  378.                                         }
  379.                                 }
  380.                         }
  381.                         if(value < 6)
  382.                         for(i=0;i<6;i++)
  383.                         {
  384.                                 if(password_bj[i] == password[i])
  385.                                 {
  386.                                         flag_password = 1;         //密码正确
  387.                                         relay = 0;     //打开密码锁
  388.                                         for(i=0;i<6;i++)
  389.                                                 dis_smg[i] = 0xbf;
  390.                                 }
  391.                                 else
  392.                                 {
  393.                                         flag_password = 0;
  394.                                         flag_password_cichu1 ++;
  395.                                         write_string(1,0," Password error ");        
  396.                                         write_string(2,0,"   cishu:       ");
  397.                                         write_sfm2(2,9,flag_password_cichu1);
  398.                                         delay_1ms(280);
  399.                         
  400.                                         for(i=0;i<6;i++)
  401.                                         {
  402.                                                 beep = ~beep;
  403.                                                 delay_1ms(200);
  404.                                         }
  405.                                         beep = 1;
  406.                                         delay_1ms(800);
  407.                                         break;               //密码不正确
  408.                                 }
  409.                         }
  410.                         clear_shuzu(dis_smg);
  411.                         write_string(1,0," Password Lock  ");        
  412.                         write_string(2,0," Input:         ");
  413.                         lcd1602_guanbiao(1,7+0x40);  //开光标
  414.                         menu_i = 0;
  415.                 }
  416.         }                                                                        
  417. }

  418. /****************修改密码********************/           
  419. void xiugai_password()
  420. {
  421.         if(key_can == 13)   //修改密码
  422.         {
  423.                 if((relay == 0) && (menu_1 == 0))
  424.                 {
  425.                         menu_1 = 1;        menu_i = 0;
  426.                         clear_shuzu(password_bj);          //数据清空
  427.                         clear_shuzu(dis_smg);
  428.                         write_string(1,0,"Input1:          ");        
  429.                         write_string(2,0,"Input2:          ");
  430.                         lcd1602_guanbiao(1,7);  //开光标
  431.                 }        
  432.         }
  433.         if(menu_1 == 1)   //第一次输入修改的密码
  434.         {
  435.                 if(key_can <= 9)
  436.                 {
  437.                         if(menu_i < 6)
  438.                         {
  439.                                 menu_i ++;
  440.                                 if(menu_i > 6)
  441.                                         menu_i = 6;
  442.                                 smg_i = menu_i;
  443.                                 for(i=7;i>0;i--)
  444.                                         password_bj[i] = password_bj[i-1];        
  445.                                 password_bj[0] = key_can;
  446.                                 for(i=0;i<menu_i;i++)
  447.                                         dis_smg[i] ='*';
  448.                                 write_string(1,7,dis_smg);
  449.                                 lcd1602_guanbiao(1,7 + menu_i);  //开光标        
  450.                         }        
  451.                 }
  452.                 if(key_can == 11)  //删除键
  453.                 {
  454.                         for(i=0;i<menu_i;i++)
  455.                                 password_bj[i] = password_bj[i+1];        
  456.                         menu_i --;
  457.                         password_bj[menu_i] = ' ';        
  458.                         dis_smg[menu_i] = ' ';
  459.                         write_string(1,7,dis_smg);        
  460.                         lcd1602_guanbiao(1,7 + menu_i);  //开光标        
  461.                 }        
  462.                 if(key_can == 15)  //确定键
  463.                 {
  464.                         clear_shuzu(password_xg);
  465.                         clear_shuzu(dis_smg);
  466.                         lcd1602_guanbiao(1,8 + 0x40);  //开光标
  467.                         menu_1 = 2;
  468.                     menu_i = 0;
  469.                         key_can = 20;
  470.                 }
  471.         }
  472.         if(menu_1 == 2)   //第二次输入修改的密码
  473.         {
  474.                 if(key_can <= 9)
  475.                 {
  476.                         if(menu_i < 6)
  477.                         {
  478.                                 menu_i ++;               
  479.                                 if(menu_i > 6)
  480.                                         menu_i = 6;
  481.                                 for(i=5;i>0;i--)
  482.                                         password_xg[i] = password_xg[i-1];        
  483.                                 password_xg[0] = key_can;
  484.                                 for(i=0;i<menu_i;i++)
  485.                                         dis_smg[i] ='*';//0x30 + password_xg[i];
  486.                                 write_string(2,7,dis_smg);           
  487.                                 lcd1602_guanbiao(1,7 + menu_i + 0x40);  //开光标
  488.                         }        
  489.                 }
  490.                 if(key_can == 11)  //删除键
  491.                 {
  492.                         for(i=0;i<menu_i;i++)
  493.                                 password_xg[i] = password_xg[i+1];        
  494.                         password_xg[menu_i] = ' ';        
  495.                         dis_smg[menu_i] = ' ';
  496.                         write_string(2,7,dis_smg);        
  497.                         lcd1602_guanbiao(1,7 + menu_i + 0x40);  //开光标
  498.                 }        
  499.                 if(key_can == 15)  //确定键
  500.                 {
  501.                         for(i=0;i<6;i++)
  502.                         {
  503.                                 if(password_bj[i] == password_xg[i])
  504.                                 {
  505.                                         flag_password = 1;         //两次输入的密码一样                        
  506.                                 }
  507.                                 else
  508.                                 {
  509.                                 flag_password = 0;
  510.                                         write_string(1,0," Password Error ");        
  511.                                         write_string(2,0,"     reenter    ");
  512.                                         delay_1ms(300);
  513.                                         for(i=0;i<6;i++)
  514.                                         {
  515.                                                 beep = ~beep;                //提示三声
  516.                                                 delay_1ms(300);
  517.                                         }
  518.                                         beep = 1;
  519.                                         delay_1ms(1000);
  520.                                         break;               //密码不正确
  521.                                 }
  522.                         }
  523.                         if(flag_password == 1)                 //两次输入的密码一样的
  524.                         {                        
  525.                                 for(i=0;i<6;i++)
  526.                                 {
  527.                                         write_string(1,0,"    Password    ");        
  528.                                         write_string(2,0,"    Succeed     ");
  529.                                         password[i] = password_bj[i];   //保存密码
  530.                                 }
  531.                                 write_24c02_8(6,0,password);
  532.                                 delay_1ms(300);
  533.                                 beep = 0;
  534.                                 delay_1ms(2000);
  535.                                 beep = 1;
  536.                         }
  537.                         clear_shuzu(password_xg);
  538.                         clear_shuzu(dis_smg);
  539.                         write_string(1,0," Password Lock  ");        
  540.                         write_string(2,0," Input:         ");
  541.                         lcd1602_guanbiao(1,7+0x40);  //开光标
  542.                         menu_1 = 0;
  543.                     menu_i = 0;

  544.                 }
  545.         }        
  546. }


  547. /******************主程序**********************/           
  548. void main()
  549. {
  550.         static uint value ;
  551.         password_chushifa();
  552.         time_init();   //定时器初始化
  553.         read_24c02_8(6,0,password);
  554.         init_1602();
  555.         beiguan = 0;
  556.         while(1)
  557.         {        
  558.                 if(flag_password_cichu1 < 3)     //错误三次按键不能用了
  559.                 {
  560.                         key();                                         //按键函数
  561.                         if(key_can < 20)
  562.                         {
  563.                                 if(beiguan == 0)
  564.                                 {
  565.                                         if(menu_1 == 0)
  566.                                                 key_with();                         //按键处理函数
  567.                                         xiugai_password();       //修改密码
  568.                                 }
  569.                                 else
  570.                                         beiguan = 0;
  571.                                 flag_time = 0;               
  572.                         }
  573.                 }

  574.                 if(flag_200ms == 1)
  575.                 {
  576.                         flag_200ms = 0;         
  577.                         if(beiguan == 0)         //延时关闭锁20秒关闭背光
  578.                         {
  579.                                 flag_time ++;
  580.                                 if(flag_time >= 5 * 30)        //30秒  
  581.                                 {
  582.                                         flag_time = 0;
  583.                                         beiguan = 1;        //关闭背光
  584.                                 }
  585.                         }
  586.                         if(relay == 0)  //延时关闭锁
  587.                         {
  588.                                 flag_guan++;
  589.                                 if(flag_guan >= 5 * 10)        //10秒  
  590.                                 {
  591.                                         flag_guan = 0;
  592.                                     relay = 1;   //关闭密码锁
  593.                                 }
  594.                         }else
  595.                                 flag_guan = 0;        
  596.                         if(flag_password_cichu1 >= 3)
  597.                         {
  598.                                 value ++;           //200ms
  599.                                 beep = ~beep;  //蜂鸣器报警
  600.                                 if(value >= 5 * 60)        //1分钟  
  601.                                 {
  602.                                         value = 0;
  603.                                         beep = 1;
  604.                                         flag_password_cichu1 = 0;
  605.                                 }
  606.                         }
  607.                 }
  608.                 delay_1ms(1);  
  609.         }
  610. }

  611. /*************定时器0中断服务程序***************/
  612. void time0_int() interrupt 1
  613. {        
  614.         static uchar value;
  615.         TH0 = 0x3c;
  616.         TL0 = 0xb0;     // 50ms         12M

  617.     value ++;
  618.         if(value % 4 == 0)  
  619.         {         
  620.                 flag_200ms = 1;
  621.         }
  622.         
  623. }
复制代码
回复

使用道具 举报

ID:111634 发表于 2018-11-4 21:27 | 显示全部楼层
本帖最后由 zl2168 于 2018-11-4 22:19 编辑

功能齐全的电子密码锁
⑴ 电路设计    …
电子密码锁电路.jpg
电子密码锁电路说明.jpg
⑵ 功能设计    …
电子密码锁功能1.jpg 电子密码锁功能2.jpg 电子密码锁功能3.jpg

⑶ 程序设计    … 电子密码锁流程图.jpg
⑷ Proteus仿真    …
Proteus仿真一下,确认有效,验证上述功能。 电子密码锁1.rar (1.13 MB, 下载次数: 12)
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表