51单片机 LCD12864 矩阵键盘
软件部分
#include"reg51.h"
/********************************************************************************************************************************* 实验名称:普中单片机12864的使用 实验效果:倒计时100显示 *****************************************************************************************************************************/
/********************************************************************************************************** 端口定义 ************************************************************************************************************/
sbit RS=P2^6; //命令/数据选择
sbit RW=P2^5; //读写口
sbit E=P2^7; //锁存控制
sbit RES = P2^0;
sbit PSB = P2^2;
/********************************************************************************************************** 函数声明 ************************************************************************************************************/
void InitLCD(void);
void Display_Char(unsigned char x,unsigned char y,unsigned char Char);
void Display_String(unsigned char x,unsigned char y,unsigned char *s);
void Display_UnsignedInt(unsigned char x,
unsigned char y,
unsigned int Number,
unsigned char Count);
void Display_SignedInt(unsigned char x,
unsigned char y,
signed int Number,
unsigned char Count) ;
void Display_Float(unsigned char x,
unsigned char y,
float Number,
unsigned char Count1,
unsigned char Count2);
void DELAY_nUS(unsigned int Time);
void DELAY_nMS(unsigned int time);
void delay(unsigned int time);
#define GPIO_KEY P1
unsigned char KeyValue;
//用来存放读取到的键值
unsigned char KeyState;
//用来存放按键状态
unsigned char PuZh[]=" MCU Science ";
unsigned char dat[]="0123456789ABCDEF";
/********************************************************************** 函数主体部分 ***************************************************************************/
void DELAY_nUS(unsigned int Time)
{
while(--Time);
}
void DELAY_nMS(unsigned int time)
{
unsigned int i,j;
for(i=0;i<time;i++)
for(j=0;j<939;j++);
}
void delay(unsigned int time) //int型数据为16位,所以最大值为65535
{ //0.1ms
unsigned int i,j; //定义变量i,j,用于循环语句
for(i=0;i<time;i++) //for循环,循环50*time次
for(j=0;j<50;j++); //for循环,循环50次
}
/******************************************************************************* * 函 数 名 : Delay10ms * 函数功能 : 延时函数,延时10ms * 输 入 : 无 * 输 出 : 无 *******************************************************************************/
void Delay10ms(void) //误差 0us
{
unsigned char a,b,c;
for(c=1;c>0;c--)
for(b=38;b>0;b--)
for(a=130;a>0;a--);
}
/******************************************************************************* * 函 数 名 : checkbusy() * 函数功能 : 查忙 * 输 入 : 无 * 输 出 : 无 *******************************************************************************/
void checkbusy(void)
{
RS=0;
RW=1;
E=1;
while((P0&0x80)==0x80);
E=0;
}
/******************************************************************************* * 函 数 名 : LcdWriteCom * 函数功能 : 向LCD写入一个字节的数据 * 输 入 : dat * 输 出 : 无 *******************************************************************************/
void LcdWriteCom(unsigned char cmdcode) //写入命令
{
checkbusy();
RS=0;
RW=0;
E=1;
P0=cmdcode;
delay(10);
E=0;
}
/******************************************************************************* * 函 数 名 : LcdWriteData * 函数功能 : 向LCD写入一个字节的数据 * 输 入 : dat * 输 出 : 无 *******************************************************************************/
void LcdWriteData(unsigned char dispdata)
{
checkbusy();
RS=1;
RW=0;
E=1;
P0=dispdata;
delay(10);
E=0;
}
/******************************************************************************* * 函 数 名 : InitLCD() * 函数功能 : 初始化LCD屏 * 输 入 : 无 * 输 出 : 无 *******************************************************************************/
void InitLCD(void)
{
PSB=1;
RES=0;
delay(10);
RES=1;
LcdWriteCom(0x30);
LcdWriteCom(0x0c);
LcdWriteCom(0x01);
LcdWriteCom(0x06);
}
/******************************************************************************* * 函 数 名 : Display_Char() * 函数功能 : 显示字符 * 输 入 : 无 * 输 出 : 无 *******************************************************************************/
void Display_Char(unsigned char x,unsigned char y,unsigned char Char)
{
switch(y)
{
case 0: LcdWriteCom(0x80+x);break;
case 1: LcdWriteCom(0x90+x);break;
case 2: LcdWriteCom(0x88+x);break;
case 3: LcdWriteCom(0x98+x);break;
default:break;
}
LcdWriteData(Char);
}
/******************************************************************************* * 函 数 名 : Display_String() * 函数功能 : 显示字符串 * 输 入 : 无 * 输 出 : 无 *******************************************************************************/
void Display_String(unsigned char x,unsigned char y,unsigned char *s)
{
switch(y)
{
case 0: LcdWriteCom(0x80+x);break;
case 1: LcdWriteCom(0x90+x);break;
case 2: LcdWriteCom(0x88+x);break;
case 3: LcdWriteCom(0x98+x);break;
default:break;
}
while(*s>0)
{
LcdWriteData(*s);
delay(10);
s++;
}
}
/******************************************************************************* * 函 数 名 : Display_Unsignedint() * 函数功能 : 显示无符号整形 * 输 入 : 无 * 输 出 : 无 *******************************************************************************/
void Display_UnsignedInt(unsigned char x,unsigned char y,unsigned int Number,unsigned char Count)
{
unsigned char NumbArray[6]={0};
NumbArray[0]=(Number/10000)%10+0x30;
NumbArray[1]=(Number/1000) %10+0x30;
NumbArray[2]=(Number/100) %10+0x30;
NumbArray[3]=(Number/10) %10+0x30;
NumbArray[4]=(Number/1) %10+0x30;
NumbArray[5]= 0;
Display_String(x,y,&NumbArray[5-Count]);
}
/******************************************************************************* * 函 数 名 : Display_Signedint() * 函数功能 : 显示有符号整形 * 输 入 : 无 * 输 出 : 无 *******************************************************************************/
void Display_SignedInt(unsigned char x,
unsigned char y,
signed int Number,
unsigned char Count)
{
unsigned char NumberArray[7]={0};
signed int Number_Temp;
Number_Temp = Number;
if(Number_Temp<0)
{
Number_Temp = 0 - Number_Temp;
}
NumberArray[0]='+';
NumberArray[1]=(Number_Temp/10000)%10+0x30;
NumberArray[2]=(Number_Temp/1000) %10+0x30;
NumberArray[3]=(Number_Temp/100) %10+0x30;
NumberArray[4]=(Number_Temp/10) %10+0x30;
NumberArray[5]=(Number_Temp/1) %10+0x30;
NumberArray[6]=0;
if(Number>0)
{
NumberArray[5-Count] = '+';
}
else
{
NumberArray[5-Count] = '-';
}
Display_String(x, y, &NumberArray[5-Count]);
}
/******************************************************************************* * 函 数 名 : Display_Float() * 函数功能 : 显示浮点数 * 输 入 : 无 * 输 出 : 无 *******************************************************************************/
void Display_Float(unsigned char x,
unsigned char y,
float Number,
unsigned char Count1,
unsigned char Count2)
{
unsigned char NumberArray[11]={0};
unsigned int Number_Integer = 0;
unsigned int Number_Decimal = 0;
float Number_Temp;
Number_Temp = Number;
if(Number_Temp < 0)
{
Number_Temp= 0 - Number_Temp;
}
Number_Integer = (unsigned int)(Number_Temp);
Number_Decimal = (unsigned short)((Number_Temp - Number_Integer + 0.0005) * 1e3);
NumberArray[ 0] = '+';
NumberArray[ 1] = Number_Integer/10000 % 10 + 0x30;
NumberArray[ 2] = Number_Integer/ 1000 % 10 + 0x30;
NumberArray[ 3] = Number_Integer/ 100 % 10 + 0x30;
NumberArray[ 4] = Number_Integer/ 10 % 10 + 0x30;
NumberArray[ 5] = Number_Integer/ 1 % 10 + 0x30;
NumberArray[ 6] ='.';
NumberArray[ 7] = Number_Decimal/ 100 % 10 + 0x30;
NumberArray[ 8] = Number_Decimal/ 10 % 10 + 0x30;
NumberArray[ 9] = Number_Decimal/ 1 % 10 + 0x30;
NumberArray[10] = 0;
if(Number>0)
{
NumberArray[5-Count1] = '+';
}
else
{
NumberArray[5-Count1] = '-';
}
NumberArray[7+Count2] = 0;
Display_String(x, y, &NumberArray[5-Count1]);
}
/******************************************************************************* * 函 数 名 : KeyDown * 函数功能 : 检测有按键按下并读取键值 * 输 入 : 无 * 输 出 : 无 *******************************************************************************/
void KeyDown(void)
{
char a;
GPIO_KEY=0x0f;
if(GPIO_KEY!=0x0f)
{
Delay10ms();
if(GPIO_KEY!=0x0f)
{
KeyState=1;
//测试列
GPIO_KEY=0X0F;
Delay10ms();
switch(GPIO_KEY)
{
case(0X07): KeyValue=0;break;
case(0X0b): KeyValue=1;break;
case(0X0d): KeyValue=2;break;
case(0X0e): KeyValue=3;break;
default: KeyValue=17; //检测出错回复17意思是把数码管全灭掉。
}
//测试行
GPIO_KEY=0XF0;
Delay10ms();
switch(GPIO_KEY)
{
case(0X70): KeyValue=KeyValue;break;
case(0Xb0): KeyValue=KeyValue+4;break;
case(0Xd0): KeyValue=KeyValue+8;break;
case(0Xe0): KeyValue=KeyValue+12;break;
default: KeyValue=17;
}
while((a<50)&&(GPIO_KEY!=0xf0)) //检测按键松手检测
{
Delay10ms();
a++;
}
a=0;
}
}
}
void main()
{
unsigned char i;
unsigned char temp;
InitLCD();
KeyState=0;
for(i=0;i<16;i++)
{
// wcode(0x80);
LcdWriteData(PuZh[i]);
}
while(1)
{
KeyDown();
if(KeyState)
{
KeyState=0;
LcdWriteCom(0x80+0x40);
LcdWriteData(dat[KeyValue]);
}
}
}
参考资料
- STM32 固件库 矩阵键盘 https://blog.csdn.net/weixin_43599390/article/details/105181107
- 51单片机 LCD液晶显示模块使用
https://blog.csdn.net/weixin_43599390/article/details/105058048 - 博客链接https://lemonhubs.github.io/