📄 lcd.c
字号:
#include <intrins.h>
#include <AT89X51.h>
/*--------------------系统变量定义------------------*/
//LCD模块
#define LCD_RW P2_6 //读写控制端
#define LCD_RS P2_7 //数据命令选择端
#define LCD_E P2_5 //执行使能端
#define LCD_Data P1 //P1口
#define Write 0x00 //低电平写入
#define Read 0x01 //高电平读出
#define Data 0x01 //高电平选择数据
#define Cmd 0x00 //低电平选择命令
#define Enable 0x00 //跃变到低电平时执行命令
#define Disable 0x01
#define True 0x01
#define False 0x00
#define LCD_Init 0x38 //初始化模式
#define LCD_DispCtr 0x0C //开显示及光标设置
#define LCD_CloseCtr 0x08 //关显示
#define LCD_CLS 0x01 //清屏幕
#define LCD_EnterSet 0x06 //显示光标
#define Busy P1_7 //忙信号
//测速/测距/测时模块
#define CircleLength 0x0C //小车转一轮的长度为12cm
//控速模块
#define P00 P0_0
#define LowSpeedHighTime 0x04
#define HighSpeedHighTime 0x08
/*--------------------------------------------------*/
/*--------------------全局函数----------------------*/
//LCD显示模块
void LCDInit(void); //LCD初始化
void SetWriteCmd(void); //设置写命令模式
void SetReadCmd(void); //设置读命令模式
void SetWriteData(void); //设置写数据模式
void WriteCmd(char cmd); //写命令
void WriteData(char ddata); //写数据
void ExecuteCmd(void); //执行命令
void SetXY(char x,char y); //定位显示地址
void DisplaySingleChar(char x,char y,char cchar); //显示单个字符
void DisplayString(char x,char y,char *str); //显示一段字符串
void Delay(unsigned int time); //延时主程序
void DelayUs(unsigned int time); //延时子程序
bit IsBusy(void); //判断忙标志函数
void DisplayTime(void); //显示时间
void DisplaySpeedANDDistance(void); //显示速度和时间
void DisplayAverageSpeed(void); //显示平均速度
//测速/测距/测时模块
void INTInit(void); //所有中断初始化
void Clock0_Init(void); //时钟0中断初始化
void SpeedINT(void); //测速中断
void Time0INT(void); //测速单位时间中断
//控速模块
void CtrSpeedINT(void); //控速中断
void Time1INT(void); //控速单位时间中断
void Clock1_Init(void); //时钟1中断初始化
void CtrSpeed(void);
/*--------------------------------------------------*/
/*--------------------全局变量----------------------*/
char SpeedCount = 0; //测速计数脉冲
char SpeedStr[] = "V:"; //速度提示符
char SpeedUnitStr[] = "cm/s"; //速度单位提示符
int Speed = 0; //速度显示
char TimeStr[] = "T:"; //小车行走时间提示符
char TimeUnitStr[] = "s"; //时间单位提示符
int Time0INTCount = 0; //T0中断时间计时
char DistanceStr[] = "S:"; //行走路程提示符
char DistanceUnitStr[] = "cm"; //路程单位提示符
int Distance = 0; //行走路程
char Time; //高电平持续时间变量
char Period=0x0A; //输出方波周期
char Area=0; //区域变量
char HighTime; //高电平持续时间
char Time1INTCount=0; //T1中断时间计时
char PassTime=0; //小车行走的时间
char DisplaySwitch=0; //显示切换变量
bit IsT0INT; //判断T0是否已经响应中断
char Maker[]="106Pro"; //制作单位名称
int AverageSpeed;
/*---------------------主函数-----------------------*/
void main()
{
INTInit(); //初始化所有中断
Clock0_Init(); //初始化时钟中断0
Clock1_Init(); //初始化时钟中断1
Delay(40); //延时等待LCD启动
LCDInit(); //初始化LCD
DisplayString(0x0A,0,TimeStr); //显示时间提示符
DisplayString(0x0F,0,TimeUnitStr);
DisplayString(0,0,SpeedStr); //显示速度提示符
DisplayString(0x05,0,SpeedUnitStr);
DisplayString(0,1,DistanceStr); //显示路程提示符
DisplayString(0x06,1,DistanceUnitStr);
DisplayString(0x0A,1,Maker) ; //显示制作单位
while(1)
{
if (IsT0INT==1 && Area>=1 && Area<6)
DisplayTime();
if (IsT0INT==1 && Area>=6)
{
DisplayAverageSpeed();
EX0=0;
ET0=0;
P00=0;
}
}
while(1); //等待中断,循环处理
}
void LCDInit(void)
{
//三次显示模式设置
LCD_Data=0;
LCD_E=Disable;
Delay(5);
WriteCmd(LCD_Init);
Delay(5);
WriteCmd(LCD_Init);
Delay(5);
WriteCmd(LCD_Init);
WriteCmd(LCD_Init); //初始化
WriteCmd(LCD_CloseCtr); //关显示
WriteCmd(LCD_CLS); //清屏幕
WriteCmd(LCD_EnterSet); //光标移动设置
WriteCmd(LCD_DispCtr); //显示开以及光标设置
}
void SetWriteCmd(void)
{
LCD_RW=Write;
LCD_RS=Cmd;
}
void SetReadCmd(void)
{
LCD_RW=Read;
LCD_RS=Cmd;
}
void SetWriteData(void)
{
LCD_RW=Write;
LCD_RS=Data;
}
void WriteCmd(char cmd)
{
while(IsBusy());
LCD_Data=cmd;
SetWriteCmd();
ExecuteCmd();
}
void WriteData(char ddata)
{
while(IsBusy());
LCD_Data=ddata;
SetWriteData();
ExecuteCmd();
}
void ExecuteCmd(void)
{
LCD_E=Enable;
LCD_E=Disable;
}
void SetXY(char x,char y)
{
if (y)
x|=0x40;
x|=0x80;
Delay(5);
WriteCmd(x);
}
void DisplaySingleChar(char x,char y,char cchar)
{
SetXY(x,y);
WriteData(cchar);
}
void DisplayString(char x,char y,char *str)
{
while(*str)
{
Delay(5);
DisplaySingleChar(x++,y,*str);
str++;
}
}
void Delay(unsigned int time)
{
unsigned int timeCounter = 0;
for (timeCounter = time;timeCounter > 0 ;timeCounter --)
DelayUs(255);
}
void DelayUs(unsigned int time)
{
unsigned int timeCounter = 0;
for (timeCounter = 0;timeCounter < time;timeCounter ++)
_nop_();
}
bit IsBusy(void)
{
LCD_Data=0xFF;
SetReadCmd();
ExecuteCmd();
return (bit)(P1 & 0x80);
}
void INTInit(void)
{
EA=1; //开总中断
EX0=1; //开INTO中断
IT0=1; //INTO边沿触发
PX0=1; //INTO优先级为高级
EX1=1; //开INT1中断
IT1=1; //INT1边沿触发
PX1=1; //INT1优先级为高级
TMOD=0x01; //T0定时方式1
ET0=0x01; //开T0中断
ET1=0x01; //开T1中断
Time=0;
HighTime=LowSpeedHighTime;
}
/*-----------------中断处理----------------------*/
void SpeedINT(void) interrupt 0 using 0
{
SpeedCount++;
}
void Time0INT(void) interrupt 1 using 1
{
Clock0_Init();
Time0INTCount++;
if (Time0INTCount == 20) //1S时间到
{
EX0=0x00; //关INT0中断
IsT0INT=1;
DisplaySpeedANDDistance();
SpeedCount=0;
Time0INTCount=0; //计数清0
EX0=0x01; //重开INT0
}
}
void CtrSpeedINT(void) interrupt 2 using 2
{
TR1=0x00; //关闭T1计时
Area++;
if (Area==2) //区域1--低速区
HighTime=LowSpeedHighTime;
else if (Area==3) //区域2--高速区
HighTime=HighSpeedHighTime;
else if (Area==4) //区域3--低速区
HighTime=LowSpeedHighTime;
else if (Area>4 && Area<6)
HighTime=LowSpeedHighTime;
else
HighTime=0; //经过3个区域后停止
if (Area<6)
TR1=0x01; //重新开启T1
}
void Time1INT(void) interrupt 3 using 3
{
Clock1_Init();
CtrSpeed();
}
void Clock0_Init(void)
{
TR0=0x01; //启动T0
TH0=0x3C; //定时初值
TL0=0x0B0;
}
void Clock1_Init(void)
{
TR1=0x01; //启动T1
TH1=0x3C; //定时初值
TL1=0x0B0;
}
void DisplayTime(void)
{
char PassTime1=0x30;
char PassTime2=0x30;
IsT0INT=0;
PassTime++;
PassTime1+=(PassTime%10);
if (PassTime > 9)
PassTime2+=(PassTime/10);
DisplaySingleChar(0x0D,0,PassTime2);
DisplaySingleChar(0x0E,0,PassTime1);
}
void CtrSpeed(void)
{
//方波控制--速度控制
if (++Time==HighTime)
P00=0;
if (Time==Period)
{
P00=1;
Time=0;
}
}
void DisplaySpeedANDDistance(void)
{
char Speed1=0x30; //初始化为0的ASCII码
char Speed2=0x30;
char Distance1=0x30;
char Distance2=0x30;
char Distance3=0x30;
char Distance4=0x30;
Speed=SpeedCount*CircleLength; //计算速度
Speed1+=(Speed%10); //取个位数
Speed2+=(Speed/10); //取十位数
Distance+=Speed; //路程计算
Distance1+=(Distance%10);
Distance4+=(Distance/1000);
if (Distance > 99)
Distance2+=(Distance/10%10);
else
Distance2+=(Distance/10);
if (Distance > 999)
Distance3+=(Distance/100%10);
else
Distance3+=(Distance/100);
DisplaySingleChar(0x3,0,Speed2); //显示速度
DisplaySingleChar(0x4,0,Speed1);
DisplaySingleChar(0x02,1,Distance4);
DisplaySingleChar(0x03,1,Distance3); //显示路程
DisplaySingleChar(0x04,1,Distance2);
DisplaySingleChar(0x05,1,Distance1);
}
void DisplayAverageSpeed(void)
{
char AverageSpeed1=0x30; //初始化为0的ASCII码
char AverageSpeed2=0x30;
AverageSpeed=Distance/PassTime%100;
AverageSpeed1+=(AverageSpeed%10); //取个位数
AverageSpeed2+=(AverageSpeed/10);
DisplaySingleChar(0x3,0,AverageSpeed2); //显示平均速度
DisplaySingleChar(0x4,0,AverageSpeed1);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -