📄 lcd12864.c
字号:
#include "system.h"
#define DISPLAY_ON 0X3F
#define DISPLAY_START_LINE 0XC0
#define SET_X_ADDRESS 0XB8
#define SET_Y_ADDRESS 0X40
#define CLMADD 0x40 //第1单元的起始地址
#define PAGEADD 0xb8 //第1页的起始地址
//-----------------------
volatile uint32 key_delay=0;
volatile uint8 key_value=0;
volatile uint8 key_value0=0;
volatile uint8 Bkey_been_down=0;
volatile uint8 temp_value=0;
volatile uint8 Bkey_delay=0;
uint8 data;
uint8 Bread_key=0;
void lcd_input(void)//端口配置为输入
{
IO0DIR = IO0DIR&0xe47fffff;
IO1DIR = IO1DIR&0xfff1ffff;
}
void lcd_output(void) //端口配置为输出
{
IO0DIR |= IO0DIR|LCD_CS1|LCD_CS2|LCD_RW|LCD_E|LCD_D0|LCD_D2|LCD_D3|LCD_D5|LCD_D7;
IO1DIR |= IO1DIR|LCD_RS|LCD_D1|LCD_D4|LCD_D6;
}
uint8 Read_Byte(void)//回读一个字节
{
uint8 D0,D1,D2,D3,D4,D5,D6,D7,RDAT;
lcd_input();
if((IO0PIN&LCD_D0)>1) D0=1;
else D0=0;
if((IO1PIN&LCD_D1)>1) D1=2;
else D1=0;
if((IO0PIN&LCD_D2)>1) D2=4;
else D2=0;
if((IO0PIN&LCD_D3)>1) D3=8;
else D3=0;
if((IO1PIN&LCD_D4)>1) D4=16;
else D4=0;
if((IO0PIN&LCD_D5)>1) D5=32;
else D5=0;
if((IO1PIN&LCD_D6)>1) D6=64;
else D6=0;
if((IO0PIN&LCD_D7)>1) D7=128;
else D7=0;
RDAT=0;
RDAT=D0|D1|D2|D3|D4|D5|D6|D7;
return RDAT;
}
uint8 Read_LCD(void)//从LCD读回一个字节
{
uint8 rdata;
Busy();
// lcd_input();
lcd_delay(40);
IO0SET|=LCD_RS; //D/I=0
lcd_delay(40);
IO0SET|=LCD_RW; //R/W=1
lcd_delay(40);
IO0SET|=LCD_E;//E=1
lcd_delay(40);
rdata=Read_Byte();
lcd_delay(40);
IO0CLR|=LCD_E;//E=0
return rdata;
}
void Write_LCDByte(uint8 comd_word)//写入一个字节
{
if(comd_word&0x01) IO0SET|=LCD_D0;
else IO0CLR|=LCD_D0;
if(comd_word&0x02) IO1SET|=LCD_D1;
else IO1CLR|=LCD_D1;
if(comd_word&0x04) IO0SET|=LCD_D2;
else IO0CLR|=LCD_D2;
if(comd_word&0x08) IO0SET|=LCD_D3;
else IO0CLR|=LCD_D3;
if(comd_word&0x10) IO1SET|=LCD_D4;
else IO1CLR|=LCD_D4;
if(comd_word&0x20) IO0SET|=LCD_D5;
else IO0CLR|=LCD_D5;
if(comd_word&0x40) IO1SET|=LCD_D6;
else IO1CLR|=LCD_D6;
if(comd_word&0x80) IO0SET|=LCD_D7;
else IO0CLR|=LCD_D7;
}
//========================================================================//
void lcd_delay(uint8 delay_timer)
{
uint8 delay_t;
for(delay_t=0;delay_t<delay_timer;delay_t++);
}
void Busy(void)//忙判别
{
lcd_output();
IO1CLR|=LCD_RS; //D/I=0
lcd_delay(40);
IO0SET|=LCD_RW; //R/W=1
lcd_delay(40);
Write_LCDByte(0X80);//PORTD=0X\F;
IO0DIR=IO0DIR&0xff7fffff;
while(1)
{
IO0SET|=LCD_E; //E=1
lcd_delay(25);
IO0CLR|=LCD_E; //E=0
if((IO0PIN&0x00800000)==0) break;
}
}
//===========================================================================//
void write_LCD_comd0(uint8 comd_word)//向LCD写入一个字节
{
Busy();
lcd_output();
lcd_delay(40);
IO1SET|=LCD_RS; //D/I=1;
lcd_delay(40);
IO0CLR|=LCD_RW; //R/W=0
lcd_delay(40);
Write_LCDByte(comd_word);
lcd_delay(40);
IO0SET|=LCD_E; //E=1
lcd_delay(40);
IO0CLR|=LCD_E;//E=0
}
//===========================================================================//
void write_LCD_comd1(uint8 d1,uint8 comd_word)//向LCD写一个命令字
{
Busy();
lcd_output();
lcd_delay(40);
IO0CLR|=LCD_RS;
lcd_delay(40);
IO0CLR|=LCD_RW;
lcd_delay(40);
Write_LCDByte(comd_word|d1);
lcd_delay(40);
IO0SET|=LCD_E;
lcd_delay(40);
IO0CLR|=LCD_E;
}
//----------------------------------------
void clr_LCD_screen0(uint8 Bselect_area)////// clear the LCD_screen
{
unsigned char i,j;
if(Bselect_area)
{
IO0CLR|=LCD_CS2;
IO0SET|=LCD_CS1;
}
else
{
IO0CLR|=LCD_CS1;
IO0SET|=LCD_CS2;
}
lcd_delay(40);
for (i=0;i<8;i++)
{
write_LCD_comd1(SET_X_ADDRESS,i);//set the page address
write_LCD_comd1(SET_Y_ADDRESS,0);//set the list address
for (j=0;j<64;j++)
{
write_LCD_comd0(0);
}
}
}
void clr_LCD_screen(void)
{
clr_LCD_screen0(1);
clr_LCD_screen0(0);
}
//===========================================================================
void init_LCD(void)
{
IO0SET|=LCD_CS2;
lcd_delay(40);
IO0CLR|=LCD_CS1;
lcd_delay(40);
write_LCD_comd1(DISPLAY_ON,0);
write_LCD_comd1(DISPLAY_START_LINE,0);
clr_LCD_screen0(0);
lcd_delay(40);
IO0SET|=LCD_CS1;
lcd_delay(40);
IO0CLR|=LCD_CS2;
write_LCD_comd1(DISPLAY_ON,0);
write_LCD_comd1(DISPLAY_START_LINE,0);
clr_LCD_screen0(1);
}
//*******************************************************************************
//function:
//description: picture modle
//
//parameter: *word_tab---the first address of the word modle in code area
// word_position_x,word_position_y---the coordinate of the word or
// picture corresponding to the character
// word in the screen
// m---the dots number per row ex. 8,16,24,32....
// n---the dots number per list ex. 8,16,24,32....
//return value:
//*******************************************************************************
// 首址 (---)起始行 (|) 起始列 宽度 高度
void show_picture(uint8 const *word_tab,uint8 word_position_x,uint8 word_position_y,uint8 m,uint8 n)
{
uint8 const *temp_pointer;
uint8 i,j;
uint8 Bchange_area;
temp_pointer=word_tab;
for (i=0;i<n/8;i++)
{
if(word_position_y<64&&word_position_y+m>64)
Bchange_area=1;
else
Bchange_area=0;
if(word_position_y/64)
{
IO0CLR|=LCD_CS2;
IO0SET|=LCD_CS1;
}
else
{
IO0CLR|=LCD_CS1;
IO0SET|=LCD_CS2;
}
lcd_delay(40);
write_LCD_comd1(SET_X_ADDRESS,word_position_x/8+i);//写地址命令
write_LCD_comd1(SET_Y_ADDRESS,word_position_y%64);
for (j=0;j<m;j++)
{
if(Bchange_area)
{
if(word_position_y+j>=64)
{
Bchange_area=0;
IO0CLR|=LCD_CS2;
IO0SET|=LCD_CS1;
write_LCD_comd1(SET_X_ADDRESS,word_position_x/8+i);
write_LCD_comd1(SET_Y_ADDRESS,0);
}
}
write_LCD_comd0(*temp_pointer++);
//--------------------
// lcd_delay(40);
// write_LCD_comd1(SET_X_ADDRESS,word_position_x/8+i);
// write_LCD_comd1(SET_Y_ADDRESS,0);
// rdat=Read_LCD();
// UART0_SendByte(rdat);
//----------------
}
}
}
void read_test(void)
{ uint8 rdat;
show_dot(0,0);
write_LCD_comd1(SET_X_ADDRESS,0);
write_LCD_comd1(SET_Y_ADDRESS,0);
rdat=Read_LCD();
UART0_SendByte(rdat);
}
void show_picture_n(uint8 const *word_tab,uint8 word_position_x,uint8 word_position_y,uint8 m,uint8 n)
{
uint8 const *temp_pointer;
uint8 i,j;
uint8 Bchange_area;
temp_pointer=word_tab;
for (i=0;i<n/8;i++)
{
if(word_position_y<64&&word_position_y+m>64)
Bchange_area=1;
else
Bchange_area=0;
if(word_position_y/64)
{
IO0CLR|=LCD_CS2;
IO0SET|=LCD_CS1;
}
else
{
IO0CLR|=LCD_CS1;
IO0SET|=LCD_CS2;
}
lcd_delay(40);
write_LCD_comd1(SET_X_ADDRESS,word_position_x/8+i);
write_LCD_comd1(SET_Y_ADDRESS,word_position_y%64);
for (j=0;j<m;j++)
{
if(Bchange_area)
{
if(word_position_y+j>=64)
{
Bchange_area=0;
IO0CLR|=LCD_CS2;
IO0SET|=LCD_CS1;
lcd_delay(40);
write_LCD_comd1(SET_X_ADDRESS,word_position_x/8+i);
write_LCD_comd1(SET_Y_ADDRESS,0);
}
}
write_LCD_comd0(~(*temp_pointer++));
}
}
}
void erase_picture(uint8 word_position_x,uint8 word_position_y,uint8 m,uint8 n)
{
uint8 i,j;
uint8 Bchange_area;
lcd_delay(40);
for (i=0;i<n/8;i++)
{
if(word_position_y<64&&word_position_y+m>64)
Bchange_area=1;
else
Bchange_area=0;
if(word_position_y/64)
{
IO0CLR|=LCD_CS2;
IO0SET|=LCD_CS1;
}
else
{
IO0CLR|=LCD_CS1;
IO0SET|=LCD_CS2;
}
lcd_delay(40);
write_LCD_comd1(SET_X_ADDRESS,word_position_x/8+i);
write_LCD_comd1(SET_Y_ADDRESS,word_position_y%64);
lcd_delay(10);
for (j=0;j<m+1;j++)
{
if(Bchange_area)
{
if(word_position_y+j>=64)
{
Bchange_area=0;
IO0CLR|=LCD_CS2;
IO0SET|=LCD_CS1;
lcd_delay(10);
write_LCD_comd1(SET_X_ADDRESS,word_position_x/8+i);
write_LCD_comd1(SET_Y_ADDRESS,0);
}
}
write_LCD_comd0(0);
}
}
}
//在图形方式下,绘点子程序。该程序在第row(0-63)行、第col(0-127)列绘点,行、列坐标均以点为单位
void show_dot(uint8 word_position_x,uint8 word_position_y)
{
if(word_position_y/64)
{
IO0CLR|=LCD_CS2;
IO0SET|=LCD_CS1;
}
else
{
IO0CLR|=LCD_CS1;
IO0SET|=LCD_CS2;
}
lcd_delay(40);
write_LCD_comd1(SET_X_ADDRESS,word_position_x/8);
write_LCD_comd1(SET_Y_ADDRESS,word_position_y%64);
write_LCD_comd0(0x57);
}
//画线子程序:为了回避复杂的浮点运算,采用了整数数字微分的方法
//以(x行,y列)为起点,以(x1行,y1列)为终点画一条直线
void DrawLines(int8 x,int8 y,int8 x1,int8 y1)
{
int dx,dy,err = 0;
if(y != y1)
{
if(y1 < y) //这个判断语句保证了y1>=y这个前提
{
dx = y1; dy = x1;
y1 = y; x1 = x;
y = dx; x = dy;
}
dy = y1 - y;
dx = x1 - x;
if((x1 >= x)&&((y1 - y) <= (x1 - x)))
{
for(;x != x1;)
{
if(err < 0)
{
show_dot(x + 1,y);
x += 1;
err += dy;
}
else
{
show_dot(x + 1,y + 1);
x += 1;
y += 1;
err += (dy - dx);
}
}
}
else
if((x1 >= x)&&((y1 - y) > (x1 - x)))
{
for(;y != y1;)
{
if(err < 0)
{
show_dot(x + 1,y + 1);
x += 1;
y += 1;
err += (dy - dx);
}
else
{
show_dot(x,y + 1);
y += 1;
err -= dx;
}
}
}
else
if((x1 < x)&&((y1 - y) <= (x - x1)))
{
for(;x != x1;)
{
if(err < 0)
{
show_dot(x - 1,y);
x -= 1;
err += dy;
}
else
{
show_dot(x - 1,y + 1);
x -= 1;
y += 1;
err += (dy + dx);
}
}
}
else
if((x1 < x)&&((y1 - y) > (x1 - x)))
{
for(;y != y1;)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -