本帖最后由 jinglixixi 于 2020-5-26 15:04 编辑
熟练地掌握GPIO口的使用,既是基本功的训炼,也为其他的应用提供了方便,这里就模拟SPI接口来实现2种显示屏的显示功能。
1. LCD5510显示屏 该显示屏与GPIO口的连接情况如下: PB3 -- LED+ PA15 -- D0 (SCL) PB12 -- D1 (SDI) PB15 -- D/C PB14 -- RST PB13 -- CS
为实现显示功能相应的定义如下: #define X_Col_Addr 0x80 #define Y_Page_Addr 0x40
#define LCD_reset_hard LCD_RST_L; LCD_RST_H #define LCD_reset_soft LCD_reset_5510() #define LCD_write_cmd(cmd) LCD_write_byte(cmd, 0) #define LCD_write_dat(dat) LCD_write_byte(dat, 1)
#define LCD_LED_High() GPIO_SetBits(GPIOB,GPIO_Pin_3)
#define LCD_CLK_H GPIO_SetBits(GPIOA,GPIO_Pin_15); // CLK PA15 #define LCD_CLK_L GPIO_ResetBits(GPIOA,GPIO_Pin_15);
#define LCD_DIN_H GPIO_SetBits(GPIOB,GPIO_Pin_12); // DIN PB12 #define LCD_DIN_L GPIO_ResetBits(GPIOB,GPIO_Pin_12);
#define LCD_DC_H GPIO_SetBits(GPIOB,GPIO_Pin_15); //DC PB15 #define LCD_DC_L GPIO_ResetBits(GPIOB,GPIO_Pin_15);
#define LCD_CS_H GPIO_SetBits(GPIOB,GPIO_Pin_13); //SCE PB13 #define LCD_CS_L GPIO_ResetBits(GPIOB,GPIO_Pin_13);
#define LCD_RST_H GPIO_SetBits(GPIOB,GPIO_Pin_14); //RST PB14 #define LCD_RST_L GPIO_ResetBits(GPIOB,GPIO_Pin_14);
对相关引脚的配置函数为: void LCD_GPIO_Cogfig(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA|RCC_AHBPeriph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
LCD_LED_High();
}
实现 LCD5510显示屏的初始化函数为: void LCD5510_Init(void)
{
LCD_GPIO_Cogfig();
LCD_reset_hard;
LCD_write_cmd(0x21);
LCD_write_cmd(0x06);
LCD_write_cmd(0x13);
LCD_write_cmd(0xc8);
LCD_write_cmd(0x20);
LCD_write_cmd(0x0c);
LCD_write_cmd(Y_Page_Addr);
LCD_write_cmd(X_Col_Addr);
LCD_clr_scr();
}
相关的显示函数有: void LCD_printc(unsigned char x, unsigned char y, unsigned char c_dat)
{
unsigned char i, j;
c_dat -= 32;
x <<= 3; //8
y <<= 1; //16
for(j = 0; j < 2; j++)
{
LCD_pos_byte(x, (y + j));
for(i = 0; i < 8; i++)
LCD_write_dat(Font_code[c_dat][8 * j + i]);
}
}
void LCD_prints(unsigned char x, unsigned char y, unsigned char *s_dat)
{
while(*s_dat && x < 10)
{LCD_printc(x++, y, *s_dat); s_dat++;}
}
void LCD_printch(unsigned char x, unsigned char y, unsigned char *h_dat)
{
unsigned char i, j;
x <<= 4;
y <<= 1;
for(j = 0; j < 2; j++)
{
LCD_pos_byte(x, (y + j));
for(i = 0; i < 16; i++) LCD_write_dat(h_dat[16 * j + i]);
}
}
void LCD_showch(unsigned char x, unsigned char y, unsigned char *dat)
{
unsigned char i;
for(i = 0; i < 20; i++)
{
if((GB_16[i].Index[0] == dat[0]) && (GB_16[i].Index[1] == dat[1])) break;
}
LCD_printch(x, y, GB_16[i].Msk);
}
void LCD_showsh(unsigned char x, unsigned char y, unsigned char *dat)
{
while(*dat) {LCD_showch(x++, y, dat); dat += 2;}
}
实现图1显示效果的主程序为: int main(void)
{
delay_init();
delay_ms(300);
LCD5510_Init();
LCD_prints(0,0,"MM32L073PF");
LCD_prints(0,1,"LCD5510 ");
LCD_prints(0,2,"JINGLIXIXI");
while(1);
}
图1显示效果
2. TFT2.4’彩色显示屏 该显示屏对GPIO口的使用情况与前一个显示屏相近,其设置相关引脚输出高低电平的定义如下:
#define LCD_LED_High() GPIO_SetBits(GPIOB,GPIO_Pin_3)
#define LCD_CS_High() GPIO_SetBits(GPIOB,GPIO_Pin_13); //SC PB13 #define LCD_CS_Low() GPIO_ResetBits(GPIOB,GPIO_Pin_13); #define LCD_SCK_High() GPIO_SetBits(GPIOA,GPIO_Pin_15); // CLK PA15 #define LCD_SCK_Low() GPIO_ResetBits(GPIOA,GPIO_Pin_15); #define LCD_SDI_High() GPIO_SetBits(GPIOB,GPIO_Pin_12); // SDI PB12 #define LCD_SDI_Low() GPIO_ResetBits(GPIOB,GPIO_Pin_12); #define LCD_DC_High() GPIO_SetBits(GPIOB,GPIO_Pin_15); //DC PB15 #define LCD_DC_Low() GPIO_ResetBits(GPIOB,GPIO_Pin_15); #define LCD_REST_High() GPIO_SetBits(GPIOB,GPIO_Pin_14); //RST PB14 #define LCD_REST_Low() GPIO_ResetBits(GPIOB,GPIO_Pin_14);
定义相关引脚的函数如下: void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA|RCC_AHBPeriph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
LCD_LED_High();
}
其TFT显示屏的初始化函数为: void Lcd_Init(void)
{
LCD_REST_Low();
delay_ms(20);
LCD_REST_High();
delay_ms(20);
LCD_CS_Low();
LCD_WR_REG(0xCB);
LCD_WR_DATA8(0x39);
LCD_WR_DATA8(0x2C);
LCD_WR_DATA8(0x00);
LCD_WR_DATA8(0x34);
LCD_WR_DATA8(0x02);
LCD_WR_REG(0xCF);
LCD_WR_DATA8(0x00);
LCD_WR_DATA8(0XC1);
LCD_WR_DATA8(0X30);
LCD_WR_REG(0xE8);
LCD_WR_DATA8(0x85);
LCD_WR_DATA8(0x00);
LCD_WR_DATA8(0x78);
LCD_WR_REG(0xEA);
LCD_WR_DATA8(0x00);
LCD_WR_DATA8(0x00);
LCD_WR_REG(0xED);
LCD_WR_DATA8(0x64);
LCD_WR_DATA8(0x03);
LCD_WR_DATA8(0X12);
LCD_WR_DATA8(0X81);
LCD_WR_REG(0xF7);
LCD_WR_DATA8(0x20);
LCD_WR_REG(0xC0); //Power control
LCD_WR_DATA8(0x23); //VRH[5:0]
LCD_WR_REG(0xC1); //Power control
LCD_WR_DATA8(0x10); //SAP[2:0];BT[3:0]
LCD_WR_REG(0xC5); //VCM control
LCD_WR_DATA8(0x3e);
LCD_WR_DATA8(0x28);
LCD_WR_REG(0xC7); // VCM control2
LCD_WR_DATA8(0x86);
LCD_WR_REG(0x36); // Memory Access Control
LCD_WR_DATA8(0x48); // C8
LCD_WR_REG(0x3A);
LCD_WR_DATA8(0x55);
LCD_WR_REG(0xB1);
LCD_WR_DATA8(0x00);
LCD_WR_DATA8(0x18);
LCD_WR_REG(0xB6); // Display Function Control
LCD_WR_DATA8(0x08);
LCD_WR_DATA8(0x82);
LCD_WR_DATA8(0x27);
LCD_WR_REG(0xF2); // 3Gamma Function Disable
LCD_WR_DATA8(0x00);
LCD_WR_REG(0x26); // Gamma curve selected
LCD_WR_DATA8(0x01);
LCD_WR_REG(0xE0); // Set Gamma
LCD_WR_DATA8(0x0F);
LCD_WR_DATA8(0x31);
LCD_WR_DATA8(0x2B);
LCD_WR_DATA8(0x0C);
LCD_WR_DATA8(0x0E);
LCD_WR_DATA8(0x08);
LCD_WR_DATA8(0x4E);
LCD_WR_DATA8(0xF1);
LCD_WR_DATA8(0x37);
LCD_WR_DATA8(0x07);
LCD_WR_DATA8(0x10);
LCD_WR_DATA8(0x03);
LCD_WR_DATA8(0x0E);
LCD_WR_DATA8(0x09);
LCD_WR_DATA8(0x00);
LCD_WR_REG(0XE1); //Set Gamma
LCD_WR_DATA8(0x00);
LCD_WR_DATA8(0x0E);
LCD_WR_DATA8(0x14);
LCD_WR_DATA8(0x03);
LCD_WR_DATA8(0x11);
LCD_WR_DATA8(0x07);
LCD_WR_DATA8(0x31);
LCD_WR_DATA8(0xC1);
LCD_WR_DATA8(0x48);
LCD_WR_DATA8(0x08);
LCD_WR_DATA8(0x0F);
LCD_WR_DATA8(0x0C);
LCD_WR_DATA8(0x31);
LCD_WR_DATA8(0x36);
LCD_WR_DATA8(0x0F);
LCD_WR_REG(0x11); //Exit Sleep
delay_ms(120);
LCD_WR_REG(0x29); //Display on
LCD_WR_REG(0x2c);
}
为实现汉字的显示,特定义了2种汉字显示字模,即16*16汉字字模和32*32汉字字模。
32*32汉字字模的结构为: unsigned char hanzi32[]={ // 标(0) 准(1) 化(2) 考(3) 试(4) 进(5) 程(6) 语(7) 音(8) 提(9) 示(10) 器(11) 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x03,0x00,0x00, 0x80,0x00,0x00,0x04,0x80,0xC0,0xFF,0x0F,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00, 0x80,0x00,0x00,0x00,0x80,0x08,0x00,0x00,0xFC,0x1F,0x00,0x00,0x80,0x00,0x00,0x18, 0xC0,0xF0,0xFF,0x3F,0xC0,0x00,0x30,0x00,0xC0,0x01,0x30,0x00,0xE0,0x06,0x30,0x00, 0xE0,0x0C,0x30,0x00,0xA0,0x8C,0x33,0x01,0xB0,0x88,0x31,0x03,0x90,0x80,0x31,0x06, 0x98,0xC0,0x30,0x0C,0x88,0x40,0x30,0x0C,0x84,0x60,0x30,0x18,0x84,0x20,0x30,0x18, 0x80,0x10,0x30,0x38,0x80,0x18,0x30,0x10,0x80,0x08,0x30,0x10,0x80,0x84,0x30,0x00, 0x80,0x00,0x3F,0x00,0x80,0x00,0x1C,0x00,0x80,0x00,0x08,0x00,0x00,0x00,0x00,0x00,/*"标",0*/ };
//16*16汉字字模的结构为: unsigned char hanzi16[]={ //入(0) 场(1) 开(2) 考(3) 写(4) 作(5) 听(6) 力(7) 答(8) 题(9) 结(10) 束(11) 0x20,0x00,0x40,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x40,0x01,0x40,0x01,0x40,0x01, 0x20,0x02,0x20,0x02,0x10,0x04,0x10,0x04,0x08,0x08,0x04,0x08,0x02,0x10,0x01,0x60,/*"入",0*/ };
实现汉字显示的函数有: void showhanzi16(unsigned int x,unsigned int y,unsigned char index)
{
unsigned char i,j,k;
const unsigned char *temp=hanzi16;
temp+=index*32;
for(j=0;j<16;j++)
{
LCD_SetCursor(x,y+j);
LCD_WriteRAM_Prepare();
for(k=0;k<2;k++)
{
for(i=0;i<8;i++)
{
if((*temp&(1<<i))!=0)
{
LCD_WR_DATA(POINT_COLOR);
}
else
{
LCD_WR_DATA(BACK_COLOR);
}
}
temp++;
}
}
}
void showhanzi32(unsigned int x,unsigned int y,unsigned char index)
{
unsigned char i,j,k;
const unsigned char *temp=hanzi32;
temp+=index*128;
for(j=0;j<32;j++)
{
LCD_SetCursor(x,y+j);
LCD_WriteRAM_Prepare(); //GRAM
for(k=0;k<4;k++)
{
for(i=0;i<8;i++)
{
if((*temp&(1<<i))!=0)
{
LCD_WR_DATA(POINT_COLOR);
}
else
{
LCD_WR_DATA(BACK_COLOR);
}
}
temp++;
}
}
}
显示图2显示效果的函数为: void xianshi()
{
LCD_Clear(RED);
BACK_COLOR=RED;
POINT_COLOR=WHITE;
//32*32
showhanzi32(20,10,0);
showhanzi32(60,10,1);
showhanzi32(100,10,2);
showhanzi32(140,10,3);
showhanzi32(180,10,4);
//16*16
对应的主程序为: int main(void)
{
delay_init();
delay_ms(300);
GPIO_Configuration();
Lcd_Init();
xianshi();
while(1);
}
图2显示效果
|