916|5

445

帖子

0

TA的资源

纯净的硅(初级)

楼主
 

【全能小网关|CH32V208】--4.LCD显示 [复制链接]

 
本帖最后由 dirty 于 2024-6-29 21:59 编辑

      本篇讲述使用沁恒CH32V208驱动LCD屏显示。

一.硬件准备

      准备一块SPI接口LCD屏,分辨率128*160,驱动芯片ST7735。使用主控SPI2接口,硬件连接如下:

图1:LCD连接

    LCD_BLK    -- PB9
    LCD_DC     -- PB10
    LCD_RST    -- PB11
    LCD_CS     -- PB12
    LCD_SCL    -- PB13(SPI2_SCK)   
    LCD_SDA   -- PB15(SPI2_MOSI) 

 

二.代码准备

1.引脚宏定义与初始化

#define LCD_LED_RCC       RCC_APB2Periph_GPIOB
#define LCD_LED_PORT      GPIOB
#define LCD_LED_PIN       (GPIO_Pin_9)

#define LCD_DC_RCC        RCC_APB2Periph_GPIOB
#define LCD_DC_PORT       GPIOB
#define LCD_DC_PIN        (GPIO_Pin_10)

#define LCD_RST_RCC       RCC_APB2Periph_GPIOB
#define LCD_RST_PORT      GPIOB
#define LCD_RST_PIN       (GPIO_Pin_11)

#define LCD_CS_RCC        RCC_APB2Periph_GPIOB
#define LCD_CS_PORT       GPIOB
#define LCD_CS_PIN        (GPIO_Pin_12)

/*********************************************************************
 * @fn      SPI2_Init
 * 
 * @brief   Initialize SPI2
 * 
 * @return   none
 */
void SPI2_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure = {0};
    SPI_InitTypeDef  SPI_InitStructure  = {0};

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);

    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_13;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_14;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_15;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    SPI_InitStructure.SPI_Direction         = SPI_Direction_1Line_Tx;
    SPI_InitStructure.SPI_Mode              = SPI_Mode_Master;
    SPI_InitStructure.SPI_DataSize          = SPI_DataSize_8b;
    SPI_InitStructure.SPI_CPOL              = SPI_CPOL_Low;
    SPI_InitStructure.SPI_CPHA              = SPI_CPHA_1Edge;
    SPI_InitStructure.SPI_NSS               = SPI_NSS_Soft;
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;
    SPI_InitStructure.SPI_FirstBit          = SPI_FirstBit_MSB;
    SPI_InitStructure.SPI_CRCPolynomial     = 7;
    SPI_Init(SPI2, &SPI_InitStructure);

    SPI_Cmd(SPI2, ENABLE);
}

/*********************************************************************
 * @fn      SPI2_DMA_Init
 * 
 * @brief   Initialize DMA for SPI2
 * 
 * @return  none
 */
void SPI2_DMA_Init()
{
    DMA_InitTypeDef DMA_InitStructure = {0};

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

    DMA_DeInit(SPI2_DMA_TX_CH);

    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&SPI2->DATAR;
    DMA_InitStructure.DMA_MemoryBaseAddr     = (uint32_t)NULL;
    DMA_InitStructure.DMA_DIR                = DMA_DIR_PeripheralDST;
    DMA_InitStructure.DMA_BufferSize         = 0;
    DMA_InitStructure.DMA_PeripheralInc      = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc          = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
    DMA_InitStructure.DMA_MemoryDataSize     = DMA_MemoryDataSize_Byte;
    DMA_InitStructure.DMA_Mode               = DMA_Mode_Normal;
    DMA_InitStructure.DMA_Priority           = DMA_Priority_High;
    DMA_InitStructure.DMA_M2M                = DMA_M2M_Disable;
    DMA_Init(SPI2_DMA_TX_CH, &DMA_InitStructure);

    SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, ENABLE);
}
/*********************************************************************
 * @fn      LCD_GPIOInit
 * 
 * @brief   Configuring the control gpio for the lcd screen
 * 
 * @return  none
 */
void LCD_GPIOInit(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(LCD_LED_RCC, ENABLE);
    RCC_APB2PeriphClockCmd(LCD_DC_RCC, ENABLE);
    RCC_APB2PeriphClockCmd(LCD_RST_RCC, ENABLE);
    RCC_APB2PeriphClockCmd(LCD_CS_RCC, ENABLE);

    GPIO_InitStructure.GPIO_Pin   = LCD_LED_PIN;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;
    GPIO_Init(LCD_LED_PORT, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin   = LCD_DC_PIN;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;
    GPIO_Init(LCD_DC_PORT, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin   = LCD_RST_PIN;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;
    GPIO_Init(LCD_RST_PORT, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin   = LCD_CS_PIN;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;
    GPIO_Init(LCD_CS_PORT, &GPIO_InitStructure);
}

2.LCD写命令函数

/*********************************************************************
 * @fn      SPI2_Write
 * 
 * @brief   send one byte
 * 
 * @param   data -  the data to send
 * 
 * @return  none
 */
void SPI2_Write(uint8_t data)
{
    while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET)
        ;
    SPI_I2S_SendData(SPI2, data);

    while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) == SET)
        ;
}

/*********************************************************************
 * @fn      LCD_WR_REG
 *
 * @brief   Write an 8-bit command to the LCD screen
 * 
 * @param   data - Command value to be written
 *
 * @return  none
 */
static void LCD_WR_REG(uint8_t data)
{
    LCD_CS_CLR;
    LCD_DC_CLR;
    SPI2_Write(data);
    LCD_CS_SET;
}

3.LCD写数据函数

/*********************************************************************
 * @fn      LCD_WR_DATA
 *
 * @brief   Write an 8-bit data to the LCD screen
 * 
 * @param   data - the data to write
 * 
 */
static void LCD_WR_DATA(uint8_t data)
{
    LCD_CS_CLR;
    LCD_DC_SET;
    SPI2_Write(data);
    LCD_CS_SET;
}

4.LCD设置显示方向及像素宏定义。

/* LCD Screen Definition */
#define USE_HORIZONTAL    0
#define LCD_W             (128u)//(240u)
#define LCD_H             (160u)//(320u)

/*********************************************************************
 * @fn      LCD_Init
 * 
 * @brief   Initialization LCD screen
 * 
 * @return  none
 */
void LCD_Init(void)
{

    SPI2_Init();
    SPI2_DMA_Init();
    LCD_GPIOInit();
    LCD_RESET();
    LCD_LED_SET;

    //LCD Init For 1.44Inch LCD Panel with ST7735R.
    LCD_WR_REG(0x11);//Sleep exit
    Delay_Ms(120);

#if 1
    LCD_WR_REG(0xB1);
    LCD_WR_DATA(0x00);//0x05
    LCD_WR_DATA(0x08);//0x3A
    LCD_WR_DATA(0x05);//0x3A
    LCD_WR_REG(0xB2);
    LCD_WR_DATA(0x05);
    LCD_WR_DATA(0x3A);
    LCD_WR_DATA(0x3A);
    LCD_WR_REG(0xB3);
    LCD_WR_DATA(0x05);
    LCD_WR_DATA(0x3A);
    LCD_WR_DATA(0x3A);
    LCD_WR_DATA(0x05);
    LCD_WR_DATA(0x3A);
    LCD_WR_DATA(0x3A);
    //------------------------------------End ST7735S Frame Rate-----------------------------------------//
    LCD_WR_REG(0xB4); //Dot inversion
    LCD_WR_DATA(0x03);
    //------------------------------------ST7735S Power Sequence-----------------------------------------//
    LCD_WR_REG(0xC0);
    LCD_WR_DATA(0x62);
    LCD_WR_DATA(0x02);
    LCD_WR_DATA(0x04);
    LCD_WR_REG(0xC1);
    LCD_WR_DATA(0xC0);
    LCD_WR_REG(0xC2);
    LCD_WR_DATA(0x0D);
    LCD_WR_DATA(0x00);
    LCD_WR_REG(0xC3);
    LCD_WR_DATA(0x8D);
    LCD_WR_DATA(0x6A);
    LCD_WR_REG(0xC4);
    LCD_WR_DATA(0x8D);
    LCD_WR_DATA(0xEE);
    //---------------------------------End ST7735S Power Sequence-------------------------------------//
    LCD_WR_REG(0xC5); //VCOM
    LCD_WR_DATA(0x08);//0x12
    //------------------------------------ST7735S Gamma Sequence-----------------------------------------//
    LCD_WR_REG(0xE0);
    LCD_WR_DATA(0x03);
    LCD_WR_DATA(0x1B);
    LCD_WR_DATA(0x12);
    LCD_WR_DATA(0x11);
    LCD_WR_DATA(0x3F);
    LCD_WR_DATA(0x3A);
    LCD_WR_DATA(0x32);
    LCD_WR_DATA(0x34);
    LCD_WR_DATA(0x2F);
    LCD_WR_DATA(0x2B);
    LCD_WR_DATA(0x30);
    LCD_WR_DATA(0x3A);
    LCD_WR_DATA(0x00);
    LCD_WR_DATA(0x01);
    LCD_WR_DATA(0x02);
    LCD_WR_DATA(0x05);
    LCD_WR_REG(0xE1);
    LCD_WR_DATA(0x03);
    LCD_WR_DATA(0x1B);
    LCD_WR_DATA(0x12);
    LCD_WR_DATA(0x11);
    LCD_WR_DATA(0x32);
    LCD_WR_DATA(0x2F);
    LCD_WR_DATA(0x2A);
    LCD_WR_DATA(0x2F);
    LCD_WR_DATA(0x2E);
    LCD_WR_DATA(0x2C);
    LCD_WR_DATA(0x35);
    LCD_WR_DATA(0x3F);
    LCD_WR_DATA(0x00);
    LCD_WR_DATA(0x00);
    LCD_WR_DATA(0x01);
    LCD_WR_DATA(0x05);
    //------------------------------------End ST7735S Gamma Sequence-----------------------------------------//

    LCD_WR_REG(0x3A); //65k mode
    LCD_WR_DATA(0x05);
    //LCD_WR_REG(0x36); //65k mode
    //LCD_WR_DATA(0x40);
    LCD_direction(USE_HORIZONTAL);//设置图像旋转角度
    LCD_WR_REG(0x29); //Display on
    LCD_WR_REG(0x2C);

    LCD_WR_REG(0x29);//Display on
}

5.清屏

/*********************************************************************
 * @fn      LCD_Clear
 * 
 * @brief   Full screen filled LCD screen
 * 
 * @param   Color -   Filled color
 * 
 * @return  none
 */
void LCD_Clear(uint16_t Color)
{
    unsigned int i, m;
    LCD_SetWindows(0, 0, width - 1, height - 1);
    LCD_CS_CLR;
    LCD_DC_SET;
    //LCD_WR_REG(0x2C);//add
    for (i = 0; i < height; i++)
    {
        for (m = 0; m < width; m++)
        {
            LCD_WR_DATA_16Bit(Color);
        }
    }
    LCD_CS_SET;
}

6.设置区域

/*********************************************************************
 * @fn      LCD_SetWindows
 * 
 * @brief   Setting LCD display window
 * 
 * @param   xStar -  the bebinning x coordinate of the LCD display window
 *          yStar -  the bebinning y coordinate of the LCD display window
 *          xEnd -  the endning x coordinate of the LCD display window
 *          yEnd -  the endning y coordinate of the LCD display window
 * 
 * @return  none
 */
void LCD_SetWindows(uint16_t xStar, uint16_t yStar, uint16_t xEnd, uint16_t yEnd)
{
    LCD_WR_REG(LCD_SET_X);
    LCD_WR_DATA(xStar >> 8);
    LCD_WR_DATA(0x00FF & xStar);
    LCD_WR_DATA(xEnd >> 8);
    LCD_WR_DATA(0x00FF & xEnd);

    LCD_WR_REG(LCD_SET_Y);
    LCD_WR_DATA(yStar >> 8);
    LCD_WR_DATA(0x00FF & yStar);
    LCD_WR_DATA(yEnd >> 8);
    LCD_WR_DATA(0x00FF & yEnd);
    LCD_WR_REG(LCD_MEM_WRITE);  
}

7.显示图片。使用图片取模软件Img2Lcd生成图片字模数组。

/******************************************************************************
      函数说明:显示图片
      入口数据:x,y起点坐标
                length 图片长度
                width  图片宽度
                pic[]  图片数组
      返回值:  无
******************************************************************************/
void LCD_ShowPicture(uint16_t x,uint16_t y,uint16_t length,uint16_t width,const uint8_t pic[])
{
    uint16_t i,j;
    uint32_t k=0;
    unsigned char picH,picL;
//    Lcd_SetRegion(x,y,x+length-1,y+width-1);
    LCD_SetWindows(x,y,x+length-1,y+width-1);
    for(i=0;i<length;i++)
    {
        for(j=0;j<width;j++)
        {
            picL=*(pic+k*2);  //数据低位在前
            picH=*(pic+k*2+1);
            LCD_WR_DATA_16Bit(picH<<8|picL);
            k++;
        }
    }
}

8.设计显示界面,开机刷屏红、绿、蓝,然后显示沁恒LOGO及开发板照片。

int main(void)
{
//    uint32_t addr = 0;
//    uint16_t i    = 0;

    SystemCoreClockUpdate();
    Delay_Init();
    USART_Printf_Init(115200);
    printf("SystemClk:%d\r\n", SystemCoreClock);
    //SPI_FLASH_Init();
    LCD_Init();
    printf("LCD_Init\r\n");
    LCD_Clear(LCD_RED);
    Delay_Ms(1000);
    printf("LCD_RED\r\n");

    LCD_Clear(LCD_GRED);
    Delay_Ms(1000);
    printf("LCD_GRED\r\n");

    LCD_Clear(LCD_BLUE);
    Delay_Ms(1000);
    printf("LCD_BLUE\r\n");

    LCD_ShowPicture(0,0,128,25,gImage_img_logo);
    LCD_ShowPicture(0,25,128,135,gImage_img_board);

    while (1)
    {
        Delay_Ms(2000);
//        addr = 0;
//        i    = 0;
//        while (i < 11)
//        {
//            i++;
//            LCD_drawImageWithSize(0, 0, LCD_W, LCD_H, addr);
//            addr += (LCD_W * LCD_H * COLOR_BYTE);
//        }
    }
}

 

三.测验

      编译烧录后,LCD竖屏显示红、绿、蓝,最后显示图片界面。

 

图2:LCD显示
lcd_show

 

    至此,实现LCD驱动显示。

 

CH32V208_LCD.rar

739.54 KB, 下载次数: 6

LCD驱动显示工程

最新回复

感觉LCD显示功能不是全能小网关|CH32V208的主要对象   详情 回复 发表于 2024-7-1 10:21
点赞 关注
 
 

回复
举报

6841

帖子

11

TA的资源

版主

沙发
 
看起来刷新的速度非常快呀。

点评

硬件spi,速度还是可以的  详情 回复 发表于 2024-7-16 13:42
 
 
 

回复

6773

帖子

2

TA的资源

版主

板凳
 

内部Flash是不是存不了多少图片?

点评

有些小技巧,在Link.ld文件做下配置修改  详情 回复 发表于 2024-7-16 13:41
 
 
 

回复

6060

帖子

6

TA的资源

版主

4
 

感觉LCD显示功能不是全能小网关|CH32V208的主要对象

个人签名

在爱好的道路上不断前进,在生活的迷雾中播撒光引

 
 
 

回复

445

帖子

0

TA的资源

纯净的硅(初级)

5
 
wangerxian 发表于 2024-6-30 11:44 内部Flash是不是存不了多少图片?

有些小技巧,在Link.ld文件做下配置修改

 
 
 

回复

445

帖子

0

TA的资源

纯净的硅(初级)

6
 
lugl4313820 发表于 2024-6-30 06:59 看起来刷新的速度非常快呀。

硬件spi,速度还是可以的

 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
推荐帖子
滤波器设计基础

滤波器基础设计讲义 6547 6548

我的Beaglebone学习历程

整理一下前面发的帖子,搞个总帖,方便大家交流。1.BeagleBone 硬件性能测试 _周计划https://bbs.eeworld.com.cn/thread-324885-1 ...

helper2416_tl-wn725n移植02_wpa-supplicant篇

这个工具包移植,依赖的包比较繁杂,大家注意一下,想了解他的话请参考源码主页,搞wifi的人对这个包都是很熟悉的,相当熟悉应该 ...

(动画版)处理器是如何制造的--EEWORLD大学堂

处理器是如何制造的(动画版):https://training.eeworld.com.cn/course/2209本视频解释了处理器的制作过程:把沙子变成晶圆,再 ...

分享 JLink 软件复位、Halt及运行小工具

本帖最后由 sblpp 于 2016-1-15 09:47 编辑 调试硬件时常常需要复位目标芯片,每次断电上电太麻烦,又不喜欢总打开segger的 ...

Qorvo 如何实现的5G自屏蔽技术介绍

5G 使得通信行业迎来重大变革,通信频段数量从 4G 时代开始就处于快速增长的状态,其中射频前端作为手机通信功能的核心组件,将 ...

CycloneIII的FPGA能锁死JTAG吗?

我最近拆了一个宝马的热成像相机, 里边的FPGA是ALTERA的EP3C25U256A7N。我现在想尝试逆向PCB后直接在这个FPGA上做开发,看PCB好 ...

cadence ic 设计教学

大学或公司里的cadence ic设计教学资料有有啊。

优化大功率 DC/DC 转换器的 EMC 和效率 第 2 部分

优化大功率 DC/DC 转换器的 EMC 和效率 第 2 部分 在第 1 部分中,我们讲解了如何选择正确的电容器种类、功率 ...

原创首发+电流采样模块

710153 公司电流探头不够用了,整个电流采样的用用,因为我对带宽要求不高看下低频趋势就行,电路比较简单 710154 原理图和PC ...

关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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

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

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

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