//Lall_G01:单片机硬件串口C51例程(含指令的C函数)
//=====================================================================================
//本程序为Franklin/keil C51源程序,可以在所有51系列(或兼容)单片机中运行。
//完成功能:使用P3.1硬件串行接口,实现对智能液晶模块进行控制.
//程序中给出了设计方法,通过修改TIMEth使本程序适用于各种晶振及各种波特率.
//本例为:当通讯波特率=9600Hz,单片机晶振=18.432MHz时,TIMEth=246
// 使用P3.1硬件串口,使用P1.2检测"忙"信号.
//本程序在Wave For windows ver 2.80仿真软件编译成功。
//在AT89C51(9600Hz,18.432MHz)中运行通过
//=====================================================================================
#include "reg51.h"
sbit ZD_DATA =P3^1; //向液晶输出串行数据
sbit ZD_BUSY =P1^2; //接收液晶发来的"忙"(BUSY)信号,可以连接于任意一位输入引脚上.
//=========================================================================================
#define TIMEth 246 //9600Hz,18.432MHz(修改TIMEth可使本程序适用于各种晶振及各种波特率)
//#define TIMEth 250 //9600Hz,11.0592MHz
//=========================================================================================
void FSsj(unsigned char A)
//通过硬件串口发送1字节
{ while(ZD_BUSY); // 如果终端"忙",则等待
SBUF = A; // 发送一字节
while( !TI ); // 等待本字节发送完毕
TI = 0; // 清除 TI
}
//例:FSsj(0x1B);FSsj(0x31);
//=========================================================================================
void XS16(unsigned char zj)
//显示2位16进制数(后跟H和空格),调试时使用。
{unsigned char j;
FSsj(0x1B);FSsj('1');//选择字符集1
j=zj>>4&15;FSsj((j>9)?(j+0x37):(j+0x30));
j=zj&15;FSsj((j>9)?(j+0x37):(j+0x30));
FSsj('H');FSsj(' ');
}
//例:XS16(34);XS16(0x10);
//=========================================================================================
void ZFJ(unsigned char n)
//选择字符集1:n=1,选择字符集2:n=2,选择字符集3:n=3,选择字符集4:n=4
{FSsj(0x1B);FSsj(n|0x30); }
//例:ZFJ(2);//选择字符集2
//=========================================================================================
void ZJU(unsigned char z,unsigned char n)
//设置字间距:n=0-127。z=0:字间距为正。z=1:字间距为负(这时将出现字符叠加的情况)。
{FSsj(0x1B);FSsj(0x5A);FSsj((z*128)|n);}
//例:ZJU(1,3);//设置字间距为-3
//=========================================================================================
void HJU(unsigned char z,unsigned char n)
//设置行间距:n=0-127。z=0:行间距为正。z=1:行间距为负(这时将出现字符叠加的情况)。
{FSsj(0x1B);FSsj(0x48);FSsj((z*128)|n);}
//例:HJU(0,3);//设置行间距为3
//=========================================================================================
void CSH(unsigned char n)
//初始化
{FSsj(0x1B);FSsj(0x40);}
//例:CSH(0);
//=========================================================================================
void YS(unsigned char n)
//延时0.1秒 — 25.5秒,n=1 — 255
{FSsj(0x1B);FSsj(0x6C);FSsj(n);}
//例:YS(60);//延时6秒
//=========================================================================================
void YS2(unsigned char n)
//延时1分钟 — 255分钟,n=1 — 255
{for(;n>0;n--)
{FSsj(0x1B);FSsj(0x6C);FSsj(200);
FSsj(0x1B);FSsj(0x6C);FSsj(200);
FSsj(0x1B);FSsj(0x6C);FSsj(200);
}
}
//例:YS2(60);//延时60分钟
//=========================================================================================
void QPM(unsigned char ys)
//清屏幕为ys=0(底色),7(显示色)
{FSsj(0x1B);FSsj(0x51);FSsj(ys);}
//例:QPM(0);
//=========================================================================================
void FDXZ(sp,cz,fx)
//字符放大及旋转
unsigned char sp;//水平放大倍数 sp=0(不放大),1(放大1倍),2(放大2倍),3(放大3倍)
unsigned char cz;//垂直放大倍数 cz=0(不放大),1(放大1倍),2(放大2倍),3(放大3倍)
unsigned char fx;//字符旋转方向
// fx=0(向左),字符方向朝左,字符串方向从左向右,纵向排列,(需要横向排列时可以分别单独显示每个字符)
// 注意字符串的宽度不要超过屏幕的右侧。
// fx=1(向上),字符方向朝上,字符串方向从左向右,横向排列,
// 这是普通的使用方法。注意字符串的宽度不要超过屏幕的右侧。
// fx=2(向右),字符方向朝右,字符串方向从右向左,纵向排列,(需要横向排列时可以分别单独显示每个字符)
// 注意X坐标应该大于字符串的总高度。
// fx=3(向下),字符方向朝下,字符串方向从右向左,横向排列,
// 注意X坐标应该大于字符串的总宽度。
{FSsj(0x1B);FSsj(0x66);FSsj(sp<<6 | cz<<4 | fx<<2);}
//例:FDXZ(0,0,1);//放大旋转
//=========================================================================================
void HD(X,Y,ys)
//画点
unsigned int X,Y;//点的坐标(0-1023)。
unsigned char ys;
// ys=8时,将对应点取反。
// ys<8时,点颜色为ys=0(底色),7(显示色)
{FSsj(0x1B);FSsj(0x64);
if(ys<8){FSsj((ys<<4|0x80)|(X>>8&3));}
else {FSsj(X>>8&3);}
FSsj(X&0xFF) ;
FSsj(Y>>8&3);FSsj(Y&0xFF);
}
//例:HD(5,10,7);//在(5,10)划1点
//=========================================================================================
void ZYS(X,Y,ys1,ys2)
//设置:系统坐标,字颜色
unsigned int X,Y;//下一个字符左上角的坐标(0-1023)。
unsigned char ys1;
//前景色 ys1=8时,字符前景为对应点取反。
//前景色 ys1<8时,字符背景为ys1=0(底色),7(显示色)
unsigned char ys2;
//背景色 ys2=8时,叠加方式,字符背景仍为原来的内容。
//背景色 ys2<8时,覆盖方式,字符背景为ys2=0(底色),7(显示色)
{
FSsj(0x1B);FSsj(0x7A);
if(ys1<8){FSsj((ys1<<4|0x80)|(X>>8&3));}
else {FSsj(X>>8&3);}
FSsj(X&0xFF) ;
if(ys2<8){FSsj((ys2<<4|0x80)|(Y>>8&3));}
else {FSsj(Y>>8&3);}
FSsj(Y&0xFF);
}
//例:ZYS(8,10,8,8);ZYS(8,10,7,0);
//=========================================================================================
void HZX(X1,Y1,X2,Y2,ys)
//画直线
unsigned int X1,Y1;// =直线起点的坐标(0-1023)。
unsigned int X2,Y2;// =直线终点的坐标(0-1023)。
unsigned char ys;
// ys=8时,将对应点取反。
// ys<8时,线颜色为ys=0(底色),7(显示色)
{FSsj(0x1B);FSsj(0x78);
if(ys<8){FSsj((ys<<4|0x80)|(X1>>8&3));}
else {FSsj(X1>>8&3);}
FSsj(X1&0xFF) ;
FSsj(Y1>>8&3); FSsj(Y1&0xFF);
FSsj(X2>>8&3); FSsj(X2&0xFF);
FSsj(Y2>>8&3); FSsj(Y2&0xFF);
}
//例:HZX(0,0,127,63,8);
//=========================================================================================
void HLXZX(X,Y,ys)
//画连续直线
unsigned int X,Y;//直线终点坐标(0-1023)。
//本指令输入1个点坐标,即可将当前系统坐标与该点连接为直线,并将该点作为新的系统坐标。
//连续使用本命令可绘制任意形状的曲线。在第1次使用本指令前,应执行ESC z指令设置系统坐标。
unsigned char ys;
//ys=8时,将对应点取反。
//ys<8时,线颜色为ys=0(底色),7(显示色)
{FSsj(0x1B);FSsj(0x76);
if(ys<8){FSsj((ys<<4|0x80)|(X>>8&3));}
else {FSsj(X>>8&3);}
FSsj(X&0xFF) ;
FSsj(Y>>8&3); FSsj(Y&0xFF);
}
//例:HLXZX(2,3,7);
//=========================================================================================
void HYH(X,Y,R,ys,xx,tc,yxh,ysh,zsh,zxh)
//画圆弧
unsigned int X,Y;//圆心坐标(0-1023)。
unsigned char R; // 圆的半径(1-255)。
unsigned char ys;
// ys=8时,为对应点取反。
// ys<8时,颜色为ys=0(底色),7(显示色)
bit xx;// =0:实线。 =1:虚线。
bit tc;// =0:不填充 =1:填充。
bit yxh;// =0:画右下弧,=1:不画。
bit ysh;// =0:画右上弧,=1:不画。
bit zsh;// =0:画左上弧,=1:不画。
bit zxh;// =0:画左下弧,=1:不画。
{FSsj(0x1B);FSsj(0x79);
if(ys<8){FSsj((ys<<4|0x80)|(X>>8&3)|((xx)?4:0));}
else {FSsj((X>>8&3)|((xx)?4:0));}
FSsj(X&0xFF);
FSsj((Y>>8&3)|((tc)?4:0)|((yxh)?0x80:0)|((ysh)?0x40:0)|((zsh)?0x20:0)|((zxh)?0x10:0));
FSsj(Y&0xFF);
FSsj(R);
}
//例:HYH(8,56,5,7,0,0,0,0,0,0);
//=========================================================================================
void HSXE(X,Y,R,QS,JS,ys,tc,ms)
//画扇形。本指令可绘制任意圆弧或扇形,且圆心,半径,弧,是否填充均可设定。
unsigned int X,Y;//圆心坐标
unsigned char R