|
//==========================define.h文件============================
#define unint unsigned int
#define unchar unsigned char
#define cchar const unsigned char
#define ADDRESS_POINT 0x24
#define AUTO_WRITE 0xB0 //显示数据自动写方式
#define AUTO_DOWN 0xB2 //退出自动读写方式
#define AUTO_SIGN 0x08
#define CMD_MODE1 0x80 //文本与图形逻辑“或”合成显示
#define CMD_MODE2 0x9c //文本和图形都显示
#define CMD_PICTURRE 0x98 //文本关闭,显示图形
#define CMD_FIGURE_ADDRESS 0x42 //图形显示区首地址
#define CMD_FIGURE_WIDTH 0x43 //图形显示区宽度
#define CMD_TEXT_ADDRESS 0x40 //文本显示区首地址
#define CMD_TEXT_WIDTH 0x41 //文本显示区宽度
#define LCD_WR PG0
#define LCD_RD PG1
#define LCD_CD PG2
#define LCD_CODE_P PORTB
#define LCD_DATA PINA
#define LCD_DDR DDRA
#define LCD_PORT PORTA
#define SET_LCD_WR (PORTG |= 0x01)
#define CLR_LCD_WR (PORTG &=~ 0x01)
#define SET_LCD_RD (PORTG |= 0x02)
#define CLR_LCD_RD (PORTG &=~ 0x02)
#define SET_LCD_CD (PORTG |= 0x04)
#define CLR_LCD_CD (PORTG &=~ 0x04)
/**********************所有函数定义*************************/
unchar Read_Sign(void); //读标志
unchar Judge_Sign(unchar str); //判断标志字,看是否处于忙状态
void LCD_init(void); //LCD初始化
void Write_Cmd(unchar command);//写命令函数
void Write_Data(unchar data); //写数据函数
void Lcd_Delay(unint time); //延时
void Write_Cmd3(unchar lcd_code,unchar lcd_date1,unchar lcd_date2);//写带参数的命令函数
void Lcd_Print(cchar *str); //输入一张图形到LCD
void Lcd_Clear(void); //清屏
void Lcd_Word(unchar *str_ww,unchar x,unchar y);//写一个汉字
void Lcd_String(unchar *str,unchar n,unchar x,unchar y);//写多个汉字
void Lcd_point(unchar x,unchar y); //准确位置打点
void Lcd_Line(unchar x1,unchar y1,unchar x2,unchar y2);//画线
void circle(unsigned char x,unsigned char y,unsigned char r );//画圆
//============================================================================
//===============================所有函数fuction.c文件=====================================
void Lcd_Busy(unchar busy)
/*功能:用于SGY240128液晶显示,判断忙状态
说明:busy 是状态标志字,根据不同的需要,判断不同的忙状态。
读写命令和数据是判断STA0、STA1(busy=0X03) ;
数据自动读/写判断STA2、STA3 (busy=0x0c).
*/
{
unchar i;
i=busy;
LCD_DDR = 0x00; //PC口设置为输入方式
LCD_CODE_P |= (BIT(LCD_WR)|BIT(LCD_CD));
CLR_LCD_RD;
while(i!=(LCD_DATA&busy));
LCD_DDR = 0xFF;//还原为输出方式
}
void LCD_init(void)
/*功能:用于SGY240128液晶显示,对LCD进行初始化;(1)设置文本和图形的显示方式
(2)设置文本和图形显示的首地址 (3)写入文本和图形显示的宽度
*/
{
Lcd_Delay(15);
Write_Cmd(CMD_MODE1); //设置文本和图象显示的方式
Write_Cmd(CMD_MODE2);
Write_Cmd3(CMD_FIGURE_ADDRESS,0,0);//写图片显示首地址
Write_Cmd3(CMD_FIGURE_WIDTH,30,0);//设置图形显示的宽度
Write_Cmd3(CMD_TEXT_ADDRESS,0,0);//写文本的显示首地址
Write_Cmd3(CMD_TEXT_WIDTH,30,0); //设置文本显示的宽度
}
void Write_Cmd(unchar command)
/*功能:用于SGY240128液晶显示,写命令字
说明:先判断忙状态,在没有处于忙时,写入命令字
控制端口RD=1,CD=1,WR的下降沿有效
*/
{
Lcd_Busy(0x03);
SET_LCD_CD;
SET_LCD_RD;
LCD_PORT = command;
CLR_LCD_WR;
LCD_CODE_P |= (BIT(LCD_RD) | BIT(LCD_WR) | BIT(LCD_CD));
}
void Write_Cmd3(unchar lcd_code,unchar lcd_date1,unchar lcd_date2)
/*功能:用于SGY240128液晶显示,写有两个参数的命令码
*/
{
Write_Data(lcd_date1);
Write_Data(lcd_date2);
Write_Cmd(lcd_code);
}
void Write_Data(unchar data)
/*功能:用于SGY240128液晶显示,写数据到LCD
说明:首先判断忙状态,再写数据到LCD,写数据时,控制断口RD=1,CD=0,WR的下降盐有效
*/
{
Lcd_Busy(0x03);
SET_LCD_RD;
CLR_LCD_CD;
LCD_PORT = data;
CLR_LCD_WR;
LCD_CODE_P |= (BIT(LCD_RD) | BIT(LCD_WR) | BIT(LCD_CD));
}
void Lcd_Delay(unint time)
/*功能:延时
*/
{
int i;
while(time--)
{
i = 10;
while(i--);
}
}
void Lcd_Clear(void)
/*
功能:用于SGY240128液晶显示,清屏
说明:在自动写方式下,给LCD写数据0X00实现清屏
*/
{
unint i,j;
Write_Cmd3(ADDRESS_POINT,0,0); /*设置显示RAM首地址*/
Write_Cmd(AUTO_WRITE); /*设置自动写方式*/
for (i=0;i<128;i++) /*最大显示点阵为:320×240=9600*/
{
for(j=0;j<30;j++)
{
Lcd_Busy(AUTO_SIGN);
Write_Data(0x00);
}
} /*写00H清屏*/
Lcd_Busy(AUTO_SIGN);
Write_Cmd(AUTO_DOWN); /*设置自动写结束*/
}
void Lcd_Print(cchar *str)
/*功能:用于SGY240128液晶显示,全屏显示一张图形在LCD上
说明:先设置成图形显示,关闭文本显示方式;开启自动写模式,将要写的图形数据
依次写入LCD中,即成一张图画显示在LCD上。
**/
{
unchar i,j;
Write_Cmd(CMD_PICTURRE); // 打开图形显示,关闭文本显示
Write_Cmd3(ADDRESS_POINT,0,0); // 设置地址指针
Write_Cmd(AUTO_WRITE); // 设置自动写数据
for(i=0;i<128;i++)
{
for(j=0;j<30;j++)
{
Lcd_Busy(AUTO_SIGN);
Write_Data(*str); // Write display data
str++;
}
}
Lcd_Busy(AUTO_SIGN);
Write_Cmd(AUTO_DOWN);
}
void Lcd_Word(unchar *str_ww,unchar x,unchar y)
/* 功能:用于SGY240128液晶显示,写汉字到LCD
说明:str_ww是要显示的字,x表示显示的列(0-14),y表示显示的行(0-7)
*/
{
unchar j,i;
unint w;
Write_Cmd(CMD_PICTURRE);
x=x<<1;
for(i=0;i<=1;i++)
{
x=x+i;
for(j=0;j<16;j++)
{
w=y*16*30+x+30+j*30;
Write_Cmd3(ADDRESS_POINT,w%256,w>>8); //w%256为地址的低位字节,w>>8为地址的高位字节
Write_Data(*str_ww);
Write_Cmd(0xc2);
str_ww++;
}
}
}
void Lcd_String(unchar *str,unchar n,unchar x,unchar y)
/*功能:用于SGY240128液晶显示,写一句汉字到LCD
说明:*str--是要写的汉字 n--汉字的个数
x -- 列坐标(0-14) y--行坐标(0-7)
*/
{
unchar i,xx,yy;
unchar *p;
p=str;
yy=y;
for(i=0;i<n;i++)
{
xx=x+i;
if(yy<15&&yy>=0)
Lcd_Word(p,xx,yy);
p=p+32;
}
}
void Lcd_Point(unchar x,unchar y)
/*功能:用于SGY240128液晶显示,实现准确打点
说明:x-列(0-239),y-行(0-127)
由于地址指针不能够知道具体位置,只能够指到8*8的区间,因此需要处理来实现具体点打点.
*/
{
unchar x1,x2,y1,y2;
unint w;
x1=x/8; //确定落在哪个行指针内
x2=x%8; //确定是那一位
y1=y/8;
y2=y%8; //行转换,因为只能指向8*8区间
w=240*y1+x1+y2*30;
//以上是点坐标处理
Write_Cmd(CMD_PICTURRE);
Write_Cmd3(ADDRESS_POINT,w%256,w>>8);//w%256为坐标低位,w>>8为点坐标高位
switch(x2)
{
case 0: Write_Cmd(0xFF);break;
case 1: Write_Cmd(0xFE);break;
case 2: Write_Cmd(0xFD);break;
case 3: Write_Cmd(0xFC);break;
case 4: Write_Cmd(0xFB);break;
case 5: Write_Cmd(0xFA);break;
case 6: Write_Cmd(0xF9);break;
case 7: Write_Cmd(0xF8);break;
}
}
void Lcd_Line(unchar x1,unchar y1,unchar x2,unchar y2)
/*功能:用于SGY240128液晶显示,画一条直线在LCD上
说明:在LCD上画任意一条直线,(x1,y1)为开始点 ,(x2,y2)为结束点
*/
{
unchar xx,yy,j,n,nn;
unchar num,xmin,ymin;
float error,m;
if(x1==x2)
{
n=y2-y1;
nn=abs(y2-y1);
for(j=0;j<=nn;j++)
{
xx=x1;
yy=y1+j;
Lcd_Point(xx,yy);
}
}
else if(x1<x2)
{
n=x2-x1;
m=y2-y1;
ymin=y1;
xmin=x1;
error=m/n;
for(j=0;j<=n;j++)
{
xx=xmin+j;
yy=(unchar)(ymin+error*j);
Lcd_Point(xx,yy);
}
}
else if(x1>x2)
{
n=x1-x2;
m=y1-y2;
ymin=y2;
xmin=x2;
error=m/n;
for(j=0;j<=n;j++)
{
xx=xmin+j;
yy=(unchar)(ymin+error*j);
Lcd_Point(xx,yy);
}
}
}
void circle(unsigned char x,unsigned char y,unsigned char r )
{
/***********************************************
功能描述;在指定位置画一个半径为R的圆
参数说明:x、y、r 分别为圆的中心坐标,
圆的半径
资源使用情况:占用相应控制口线
***********************************************/
signed int delta, delta1,delta2;
signed char drection,x0,y0;
//*************************************
x0=0; y0=r;
delta=2*(1-r);
while(y0>=0)
{
Lcd_Point(x0+x,y0+y);//第四象限圆弧
Lcd_Point(x-x0,y+y0);//第三象限圆弧
Lcd_Point(x-x0,y-y0);//第二象限圆弧
Lcd_Point(x+x0,y-y0);//第一象限圆弧
if (delta<0)
{
delta1=2*(delta+y0)-1;
if(delta1<=0)
{
x0++;
delta+=2*x0+1;
}
else
{
x0++;
y0--;
delta+=2*(x0-y0+1);
}
}
else if (delta>0)
{
delta2=2*(delta-x0)-1;
if(delta2<=0)
{
x0++;
y0--;
delta+=2*(x0-y0+1);
}
else
{
y0--;
delta+=-2*y0+1;
}
}
else
{
x0++;
y0--;
delta+=2*(x0-y0+1);
}
}
//*************************************
} |
|