⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shixun5.c

📁 单片机C语言程序设计教程与实训源代码及图片 单片机C语言程序设计教程与实训源代码及图片
💻 C
字号:
/**********************************************************************
程序名称:ShiXun5.c
程序功能:由16×2点阵字符型LCD和4×3矩阵非编码键盘组成的模拟数字密码锁
程序作者:张三
创建时间:2008-3-28
**********************************************************************/
#include <reg51.h>
#define unchar unsigned char
#define unint  unsigned int

sbit RS = P3^0;					// 定义LCD的控制信号线
sbit RW = P3^1;
sbit E  = P3^4;
sbit LED1 = P3^6;				// 绿色指示灯
	
unchar code L1[]= "PASS  WORD";			// 第1行常显字符
unchar code L21[]= "                " ;		// 16个空格,用于清屏显示器的第2行
unchar code L23[]= "ERROR!!!        " ;		// 第2行错误提示字符, 共16个
unchar mima1[8]="12345678";			// 内置密码
unchar mima2[8];				// 用于存储输入密码
unchar *PTR;					// 指向字符数组的首地址
unchar CH;					// 单个字符 
unchar  n;					// 字符数组中字符的个数
unchar HSM, LJC, keyvalue;		// HSM为行扫描码,LJC为列检测数据,keyvalue为键值
unchar tmp;				// 用于主函数中接收键值
unchar CNT = 0;				// 输入数据的个数

void delayXms( unint x );		// 函数声明
void lcd_init( void );
void write_ir( void );
void write_dr( unchar *ch, unchar n );
void write_dr1( unchar ch );
unchar keyscan( void );
void mm_cmp( void );
/**********************************************************************
函数名称:main( void )
函数功能:主函数,在指定的位置显示指定的字符串
函数作者:张三
创建时间:2008-3-28
**********************************************************************/
void main( void )
{
	LED1 = 0;			// 绿色指示灯灭
	lcd_init( );			// LCD初始化
	while( 1 ){
		tmp = keyscan( );

		switch( tmp ){
			case 0x11:	// 1
				CNT++;
				if( CNT==9 ){
					CNT = 0;
					break;
				}
				else{
					CH = '*';
					mima2[CNT-1] = '1';
					write_dr1( CH );
				}
				break;	
			case 0x21:	// 2
				CNT++;
				if( CNT==9 ){
					CNT = 0;
					break;
				}
				else{
					CH = '*';
					mima2[CNT-1] = '2';
					write_dr1( CH );
				}
				break;	
			case 0x41:	// 3
				CNT++;
				if( CNT==9 ){
					CNT = 0;
					break;
				}
				else{
					CH = '*';
					mima2[CNT-1] = '3';
					write_dr1( CH );
				}	
				break;	
			case 0x12:	// 4
				CNT++;
				if( CNT==9 ){
					CNT = 0;
					break;
				}
				else{
					CH = '*';
					mima2[CNT-1] = '4';
					write_dr1( CH );
				}	
				break;				
			case 0x22:	// 5
				CNT++;
				if( CNT==9 ){
					CNT = 0;
					break;
				}
				else{
					CH = '*';
					mima2[CNT-1] = '5';
					write_dr1( CH );
				}	
				break;	
			case 0x42:	// 6
				CNT++;
				if( CNT==9 ){
					CNT = 0;
					break;
				}
				else{
					CH = '*';
					mima2[CNT-1] = '6';
					write_dr1( CH );							}	
				break;
			case 0x14:	// 7
				CNT++;
				if( CNT==9 ){
					CNT = 0;
					break;
				}
				else{
					CH = '*';
					mima2[CNT-1] = '7';
					write_dr1( CH );
				}	
				break;	
			case 0x24:	// 8
				CNT++;
				if( CNT==9 ){
					CNT = 0;
					break;
				}
				else{
					CH = '*';
					mima2[CNT-1] = '8';
					write_dr1( CH );
				}	
				break;	
			case 0x44:	// 9
				CNT++;
				if( CNT==9 ){
					CNT = 0;
					break;
				}
				else{
					CH = '*';
					mima2[CNT-1] = '9';
					write_dr1( CH );
				}	
				break;	
			case 0x18:	// *
				CNT = 0;
				P1 = 0xc0;	// 第2行起始地址
				write_ir( );
				PTR = &L21; 		
				n=16;
				write_dr( PTR, n );

				P1 = 0xc0;	// 光标最后停留在LCD 的0xc0位置
				write_ir( );	
				break;	
			case 0x28:	// 0
				CNT++;
				if( CNT==9 ){
					CNT = 0;
					break;
				}
				else{
					CH = '*';
					mima2[CNT-1] = '0';
					write_dr1( CH );							}	
				break;	
			case 0x48:	// #
				mm_cmp( );
				break;
			default:	LED1 = 0;
		}
		delayXms( 1 );
	}

}
/**********************************************************************
函数名称:delayXms( unint x )
函数功能:延时xms,振荡器频率为12MHz
函数作者:张三
创建时间:2008-3-28
**********************************************************************/
void delayXms( unint x )
{
	unint y,z;
	for( ; x>0; x-- )
		for( y=4; y>0; y-- )
			for( z=250; z>0; z--);
}
/**********************************************************************
函数名称:lcd_init( void )
函数功能:LCD初始化,显示开机画面
函数作者:张三
创建时间:2008-3-28
*********************************************************************/
void lcd_init( void )
{
	P1 = 0x01;		// 清屏指令
	write_ir( );	 

	P1 = 0x38;		// 功能设定指令:8位,2行,5×7点矩阵
	write_ir( );

	P1 = 0x0c;		// 开显示指令:开显示屏,不显示光标
	write_ir( );

	P1 = 0x06;		// 设置字符/光标移动模式:光标右移,整屏显示不移动
	write_ir( );	

	P1 = 0x83;		// 第1行起始地址,开机画面
	write_ir( );
	PTR = &L1; 		// L1[]= "PASS  WORD";	
	n=10;
	write_dr( PTR, n );

	P1 = 0x0f;		// 开显示指令:开显示屏,显示光标,光标闪烁
	write_ir( );	
	P1 = 0xc0;		// 光标最后停留在LCD 的0xc0位置
	write_ir( );	
}
/**********************************************************************
函数名称:write_ir( void )
函数功能:写指令到LCD指令寄存器
函数作者:张三
创建时间:2008-3-28
**********************************************************************/
void write_ir( void )
{
	RS = 0;			// 选择LCD指令寄存器
	RW = 0;			// 执行写入操作
	E = 0;			// 禁用LCD
	delayXms( 50 );
	E = 1;			// 启动LCD 
}
/**********************************************************************
函数名称:write_dr( unchar *ch, unchar n )
函数功能:写字符串数据到LCD数据寄存器。指针ch指向字符串数据的首地址,n为数据个数
函数作者:张三
创建时间:2008-3-28
**********************************************************************/
void write_dr( unchar *ch, unchar n )
{
	unchar i;
	for( i=0; i<n; i++ ){
		P1 = *(ch+i);	// 送字符数据
		RS = 1;		// 选择LCD数据寄存器
		RW = 0;		// 执行写入操作
		E = 0;		// 禁用LCD
		delayXms( 50 );
		E = 1;		// 启动LCD
	}
}

/**********************************************************************
函数名称:unchar keyscan( void )
函数功能:键盘扫描及键值确定
函数作者:张三
创建时间:2008-3-28
**********************************************************************/
unchar keyscan( void )
{
	P2 = 0xf0;			// 行线全为低电平, 列线全为高电平
	LJC = P2&0xf0;			// 第1次读列检测状态
	if( LJC != 0xf0 ){		
		delayXms( 10 );		// 若有键被按下, 则延时10ms
		LJC = P2&0xf0;		// 第2次读列检测状态:0xe0, 0xd0, 0xb0, 0x70
		if( LJC != 0xf0 ){	// 若有闭合键,则逐行扫描
   			HSM = 0xfe;	// 扫描码分别为0xfe, 0xfd, 0xfb, 0xf7
			while((HSM&0x10)!=0){	// 若扫描码为0xef, 则结束扫描
				P2 = HSM;	// 输出行扫描码
				LJC = P2&0xf0;	// 读列检测数据:0xe0, 0xd0, 0xb0, 0x70
				if( LJC != 0xf0 ){	// 本行有闭合键
					keyvalue = ( ~HSM )+( ~(LJC|0x0f) );	// 计算键值
					return( keyvalue );			// 返回键值
				}
				else HSM = (HSM<<1)|0x01;	// 行扫描码左移1位,准备扫描下一行
			}
		}
	}
	return( 0x00 );	
}
/**********************************************************************
函数名称:write_dr1( unchar x )
函数功能:将字符数据x写到LCD数据寄存器
函数作者:张三
创建时间:2008-3-28
**********************************************************************/
void write_dr1( unchar x )
{
	P1 = x;			// 送字符“x”
	RS = 1;			// 选择LCD数据寄存器
	RW = 0;			// 执行写入操作
	E = 0;			// 禁用LCD
	delayXms( 50 );
	E = 1;			// 启动LCD
}
/**********************************************************************
函数名称:mm_cmp( void )
函数功能:密码比较,相同则绿色指示灯亮,不同则显示“ERROR!”
函数作者:张三
创建时间:2008-3-28
**********************************************************************/
void mm_cmp( void )
{
	unchar x;
	bit flag = 1;
	for( x=0; x<8; x++ ){
		if( mima1[x]==mima2[x] )	continue;
		else{
			flag = 0;
			break;
		}
	}
	if( flag ){
		LED1 = 1;		// 绿色指示灯亮50ms
		delayXms( 50 );
	}
	else{
		P1 = 0xc0;		// 第2行起始地址
		write_ir( );
		PTR = &L23; 		// L23[]= "ERROR!!!" ;
		n=16;
		write_dr( PTR, n );
		P1 = 0xc8;		// 光标最后停留在LCD 的0xc8位置
		write_ir( );
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -