打印
[APM32F4]

【APM32F402R Micro-EVB开发板测评】+TFT屏显示驱动及信息显示

[复制链接]
172|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主

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


使用特权

评论回复
沙发
阳光爆裂| | 2025-7-24 11:24 | 只看该作者
楼主这是使用GPIO来模拟的SPI时序吗?

使用特权

评论回复
板凳
jinglixixi|  楼主 | 2025-7-24 15:25 | 只看该作者
阳光爆裂 发表于 2025-7-24 11:24
楼主这是使用GPIO来模拟的SPI时序吗?

是的,只要能显示后面改为SPI驱动就有保障了。

使用特权

评论回复
地板
暖茶轻语| | 2025-7-24 21:04 | 只看该作者
这个开发板测评很详细,特别是TFT屏的驱动部分,代码注释也很清晰,对初学者来说很有帮助。

使用特权

评论回复
5
阳光爆裂| | 2025-7-25 10:15 | 只看该作者
也是,也要先确定一下LCD屏的接收是否正常。
调试了半天,LCD屏有bug,这事就有点xx了

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

508

主题

2911

帖子

39

粉丝