📄 display.c
字号:
/*********************************************
*LCD液晶显示程序
*支持松山的CA12864K的串行接口LCD
*此LCD支持8X4个汉字的显示。
**********************************************/
#include "w77e532.h"
#include <intrins.h>
#include "display.h"
#define LCD_WIDTH 16 /*液晶屏的列数*/
#define LCD_LINES 4 /*液晶屏的行数*/
#define LCD_SIZE 64 /*液晶屏的总字符数*/
/************************/
#define LCD_CMD_CLS 0x01 /*清屏命令*/
#define LCD_CMD_ZERO 0x02 /*显示位置清0*/
#define LCD_CMD_INC 0x06 /*指定计数器增加*/
#define LCD_CMD_NORMAL 0x0C /*打开显示,无光标,显示正常*/
#define LCD_CMD_REVERSE 0x0D /*打开显示,无光标,反显*/
#define LCD_CMD_BASE 0x10 /*采用基本指令集*/
#define LCD_CMD_CGRAM 0x40 /*设置自定义字库的位置*/
#define LCD_CMD_DDRAM 0x80 /*设置显示位置*/
unsigned char code bitmap_gps_up[16][2]={{0x00,0x00},{0x01,0x00},{0x01,0x04},{0x01,0x88},
{0x10,0x90},{0x30,0x20},{0x3f,0x80},{0x30,0xb0},
{0x18,0x9c},{0x18,0x80},{0x3e,0x80},{0x37,0xe0},
{0x21,0xc0},{0x38,0x00},{0x7e,0x00},{0x00,0x00}};
unsigned char code bitmap_gprs_up[16][2]={{0x00,0x00},{0x00,0x00},{0x20,0x80},{0x40,0x40},
{0x40,0x44},{0x51,0x44},{0x4a,0x44},{0x44,0x54},
{0x24,0x94},{0x04,0x14},{0x04,0x54},{0x04,0x54},
{0x04,0x54},{0x0e,0x54},{0x3f,0xd4},{0x00,0x00}};
unsigned char code bitmap_message[16][2]={{0x00,0x00},{0x00,0x00},{0x00,0x00},{0x7f,0xfc},
{0x60,0x0c},{0x50,0x14},{0x48,0x24},{0x44,0x44},
{0x4a,0xa4},{0x49,0x24},{0x50,0x14},{0x50,0x14},
{0x60,0x0c},{0x7f,0xfc},{0x00,0x00},{0x00,0x00}};
unsigned char code bitmap_warning[16][2]={{0x00,0x00},{0x00,0x00},{0x01,0x80},{0x03,0xc0},
{0x06,0x60},{0x0c,0x30},{0x18,0x18},{0x30,0x0c},
{0x60,0x06},{0x7f,0xfe},{0x0c,0x30},{0x04,0x20},
{0x06,0x60},{0x03,0xc0},{0x00,0x00},{0x00,0x00}};
#if 1
#define LCD_SDA P3_4
#define LCD_SCL P3_5
#define LCD_HIGH { \
LCD_SCL=0; /*SCL=0*/ \
_nop_();_nop_();_nop_(); \
LCD_SDA=1; /*SCL=0,SDA=1*/ \
LCD_SCL=1; /*SCL=1*/ \
_nop_();_nop_();_nop_(); \
}
#define LCD_LOW { \
LCD_SCL=0; /*SCL=0*/ \
_nop_();_nop_();_nop_(); \
LCD_SDA=0; /*SCL=0,SDA=0*/\
LCD_SCL=1; /*SCL=1*/ \
_nop_();_nop_();_nop_(); \
}
#else
#define LCD_HIGH { \
P4 &= ~0x01; /*SCL=0*/ \
_nop_();_nop_();_nop_(); \
P4 |= 0x02; /*SCL=0,SDA=1*/ \
P4 |= 0x01; /*SCL=1*/ \
_nop_();_nop_();_nop_(); \
}
#define LCD_LOW { \
P4 &= ~0x01; /*SCL=0*/ \
_nop_();_nop_();_nop_(); \
P4 &= ~0x03; /*SCL=0,SDA=0*/\
P4 |= 0x01; /*SCL=1*/ \
_nop_();_nop_();_nop_(); \
}
#endif
/********************************以上是与具体的液晶屏驱动程序*****************************/
void lcd_delay(void)
{
unsigned int loop;
loop = 10000;
while(loop) loop--;
}
void lcd_serial_send(unsigned char value)
{
unsigned char i;
for(i=0; i<8; i++)
{
if( value & 0x80 )
LCD_HIGH
else
LCD_LOW
value <<= 1;
}
//lcd_delay();
}
void lcd_write_command(unsigned char value)
{
unsigned char tmp;
lcd_serial_send(0xF8); /*RW=0, RS=0*/
tmp = value & 0xF0;
lcd_serial_send(tmp);
tmp = (value & 0x0F) * 16;
lcd_serial_send(tmp);
//lcd_delay();
}
void lcd_write_data(unsigned char value)
{
unsigned char tmp;
lcd_serial_send(0xFA); /*RW=0, RS=0*/
tmp = value & 0xF0;
lcd_serial_send(tmp);
tmp = (value & 0x0F) * 16;
lcd_serial_send(tmp);
}
void lcd_set_cgram_site(unsigned char lcd_col,unsigned char lcd_line) // set gdram address to AC,bit7=1,bit6~0:address
{ // need set RE=1 to extern command mode, first set y_addr(AC6...AC0),then set x_addr(AC3...AC0)
unsigned char lcd_site;
if(lcd_col==0)
lcd_site=0x40;
if(lcd_col==1)
lcd_site=0x50;
if(lcd_col==2)
lcd_site=0x60;
if(lcd_col==3)
lcd_site=0x70;
lcd_write_command(lcd_site | lcd_line);
//lcd_delay();
}
/*向自定义字库中写入点阵数据,一共有4个自定义字,每个字32个字节*/
/*void lcd_write_cgram(char index, char *ptr)
{
unsigned char i;
for(i=0; i<32; i++)
{
}
}
*/
/****************************************************
*移动显示位置到指定的行和列
*column 0-15列
*line 0-3行
*flag 0:正常显示,1:反显
*****************************************************/
static volatile unsigned char display_column,display_row, display_flag;
static char displayBuffer[16*4];
static char *dispBufPtr;
char display_attribute(unsigned char column, unsigned char row, unsigned char flag)
{
unsigned char tmp;
if( (column >= LCD_WIDTH) || (row >= LCD_LINES) )
return(-1);
display_column = column;
display_row = row;
switch( row )
{
case 0:
tmp = 0;
break;
case 1:
tmp = 0x10;
break;
case 2:
tmp = 8;
break;
case 3:
default:
tmp = 0x18;
break;
}
tmp |= (column>>1) | LCD_CMD_DDRAM;
lcd_write_command(tmp);
dispBufPtr = displayBuffer + display_row*16 + (display_column&0xFE);
display_flag = flag;
if( display_flag )
{/*要求反显*/
lcd_write_command(LCD_CMD_REVERSE);
}
else
{/*正常显示*/
lcd_write_command(LCD_CMD_NORMAL);
}
return(0);
}
/***************************************
*
*return 0:OK, other:ERROR
****************************************/
char display_position_increment(void)
{
display_column ++;
if( display_column == LCD_WIDTH )
{
if( display_row == (LCD_LINES-1) )
return -1;
else
{
display_column = 0;
display_row ++;
}
display_attribute(display_column, display_row, display_flag);
}
return 0;
}
void lcd_start_ddram(void)
{
lcd_serial_send(0xFA); /*RW=0, RS=1*/
}
/*向LCD的显示缓冲区中写入数据*/
char lcd_write_ddram(unsigned char value)
{
unsigned char tmp;
if( display_column >= LCD_WIDTH )
{
if( display_row >= (LCD_LINES-1) )
return -1;
else
{
display_column = 0;
display_row ++;
}
lcd_delay();
display_attribute(display_column, display_row, display_flag);
lcd_delay();
lcd_start_ddram();
}
tmp = value & 0xF0;
lcd_serial_send(tmp);
tmp = (value & 0x0F) * 16;
lcd_serial_send(tmp);
display_column ++;
*dispBufPtr++ = value;
//lcd_delay();
return(0);
}
void lcd_clear_srceen(void)
{
unsigned char i;
lcd_write_command(LCD_CMD_CLS);
for(i=0; i<LCD_WIDTH*LCD_LINES; i++)
displayBuffer[i] = 0x20;
lcd_delay();
}
/****************************************************
*在当前位置显示一串字符串。
*汉字要求在0,2,4,6,8,10,12,14列。否则无法正常显示汉字和自定义字符。
*****************************************************/
unsigned char display_string(unsigned char *strLcd)
{
unsigned char tmp;
if( *strLcd )
lcd_start_ddram();
if( (*strLcd < 0xA0) && (display_column&1) )
{/*第1个字符是ASCII,且显示在半个汉字位置,要补齐高位字节*/
tmp = *dispBufPtr;
display_column--;
lcd_write_ddram(tmp);
lcd_delay();
}
while( *strLcd )
{
if( *strLcd <0x80 )
{/*显示ASCII*/
lcd_write_ddram(*strLcd++);
}
else if( *strLcd >= 0xA0 )
{/*显示汉字*/
if( display_column&1 )
{
lcd_write_ddram(0x20);
}
lcd_write_ddram(*strLcd++);
lcd_write_ddram(*strLcd++);
}
else
{/*显示自定义符号*/
tmp = *strLcd ++;
if( display_column&1 )
{
lcd_write_ddram(0x20);
}
if( tmp == GRAPHICS_GPS )
{
lcd_write_ddram(0x00);
lcd_write_ddram(0x00);
}
else if( tmp == GRAPHICS_GPRS )
{
lcd_write_ddram(0x00);
lcd_write_ddram(0x02);
}
else if(tmp == GRAPHICS_ALARM)
{
lcd_write_ddram(0x00);
lcd_write_ddram(0x04);
}
else
{
lcd_write_ddram(0x00);
lcd_write_ddram(0x06);
}
}
}
return 1;
}
void lcd_set_bitmap(void)
{
unsigned char gi;
for(gi=0;gi<16;gi++)
{
lcd_set_cgram_site(GRAPHICS_GPS & 0x03, gi);
lcd_write_data(bitmap_gps_up[gi][0]);
lcd_write_data(bitmap_gps_up[gi][1]);
}
for(gi=0;gi<16;gi++)
{
lcd_set_cgram_site(GRAPHICS_GPRS & 0x03, gi);
lcd_write_data(bitmap_gprs_up[gi][0]);
lcd_write_data(bitmap_gprs_up[gi][1]);
}
for(gi=0;gi<16;gi++)
{
lcd_set_cgram_site(GRAPHICS_ALARM & 0x03, gi);
lcd_write_data(bitmap_warning[gi][0]);
lcd_write_data(bitmap_warning[gi][1]);
}
for(gi=0;gi<16;gi++)
{
lcd_set_cgram_site(GRAPHICS_MESSAGE & 0x03, gi);
lcd_write_data(bitmap_message[gi][0]);
lcd_write_data(bitmap_message[gi][1]);
}
}
void lcd_init(void)
{
display_column = 0;
display_row = 0;
dispBufPtr = displayBuffer;
lcd_write_command(LCD_CMD_BASE);
lcd_write_command(LCD_CMD_INC);
lcd_write_command(LCD_CMD_ZERO);
lcd_clear_srceen();
lcd_set_bitmap();
lcd_write_command(LCD_CMD_NORMAL);
//lcd_delay();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -