#include"12864.h"
#include<intrins.h>
#include <math.h>
#define uchar unsigned char
#define uint unsigned int
/**********************************************************************
*************** 延時(shí)函數(shù) *****************************
**********************************************************************/
void delaynop()
{
_nop_();_nop_();
_nop_();_nop_();
}
void delayms(uint t)
{
uint i,j;
for(i=0;i<t;i++)
for(j=0;j<125;j++);
}
/**********************************************************************
*************** 忙檢測(cè) *****************************
**********************************************************************/
bit Lcd_busy()
{
bit result;
LCD_RS = 0;
LCD_RW = 1;
LCD_EN = 1;
delaynop();
result = (bit)(P0&0x80);
LCD_EN = 0;
return(result);
}
/**********************************************************************
*************** 寫指令 *****************************
**********************************************************************/
void Lcd_wcom(uchar cmd)
{
while(Lcd_busy());
LCD_RS = 0;
LCD_RW = 0;
LCD_EN = 0;
_nop_();
_nop_();
P0 = cmd;
delaynop();
LCD_EN = 1;
delaynop();
LCD_EN = 0;
}
/**********************************************************************
*************** 寫數(shù)據(jù) *****************************
**********************************************************************/
void Lcd_wdate(uchar dat)
{
while(Lcd_busy());
LCD_RS = 1;
LCD_RW = 0;
LCD_EN = 0;
P0 = dat;
delaynop();
LCD_EN = 1;
delaynop();
LCD_EN = 0;
}
/**********************************************************************
*************** 讀數(shù)據(jù) *****************************
**********************************************************************/
unsigned char Lcd_rdate()
{
uchar read_data;
Lcd_busy();
P0=0xff;
LCD_RS=1;
LCD_RW=1;
LCD_EN=0;
LCD_EN=1;
read_data=P0;
LCD_EN=0;
return read_data;
}
/**********************************************************************
*************** 設(shè)置地址 *****************************
**********************************************************************/
void Set_address(uchar x,uchar y)
{
switch(y)
{
case 1: Lcd_wcom(0x7f+x);break;
case 2: Lcd_wcom(0x8f+x);break;
case 3: Lcd_wcom(0x87+x);break;
case 4: Lcd_wcom(0x97+x);break;
}
}
/**********************************************************************
*************** 顯示單個(gè)字符 *****************************
**********************************************************************/
void Lcd_12864_char(uchar dat)
{
if((dat>=0)&&(dat<=9))
dat|=0x30;
Lcd_wdate(dat);
}
/**********************************************************************
*************** 顯示字符串 *****************************
**********************************************************************/
void Lcd_12864_str(uchar x,uchar y,uchar *p)
{
Set_address(x,y);
while(*p!='\0')
{
Lcd_wdate(*p);
p++;
}
}
/**********************************************************************
*************** 顯示圖片 *****************************
**********************************************************************/
void Lcd_12864_picture(uchar *gImage)
{
uchar x=0x80,y=0x80;
uchar i,j;
for(i=0;i<64;i++)
{
for(j=0;j<16;j++)
{
Lcd_wcom(0x34);
Lcd_wcom(y);
Lcd_wcom(x);
Lcd_wdate(*(gImage+i*16+j));
Lcd_wdate(*(gImage+i*16+j+1));
Lcd_wcom(0x36);
x++;
j++;
}
y++;
if(y>0x9f)
y=0x80;
x=0x80+((i+1)/32)*8;
}
Lcd_wcom(0x30);
}
/**********************************************************************
*************** 清屛操作 *****************************
**********************************************************************/
void clear_lcd()
{
Lcd_wcom(0x01);
_nop_();
}
void clearRAM()
{
uchar x,y;
for(y=0;y<64;y++)
for(x=0;x<16;x++)
{
Lcd_wcom(0x34);
Lcd_wcom(y+0x80);
Lcd_wcom(x+0x80);
Lcd_wcom(0x30);
Lcd_wdate(0x00);
Lcd_wdate(0x00);
}
}
/**********************************************************************
*************** 顯示初始化 *****************************
**********************************************************************/
void Lcd_12864_init(void)
{
clear_lcd();
Lcd_wcom(0x30);
delayms(5);
Lcd_wcom(0x02);
delayms(5);
Lcd_wcom(0x0c);
delayms(5);
Lcd_wcom(0x03);
delayms(5);
Lcd_wcom(0x06);
clear_lcd();
}
/**********************************************************************
*************** 打點(diǎn)操作 *****************************
**********************************************************************/
void Lcd_12864_drawpoint(uchar x,uchar y,uchar color)
{
uchar row,tier,tier_bit;
uchar read_H,read_L;
Lcd_wcom(0x34);
delayms(1);
Lcd_wcom(0x36);
tier=x>>4;
tier_bit=x&0x0f;
if(y<32)
row=y;
else
{
row=y-32;
tier+=8;
}
Lcd_wcom(row+0x80);
Lcd_wcom(tier+0x80);
Lcd_rdate();
read_H=Lcd_rdate();
read_L=Lcd_rdate();
Lcd_wcom(row+0x80);
Lcd_wcom(tier+0x80);
if(tier_bit<8)
{
switch(color)
{
case 0:read_H&=(~(0x01<<(7-tier_bit)));break;
case 1:read_H|=(0x01<<(7-tier_bit));break;
case 2:read_H^=(0x01<<(7-tier_bit));break;
default :break;
}
Lcd_wdate(read_H);
Lcd_wdate(read_L);
}
else
{
switch(color)
{
case 0:read_L&=(~(0x01<<(15-tier_bit)));break;
case 1:read_L|=(0x01<<(15-tier_bit));break;
case 2:read_L^=(0x01<<(15-tier_bit));break;
default :break;
}
Lcd_wdate(read_H);
Lcd_wdate(read_L);
}
Lcd_wcom(0x30);
}
/**********************************************************************
*************** 畫水平線 *****************************
**********************************************************************/
void Lcd_12864_drawline_x(uchar x0,uchar x1,uchar y,uchar color)
{
uchar temp;
if(x0>x1)
{
temp=x1;
x1=x0;
x0=temp;
}
for(;x0<=x1;x0++)
Lcd_12864_drawpoint(x0,y,color);
}
/**********************************************************************
*************** 畫垂直線 *****************************
**********************************************************************/
void Lcd_12864_drawline_y(uchar x,uchar y0,uchar y1,uchar color)
{
uchar temp;
if(y0>y1)
{
temp=y1;
y1=y0;
y0=temp;
}
for(;y0<y1;y0++)
Lcd_12864_drawpoint(x,y0,color);
}
/**********************************************************************
*************** 畫 圓 (采用Bresenham算法) *****************************
**********************************************************************/
void Lcd_12864_drawcircle(uchar x,uchar y,uchar R,uchar color)
{
uchar a,b;
int c;
a=0;b=R;c=3-2*R;
while(a<b)
{
Lcd_12864_drawpoint(x+a,y+b,color);
Lcd_12864_drawpoint(x-a,y+b,color);
Lcd_12864_drawpoint(x+a,y-b,color);
Lcd_12864_drawpoint(x-a,y-b,color);
Lcd_12864_drawpoint(x+b,y+a,color);
Lcd_12864_drawpoint(x-b,y+a,color);
Lcd_12864_drawpoint(x+b,y-a,color);
Lcd_12864_drawpoint(x-b,y-a,color);
if(c<0)
c=c+4*a+6;
else
{
c=c+4*(a-b)+10;
b-=1;
}
a+=1;
}
if(a==b)
{
Lcd_12864_drawpoint(x+a,y+b,color);
Lcd_12864_drawpoint(x+a,y+b,color);
Lcd_12864_drawpoint(x+a,y-b,color);
Lcd_12864_drawpoint(x-a,y-b,color);
Lcd_12864_drawpoint(x+b,y+a,color);
Lcd_12864_drawpoint(x-b,y+a,color);
Lcd_12864_drawpoint(x+b,y-a,color);
Lcd_12864_drawpoint(x-b,y-a,color);
}
}
/**********************************************************************
*************** 畫任意直線 (采用Bresenham算法) *****************************
**********************************************************************/
void Lcd_12864_drawLine(uchar start_x,uchar start_y,uchar end_x,uchar end_y,uchar color)
{
int t,distance;
int x=0,y=0,delta_x,delta_y;
char inc_x,inc_y;
delta_x=end_x-start_x;
delta_y=end_y-start_y;
if(delta_x>0)
inc_x=1;
else
if(delta_x==0)
{
Lcd_12864_drawline_y(start_x,start_y,end_y,color);
return;
}
else
inc_x=-1;
if(delta_y>0)
inc_y=1;
else
if(delta_y==0)
{
Lcd_12864_drawline_x(start_x,end_x,start_y,color);
return;
}
else
inc_y=-1;
delta_x=abs(delta_x);
delta_y=abs(delta_y);
if(delta_x>delta_y)
distance=delta_x;
else
distance=delta_y;
Lcd_12864_drawpoint(start_x,start_y,color);
for(t=0;t<=distance+1;t++)
{
Lcd_12864_drawpoint(start_x,start_y,color);
x+=delta_x;
y+=delta_y;
if(x>distance)
{
x-=distance;
start_x+=inc_x;
}
if(y>distance)
{
y-=distance;
start_y+=inc_y;
}
}
}