1180|1

441

帖子

3

TA的资源

纯净的硅(高级)

楼主
 

【极海APM32F407 Tiny Board】 SPI方式驱动TFTLCD显示屏 [复制链接]

 

这篇使用APM32F407 Tiny Board开发板的SPI方式来驱动TFTLCD显示屏。

 

一、硬件部分

 

1.1、使用开发板上的PI0~PI2端口映射的SPI2方式

手册中,引脚对应的映射 

SPI2_NSS使用软件控制方式,来片选LCD

 

二、软件部分

 

2.1、spi.c

#include "main.h"

void init_spi(void)
{
    GPIO_Config_T GPIO_InitStructure;
    SPI_Config_T  SPI2_InitStructure;

//    /** Enable related Clock */
    RCM_EnableAHB1PeriphClock (RCM_AHB1_PERIPH_GPIOI);
    RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_SPI2);
    RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_SYSCFG);

    /** Config SPI2 PinAF */
    GPIO_ConfigPinAF(GPIOI, GPIO_PIN_SOURCE_1, GPIO_AF_SPI2);
    GPIO_ConfigPinAF(GPIOI, GPIO_PIN_SOURCE_2, GPIO_AF_SPI2);
    GPIO_ConfigPinAF(GPIOI, GPIO_PIN_SOURCE_3, GPIO_AF_SPI2);
    //GPIO_ConfigPinAF(GPIOI, GPIO_PIN_SOURCE_0, GPIO_AF_SPI2);

    /** Config SPI2, SCK=PI1, MISO=PI2, MOSI=PI3 */
    GPIO_ConfigStructInit(&GPIO_InitStructure);
    GPIO_InitStructure.pin = GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3;
    GPIO_InitStructure.speed = GPIO_SPEED_100MHz;
    GPIO_InitStructure.mode = GPIO_MODE_AF;
    GPIO_InitStructure.otype = GPIO_OTYPE_PP;
    GPIO_InitStructure.pupd = GPIO_PUPD_NOPULL;
    GPIO_Config(GPIOI, &GPIO_InitStructure);
		
    /** Config SPI2 */
    SPI_ConfigStructInit(&SPI2_InitStructure);
    SPI2_InitStructure.direction = SPI_DIRECTION_2LINES_FULLDUPLEX;
    SPI2_InitStructure.mode = SPI_MODE_MASTER;
    SPI2_InitStructure.length = SPI_DATA_LENGTH_8B;
    SPI2_InitStructure.polarity = SPI_CLKPOL_LOW;
    SPI2_InitStructure.phase = SPI_CLKPHA_1EDGE;
    SPI2_InitStructure.nss = SPI_NSS_SOFT;
    SPI2_InitStructure.baudrateDiv = SPI_BAUDRATE_DIV_2;
    SPI2_InitStructure.firstBit = SPI_FIRSTBIT_MSB;
    SPI2_InitStructure.crcPolynomial = 7;
    SPI_Config(SPI2, &SPI2_InitStructure);
    SPI_DisableCRC(SPI2);
		SPI_DisableSSOutput(SPI2);

    /** Enable SPI  */
    //SPI_Enable(SPI1);
    SPI_Enable(SPI2);
}

uint8_t spi_sendbyte(uint8_t dat)
{
	/** SPI master send data */
    while (SPI_I2S_ReadStatusFlag(SPI2, SPI_FLAG_TXBE) == RESET);

    SPI_I2S_TxData(SPI2, dat);

    /** SPI1 slave receive data */
    while (SPI_I2S_ReadStatusFlag(SPI2, SPI_FLAG_RXBNE) == RESET);

    return SPI_I2S_RxData(SPI2);
}

 

2.2、spi.h

#ifndef _USER_SPI_H
#define _USER_SPI_H

#include "stdint.h"

void init_spi(void);
uint8_t spi_sendbyte(uint8_t dat);

#endif

2.3、lcd.c

#include "main.h"
#include "lcd_ili9341.h"
#include "user_spi.h"

_lcd_dev lcddev;
static void LCD_RESET(void)
{
    LCD_RES_CLR;
		SysTick_Delay_ms(100);
    LCD_RES_SET;
    SysTick_Delay_ms(100);
}

static void LCD_WR_REG(uint8_t reg)
{
    LCD_DC_CLR;
	
		LCD_CS_CLR;
		spi_sendbyte(reg);
		LCD_CS_SET;
	
    LCD_DC_SET;
}

static void LCD_WR_DATA(uint8_t dat)
{
		LCD_DC_SET;
	
		LCD_CS_CLR;
    spi_sendbyte(dat);
		LCD_CS_SET;
}
/*
static void LCD_ReadData(uint8_t *data, uint16_t length)
{
    LCD_DC_SET;
    rt_spi_transfer(lcd_dev, RT_NULL, &data, length);
}
*/
static void LCD_WriteReg(uint8_t reg, uint16_t regdata)
{
    LCD_WR_REG(reg);
    LCD_WR_DATA(regdata);
}

static void LCD_WriteRAM_Prepare(void)
{
    LCD_WR_REG(lcddev.wramcmd);
}

static void LCD_WriteData_16Bit(uint16_t Data)
{
    uint8_t buf[2];
    
    buf[0] = Data >> 8;
    buf[1] = Data & 0xff;
		LCD_DC_SET;
		LCD_CS_CLR;
		spi_sendbyte(buf[0]);
		spi_sendbyte(buf[1]);
		LCD_CS_SET;
}

void LCD_direction(uint8_t direction)
{
    lcddev.setxcmd = 0x2A;
    lcddev.setycmd = 0x2B;
    lcddev.wramcmd = 0x2C;
    switch (direction)
    {
    case 0:
        lcddev.width = LCD_W;
        lcddev.height = LCD_H;
        LCD_WriteReg(0x36, (1 << 3) | (0 << 6) | (0 << 7)); /* BGR==1,MY==0,MX==0,MV==0 */
        break;
    case 1:
        lcddev.width = LCD_H;
        lcddev.height = LCD_W;
        LCD_WriteReg(0x36, (1 << 3) | (0 << 7) | (1 << 6) | (1 << 5)); /* BGR==1,MY==1,MX==0,MV==1 */
        break;
    case 2:
        lcddev.width = LCD_W;
        lcddev.height = LCD_H;
        LCD_WriteReg(0x36, (1 << 3) | (1 << 6) | (1 << 7)); /* BGR==1,MY==0,MX==0,MV==0 */
        break;
    case 3:
        lcddev.width = LCD_H;
        lcddev.height = LCD_W;
        LCD_WriteReg(0x36, (1 << 3) | (1 << 7) | (1 << 5)); /* BGR==1,MY==1,MX==0,MV==1 */
        break;
    default:
        break;
    }
}

void LCD_SetWindows(uint16_t xStar, uint16_t yStar, uint16_t xEnd, uint16_t yEnd)
{
    LCD_WR_REG(lcddev.setxcmd);
    LCD_WR_DATA(xStar >> 8);
    LCD_WR_DATA(0x00FF & xStar);
    LCD_WR_DATA(xEnd >> 8);
    LCD_WR_DATA(0x00FF & xEnd);

    LCD_WR_REG(lcddev.setycmd);
    LCD_WR_DATA(yStar >> 8);
    LCD_WR_DATA(0x00FF & yStar);
    LCD_WR_DATA(yEnd >> 8);
    LCD_WR_DATA(0x00FF & yEnd);

    LCD_WriteRAM_Prepare();
}

void LCD_SetCursor(uint16_t Xpos, uint16_t Ypos)
{
    LCD_SetWindows(Xpos, Ypos, Xpos, Ypos);
}

void LCD_Clear(uint16_t Color)
{
    unsigned int i, m;
    uint8_t buf[80];
		uint8_t s=0;

    for (i = 0; i < 40; i++)
    {
        buf[2 * i] = Color >> 8;
        buf[2 * i + 1] = Color & 0xff;
    }

    LCD_SetWindows(0, 0, lcddev.width - 1, lcddev.height - 1);

    for (i = 0; i < lcddev.height; i++)
    {
        for (m = 0; m < lcddev.width;)
        {
            m += 40;
						LCD_CS_CLR;
						for(s=0;s<80;s++)
						{							
							spi_sendbyte(buf[s]);
						}
						LCD_CS_SET;
        }
    }
}

void LCD_Fill(uint16_t xsta, uint16_t ysta, uint16_t xend, uint16_t yend, uint16_t color)
{
    uint16_t i, j;
    LCD_SetWindows(xsta, ysta, xend - 1, yend - 1);
	  LCD_DC_SET;
    for (i = ysta; i < yend; i++)
    {
        for (j = xsta; j < xend; j++)
        {
            LCD_WriteData_16Bit(color);
        }
    }
}

void lcd_fill_array_spi(uint16_t Xstart, uint16_t Ystart, uint16_t Xend, uint16_t Yend, uint8_t *Image)
{
    uint32_t size = 0;
		uint32_t s=0;

    size = (Xend - Xstart + 1) * (Yend - Ystart + 1) * 2;/*16bit*/
    LCD_SetWindows(Xstart, Ystart, Xend, Yend);
    LCD_DC_SET;
		LCD_CS_CLR;
		for(s=0;s<size;s++)
		{
			spi_sendbyte(Image[s]);
		}
		LCD_CS_SET;
}

static void _ili9341_init(void)
{
    LCD_WR_REG(0xCF);
    LCD_WR_DATA(0x00);
    LCD_WR_DATA(0X83);
    LCD_WR_DATA(0X30);

    LCD_WR_REG(0xED);
    LCD_WR_DATA(0x64);
    LCD_WR_DATA(0x03);
    LCD_WR_DATA(0X12);
    LCD_WR_DATA(0X81);

    LCD_WR_REG(0xE8);
    LCD_WR_DATA(0x85);
    LCD_WR_DATA(0x00);
    LCD_WR_DATA(0x79);

    LCD_WR_REG(0xCB);
    LCD_WR_DATA(0x39);
    LCD_WR_DATA(0x2C);
    LCD_WR_DATA(0x00);
    LCD_WR_DATA(0x34);
    LCD_WR_DATA(0x02);

    LCD_WR_REG(0xF7);
    LCD_WR_DATA(0x20);

    LCD_WR_REG(0xEA);
    LCD_WR_DATA(0x00);
    LCD_WR_DATA(0x00);

    LCD_WR_REG(0xC0);   /* Power control */
    LCD_WR_DATA(0x26);  /* VRH[5:0] */

    LCD_WR_REG(0xC1);   /* Power control */
    LCD_WR_DATA(0x11);  /* SAP[2:0];BT[3:0] */

    LCD_WR_REG(0xC5);   /* VCM control */
    LCD_WR_DATA(0x35);
    LCD_WR_DATA(0x3E);

    LCD_WR_REG(0xC7);   /* VCM control2 */
    LCD_WR_DATA(0XBE);

    LCD_WR_REG(0x36);   /* Memory Access Control */
    LCD_WR_DATA(0x28);

    LCD_WR_REG(0x3A);
    LCD_WR_DATA(0x55);

    LCD_WR_REG(0xB1);
    LCD_WR_DATA(0x00);
    LCD_WR_DATA(0x1B);

    LCD_WR_REG(0xB6);   /* Display Function Control */
    LCD_WR_DATA(0x0A);
    LCD_WR_DATA(0xA2);

    LCD_WR_REG(0xF2);   /* 3Gamma Function Disable */
    LCD_WR_DATA(0x08);

    LCD_WR_REG(0x26);   /* Gamma curve selected */
    LCD_WR_DATA(0x01);

    LCD_WR_REG(0xE0);   /* set Gamma */
    LCD_WR_DATA(0X1F);
    LCD_WR_DATA(0X1A);
    LCD_WR_DATA(0X18);
    LCD_WR_DATA(0X0A);
    LCD_WR_DATA(0X0F);
    LCD_WR_DATA(0X06);
    LCD_WR_DATA(0X45);
    LCD_WR_DATA(0X87);
    LCD_WR_DATA(0X32);
    LCD_WR_DATA(0X0A);
    LCD_WR_DATA(0X07);
    LCD_WR_DATA(0X02);
    LCD_WR_DATA(0X07);
    LCD_WR_DATA(0X05);
    LCD_WR_DATA(0X00);

    LCD_WR_REG(0xE1);   /* set Gamma */
    LCD_WR_DATA(0X00);
    LCD_WR_DATA(0X25);
    LCD_WR_DATA(0X27);
    LCD_WR_DATA(0X05);
    LCD_WR_DATA(0X10);
    LCD_WR_DATA(0X09);
    LCD_WR_DATA(0X3A);
    LCD_WR_DATA(0X78);
    LCD_WR_DATA(0X4D);
    LCD_WR_DATA(0X05);
    LCD_WR_DATA(0X18);
    LCD_WR_DATA(0X0D);
    LCD_WR_DATA(0X38);
    LCD_WR_DATA(0X3A);
    LCD_WR_DATA(0X2F);

    LCD_WR_REG(0x29);
}

static void Lcd_pin_init(void)
{
	GPIO_Config_T  configStruct;

	RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOH);
	RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOI);
	RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOA);
	
	GPIO_ConfigStructInit(&configStruct);
	configStruct.pin = ILI_9341_DC_PIN;
	configStruct.mode = GPIO_MODE_OUT;
	configStruct.speed = GPIO_SPEED_100MHz;
	GPIO_Config(ILI_9341_DC_PORT, &configStruct);
	
	GPIO_ConfigStructInit(&configStruct);
	configStruct.pin = ILI_9341_CS_PIN;
	configStruct.mode = GPIO_MODE_OUT;
	configStruct.speed = GPIO_SPEED_100MHz;
	GPIO_Config(ILI_9341_CS_PORT, &configStruct);
	
	GPIO_ConfigStructInit(&configStruct);
	configStruct.pin = ILI_9341_RES_PIN;
	configStruct.mode = GPIO_MODE_OUT;
	configStruct.speed = GPIO_SPEED_100MHz;
	GPIO_Config(ILI_9341_RES_PORT, &configStruct);

	GPIO_ConfigStructInit(&configStruct);
	configStruct.pin = ILI_9341_BLK_PIN;
	configStruct.mode = GPIO_MODE_OUT;
	configStruct.speed = GPIO_SPEED_100MHz;
	GPIO_Config(ILI_9341_BLK_PORT, &configStruct);
}

static void LCD_Init(void)
{
    Lcd_pin_init();

    LCD_RESET();        /* LCD Hardware Reset */
    LCD_WR_REG(0x11);   /* Sleep out */
		SysTick_Delay_ms(120);
    _ili9341_init();    /* IlI9341 init */
    LCD_BLK_CLR;        /* Open Backlight */
    LCD_direction(USE_DIRECTION);
}


void spi_lcd_init(void)
{
    LCD_Init();
}

static uint16_t color_array[] =
{
    WHITE, BLACK, BLUE, BRED,
    GRED, GBLUE, RED, YELLOW
};

void lcd_spi_test(void)
{
    uint8_t index = 0;
    for (index = 0; index < sizeof(color_array) / sizeof(color_array[0]); index++)
    {
        LCD_Clear(color_array[index]);
        
        SysTick_Delay_ms(200);
    }
}

void lcd_draw_point(uint16_t x, uint16_t y, uint32_t color)
{
		LCD_SetCursor(x, y); 
		LCD_WriteRAM_Prepare();
		LCD_WriteData_16Bit(color);
}

void lcd_show_char(uint16_t x, uint16_t y, char chr, uint8_t size, uint8_t mode, uint16_t color)
{
    uint8_t temp, t1, t;
    uint16_t y0 = y;
    uint8_t csize = 0;
    uint8_t *pfont = 0;

    csize = (size / 8 + ((size % 8) ? 1 : 0)) * (size / 2); 
    chr = chr - ' ';    

    switch (size)
    {
        case 12:
            pfont = (uint8_t *)asc2_1206[chr];  
            break;

        case 16:
            pfont = (uint8_t *)asc2_1608[chr];  
            break;

        case 24:
            pfont = (uint8_t *)asc2_2412[chr];  
            break;

        case 32:
            pfont = (uint8_t *)asc2_3216[chr];  
            break;

        default:
            return ;
    }

    for (t = 0; t < csize; t++)
    {
        temp = pfont[t];                             

        for (t1 = 0; t1 < 8; t1++)                   
        {
            if (temp & 0x80)                         
            {
                lcd_draw_point(x, y, color);        
            }
            else if (mode == 0)                     
            {
                lcd_draw_point(x, y, g_back_color);  
            }

            temp <<= 1;                              
            y++;

            if (y >= lcddev.height)return;          

            if ((y - y0) == size)                    
            {
                y = y0;  
                x++;     

                if (x >= lcddev.width)
                {
                    return;        
                }

                break;
            }
        }
    }
}

void lcd_show_string(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint8_t size, char *p, uint16_t color)
{
    uint8_t x0 = x;
    
    width += x;
    height += y;

    while ((*p <= '~') && (*p >= ' '))   
    {
        if (x >= width)
        {
            x = x0;
            y += size;
        }

        if (y >= height)
        {
            break;      
        }

        lcd_show_char(x, y, *p, size, 0, color);
        x += size / 2;
        p++;
    }
}

 

2.3、main.c

#include "main.h"
#include "Board.h"

int main(void)
{
	uint8_t i=0;
	SysTick_Init();
	init_led();
	init_usart();
  init_can();
	init_spi();
	spi_lcd_init();
	led2_off();
	led3_on();
	lcd_spi_test();
	
	g_point_color = RED;

	lcd_show_string(10, 40, 240, 32, 32, "APM32F407IGT", RED);
	lcd_show_string(10, 80, 240, 24, 24, "LCD TEST", RED);
	lcd_show_string(10, 110, 240, 16, 16, "https://bbs.eeworld.com.cn/", RED);

    while (1)
    {
			led2_tog();
			SysTick_Delay_ms(100);
    }
}

 

三、程序运行

下载程序后、程序运行

200

 

 

 

最新回复

跟着楼主学习 SPI方式驱动TFTLCD显示屏   详情 回复 发表于 2023-7-2 09:28
点赞 关注
 
 

回复
举报

1708

帖子

0

TA的资源

五彩晶圆(初级)

沙发
 

跟着楼主学习 SPI方式驱动TFTLCD显示屏

 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表