今天想点个屏,本来想用SPI驱动来这,但是从能不能驱动行了方面考量,我还是选择了模拟管脚驱动。因为我的屏还有一些零碎的东东,不是纯SPI所能办得到地。
我的管脚分配在屏后边印的我只好整里出管脚的对应关系:
CS ------------ P5.7
DC------------- P0.5
RES------------ P0.2
MOS------------ P0.3
CLK------------- P0.4
BLK------------- P5.6
另外的电源地,接开发板的3.3V电源和GND
以下是程序:
lcd.h:
#ifndef __LCD_INIT_H
#define __LCD_INIT_H
#include <rtthread.h>
#include <rtdevice.h>
#include "drv_gpio.h"
#define USE_HORIZONTAL 1 //设置横屏或者竖屏显示 0或1为竖屏 2或3为横屏
#if USE_HORIZONTAL==0||USE_HORIZONTAL==1
#define LCD_W 128
#define LCD_H 160
#else
#define LCD_W 160
#define LCD_H 128
#endif
#define u8 unsigned char
#define u16 unsigned int
#define LCD_CS GET_PIN(5, 7)//SCLK
#define LCD_SDA GET_PIN(0, 3)//MOSI
#define LCD_RES GET_PIN(0, 2)//RES
#define LCD_DC GET_PIN(0, 5)//DC
#define LCD_CLK GET_PIN(0, 4)
#define LCD_BLK GET_PIN(5, 6)
//sbit LCD_BLK=P0^4; //BLK
//sbit LCD_CS =P0^6; //CS1
//-----------------LCD端口定义----------------
#define LCD_SCLK_Clr() rt_pin_write(LCD_CLK, PIN_LOW)
#define LCD_SCLK_Set() rt_pin_write(LCD_CLK, PIN_HIGH)
#define LCD_MOSI_Clr() rt_pin_write(LCD_SDA, PIN_LOW)
#define LCD_MOSI_Set() rt_pin_write(LCD_SDA, PIN_HIGH)
#define LCD_RES_Clr() rt_pin_write(LCD_RES, PIN_LOW)//RES
#define LCD_RES_Set() rt_pin_write(LCD_RES, PIN_HIGH)
#define LCD_DC_Clr() rt_pin_write(LCD_DC, PIN_LOW)//DC
#define LCD_DC_Set() rt_pin_write(LCD_DC, PIN_HIGH)
#define LCD_BLK_Clr() rt_pin_write(LCD_BLK, PIN_LOW)//BLK
#define LCD_BLK_Set() rt_pin_write(LCD_BLK, PIN_HIGH)
#define LCD_CS_Clr() rt_pin_write(LCD_CS, PIN_LOW)//CS1
#define LCD_CS_Set() rt_pin_write(LCD_CS, PIN_HIGH)
void delay_ms(unsigned int ms);//不准确延时函数
void LCD_GPIO_Init(void);//初始化GPIO
void LCD_Writ_Bus(u8 dat);//模拟SPI时序
void LCD_WR_DATA8(u8 dat);//写入一个字节
void LCD_WR_DATA(u16 dat);//写入两个字节
void LCD_WR_REG(u8 dat);//写入一个指令
void LCD_Address_Set(u16 x1,u16 y1,u16 x2,u16 y2);//设置坐标函数
void LCD_Init(void);//LCD初始化
#endif
lcd.c
include "lcd.h"
#include "lcd_init.h"
#include "lcdfont.h"
#include "delay.h"
/******************************************************************************
oˉêyËμÃ÷£oÔúÖ¸¶¨Çøóòìî3äÑÕé«
èë¿úêy¾Y£oxsta,ysta Æeê¼×ø±ê
xend,yend ÖÕÖ1×ø±ê
color òaìî3äμÄÑÕé«
·μ»ØÖμ£o ÎT
******************************************************************************/
void LCD_Fill(u16 xsta,u16 ysta,u16 xend,u16 yend,u16 color)
{
u16 i,j;
LCD_Address_Set(xsta,ysta,xend-1,yend-1);//éèÖÃÏÔê¾·¶Î§
for(i=ysta;i<yend;i++)
{
for(j=xsta;j<xend;j++)
{
LCD_WR_DATA(color);
}
}
}
/******************************************************************************
oˉêyËμÃ÷£oÔúÖ¸¶¨Î»Öû-μã
èë¿úêy¾Y£ox,y »-μã×ø±ê
color μãμÄÑÕé«
·μ»ØÖμ£o ÎT
******************************************************************************/
void LCD_DrawPoint(u16 x,u16 y,u16 color)
{
LCD_Address_Set(x,y,x,y);//éèÖÃ1a±êλÖÃ
LCD_WR_DATA(color);
}
/******************************************************************************
oˉêyËμÃ÷£o»-Ïß
èë¿úêy¾Y£ox1,y1 Æeê¼×ø±ê
x2,y2 ÖÕÖ1×ø±ê
color ÏßμÄÑÕé«
·μ»ØÖμ£o ÎT
******************************************************************************/
void LCD_DrawLine(u16 x1,u16 y1,u16 x2,u16 y2,u16 color)
{
u16 t;
int xerr=0,yerr=0,delta_x,delta_y,distance;
int incx,incy,uRow,uCol;
delta_x=x2-x1; //¼ÆËã×ø±êÔöá¿
delta_y=y2-y1;
uRow=x1;//»-ÏßÆeμã×ø±ê
uCol=y1;
if(delta_x>0)incx=1; //éèÖÃμ¥2½·½Ïò
else if (delta_x==0)incx=0;//′1Ö±Ïß
else {incx=-1;delta_x=-delta_x;}
if(delta_y>0)incy=1;
else if (delta_y==0)incy=0;//ˮƽÏß
else {incy=-1;delta_y=-delta_y;}
if(delta_x>delta_y)distance=delta_x; //Ñ¡è¡»ù±¾Ôöá¿×ø±êÖá
else distance=delta_y;
for(t=0;t<distance+1;t++)
{
LCD_DrawPoint(uRow,uCol,color);//»-μã
xerr+=delta_x;
yerr+=delta_y;
if(xerr>distance)
{
xerr-=distance;
uRow+=incx;
}
if(yerr>distance)
{
yerr-=distance;
uCol+=incy;
}
}
}
/******************************************************************************
oˉêyËμÃ÷£o»-¾ØDÎ
èë¿úêy¾Y£ox1,y1 Æeê¼×ø±ê
x2,y2 ÖÕÖ1×ø±ê
color ¾ØDÎμÄÑÕé«
·μ»ØÖμ£o ÎT
******************************************************************************/
void LCD_DrawRectangle(u16 x1, u16 y1, u16 x2, u16 y2,u16 color)
{
LCD_DrawLine(x1,y1,x2,y1,color);
LCD_DrawLine(x1,y1,x1,y2,color);
LCD_DrawLine(x1,y2,x2,y2,color);
LCD_DrawLine(x2,y1,x2,y2,color);
}
/******************************************************************************
oˉêyËμÃ÷£o»-Ô2
èë¿úêy¾Y£ox0,y0 Ô2DÄ×ø±ê
r °ë¾¶
color Ô2μÄÑÕé«
·μ»ØÖμ£o ÎT
******************************************************************************/
void Draw_Circle(u16 x0,u16 y0,u8 r,u16 color)
{
int a,b;
a=0;b=r;
while(a<=b)
{
LCD_DrawPoint(x0-b,y0-a,color); //3
LCD_DrawPoint(x0+b,y0-a,color); //0
LCD_DrawPoint(x0-a,y0+b,color); //1
LCD_DrawPoint(x0-a,y0-b,color); //2
LCD_DrawPoint(x0+b,y0+a,color); //4
LCD_DrawPoint(x0+a,y0-b,color); //5
LCD_DrawPoint(x0+a,y0+b,color); //6
LCD_DrawPoint(x0-b,y0+a,color); //7
a++;
if((a*a+b*b)>(r*r))//ÅD¶Ïòa»-μÄμãêÇ·ñ1yÔ¶
{
b--;
}
}
}
/******************************************************************************
oˉêyËμÃ÷£oÏÔê¾oo×Ö′®
èë¿úêy¾Y£ox,yÏÔê¾×ø±ê
*s òaÏÔê¾μÄoo×Ö′®
fc ×ÖμÄÑÕé«
bc ×Öμı3¾°é«
sizey ×ÖoÅ ¿éÑ¡ 16 24 32
mode: 0·Çμt¼óÄ£ê½ 1μt¼óÄ£ê½
·μ»ØÖμ£o ÎT
******************************************************************************/
void LCD_ShowChinese(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode)
{
while(*s!=0)
{
if(sizey==12) LCD_ShowChinese12x12(x,y,s,fc,bc,sizey,mode);
else if(sizey==16) LCD_ShowChinese16x16(x,y,s,fc,bc,sizey,mode);
else if(sizey==24) LCD_ShowChinese24x24(x,y,s,fc,bc,sizey,mode);
else if(sizey==32) LCD_ShowChinese32x32(x,y,s,fc,bc,sizey,mode);
else return;
s+=2;
x+=sizey;
}
}
/******************************************************************************
oˉêyËμÃ÷£oÏÔê¾μ¥¸ö12x12oo×Ö
èë¿úêy¾Y£ox,yÏÔê¾×ø±ê
*s òaÏÔê¾μÄoo×Ö
fc ×ÖμÄÑÕé«
bc ×Öμı3¾°é«
sizey ×ÖoÅ
mode: 0·Çμt¼óÄ£ê½ 1μt¼óÄ£ê½
·μ»ØÖμ£o ÎT
******************************************************************************/
void LCD_ShowChinese12x12(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode)
{
u8 i,j,m=0;
u16 k;
u16 HZnum;//oo×ÖêyÄ¿
u16 TypefaceNum;//ò»¸ö×Ö·ûËùÕ¼×Ö½ú′óD¡
u16 x0=x;
TypefaceNum=(sizey/8+((sizey%8)?1:0))*sizey;
HZnum=sizeof(tfont12)/sizeof(typFNT_GB12); //í3¼Æoo×ÖêyÄ¿
for(k=0;k<HZnum;k++)
{
if((tfont12[k].Index[0]==*(s))&&(tfont12[k].Index[1]==*(s+1)))
{
LCD_Address_Set(x,y,x+sizey-1,y+sizey-1);
for(i=0;i<TypefaceNum;i++)
{
for(j=0;j<8;j++)
{
if(!mode)//·Çμt¼ó·½ê½
{
if(tfont12[k].Msk[i]&(0x01<<j))LCD_WR_DATA(fc);
else LCD_WR_DATA(bc);
m++;
if(m%sizey==0)
{
m=0;
break;
}
}
else//μt¼ó·½ê½
{
if(tfont12[k].Msk[i]&(0x01<<j)) LCD_DrawPoint(x,y,fc);//»-ò»¸öμã
x++;
if((x-x0)==sizey)
{
x=x0;
y++;
break;
}
}
}
}
}
continue; //2éÕò콶Ôó|μãÕó×Ö¿aᢼ′íË3ö£¬·àÖ1¶à¸öoo×ÖÖظ′è¡Ä£′øà′ó°Ïì
}
}
/******************************************************************************
oˉêyËμÃ÷£oÏÔê¾μ¥¸ö16x16oo×Ö
èë¿úêy¾Y£ox,yÏÔê¾×ø±ê
*s òaÏÔê¾μÄoo×Ö
fc ×ÖμÄÑÕé«
bc ×Öμı3¾°é«
sizey ×ÖoÅ
mode: 0·Çμt¼óÄ£ê½ 1μt¼óÄ£ê½
·μ»ØÖμ£o ÎT
******************************************************************************/
void LCD_ShowChinese16x16(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode)
{
u8 i,j,m=0;
u16 k;
u16 HZnum;//oo×ÖêyÄ¿
u16 TypefaceNum;//ò»¸ö×Ö·ûËùÕ¼×Ö½ú′óD¡
u16 x0=x;
TypefaceNum=(sizey/8+((sizey%8)?1:0))*sizey;
HZnum=sizeof(tfont16)/sizeof(typFNT_GB16); //í3¼Æoo×ÖêyÄ¿
for(k=0;k<HZnum;k++)
{
if ((tfont16[k].Index[0]==*(s))&&(tfont16[k].Index[1]==*(s+1)))
{
LCD_Address_Set(x,y,x+sizey-1,y+sizey-1);
for(i=0;i<TypefaceNum;i++)
{
for(j=0;j<8;j++)
{
if(!mode)//·Çμt¼ó·½ê½
{
if(tfont16[k].Msk[i]&(0x01<<j))LCD_WR_DATA(fc);
else LCD_WR_DATA(bc);
m++;
if(m%sizey==0)
{
m=0;
break;
}
}
else//μt¼ó·½ê½
{
if(tfont16[k].Msk[i]&(0x01<<j)) LCD_DrawPoint(x,y,fc);//»-ò»¸öμã
x++;
if((x-x0)==sizey)
{
x=x0;
y++;
break;
}
}
}
}
}
continue; //2éÕò콶Ôó|μãÕó×Ö¿aᢼ′íË3ö£¬·àÖ1¶à¸öoo×ÖÖظ′è¡Ä£′øà′ó°Ïì
}
}
/******************************************************************************
oˉêyËμÃ÷£oÏÔê¾μ¥¸ö24x24oo×Ö
èë¿úêy¾Y£ox,yÏÔê¾×ø±ê
*s òaÏÔê¾μÄoo×Ö
fc ×ÖμÄÑÕé«
bc ×Öμı3¾°é«
sizey ×ÖoÅ
mode: 0·Çμt¼óÄ£ê½ 1μt¼óÄ£ê½
·μ»ØÖμ£o ÎT
******************************************************************************/
void LCD_ShowChinese24x24(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode)
{
u8 i,j,m=0;
u16 k;
u16 HZnum;//oo×ÖêyÄ¿
u16 TypefaceNum;//ò»¸ö×Ö·ûËùÕ¼×Ö½ú′óD¡
u16 x0=x;
TypefaceNum=(sizey/8+((sizey%8)?1:0))*sizey;
HZnum=sizeof(tfont24)/sizeof(typFNT_GB24); //í3¼Æoo×ÖêyÄ¿
for(k=0;k<HZnum;k++)
{
if ((tfont24[k].Index[0]==*(s))&&(tfont24[k].Index[1]==*(s+1)))
{
LCD_Address_Set(x,y,x+sizey-1,y+sizey-1);
for(i=0;i<TypefaceNum;i++)
{
for(j=0;j<8;j++)
{
if(!mode)//·Çμt¼ó·½ê½
{
if(tfont24[k].Msk[i]&(0x01<<j))LCD_WR_DATA(fc);
else LCD_WR_DATA(bc);
m++;
if(m%sizey==0)
{
m=0;
break;
}
}
else//μt¼ó·½ê½
{
if(tfont24[k].Msk[i]&(0x01<<j)) LCD_DrawPoint(x,y,fc);//»-ò»¸öμã
x++;
if((x-x0)==sizey)
{
x=x0;
y++;
break;
}
}
}
}
}
continue; //2éÕò콶Ôó|μãÕó×Ö¿aᢼ′íË3ö£¬·àÖ1¶à¸öoo×ÖÖظ′è¡Ä£′øà′ó°Ïì
}
}
/******************************************************************************
oˉêyËμÃ÷£oÏÔê¾μ¥¸ö32x32oo×Ö
èë¿úêy¾Y£ox,yÏÔê¾×ø±ê
*s òaÏÔê¾μÄoo×Ö
fc ×ÖμÄÑÕé«
bc ×Öμı3¾°é«
sizey ×ÖoÅ
mode: 0·Çμt¼óÄ£ê½ 1μt¼óÄ£ê½
·μ»ØÖμ£o ÎT
******************************************************************************/
void LCD_ShowChinese32x32(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode)
{
u8 i,j,m=0;
u16 k;
u16 HZnum;//oo×ÖêyÄ¿
u16 TypefaceNum;//ò»¸ö×Ö·ûËùÕ¼×Ö½ú′óD¡
u16 x0=x;
TypefaceNum=(sizey/8+((sizey%8)?1:0))*sizey;
HZnum=sizeof(tfont32)/sizeof(typFNT_GB32); //í3¼Æoo×ÖêyÄ¿
for(k=0;k<HZnum;k++)
{
if ((tfont32[k].Index[0]==*(s))&&(tfont32[k].Index[1]==*(s+1)))
{
LCD_Address_Set(x,y,x+sizey-1,y+sizey-1);
for(i=0;i<TypefaceNum;i++)
{
for(j=0;j<8;j++)
{
if(!mode)//·Çμt¼ó·½ê½
{
if(tfont32[k].Msk[i]&(0x01<<j))LCD_WR_DATA(fc);
else LCD_WR_DATA(bc);
m++;
if(m%sizey==0)
{
m=0;
break;
}
}
else//μt¼ó·½ê½
{
if(tfont32[k].Msk[i]&(0x01<<j)) LCD_DrawPoint(x,y,fc);//»-ò»¸öμã
x++;
if((x-x0)==sizey)
{
x=x0;
y++;
break;
}
}
}
}
}
continue; //2éÕò콶Ôó|μãÕó×Ö¿aᢼ′íË3ö£¬·àÖ1¶à¸öoo×ÖÖظ′è¡Ä£′øà′ó°Ïì
}
}
/******************************************************************************
oˉêyËμÃ÷£oÏÔê¾μ¥¸ö×Ö·û
èë¿úêy¾Y£ox,yÏÔê¾×ø±ê
num òaÏÔê¾μÄ×Ö·û
fc ×ÖμÄÑÕé«
bc ×Öμı3¾°é«
sizey ×ÖoÅ
mode: 0·Çμt¼óÄ£ê½ 1μt¼óÄ£ê½
·μ»ØÖμ£o ÎT
******************************************************************************/
void LCD_ShowChar(u16 x,u16 y,u8 num,u16 fc,u16 bc,u8 sizey,u8 mode)
{
u8 temp,sizex,t,m=0;
u16 i,TypefaceNum;//ò»¸ö×Ö·ûËùÕ¼×Ö½ú′óD¡
u16 x0=x;
sizex=sizey/2;
TypefaceNum=(sizex/8+((sizex%8)?1:0))*sizey;
num=num-' '; //μÃμ½Æ«òÆoóμÄÖμ
LCD_Address_Set(x,y,x+sizex-1,y+sizey-1); //éèÖÃ1a±êλÖÃ
for(i=0;i<TypefaceNum;i++)
{
if(sizey==12)temp=ascii_1206[num][i]; //μ÷óÃ6x12×Öìå
else if(sizey==16)temp=ascii_1608[num][i]; //μ÷óÃ8x16×Öìå
else if(sizey==24)temp=ascii_2412[num][i]; //μ÷óÃ12x24×Öìå
else if(sizey==32)temp=ascii_3216[num][i]; //μ÷óÃ16x32×Öìå
else return;
for(t=0;t<8;t++)
{
if(!mode)//·Çμt¼óÄ£ê½
{
if(temp&(0x01<<t))LCD_WR_DATA(fc);
else LCD_WR_DATA(bc);
m++;
if(m%sizex==0)
{
m=0;
break;
}
}
else//μt¼óÄ£ê½
{
if(temp&(0x01<<t))LCD_DrawPoint(x,y,fc);//»-ò»¸öμã
x++;
if((x-x0)==sizex)
{
x=x0;
y++;
break;
}
}
}
}
}
/******************************************************************************
oˉêyËμÃ÷£oÏÔê¾×Ö·û′®
èë¿úêy¾Y£ox,yÏÔê¾×ø±ê
*p òaÏÔê¾μÄ×Ö·û′®
fc ×ÖμÄÑÕé«
bc ×Öμı3¾°é«
sizey ×ÖoÅ
mode: 0·Çμt¼óÄ£ê½ 1μt¼óÄ£ê½
·μ»ØÖμ£o ÎT
******************************************************************************/
void LCD_ShowString(u16 x,u16 y,const u8 *p,u16 fc,u16 bc,u8 sizey,u8 mode)
{
while(*p!='\0')
{
LCD_ShowChar(x,y,*p,fc,bc,sizey,mode);
x+=sizey/2;
p++;
}
}
/******************************************************************************
oˉêyËμÃ÷£oÏÔê¾êy×Ö
èë¿úêy¾Y£omμ×êy£¬nÖ¸êy
·μ»ØÖμ£o ÎT
******************************************************************************/
u32 mypow(u8 m,u8 n)
{
u32 result=1;
while(n--)result*=m;
return result;
}
/******************************************************************************
oˉêyËμÃ÷£oÏÔê¾Õûêy±äá¿
èë¿úêy¾Y£ox,yÏÔê¾×ø±ê
num òaÏÔê¾Õûêy±äá¿
len òaÏÔê¾μÄλêy
fc ×ÖμÄÑÕé«
bc ×Öμı3¾°é«
sizey ×ÖoÅ
·μ»ØÖμ£o ÎT
******************************************************************************/
void LCD_ShowIntNum(u16 x,u16 y,u16 num,u8 len,u16 fc,u16 bc,u8 sizey)
{
u8 t,temp;
u8 enshow=0;
u8 sizex=sizey/2;
for(t=0;t<len;t++)
{
temp=(num/mypow(10,len-t-1))%10;
if(enshow==0&&t<(len-1))
{
if(temp==0)
{
LCD_ShowChar(x+t*sizex,y,' ',fc,bc,sizey,0);
continue;
}else enshow=1;
}
LCD_ShowChar(x+t*sizex,y,temp+48,fc,bc,sizey,0);
}
}
/******************************************************************************
oˉêyËμÃ÷£oÏÔê¾á½Î»D¡êy±äá¿
èë¿úêy¾Y£ox,yÏÔê¾×ø±ê
num òaÏÔê¾D¡êy±äá¿
len òaÏÔê¾μÄλêy
fc ×ÖμÄÑÕé«
bc ×Öμı3¾°é«
sizey ×ÖoÅ
·μ»ØÖμ£o ÎT
******************************************************************************/
void LCD_ShowFloatNum1(u16 x,u16 y,float num,u8 len,u16 fc,u16 bc,u8 sizey)
{
u8 t,temp,sizex;
u16 num1;
sizex=sizey/2;
num1=num*100;
for(t=0;t<len;t++)
{
temp=(num1/mypow(10,len-t-1))%10;
if(t==(len-2))
{
LCD_ShowChar(x+(len-2)*sizex,y,'.',fc,bc,sizey,0);
t++;
len+=1;
}
LCD_ShowChar(x+t*sizex,y,temp+48,fc,bc,sizey,0);
}
}
/******************************************************************************
oˉêyËμÃ÷£oÏÔê¾í¼Æ¬
èë¿úêy¾Y£ox,yÆeμã×ø±ê
length í¼Æ¬3¤¶è
width í¼Æ¬¿í¶è
pic[] í¼Æ¬êy×é
·μ»ØÖμ£o ÎT
******************************************************************************/
void LCD_ShowPicture(u16 x,u16 y,u16 length,u16 width,const u8 pic[])
{
u16 i,j;
u32 k=0;
LCD_Address_Set(x,y,x+length-1,y+width-1);
for(i=0;i<length;i++)
{
for(j=0;j<width;j++)
{
LCD_WR_DATA8(pic[k*2]);
LCD_WR_DATA8(pic[k*2+1]);
k++;
}
}
}
main.c
#include <rtthread.h>
#include <rtdevice.h>
#include "drv_gpio.h"
#include "lcd.h"
#define RED 0xF800
#define LED_PIN GET_PIN(0, 0)
void LCD_Fill(u16 xsta,u16 ysta,u16 xend,u16 yend,u16 color)
{
u16 i,j;
LCD_Address_Set(xsta,ysta,xend-1,yend-1);//设置显示范围
for(i=ysta;i<yend;i++)
{
for(j=xsta;j<xend;j++)
{
LCD_WR_DATA(color);
}
}
}
int main(void)
{
LCD_Init();
delay_ms(100);
LCD_Fill(0,0,128,160,RED);
delay_ms(100);
rt_pin_mode(LED_PIN, PIN_MODE_OUTPUT);
for (;;)
{
rt_pin_write(LED_PIN, PIN_HIGH);
rt_thread_mdelay(500);
rt_pin_write(LED_PIN, PIN_LOW);
rt_thread_mdelay(500);
}
}
运行结果: