程序实例1:延时函数
#ifndef __DELAY_H__
#define __DELAY_H__
/*------------------------------------------------uS延时函数,含有输入参数 unsigned char t,无返回值unsigned char 是定义无符号字符变量,其值的范围是0~255 这里使用晶振12M,精确延时请使用汇编,大致延时长度如下 T=tx2+5 uS
------------------------------------------------*/
void DelayUs2x(unsigned char t);
/*------------------------------------------------mS延时函数,含有输入参数 unsigned char t,无返回值unsigned char 是定义无符号字符变量,其值的范围是0~255 这里使用晶振12M,精确延时请使用汇编
------------------------------------------------*/
void DelayMs(unsigned char t);#endif
#include "delay.h"
/*------------------------------------------------uS延时函数,含有输入参数 unsigned char t,无返回值unsigned char 是定义无符号字符变量,其值的范围是0~255 这里使用晶振12M,精确延时请使用汇编,大致延时长度如下 T=tx2+5 uS
------------------------------------------------*/
void DelayUs2x(unsigned char t)
{ while(--t);
}
/*------------------------------------------------mS延时函数,含有输入参数 unsigned char t,无返回值unsigned char 是定义无符号字符变量,其值的范围是0~255 这里使用晶振12M,精确延时请使用汇编
------------------------------------------------*/
void DelayMs(unsigned char t)
{while(t--){//大致延时1mSDelayUs2x(245);DelayUs2x(245);}
}
程序实例2:1602驱动
#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#include<intrins.h>#ifndef __1602_H__
#define __1602_H__bit LCD_Check_Busy(void) ;void LCD_Write_Com(unsigned char com) ;void LCD_Write_Data(unsigned char Data) ;void LCD_Clear(void) ;void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s) ;void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data) ;void LCD_Init(void) ;#endif
#include "1602.h"
#include "delay.h"#define CHECK_BUSYsbit RS = P2^4; //定义端口
sbit RW = P2^5;
sbit EN = P2^6;#define RS_CLR RS=0
#define RS_SET RS=1#define RW_CLR RW=0
#define RW_SET RW=1 #define EN_CLR EN=0
#define EN_SET EN=1#define DataPort P0/*------------------------------------------------判忙函数
------------------------------------------------*/
bit LCD_Check_Busy(void)
{
#ifdef CHECK_BUSYDataPort= 0xFF; RS_CLR; RW_SET; EN_CLR; _nop_(); EN_SET;return (bit)(DataPort & 0x80);
#elsereturn 0;
#endif
}/*------------------------------------------------写入命令函数
------------------------------------------------*/
void LCD_Write_Com(unsigned char com)
{ while(LCD_Check_Busy()); //忙则等待RS_CLR; RW_CLR; EN_SET; DataPort= com; _nop_(); EN_CLR;
}
/*------------------------------------------------写入数据函数
------------------------------------------------*/
void LCD_Write_Data(unsigned char Data)
{ while(LCD_Check_Busy()); //忙则等待RS_SET; RW_CLR; EN_SET; DataPort= Data; _nop_();EN_CLR;
}/*------------------------------------------------清屏函数
------------------------------------------------*/
void LCD_Clear(void)
{ LCD_Write_Com(0x01); DelayMs(5);
}/*------------------------------------------------写入字符串函数
------------------------------------------------*/
void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s)
{ while (*s) { LCD_Write_Char(x,y,*s); s ++; x++; }}/*------------------------------------------------写入字符函数
------------------------------------------------*/
void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data)
{ if (y == 0) { LCD_Write_Com(0x80 + x); } else { LCD_Write_Com(0xC0 + x); } LCD_Write_Data( Data);
}/*------------------------------------------------初始化函数
------------------------------------------------*/
void LCD_Init(void)
{LCD_Write_Com(0x38); /*显示模式设置*/ DelayMs(5); LCD_Write_Com(0x38); DelayMs(5); LCD_Write_Com(0x38); DelayMs(5); LCD_Write_Com(0x38); LCD_Write_Com(0x08); /*显示关闭*/ LCD_Write_Com(0x01); /*显示清屏*/ LCD_Write_Com(0x06); /*显示光标移动设置*/ DelayMs(5); LCD_Write_Com(0x0C); /*显示开及光标设置*/
}
程序实例3:按键驱动
#ifndef __KEYBOARD_H__
#define __KEYBOARD_H__/*------------------------------------------------
按键扫描函数,返回扫描键值
------------------------------------------------*/
unsigned char KeyScan(void); //键盘扫描函数,使用行列反转扫描法/*------------------------------------------------
按键值处理函数,返回扫键值
------------------------------------------------*/
unsigned char KeyPro(void);#endif
#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#include"keyboard.h"
#include"delay.h"#define KeyPort P3/*------------------------------------------------
按键扫描函数,返回扫描键值
------------------------------------------------*/
unsigned char KeyScan(void) //键盘扫描函数,使用行列反转扫描法
{unsigned char cord_h,cord_l;//行列值中间变量KeyPort=0x0f; //行线输出全为0cord_h=KeyPort&0x0f; //读入列线值if(cord_h!=0x0f) //先检测有无按键按下{DelayMs(10); //去抖if((KeyPort&0x0f)!=0x0f){cord_h=KeyPort&0x0f; //读入列线值KeyPort=cord_h|0xf0; //输出当前列线值cord_l=KeyPort&0xf0; //读入行线值while((KeyPort&0xf0)!=0xf0);//等待松开并输出return(cord_h+cord_l);//键盘最后组合码值}}return(0xff); //返回该值
}/*------------------------------------------------
按键值处理函数,返回扫键值
------------------------------------------------*/
unsigned char KeyPro(void)
{switch(KeyScan()){case 0x7e:return 0;break;//0 按下相应的键显示相对应的码值case 0x7d:return 1;break;//1case 0x7b:return 2;break;//2case 0x77:return 3;break;//3case 0xbe:return 4;break;//4case 0xbd:return 5;break;//5case 0xbb:return 6;break;//6case 0xb7:return 7;break;//7case 0xde:return 8;break;//8case 0xdd:return 9;break;//9case 0xdb:return 10;break;//acase 0xd7:return 11;break;//bcase 0xee:return 12;break;//ccase 0xed:return 13;break;//dcase 0xeb:return 14;break;//ecase 0xe7:return 15;break;//fdefault:return 0xff;break;}
}
程序实例4:main文件
#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#include<stdio.h>
#include"1602.h"
#include"delay.h"
#include"keyboard.h"unsigned char code password[]={1,2,3,4,5,6,7,8};//可以更改此密码做多组测试
//定义密码,实际上密码需要存在eeprom中,可以通过程序更改。请用户自行添加/*------------------------------------------------主程序
------------------------------------------------*/
main()
{unsigned char num,i,j; unsigned char passwordtemp[16]; //最大输入16个unsigned char inputtimes; //密码输入错误次数unsigned char passwordlength,PLEN; //输入密码长度,实际密码长度bit Flag;PLEN=sizeof(password)/sizeof(password[0]);//用于计算出实际密码长度LCD_Init(); //初始化液晶屏DelayMs(10); //延时用于稳定,可以去掉LCD_Clear(); //清屏LCD_Write_String(0,0," Welcome! "); //写入第一行信息,主循环中不再更改此信息,所以在while之前写入LCD_Write_String(0,1,"Input password!"); //写入第二行信息,提示输入密码while (1) //主循环{num=KeyPro(); //扫描键盘if(num!=0xff) //如果扫描是按键有效值则进行处理{ if(i==0) //输入是第一个字符的时候需要把改行清空,方便观看密码LCD_Write_String(0,1," ");//清除该行if(i<16){passwordtemp[i]=num;LCD_Write_Char(i,1,'*');//输入的密码用"*"代替}i++; //输入数值累加if((15==num)|| (i==16))//输入按键值15或者密码输入到最大值16,表示输入结束,需要进行比对{passwordlength=i-1; //计算输入密码长度i=0; //计数器复位if(passwordlength==PLEN)//长度相等则比较,否则直接输出错误{Flag=1;//先把比较位置1for(j=0;j<PLEN;j++)//循环比较8个数值,如果有一个不等 则最终Flag值为0Flag=Flag&&(passwordtemp[j]==password[j]);//比较输入值和已有密码}if(Flag)//如果比较全部相同,标志位置1{LCD_Write_String(0,1," ");//清除该行LCD_Write_String(0,1,"Right Open!>>>>");//密码正确显示的信息inputtimes=0;//输入正确则次数清零,重新计数Flag=0; //清除正确标志}else {LCD_Write_String(0,1," ");//清除该行LCD_Write_String(0,1,"Wrong! Retry!");//密码错误,提示重新输入inputtimes++;//连续输入错误,则次数累加if(inputtimes==3){LCD_Write_String(0,1," ");//清除该行LCD_Write_String(0,1,"Wrong 3 times!");//密码错误,提示重新输入while(1);//停止该位置,重启电源后才能输入,实际实用中则需要等到一定时间后才能再次输入。}}}} }
}