如何基于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]);
}
}
}