当前位置: 首页 > news >正文

HC32F460 - SPI+DMA+TFT

文章目录

    • 一.引脚定义
    • 二.SPI+DAM配置
    • 三.在DMA发送完成中断里清除标志位
    • 四.SPI+DMA发送TFT数据函数
    • 五.TFT驱动函数与满屏刷新函数
    • 六.测试

TFT芯片:ST7789V

一.引脚定义

/* Configuration for Example */
#define SPI_MASTER_SLAVE        (SPI_MASTER)
#define SPI_BUF_LEN             (1024UL)

/* SPI definition */
#define SPI_UNIT                        (CM_SPI1)
#define SPI_CLK                         (FCG1_PERIPH_SPI1)
#define SPI_TX_EVT_SRC                  (EVT_SRC_SPI1_SPTI)
#define SPI_RX_EVT_SRC                  (EVT_SRC_SPI1_SPRI)

/* DMA definition */
#define DMA_UNIT                        (CM_DMA1)
#define DMA_CLK                         (FCG0_PERIPH_DMA1 | FCG0_PERIPH_AOS)
#define DMA_TX_CH                       (DMA_CH0)
#define DMA_TX_TRIG_CH                  (AOS_DMA1_0)
#define DMA_TX_INT_CH                   (DMA_INT_TC_CH0)
#define DMA_TX_INT_SRC                  (INT_SRC_DMA1_TC0)
#define DMA_TX_IRQ_NUM                  (INT006_IRQn)

#define DMA_RX_CH                       (DMA_CH1)
#define DMA_RX_TRIG_CH                  (AOS_DMA1_1)

/* SS = PA7 */
#define SPI_SS_PORT                     (GPIO_PORT_A)
#define SPI_SS_PIN                      (GPIO_PIN_04)
#define SPI_SS_FUNC                     (GPIO_FUNC_42)
/* SCK = PA8 */
#define SPI_SCK_PORT                    (GPIO_PORT_A)
#define SPI_SCK_PIN                     (GPIO_PIN_03)
#define SPI_SCK_FUNC                    (GPIO_FUNC_43)
/* MOSI = PB0 */
#define SPI_MOSI_PORT                   (GPIO_PORT_A)
#define SPI_MOSI_PIN                    (GPIO_PIN_01)
#define SPI_MOSI_FUNC                   (GPIO_FUNC_40)
/* MISO = PC5 */
#define SPI_MISO_PORT                   (GPIO_PORT_A)
#define SPI_MISO_PIN                    (GPIO_PIN_00)
#define SPI_MISO_FUNC                   (GPIO_FUNC_41)

二.SPI+DAM配置


/**
 * @brief  SPI configure.
 * @param  None
 * @retval None
 */
void SPI_Config(void)
{
    stc_spi_init_t stcSpiInit;
    stc_dma_init_t stcDmaInit;
    stc_irq_signin_config_t stcIrqSignConfig;
    stc_gpio_init_t stcGpioInit;

    (void)GPIO_StructInit(&stcGpioInit);
    stcGpioInit.u16PinDrv       = PIN_HIGH_DRV;
    (void)GPIO_Init(SPI_SS_PORT,   SPI_SS_PIN,   &stcGpioInit);
    (void)GPIO_Init(SPI_SCK_PORT,  SPI_SCK_PIN,  &stcGpioInit);
    (void)GPIO_Init(SPI_MOSI_PORT, SPI_MOSI_PIN, &stcGpioInit);

    /* Configure Port */
    GPIO_SetFunc(SPI_SS_PORT,   SPI_SS_PIN,   SPI_SS_FUNC);
    GPIO_SetFunc(SPI_SCK_PORT,  SPI_SCK_PIN,  SPI_SCK_FUNC);
    GPIO_SetFunc(SPI_MOSI_PORT, SPI_MOSI_PIN, SPI_MOSI_FUNC);

    /* Configuration SPI */
    FCG_Fcg1PeriphClockCmd(SPI_CLK, ENABLE);
    SPI_StructInit(&stcSpiInit);
    stcSpiInit.u32WireMode          = SPI_4_WIRE;
    stcSpiInit.u32TransMode         = SPI_FULL_DUPLEX;
    stcSpiInit.u32MasterSlave       = SPI_MASTER_SLAVE;
    stcSpiInit.u32Parity            = SPI_PARITY_INVD;
    stcSpiInit.u32SpiMode           = SPI_MD_3;
    stcSpiInit.u32BaudRatePrescaler = SPI_BR_CLK_DIV2;
    stcSpiInit.u32DataBits          = SPI_DATA_SIZE_8BIT;
    stcSpiInit.u32FirstBit          = SPI_FIRST_MSB;
    stcSpiInit.u32FrameLevel        = SPI_1_FRAME;
    (void)SPI_Init(SPI_UNIT, &stcSpiInit);

    /* DMA configuration */
    FCG_Fcg0PeriphClockCmd(DMA_CLK, ENABLE);
    (void)DMA_StructInit(&stcDmaInit);
    stcDmaInit.u32BlockSize  = 1UL;
    stcDmaInit.u32TransCount = SPI_BUF_LEN;
    stcDmaInit.u32DataWidth  = DMA_DATAWIDTH_8BIT;
    /* Configure TX */
    stcDmaInit.u32SrcAddrInc  = DMA_SRC_ADDR_INC;
    stcDmaInit.u32DestAddrInc = DMA_DEST_ADDR_FIX;
    stcDmaInit.u32SrcAddr     = (uint32_t)(&u8TxBuf[0]);
    stcDmaInit.u32DestAddr    = (uint32_t)(&SPI_UNIT->DR);
    stcDmaInit.u32IntEn       = DMA_INT_ENABLE;
    if (LL_OK != DMA_Init(DMA_UNIT, DMA_TX_CH, &stcDmaInit)) {
        for (;;) {
        }
    }
    AOS_SetTriggerEventSrc(DMA_TX_TRIG_CH, SPI_TX_EVT_SRC);
    /* DMA receive NVIC configure */
    stcIrqSignConfig.enIntSrc    = DMA_TX_INT_SRC;
    stcIrqSignConfig.enIRQn      = DMA_TX_IRQ_NUM;
    stcIrqSignConfig.pfnCallback = &DMA_TransCompleteCallback;
    (void)INTC_IrqSignIn(&stcIrqSignConfig);
    NVIC_ClearPendingIRQ(stcIrqSignConfig.enIRQn);
    NVIC_SetPriority(stcIrqSignConfig.enIRQn, DDL_IRQ_PRIO_DEFAULT);
    NVIC_EnableIRQ(stcIrqSignConfig.enIRQn);

    /* Enable DMA and channel */
    DMA_Cmd(DMA_UNIT, ENABLE);
    DMA_ChCmd(DMA_UNIT, DMA_TX_CH, ENABLE);
}

三.在DMA发送完成中断里清除标志位

static void DMA_TransCompleteCallback(void)
{
    enTxCompleteFlag = SET;
    DMA_ClearTransCompleteStatus(DMA_UNIT, DMA_TX_INT_CH);
}

四.SPI+DMA发送TFT数据函数

void TFT_SEND_BYTE(uint8_t o_data)
{
    SPI_DC_1;
    enTxCompleteFlag = RESET;
    DMA_SetSrcAddr(DMA_UNIT, DMA_TX_CH, (uint32_t)(&o_data));
    DMA_SetTransCount(DMA_UNIT, DMA_TX_CH, 1);
    DMA_ChCmd(DMA_UNIT, DMA_TX_CH, ENABLE);
    SPI_Cmd(SPI_UNIT, ENABLE);
    while (RESET == enTxCompleteFlag) {
    }
    SPI_Cmd(SPI_UNIT, DISABLE);
}
void TFT_SEND_DATA(uint8_t * o_data,uint32_t size)
{
    SPI_DC_1;
    enTxCompleteFlag = RESET;
    DMA_SetSrcAddr(DMA_UNIT, DMA_TX_CH, (uint32_t)(o_data));
    DMA_SetTransCount(DMA_UNIT, DMA_TX_CH, size);
    DMA_ChCmd(DMA_UNIT, DMA_TX_CH, ENABLE);
    SPI_Cmd(SPI_UNIT, ENABLE);
    while (RESET == enTxCompleteFlag) {
    }
    SPI_Cmd(SPI_UNIT, DISABLE);

}
void TFT_SEND_CMD(uint8_t o_command)
{
    SPI_DC_0;
    enTxCompleteFlag = RESET;
    DMA_SetSrcAddr(DMA_UNIT, DMA_TX_CH, (uint32_t)(&o_command));
    DMA_SetTransCount(DMA_UNIT, DMA_TX_CH, 1);
    DMA_ChCmd(DMA_UNIT, DMA_TX_CH, ENABLE);
    SPI_Cmd(SPI_UNIT, ENABLE);
    while (RESET == enTxCompleteFlag) {
    }
    SPI_Cmd(SPI_UNIT, DISABLE);
}

五.TFT驱动函数与满屏刷新函数

void tft_init()
{
    SPI_RST_1;
    TFT_SEND_CMD(0x01); // Software Reset
    DDL_DelayMS(1);

    TFT_SEND_CMD(0x11); // Sleep Out
    DDL_DelayMS(120);     // DELAY120ms
                        //-----------------------ST7789V Frame rate setting-----------------//
    //************************************************
    TFT_SEND_CMD(0x3A); // 65k mode
    TFT_SEND_BYTE(0x05);
    TFT_SEND_CMD(0xC5); // VCOM
    TFT_SEND_BYTE(0x1A);
    TFT_SEND_CMD(0x36); // 锟斤拷幕锟斤拷示锟斤拷锟斤拷锟斤拷锟斤拷
    TFT_SEND_BYTE(0x00);
    //-------------ST7789V Frame rate setting-----------//
    TFT_SEND_CMD(0xb2); // Porch Setting
    TFT_SEND_BYTE(0x05);
    TFT_SEND_BYTE(0x05);
    TFT_SEND_BYTE(0x00);
    TFT_SEND_BYTE(0x33);
    TFT_SEND_BYTE(0x33);

    TFT_SEND_CMD(0xb7);  // Gate Control
    TFT_SEND_BYTE(0x05); // 12.2v   -10.43v
    //--------------ST7789V Power setting---------------//
    TFT_SEND_CMD(0xBB); // VCOM
    TFT_SEND_BYTE(0x3F);

    TFT_SEND_CMD(0xC0); // Power control
    TFT_SEND_BYTE(0x2c);

    TFT_SEND_CMD(0xC2); // VDV and VRH Command Enable
    TFT_SEND_BYTE(0x01);

    TFT_SEND_CMD(0xC3);  // VRH Set
    TFT_SEND_BYTE(0x0F); // 4.3+( vcom+vcom offset+vdv)

    TFT_SEND_CMD(0xC4);  // VDV Set
    TFT_SEND_BYTE(0x20); // 0v

    TFT_SEND_CMD(0xC6);  // Frame Rate Control in Normal Mode
    TFT_SEND_BYTE(0X01); // 111Hz

    TFT_SEND_CMD(0xd0); // Power Control 1
    TFT_SEND_BYTE(0xa4);
    TFT_SEND_BYTE(0xa1);

    TFT_SEND_CMD(0xE8); // Power Control 1
    TFT_SEND_BYTE(0x03);

    TFT_SEND_CMD(0xE9); // Equalize time control
    TFT_SEND_BYTE(0x09);
    TFT_SEND_BYTE(0x09);
    TFT_SEND_BYTE(0x08);
    //---------------ST7789V gamma setting-------------//
    TFT_SEND_CMD(0xE0); // Set Gamma
    TFT_SEND_BYTE(0xD0);
    TFT_SEND_BYTE(0x05);
    TFT_SEND_BYTE(0x09);
    TFT_SEND_BYTE(0x09);
    TFT_SEND_BYTE(0x08);
    TFT_SEND_BYTE(0x14);
    TFT_SEND_BYTE(0x28);
    TFT_SEND_BYTE(0x33);
    TFT_SEND_BYTE(0x3F);
    TFT_SEND_BYTE(0x07);
    TFT_SEND_BYTE(0x13);
    TFT_SEND_BYTE(0x14);
    TFT_SEND_BYTE(0x28);
    TFT_SEND_BYTE(0x30);

    TFT_SEND_CMD(0XE1); // Set Gamma
    TFT_SEND_BYTE(0xD0);
    TFT_SEND_BYTE(0x05);
    TFT_SEND_BYTE(0x09);
    TFT_SEND_BYTE(0x09);
    TFT_SEND_BYTE(0x08);
    TFT_SEND_BYTE(0x03);
    TFT_SEND_BYTE(0x24);
    TFT_SEND_BYTE(0x32);
    TFT_SEND_BYTE(0x32);
    TFT_SEND_BYTE(0x3B);
    TFT_SEND_BYTE(0x14);
    TFT_SEND_BYTE(0x13);
    TFT_SEND_BYTE(0x28);
    TFT_SEND_BYTE(0x2F);

    TFT_SEND_CMD(0x21); //  0x21 0x20 颜色反转
    DDL_DelayMS(1);
    TFT_SEND_CMD(0x29); // 锟斤拷锟斤拷锟斤拷示
}

void tft_full(uint16_t color)
{
    TFT_SEND_CMD(0x2a);  // Column address set
    TFT_SEND_BYTE(0x00); // start column
    TFT_SEND_BYTE(0x00);
    TFT_SEND_BYTE(0x00); // end column
    TFT_SEND_BYTE(0xF0);

    TFT_SEND_CMD(0x2b);  // Row address set
    TFT_SEND_BYTE(0x00); // start row
    TFT_SEND_BYTE(0x00);
    TFT_SEND_BYTE(0x01); // end row
    TFT_SEND_BYTE(0x40);
    TFT_SEND_CMD(0x2C);                         // Memory write
    for (uint32_t i = 0; i < (320*240*2)/SPI_BUF_LEN; i++)
    {
        for (uint32_t j = 0; j < SPI_BUF_LEN;j++)
        {
            /* code */
            u8TxBuf[j] = color>>8 & 0xff;
            j++;
            u8TxBuf[j] = (uint8_t)color;
        }
        TFT_SEND_DATA((uint8_t *)u8TxBuf,SPI_BUF_LEN);
    }
}

六.测试

int32_t main(void)
{
    /* Peripheral registers write unprotected */
    LL_PERIPH_WE(EXAMPLE_PERIPH_WE);
    /* Configure BSP */
    BSP_CLK_Init();
    BSP_LED_Init();
    // BSP_KEY_Init();
    /* Configure SPI */
    SPI_Config();
    /* Peripheral registers write protected */
    LL_PERIPH_WP(EXAMPLE_PERIPH_WP);
    tft_init();
    TFT_BL_1;
    POWER_1;
    for (;;) {
        tft_full(RED);
        DDL_DelayMS(500U);
        tft_full(GREEN);
        DDL_DelayMS(500U);
        tft_full(BLUE);
        DDL_DelayMS(500U);
    }
}

完整项目:
SPI_DMA_TFT.rar


文章转载自:
http://barnyard.hdqtgc.cn
http://ablaut.hdqtgc.cn
http://certain.hdqtgc.cn
http://chrysalid.hdqtgc.cn
http://choirgirl.hdqtgc.cn
http://atingle.hdqtgc.cn
http://beatles.hdqtgc.cn
http://animate.hdqtgc.cn
http://ascomycete.hdqtgc.cn
http://beadhouse.hdqtgc.cn
http://brahmaputra.hdqtgc.cn
http://accommodative.hdqtgc.cn
http://anglian.hdqtgc.cn
http://axolotl.hdqtgc.cn
http://catchweight.hdqtgc.cn
http://apsidiole.hdqtgc.cn
http://anne.hdqtgc.cn
http://centrifugalize.hdqtgc.cn
http://aeroallergen.hdqtgc.cn
http://aoudad.hdqtgc.cn
http://chassepot.hdqtgc.cn
http://abscissa.hdqtgc.cn
http://altimeter.hdqtgc.cn
http://chemosmotic.hdqtgc.cn
http://appurtenances.hdqtgc.cn
http://broomy.hdqtgc.cn
http://aslant.hdqtgc.cn
http://assessable.hdqtgc.cn
http://acheron.hdqtgc.cn
http://argonautic.hdqtgc.cn
http://www.dtcms.com/a/110133.html

相关文章:

  • 蓝桥杯2024省赛PythonB组——日期问题
  • 【XTerminal】【树莓派】Linux系统下的函数调用编程
  • UE5 + Rider + VsCode 接入腾讯的 Puerts 脚本
  • XEOS 与 AutoMQ 推出联合方案,共筑云原生 Kafka 新生态
  • Pytorch深度学习框架60天进阶学习计划 - 第35天:模型解释性
  • C++学习笔记 | malloc calloc realloc的作用以及区别
  • AI大模型从0到1记录学习 day13
  • 【Docker 那些事儿】如何安全地停止、删除容器
  • Flutter vs React Native:跨平台移动开发框架对比
  • GPT-4o 图像生成:重新定义 AI 视觉创作边界
  • PHP基础二【变量/输出/数据类型/常量/字符串/运算符】
  • Day 3:Leetcode 比特位计数+只出现一次的数字 II
  • DDR(双倍数据率内存)在路由中扮演的角色
  • yolo格式批量修改类别
  • 【Linux篇】操作系统揭秘:进程创建、等待与终止的无缝衔接
  • 计算机控制系统:arduino呼吸灯
  • 【嵌入式学习4】特殊参数、文件IO
  • 企业管理系统的功能架构设计与实现
  • 在 C# 中,while、for 和其他循环结构
  • 纯国产系统,首款鸿蒙电脑下月发布
  • 打破界限:Android XML与Jetpack Compose深度互操作指南
  • windows下git bash安装SDKMan报错Looking for unzip...Not found
  • android 之简述屏幕分辨率、屏幕密度、屏幕最小宽度
  • HarmonyOS学习 实验七:在页面上面添加警告弹窗、自定义弹窗、选择类弹窗、文本选择弹窗、日期选择等等
  • 三个STM32时钟配置函数的区别
  • 08_DCL
  • 安装操作系统后建议做的优化工作
  • AI绘画SD中,如何保持生成人物角色脸部一致?Stable Diffusion精准控制AI人像一致性两种实用方法教程!
  • 【PCB工艺】软件是如何控制硬件的发展过程
  • 2025年华为杯广东工业大学程序设计竞赛(A最短路,生成树,G数学,最大公因数,I贪心)