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 显示效果
|