📄 lcda_driver.c
字号:
}
/***********************************************************************************
* Function: LCDA_Init;
*
* Description: LCD初始化函数;
*
* Input: x, LCD行数; y, LCD列数; 例如:240x128 的LCD, line=128,column=240;
* fonts,LCD字体选择:FS5x8->5x8字体,FS6x8->5x8字体,FS7x8->5x8字体,FS8x8->5x8字体;
*
* Output: none;
*
* Return: none;
*
* Note: 本函数完成的设置:1.光标形状(0xa7):8x8; 2显示方式(0x80): CGROM方式文本\图形,
* 以"或"方式合成;3.设置显示开关(0x9f): 图形显示/文本显示/光标显示/光标闪烁;
* 4.显示存储器清零; 5. 设置字符显示区(编号):0, 设置图形显示区(编号):0;
************************************************************************************/
void LCDA_Init(unsigned char x, unsigned char y, unsigned char fonts)
{
LCDA_WriteCmd3(0,0,CMD_CGRAM_ADDR); //设置CGRAM区域首地址
LCDA_WriteCmd3((unsigned char)GRAPH_ADDR,(unsigned char)(GRAPH_ADDR>>8),CMD_PIC_ADDR); //设置图形显示区域首地址
LCDA_WriteCmd3((unsigned char)TEXT_ADDR,(unsigned char)(TEXT_ADDR>>8),CMD_TEXT_ADDR); //设置字符显示区域首地址
LCDA_LineChar = y/fonts;
Graph_VRAM =(unsigned int)LCDA_LineChar*x;
Text_VRAM = Graph_VRAM>>3;
Graph_BaseAddr = GRAPH_ADDR;
Text_BaseAddr = TEXT_ADDR;
LCDA_WriteCmd3(LCDA_LineChar,0x00,CMD_PIC_WIDTH); //设置图形显示区域宽度 : LCDA_LineChar
LCDA_WriteCmd3(LCDA_LineChar,0x00,CMD_TEXT_WIDTH);
LCDA_WriteCmd1(0xa7); //设置光标形状 cursor size 8x8
LCDA_WriteCmd1(0x80); //设置显示方式: CGROM方式 文本\图形 "或"
LCDA_WriteCmd1(0x9f); //设置显示开关: 1001 1111 图形显示/文本显示/光标显示/光标闪烁
LCDA_ClearVRAM();
}
/***********************************************************************************
* Function: LCDA_SetTextMaps;
*
* Description: 设置字符显示区;
*
* Input: id, 字符显示区编号, 范围:0~N-1, N=2048*64/(LCD长*LCD宽),例如:240x128的LCD
* N = 2048*64/(240*128) = 4, 即显示区编号范围:0~3;
*
* Output: none;
*
* Return: TRUE,设置正确; FALSE,设置失败;
*
* Note: none;
************************************************************************************/
unsigned char LCDA_SetTextMaps(unsigned char id)
{
if (id<(TEXT_SIZE/Text_VRAM))
{
Text_BaseAddr = TEXT_ADDR + Text_VRAM*id;
return TRUE;
}
else
return FALSE;
}
/***********************************************************************************
* Function: LCDA_SetGraphMaps;
*
* Description: 设置图形显示区;
*
* Input: id, 图形显示区编号, 范围:0~N-1, N = (显存容量)*8/(LCD长*LCD宽),例如:240x128的LCD,
* 显存容量=32KB, N = (32768-4096)*8/(240*128) = 7, 即显示区编号范围:0~6;
* 本函数默认显存容量=32KB;
* Output: none;
*
* Return: TRUE,设置正确; FALSE,设置失败;
*
* Note: none;
************************************************************************************/
unsigned char LCDA_SetGraphMaps(unsigned char id)
{
if (id<((VRAM_SIZE-4096)/Graph_VRAM))
{
Graph_BaseAddr = GRAPH_ADDR + Graph_VRAM*id;
LCDA_WriteCmd3((unsigned char)Graph_BaseAddr,(unsigned char)(Graph_BaseAddr>>8),CMD_PIC_ADDR);
return TRUE;
}
else
return FALSE;
}
/***********************************************************************************
* Function: LCDA_DrawPixel;
*
* Description: 画点(x,y);
*
* Input: x, LCD行坐标; y, LCD列坐标; bit类型标识mode,1:画点,0:擦除点;
*
* Output: none;
*
* Return: none;
*
* Note: none;
************************************************************************************/
void LCDA_DrawPixel(unsigned char x, y, bit mode)
{
unsigned int xdata StartAddr;
unsigned char xdata cmd;
StartAddr= Graph_BaseAddr + (unsigned int)x*LCDA_LineChar + (y>>3);
if(mode)
cmd = CMD_BIT_SET|(7-y&0x07);
else
cmd = CMD_BIT_CLR|(7-y&0x07);
LCDA_WriteCmd3((unsigned char)(StartAddr),(unsigned char)(StartAddr>>8),0x24); //设置该点所在单元地址
LCDA_WriteCmd1(cmd);
}
/***********************************************************************************
* Function: LCDA_DrawLine;
*
* Description: (x1,y1)--(x2,y2)处划线;
*
* Input: x1,x2, LCD行坐标; y1,y2, LCD列坐标; bit类型标识mode,1:画直线:擦除直线;
*
* Output: none;
*
* Return: none;
*
* Note: none;
************************************************************************************/
void LCDA_DrawLine(unsigned char x1, y1, x2, y2, bit mode)
{
unsigned char xdata x,y;
double xdata k,b;
if( abs(y1-y2) <= abs(x1-x2) ) // |k|<=1
{
k=(float)(y2-y1) / (float)(x2-x1) ;
b=y1-k*x1;
if( x1 <= x2 )
{
for(x=x1;x<=x2;x++)
{
y=k*x+b;
LCDA_DrawPixel(x, y, mode);
}
}
else
{
for(x=x2;x<=x1;x++)
{
y=k*x+b;
LCDA_DrawPixel(x, y, mode);
}
}
}
else // abs(y1-y2) > abs(x1-x2) |K|>1
{
k=(float)(x2-x1) / (float)(y2-y1) ;
b=x1-k*y1;
if( y1 <= y2 )
{
for(y=y1;y<=y2;y++)
{
x=k*y+b;
LCDA_DrawPixel( x , y, mode );
}
}
else
{
for(y=y2;y<=y1;y++)
{
x=k*y+b;
LCDA_DrawPixel( x , y, mode );
}
}
}
}
/***********************************************************************************
* Function: LCDA_DrawRectangle;
*
* Description: 以(x1,y1)和(x2,y2)为对角点画矩形;
*
* Input: x1,x2, LCD行坐标; y1,y2, LCD列坐标; bit类型标识mode,1:画矩形,0:擦除矩形;
*
* Output: none;
*
* Return: none;
*
* Note: none;
************************************************************************************/
void LCDA_DrawRectangle(unsigned char x1, y1, x2, y2, bit mode)
{
LCDA_DrawLine(x1,y1,x2,y1,mode);
LCDA_DrawLine(x1,y1,x1,y2,mode);
LCDA_DrawLine(x2,y1,x2,y2,mode);
LCDA_DrawLine(x1,y2,x2,y2,mode);
}
/***********************************************************************************
* Function: LCDA_DrawFillRectangle;
*
* Description: 以(x1,y1)和(x2,y2)为对角点画矩形实体;
*
* Input: x1,x2, LCD行坐标; y1,y2, LCD列坐标; bit类型标识mode,1:画矩形实体,0:擦除矩形实体;
*
* Output: none;
*
* Return: none;
*
* Note: none;
************************************************************************************/
void LCDA_DrawFillRectangle(unsigned char x1, y1, x2, y2, bit mode)
{
unsigned char xdata i;
for (i=x1; i<=x2; i++)
LCDA_DrawLine(i,y1,i,y2,mode);
}
/***********************************************************************************
* Function: LCDA_DrawCircle;
*
* Description: 以(x,y)为圆心, r为半径画圆;
*
* Input: x, LCD行坐标; y, LCD列坐标; bit类型标识mode,1:画圆,0:擦除圆;
*
* Output: none;
*
* Return: none;
*
* Note: none;
************************************************************************************/
void LCDA_DrawCircle(unsigned char x, y, r, bit mode)
{
unsigned char xdata r_2,i,x1,y1,temp_x;
unsigned short xdata temp;
r_2=0.707*r;
temp=r*r;
for (i=0; i<=r_2; i++)
{
if (mode)
{
if (!(i&0x01))
{
x1=i;
y1=sqrt(1.0*(temp-x1*x1))+0.5;
LCDA_DrawPixel(x1+x,y1+y,mode);
LCDA_DrawPixel(-x1+x,y1+y,mode);
LCDA_DrawPixel(x1+x,-y1+y,mode);
LCDA_DrawPixel(-x1+x,-y1+y,mode);
temp_x=x1;
x1=y1;
y1=temp_x;
LCDA_DrawPixel(x1+x,y1+y,mode);
LCDA_DrawPixel(-x1+x,y1+y,mode);
LCDA_DrawPixel(x1+x,-y1+y,mode);
LCDA_DrawPixel(-x1+x,-y1+y,mode);
}
}
else
{
x1=i;
y1=sqrt(1.0*(temp-x1*x1))+0.5;
LCDA_DrawPixel(x1+x,y1+y,mode);
LCDA_DrawPixel(-x1+x,y1+y,mode);
LCDA_DrawPixel(x1+x,-y1+y,mode);
LCDA_DrawPixel(-x1+x,-y1+y,mode);
temp_x=x1;
x1=y1;
y1=temp_x;
LCDA_DrawPixel(x1+x,y1+y,mode);
LCDA_DrawPixel(-x1+x,y1+y,mode);
LCDA_DrawPixel(x1+x,-y1+y,mode);
LCDA_DrawPixel(-x1+x,-y1+y,mode);
}
}
}
/***********************************************************************************
* Function: LCDA_DrawByte;
*
* Description: 向LCD(x,y)点开始写一个字节数据;
*
* Input: x, LCD行坐标; y, LCD列坐标; value,写入字节数据;
*
* Output: none;
*
* Return: none;
*
* Note: 应尽量使y(LCD列坐标)是8的整数倍,可使显示速度加快;
************************************************************************************/
void LCDA_DrawByte(unsigned char x, y, unsigned char val)
{
unsigned char xdata temp,bit_x;
unsigned int xdata StartAddr;
bit_x=y&0x07;
StartAddr=Graph_BaseAddr + (unsigned int)x*LCDA_LineChar + (y>>3);
LCDA_WriteCmd3((unsigned char)(StartAddr),(unsigned char)(StartAddr>>8),0x24); //设置该点所在单元地址
if (bit_x==0)
LCDA_WriteCmd2(val,0xC4); //数据写, 地址不变
else
{
LCDA_WriteCmd1(0xc5); //数据一次读,地址不变
temp = LCDA_ReadData(); //读入数据
temp&=~(0xff>>bit_x);
temp|=(val>>bit_x);
LCDA_WriteCmd2(temp,0xC0); //数据写, 地址加一
LCDA_WriteCmd1(0xc5); //数据一次读,地址不变
temp = LCDA_ReadData(); //读入数据
temp&=~(0xff<<(8-bit_x));
temp|=(val<<(8-bit_x));
LCDA_WriteCmd2(temp,0xC4); //数据写, 地址不变
}
}
/***********************************************************************************
* Function: LCDA_ShowHZxy;
*
* Description: 从LCD(x,y)点开始显示(line*col)的字符;
*
* Input: x, LCD行坐标; y, LCD列坐标; line,字符占用行数; col,字符占用列数;
* *p,字符数据指针;
*
* Output: none;
*
* Return: none;
*
* Note: 应尽量使y(LCD列坐标)是8的整数倍,可使显示速度加快; 本函数也可作为自定义图形显示;
************************************************************************************/
void LCDA_ShowHZxy(unsigned char x, y, unsigned char line, col, unsigned char *p)
{
unsigned char xdata i,j;
for(i=0;i<line;i++)
{
for(j=0;j<col;j+=8)
LCDA_DrawByte(x+i,y+j,*p++);
}
}
/***********************************************************************************
* Function: LCDA_ShowChar;
*
* Description: 从LCD(x,y)位置开始显示ASCII字符;
*
* Input: x, LCD行坐标/8; y, LCD列坐标/8; chr,ASCII字符; *p,传入的数据指针;len,数据长度;
*
* Output: none;
*
* Return: none;
*
* Note: none;
************************************************************************************/
void LCDA_ShowChar(unsigned char x, y, unsigned char *p, unsigned char len)
{
unsigned char xdata i;
unsigned int xdata StartAddr;
StartAddr=Text_BaseAddr + (unsigned int)x*LCDA_LineChar + y;
LCDA_WriteCmd3((unsigned char)(StartAddr),(unsigned char)(StartAddr>>8),0x24); //设置该点所在单元地址
LCDA_WriteCmd1(CMD_CGRAM_AUTO_WRITE); //设置自动写状态
for(i=0;i<len;i++)
LCDA_WriteData(*p++);
LCDA_WriteCmd1(CMD_CGRAM_AUTO_END); // 自动写结束
}
/***********************************************************************************/
// 文件结束
/***********************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -