APM32F402R Micro-EVB开发板是一款近于最小系统的开发板,为其添加相应的外设,可用起到丰富其羽翼的作用。这里是利用闲置SPI接口为其配置一个TFT显示屏,该闲置的SPI电路如图1所示。
图1 闲置SPI电路
该闲置SPI电路所使用的引脚为PA4~PA7,这里就用它与TFT屏的对应引脚连接。此外,还需为其分配一些辅助引脚。
在使用SPI进行硬件驱动前,先以模拟的方式来驱动该显示屏。
对TFT屏所用引脚的配置函数为:
void BOARD_TFT_Config()
{
GPIO_Config_T GPIO_ConfigStruct = {0U};
RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_GPIOA);
GPIO_ConfigStruct.pin = GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
GPIO_ConfigStruct.mode = GPIO_MODE_OUT_PP;
GPIO_ConfigStruct.speed = GPIO_SPEED_50MHz;
GPIO_Config(GPIOA, &GPIO_ConfigStruct);
RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_GPIOB);
GPIO_ConfigStruct.pin = GPIO_PIN_8|GPIO_PIN_9;
GPIO_Config(GPIOB, &GPIO_ConfigStruct);
}
实现高低电平输出的语句定义为:
#define LCD_CS_High() GPIOA->BSC = GPIO_PIN_4
#define LCD_CS_Low() GPIOA->BC = GPIO_PIN_4
#define LCD_REST_High() GPIOB->BSC = GPIO_PIN_8
#define LCD_REST_Low() GPIOB->BC = GPIO_PIN_8
#define LCD_DC_High() GPIOB->BSC = GPIO_PIN_9
#define LCD_DC_Low() GPIOB->BC = GPIO_PIN_9
#define LCD_SDI_High() GPIOA->BSC = GPIO_PIN_7
#define LCD_SDI_Low() GPIOA->BC = GPIO_PIN_7
#define LCD_SCK_High() GPIOA->BSC = GPIO_PIN_5
#define LCD_SCK_Low() GPIOA->BC = GPIO_PIN_5
#define LCD_LED_High() GPIOA->BSC = GPIO_PIN_6
#define LCD_LED_Low() GPIOA->BC = GPIO_PIN_6
此外,为较好地控制时序关系,还使用SysTick配置了一个起短延时作用的函数,其内容为:
void delay_u(uint32_t delay)
{
delay = 0xf*delay ;
while(delay--);
}
模拟SPI发送字节数据的函数为:
void LCD_Writ_Bus(unsigned char com)
{
unsigned char uci;
for(uci=0;uci<8;uci++)
{
if(com & 0x80)
{
LCD_SDI_High();
}
else
{
LCD_SDI_Low();
}
com = com << 1;
delay_u(1);
LCD_SCK_Low();
LCD_SCK_High();
}
}
对显示屏的初始化函数为:
void tft_Init(void)
{
// ili9220B
LCD_REST_Low();
Delay();
LCD_REST_High();
Delay();
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);
LCD_WR_DATA8(0x23);
LCD_WR_REG(0xC1);
LCD_WR_DATA8(0x10);
LCD_WR_REG(0xC5);
LCD_WR_DATA8(0x3e);
LCD_WR_DATA8(0x28);
LCD_WR_REG(0xC7);
LCD_WR_DATA8(0x86);
LCD_WR_REG(0x36);
LCD_WR_DATA8(0xE8);
LCD_WR_REG(0x3A);
LCD_WR_DATA8(0x55);
LCD_WR_REG(0xB1);
LCD_WR_DATA8(0x00);
LCD_WR_DATA8(0x18);
LCD_WR_REG(0xB6);
LCD_WR_DATA8(0x08);
LCD_WR_DATA8(0x82);
LCD_WR_DATA8(0x27);
LCD_WR_REG(0xF2);
LCD_WR_DATA8(0x00);
LCD_WR_REG(0x26);
LCD_WR_DATA8(0x01);
LCD_WR_REG(0xE0);
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);
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);
Delay();
LCD_WR_REG(0x29);
LCD_WR_REG(0x2c);
LCD_LED_High();
}
实现清除屏幕的函数为:
void LCD_Clear(unsigned int Color)
{
char VH,VL;
unsigned int i,j;
VH=Color>>8;
VL=Color;
LCD_W= 320;
LCD_H =240;
Address_set(0,0,LCD_W-1,LCD_H-1);
for(i=0;i<LCD_W;i++)
{
for (j=0;j<LCD_H;j++)
{
LCD_WR_DATA8(VH);
LCD_WR_DATA8(VL);
}
}
}
发送字符的函数为:
void LCD_ShowChar(unsigned int x,unsigned int y,char num,char mode)
{
char temp;
char pos,t;
unsigned int x0=x;
unsigned int colortemp=POINT_COLOR;
if(x>LCD_W-16||y>LCD_H-16)return;
num=num-' ';
Address_set(x,y,x+8-1,y+16-1);
if(!mode)
{
for(pos=0;pos<16;pos++)
{
temp=asc2_1608[(unsigned int)num*16+pos];
for(t=0;t<8;t++)
{
if(temp&0x01)POINT_COLOR=colortemp;
else POINT_COLOR=BACK_COLOR;
LCD_WR_DATA(POINT_COLOR);
temp>>=1;
x++;
}
x=x0;
y++;
}
}
else
{
for(pos=0;pos<16;pos++)
{
temp=asc2_1608[(unsigned int)num*16+pos];
for(t=0;t<8;t++)
{
if(temp&0x01)LCD_DrawPoint(x+t,y+pos);
temp>>=1;
}
}
}
POINT_COLOR=colortemp;
}
显示字符串的函数为:
void LCD_ShowString(unsigned int x,unsigned int y,const char *p)
{
while(*p!='\0')
{
if(x>LCD_W-16){x=0;y+=16;}
if(y>LCD_H-16){y=x=0;}
LCD_ShowChar(x,y,*p,0);
x+=8;
p++;
}
}
实现显示测试的主程序为:
int main(void)
{
BOARD_LED_Config(LED2);
BOARD_LED_Config(LED3);
BOARD_TFT_Config();
tft_Init();
LCD_Clear(RED);
BACK_COLOR=RED;
POINT_COLOR=YELLOW;
LCD_ShowString(120,10,"APM32F402");
while (1)
{
Delay();
BOARD_LED_Toggle(LED2);
BOARD_LED_Toggle(LED3);
}
}
经程序的编译和下载,其显示效果如图2和图3所示,说明功能正常。
图2 器件连接
图3 显示效果
|