同一个程序,时而运行正常,时而不正常。在两个月前这个程序运行时很稳定的 。几天前这个程序第一次出现问题,接着反复出现问题,一直在lcd上显示乱码。、换了一个
单片机之后恢复正常,可没下载几次又出问题了。单片机,1602显示器都换过,现在是都不管用。所以现在还是怀疑是代码的问题。这段代码我写的比较快,标志变量比较多。在普中单片机开发版中实现的。附件中有
开发板的原理图,lcd1602的头文件以及c语言文件。附主程序代码如下:
/************************************************************************************
*
* 密码锁
--------------------------------------------------------------------------------
* 实 验 名 : 密码锁
* 实验说明 : 打开
电源之后,显示屏显示:“Please input the code: ----”;
输入密码的时候在界面上显示的是*号而不是密码的数字,按S4可以清空已输入密码。
输入正确密码后进入界面,显示"Wlecome home." 此时按独立按键K1可以进入更改密码界面,输入新密码时显示密码值,注意输入新密码时不可清空已输入新密码。
输入错误密码提醒错误,显示"Wrong code." 输入错误密码三次后延时10S后方可继续操作。
* 连接方式 : P0通过排阵连接矩阵键盘JP4,p3.0口连接独立按键K1
* 注 意 :
************************************************************************************/
#include<reg51.h>
#include"lcd.h"
//--定义使用的IO口--//
#define GPIO_KEY P1
//--定义全局变量--//
unsigned char sentense[27]="Please input the code: ----";
unsigned char sentense1[13]="Wlecome home.";
char warn[]="Wrong code.";
char c[4]={-1,-1,-1,-1}; //存储读取的密码
bit flag1=0; //修改输入值状态标志变量
bit flag2=0; //密码输入状态标志变量,作用:当密码输入正确的时候系统将会输出欢迎界面,此时不应继续输出“****”,所以使用flag2屏蔽掉。
bit flag3=0; //密码输入界面炮灰标志变量
bit flag4=0; //设置密码标志变量
bit temp=0; //清屏时用的炮灰标志变量
bit temp1=0; //初始化密码用的炮灰标志变量
sbit k1=P3^0;
char mima[4]={1,1,1,1}; //储存正确的密码
unsigned char num=0;//输入密码位数计数变量
unsigned char num_mistake=0;//错误次数计数变量
//--声明全局函数--//
void KeyScan(void);
void Delay10ms(unsigned int c);
/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void main(void)
{
unsigned char i;
LcdInit();
while(1)
{
if (flag3==0)
{
LcdWriteCom(0x01);
for(i=0; i<27; i++)
{
if(i == 13)
{
LcdWriteCom(0x80 + 0x40);
}
LcdWriteData(sentense[i]);
}
flag3=~flag3;
}
KeyScan();
if(flag2==0)
{
for (i=0; i<4; i++)
{
if (c[i]>=0)
{
LcdWriteCom(0x80 + 0x40+10+i);
LcdWriteData('*');
}
}
if(flag1==1)
{
LcdWriteCom(0x80 + 0x40+10);
for (i=0; i<4; i++)
{
LcdWriteData('-');
}
// flag1=0; 这是一个多余的语句,如果有这一句,按下取消键之后需要重新输入密码的时候要按到第十七下才会开始输入到c[]数组中。
}
}
if (c[0]>=0 && c[1]>=0 && c[2]>=0 && c[3]>=0)
{
if(c[0]==mima[0] && c[1]==mima[1] && c[2]==mima[2] && c[3]==mima[3])
{
flag2=1;
if (temp==0)
{
LcdWriteCom(0x01);
LcdWriteCom(0x80);
for(i=0; i<13; i++)
{
LcdWriteData(sentense1[i]);
}
temp=~temp;
}
if(k1 == 0) //按键1按下
{
Delay10ms(1);
if(k1 == 0)
while((i < 50)&&(k1==0))
{
i++;
Delay10ms(1);
}
LcdWriteCom(0x80);
for(i=0; i<27; i++)
{
if(i == 13)
{
LcdWriteCom(0x80 + 0x40);
}
LcdWriteData(sentense[i]);
}
LcdWriteCom(0x80 + 0x40);
LcdWriteData('n');
LcdWriteData('e');
LcdWriteData('w');
flag4=1;
temp1=0;
flag1=1;
num=0;
}
}
else
{
LcdWriteCom(0x01);
LcdWriteCom(0x80);
for(i=0; i<11; i++)
{
LcdWriteData(warn[i]);
}
Lcd1602_Delay1ms(1000);
flag3=~flag3;
num=0;
flag1=1;
for (i=0; i<4; i++)
{
c[i]=-1;
}
num_mistake++;
if(num_mistake==3)
{
Lcd1602_Delay1ms(10000);
}
}
}
}
}
/*******************************************************************************
* 函 数 名 : void KeyScan(void)
* 函数功能 : 检测有按键按下并读取键值
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void KeyScan(void)
{
char KeyValue;
char a = 0;
char i;
GPIO_KEY=0x0f;
if(GPIO_KEY!=0x0f)//读取按键是否按下
{
Delay10ms(1);//延时10ms进行消抖
if(GPIO_KEY!=0x0f)//再次检测键盘是否按下
{
//测试列
GPIO_KEY=0X0F;
switch(GPIO_KEY)
{
case(0X07): KeyValue=0;break;
case(0X0b): KeyValue=4;break;
case(0X0d): KeyValue=8;break;
case(0X0e): KeyValue=12;break;
}
//测试行
GPIO_KEY=0XF0;
switch(GPIO_KEY)
{
case(0X70): KeyValue=KeyValue+3;break;
case(0Xb0): KeyValue=KeyValue+2;break;
case(0Xd0): KeyValue=KeyValue+1;break;
case(0Xe0): KeyValue=KeyValue;break;
}
while((a<50) && (GPIO_KEY!=0xf0)) //检测按键松手检测
{
Delay10ms(1);
a++;
}
if (KeyValue!=15)
{
num++;
flag1=0;
}
else
{
num=0;
flag1=1;
for (i=0; i<4; i++)
{
c[i]=-1;
}
}
}
}
if(flag1==0)
{
c[num-1]= KeyValue;
}
if(flag4==1)
{
if (temp1==0)
{
mima[0]=-1;mima[1]=-1;mima[2]=-1;mima[3]=-1;
c[0]=-1;c[1]=-1;c[2]=-1;c[3]=-1;
temp1=1;
}
mima[num-1]= KeyValue;
for (i=0; i<4; i++)
{
if (mima[i]>=0)
{
LcdWriteCom(0x80 + 0x40+10+i);
LcdWriteData('0'+mima[i]);
}
}
if (mima[0]>=0 && mima[1]>=0 && mima[2]>=0 && mima[3]>=0) //除了密码表以及flag1(经观察后发现进行一次取消方能达到实验效果)之外,其他一切变量恢复初始状态
{
num=0;
flag1=1;
num_mistake=0;
flag4=0;
flag3=0;
flag2=0;
temp=0;
temp1=0;
c[0]=-1;c[1]=-1;c[2]=-1;c[3]=-1;
}
}
}
/*******************************************************************************
* 函 数 名 : Delay10ms
* 函数功能 : 延时函数,延时10ms
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void Delay10ms(unsigned int c) //误差 0us
{
unsigned char a, b;
//--c已经在传递过来的时候已经赋值了,所以在for语句第一句就不用赋值了--//
for (;c>0;c--)
{
for (b=38;b>0;b--)
{
for (a=130;a>0;a--);
}
}
}
-
-
EM3_V3.0原理图.pdf
下载积分: 积分 -1 分
1.45 MB, 下载次数: 10, 下载积分: 积分 -1 分
-
-
lcd.c
下载积分: 积分 -1 分
3.54 KB, 下载次数: 10, 下载积分: 积分 -1 分
-
-
lcd.h
下载积分: 积分 -1 分
963 Bytes, 下载次数: 5, 下载积分: 积分 -1 分
一周热门 更多>