自学了一点单片机知识,写了一个6x6矩阵键盘,用的行列扫描法,P1P3口是键盘口,P0是液晶屏口,按下按键液晶屏输出字符,液晶相关代码是百度的,大佬们见笑了
电路原理图如下:
仿真
单片机源程序如下:
#include "reg51.h"
#include <math.h>
#include <stdio.h>
sbit rs=P2^6; //指令or数据 RD
sbit wela=P2^5; //读or写 WR
sbit lcden=P2^7; //使能信号LCD
unsigned int KeyValue,KeyState;
//************************************************************************/
// 描述: 延时t us函数
//************************************************************************/
void LCD_Delay_us(unsigned int t)
{
while(t--); //t=0,退出
}
//************************************************************************/
// 描述: 延时t ms函数
//************************************************************************/
void LCD_Delay_ms(unsigned int t)
{
unsigned int i,j;
for(i=0;i<t;i++) //执行t次循环
for(j=0;j<113;j++) //执行113次循环
;
}
//************************************************************************/
// 描述: 1602液晶写指令
//************************************************************************/
void write_com(unsigned char com) //1602液晶写指令
{
rs=0; //写指令
lcden=0; //使能1602
P0=com; //写入指令com
LCD_Delay_ms(1); //延时1ms
lcden=1; //使能1602
LCD_Delay_ms(2); //延时2ms
lcden=0; //使能1602
}
//************************************************************************/
// 描述:1602液晶写数据
//************************************************************************/
void write_date(unsigned char date) //1602液晶写数据
{
rs=1; //写数据
lcden=0; //使能1602
P0=date; //写入数据date
LCD_Delay_ms(1); //延时1ms
lcden=1; //使能1602
LCD_Delay_ms(2); //延时2ms
lcden=0; //使能1602
}
//************************************************************************/
// 描述:指定x,y写入字符函数
//************************************************************************/
void W_lcd(unsigned char x,unsigned char y,unsigned char Data)
{
if (y == 0){write_com(0x80 + x);} //第一行
else{write_com(0xc0 + x);} //第二行
write_date( Data); //写入数据
}
//指定x,y写入字符串函数
void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s)
{
if (y == 0){write_com(0x80 + x);} //第一行
else{write_com(0xC0 + x);} //第二行
while (*s) //
{write_date( *s); s++;} //写入数据
}
//************************************************************************/
// 描述:初始化液晶,及画面初始化
//************************************************************************/
void init_lcd(void) //初始化液晶,及画面初始化
{
wela=0; //写液晶
lcden=0; //使能1602
write_com(0x38); //8 位总线,双行显示,5X7 的点阵字符
LCD_Delay_us(100); //延时100us
write_com(0x0F); //开显示,有光标,闪烁
write_com(0x06); //光标右移动
write_com(0x01); //清屏
write_com(0x80); //DDRAM 地址归0
}
//键盘输入函数**********************************************************************
void KeyDown(void)
{
char a=0;
P3=0x3f;
P1=0x00;
KeyState=0;
if(P3!=0x3f)//读取按键是否按下
{
LCD_Delay_ms(10);//延时10ms进行消抖
if(P3!=0x3f)//再次检测键盘是否按下
{
P3=0x3f;
P1=0x00;
KeyState=1;
switch(P3) //P3口选择
{
case(0x3e): KeyValue=0;break;
case(0x3d): KeyValue=1;break;
case(0x3b): KeyValue=2;break;
case(0x37): KeyValue=3;break;
case(0x2f): KeyValue=4;break;
case(0x1f): KeyValue=5;break;
}
P1=0x3f; //高低电平对调
P3=0x00;
switch(P1) //检测P1口
{
case(0x3e): KeyValue=KeyValue;break;
case(0x3d): KeyValue=KeyValue+6;break;
case(0x3b): KeyValue=KeyValue+12;break;
case(0x37): KeyValue=KeyValue+18;break;
case(0x2f): KeyValue=KeyValue+24;break;
case(0x1f): KeyValue=KeyValue+30;break;
//default: KeyValue=0;
}
while(P1!=0x3f) //检测按键松手检测
{
LCD_Delay_ms(10);
a++;
}
}
}
}
//***********************************************************************
void main()
{
unsigned char a[]="0123456789abcdefghigklmnopqrstuvwxyz";
init_lcd() ;
while(1)
{
KeyDown();
if(KeyState)
{
write_date(a[KeyValue]);
KeyState=0;
}
}
}
|