/****************************************************************
12864显示程序
实现液晶显示固定的菜单页面及接受速度数值并计算显示出来
单片机:蓝海微芯实验板;液晶DV12864M ver1.1;
经验证,能有效稳定工作//////////祁耀金 07:37 2012-7-23
*****************************************************************/
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit RS=P2^1; //DI---数据or指令
sbit RW=P2^0; //读or写
sbit EN=P1^6; //使能
unsigned int v; //电机转速
unsigned char count; //储存定时器T0中断次数
bit flag; //计满1秒钟标志位
unsigned char code digit[ ]={"0123456789"}; //定义字符数组显示数字
uchar table0[]="电机调速测速系统";
uchar table1[]="此次调速用时 秒"; //界面固定显示内容
void delay(uint i) //延时函数
{
while(--i);
}
void read_busy() //读忙标志
{
RS=0; //rs=0,rw=1才可以读
RW=1;
EN=1;
while(P0 & 0x80); //取BF位并判断,如遇忙、则等待;等到死也不离开
EN=0;
}
/***************************************
功能:将模式设置指令或显示地址写入液晶模块
入口参数:value
****************************************/
void write_command(uchar value) //写命令和地址函数
{
read_busy(); //读写前先读忙
RS=0; //rs=0,rw=0才可以读
RW=0;
delay(10);
EN=1; //EN从1--0锁存有效数据
P0 = value;
delay(10);
EN=0;
}
/****************************************
功能:向液晶写显示数据
*****************************************/
void write_data(uchar value) //写显示数据函数
{
read_busy();
RS=1; //rs=1,rw=0才可以写
RW=0;
delay(10);
EN=1; //EN从1--0锁存有效数据
P0 = value;
delay(10);
EN=0;
}
/******************************
功能:初始化12864液晶
*******************************/
void init_LCD() //LCD12864初始化
{
write_command(0x30); //8位数据格式,基本指令显示
delay(10); //延时时间
write_command(0x30); //8位数据格式,基本指令显示
delay(10);
write_command(0x0C); //开显示、关闭光标
delay(37);
write_command(0x01); //清屏指令
delay(10); //延时
write_command(0x06); //设置显示点:指针自加1
}
/********************************************
功能:显示开机液晶界面
*********************************************/
void dis_menu(void)
{
uchar num;
write_command(0x80); //设定显示的地址
for(num=0;num<16;num++)
{
write_data(table0[num]);
}
write_command(0x90); //设置显示地址:2行1列
write_data('v'); //当前速度显示栏
write_data('=');
write_command(0x95); //显示地址:2行6列
write_data('r'); //当前速度单位
write_data('/');
write_data('s');
write_command(0x88); //设置显示地址:3行1列
write_data('s'); //设定速度提示
write_data('e');
write_data('t');
write_data(':');
write_command(0x8d); //3行6列
write_data('r'); //同上
write_data('/');
write_data('s');
write_command(0x98); //设置显示地址
for(num=0;num<16;num++) //页面内容:调速计时栏
{
write_data(table1[num]);
}
}
/***************************************************
函数功能:显示速度数值
****************************************************/
void display_val(unsigned int x)
{
unsigned char i=0,j=0,k=0,l=0; //j,k,l分别储存速度的百位、十位和个位
i=x/1000; //取千位
j=(x%1000)/100; //取百位
k=(x%100)/10; //取十位
l=x%10; //取个位
write_command(0x92); //写显示地址,将在第2行第3列开始显示
write_data(digit[i]); //将千位数字的字符常量写入LCD
write_data(digit[j]); //百
write_data(digit[k]); //十
write_data(digit[l]); //个
}
void Time0(void ) interrupt 1 using 1 //定时器T0,第1组工作寄存器
{
count++; //T0每中断1次,count加1
if(count==20) //若累计满20次,即计满1秒钟
{
flag=1; //计满1秒钟标志位置1
count=0; //清0,重新统计中断次数
}
TH0=(65536-46083)/256; //定时器T0高8位重新赋初值
TL0=(65536-46083)%256; //定时器T0低8位重新赋初值
}
/**************************************
主函数
***************************************/
void main()
{
init_LCD(); //初始化液晶
write_command(0x01); //清屏
dis_menu(); //加载屏幕主显页面
TMOD=0x51; //T1工作于计数模式1,定时器T0工作于计时模式1;
TH0=(65536-46083)/256; //定时器T0的高8位设置初值,每50ms产生一次中断
TL0=(65536-46083)%256;
EA=1; //开总中断
ET0=1; //定时器T0中断允许
TR0=1; //启动定时器T0
count=0; //将T0中断次数初始化为0
while (1)
{
TR1=1; //计数器T1启动
TH1=0; //计数器T1清零
TL1=0;
flag=0; //满1秒钟标志位
while(flag==0) //时间未满等待
;
v=(TH1*256+TL1)/4; //计算速度
display_val(v); //显示速度
}
}