#include "hdl_lcd.h" static volatile uint8_t enTxCompleteFlag = 0; lcd_dma_callback_t lcd_dma_cbs = NULL; lcd_timer_callback_t lcd_timer_cbs = NULL; static void hdl_lcd_dma_tcpl_callback(void) { enTxCompleteFlag = SET; if(lcd_dma_cbs) { lcd_dma_cbs(); } DMA_ClearTransCompleteStatus(LCD_DMA_UNIT, LCD_DMA_TX_INT_CH); } static void hdl_lcd_timer_callback(void) { if(lcd_timer_cbs) { lcd_timer_cbs(); } TMR0_ClearStatus(LCD_TIM_UINT, LCD_TIM_CH_FLAG); } void hdl_lcd_timer_config(void) { stc_tmr0_init_t stcTmr0Init; stc_irq_signin_config_t stcIrqSignConfig; LL_PERIPH_WE(LL_PERIPH_GPIO | LL_PERIPH_EFM | LL_PERIPH_FCG | LL_PERIPH_PWC_CLK_RMU | LL_PERIPH_SRAM); /* Enable timer0 and AOS clock */ FCG_Fcg2PeriphClockCmd(LCD_TIM_CLK, ENABLE); FCG_Fcg0PeriphClockCmd(FCG0_PERIPH_AOS, ENABLE); /* TIMER0 configuration */ (void)TMR0_StructInit(&stcTmr0Init); stcTmr0Init.u32ClockSrc = TMR0_CLK_SRC_INTERN_CLK; //内部时钟 stcTmr0Init.u32ClockDiv = TMR0_CLK_DIV64; //2分频 stcTmr0Init.u32Func = TMR0_FUNC_CMP; //输出比较 stcTmr0Init.u16CompareValue = (uint16_t)LCD_TIME_CMP_VALUE; (void)TMR0_Init(LCD_TIM_UINT, LCD_TIM_CH, &stcTmr0Init); hdl_delay_ms(1U); TMR0_HWStopCondCmd(LCD_TIM_UINT, LCD_TIM_CH, ENABLE); hdl_delay_ms(1U); TMR0_IntCmd(LCD_TIM_UINT, LCD_TIM_CH_INT, ENABLE); /* Interrupt configuration */ stcIrqSignConfig.enIntSrc = LCD_TIM_INT_SRC; stcIrqSignConfig.enIRQn = LCD_TIM_IRQn; stcIrqSignConfig.pfnCallback = &hdl_lcd_timer_callback; (void)INTC_IrqSignIn(&stcIrqSignConfig); NVIC_ClearPendingIRQ(stcIrqSignConfig.enIRQn); NVIC_SetPriority(stcIrqSignConfig.enIRQn, DDL_IRQ_PRIO_DEFAULT); NVIC_EnableIRQ(stcIrqSignConfig.enIRQn); TMR0_Start(LCD_TIM_UINT, LCD_TIM_CH); LL_PERIPH_WP(LL_PERIPH_EFM | LL_PERIPH_FCG | LL_PERIPH_SRAM); } void hdl_lcd_config(void) { stc_spi_init_t stcSpiInit; stc_dma_init_t stcDmaInit; stc_irq_signin_config_t stcIrqSignConfig; stc_gpio_init_t stcGpioInit; LL_PERIPH_WE(LL_PERIPH_GPIO | LL_PERIPH_EFM | LL_PERIPH_FCG | LL_PERIPH_PWC_CLK_RMU | LL_PERIPH_SRAM); /* 引脚设置 */ GPIO_SetDebugPort(GPIO_PIN_TRST,DISABLE); (void)GPIO_StructInit(&stcGpioInit); stcGpioInit.u16PinDrv = PIN_HIGH_DRV; (void)GPIO_Init(LCD_SCL_PORT, LCD_SCL_PIN, &stcGpioInit); (void)GPIO_Init(LCD_SDA_PORT, LCD_SDA_PIN, &stcGpioInit); GPIO_SetFunc(LCD_SCL_PORT, LCD_SCL_PIN, LCD_SCL_FUNC); GPIO_SetFunc(LCD_SDA_PORT, LCD_SDA_PIN, LCD_SDA_FUNC); stcGpioInit.u16PinDir = PIN_DIR_OUT; (void)GPIO_Init(LCD_RES_PORT, LCD_RES_PIN, &stcGpioInit); (void)GPIO_Init(LCD_DC_PORT, LCD_DC_PIN, &stcGpioInit); /* SPI配置 */ FCG_Fcg1PeriphClockCmd(LCD_SPI_CLK, ENABLE); SPI_StructInit(&stcSpiInit); stcSpiInit.u32WireMode = SPI_3_WIRE; stcSpiInit.u32TransMode = SPI_SEND_ONLY; stcSpiInit.u32MasterSlave = SPI_MASTER; 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(LCD_SPI_UINT, &stcSpiInit); /* DMA配置 */ FCG_Fcg0PeriphClockCmd(LCD_DMA_CLK, ENABLE); (void)DMA_StructInit(&stcDmaInit); stcDmaInit.u32BlockSize = 1UL; stcDmaInit.u32TransCount = 1; stcDmaInit.u32DataWidth = DMA_DATAWIDTH_8BIT; //数据位宽 stcDmaInit.u32SrcAddrInc = DMA_SRC_ADDR_INC; //源地址自增 stcDmaInit.u32DestAddrInc = DMA_DEST_ADDR_FIX; //目标地址固定 stcDmaInit.u32SrcAddr = (uint32_t)(0); stcDmaInit.u32DestAddr = (uint32_t)(&LCD_SPI_UINT->DR); stcDmaInit.u32IntEn = DMA_INT_ENABLE; if (LL_OK != DMA_Init(LCD_DMA_UNIT, LCD_DMA_TX_CH, &stcDmaInit)) { for (;;) { } } AOS_SetTriggerEventSrc(LCD_DMA_TX_TRIG_CH, LCD_SPI_TX_EVT_SRC); //DMA发送触发源 /* DMA 中断配置 */ DMA_TransCompleteIntCmd(LCD_DMA_UNIT, DMA_INT_BTC_CH0, DISABLE); stcIrqSignConfig.enIntSrc = LCD_DMA_TX_INT_SRC; stcIrqSignConfig.enIRQn = LCD_DMA_TX_IRQ_NUM; stcIrqSignConfig.pfnCallback = &hdl_lcd_dma_tcpl_callback; (void)INTC_IrqSignIn(&stcIrqSignConfig); NVIC_ClearPendingIRQ(stcIrqSignConfig.enIRQn); NVIC_SetPriority(stcIrqSignConfig.enIRQn, DDL_IRQ_PRIO_14); NVIC_EnableIRQ(stcIrqSignConfig.enIRQn); LL_PERIPH_WP(LL_PERIPH_EFM | LL_PERIPH_FCG | LL_PERIPH_SRAM); DMA_Cmd(LCD_DMA_UNIT, ENABLE); DMA_ChCmd(LCD_DMA_UNIT, LCD_DMA_TX_CH, ENABLE); } static void hdl_lcd_write_byte(uint8_t dat) { SPI_Cmd(LCD_SPI_UINT, ENABLE); while (RESET == SPI_GetStatus(LCD_SPI_UINT, SPI_FLAG_TX_BUF_EMPTY)){} SPI_WriteData(LCD_SPI_UINT, (uint32_t)dat); while (RESET == SPI_GetStatus(LCD_SPI_UINT, SPI_FLAG_IDLE)){} SPI_Cmd(LCD_SPI_UINT, DISABLE); } void hdl_lcd_send(uint8_t *data, uint16_t len) { LCD_DC_SET();//写数据 enTxCompleteFlag = RESET; DMA_SetSrcAddr(LCD_DMA_UNIT, LCD_DMA_TX_CH, (uint32_t)(data)); // 重新设置源地址和发送的数据 DMA_SetTransCount(LCD_DMA_UNIT, LCD_DMA_TX_CH, len); //设置传输次数,传输一次,计数器减到0停止 DMA_ChCmd(LCD_DMA_UNIT, LCD_DMA_TX_CH, ENABLE); //使能DMA1通道 SPI_Cmd(LCD_SPI_UINT, ENABLE); //使能SPI while (RESET == enTxCompleteFlag) { } SPI_Cmd(LCD_SPI_UINT, DISABLE); //失能SPI } void hdl_lcd_dma_callback_register(lcd_dma_callback_t pCBS) { if(lcd_dma_cbs == 0) { lcd_dma_cbs = pCBS; } } void hdl_lcd_timer_callback_register(lcd_timer_callback_t pCBS) { if(lcd_timer_cbs == 0) { lcd_timer_cbs = pCBS; } } /****************************************************************************** 函数说明:LCD写入数据 入口数据:dat 写入的数据 返回值: 无 ******************************************************************************/ void LCD_WR_DATA8(uint8_t dat) { LCD_DC_SET();//写数据 hdl_lcd_write_byte(dat); } /****************************************************************************** 函数说明:LCD写入数据 入口数据:dat 写入的数据 返回值: 无 ******************************************************************************/ void LCD_WR_DATA(uint16_t dat) { LCD_DC_SET();//写数据 hdl_lcd_write_byte(dat>>8); hdl_lcd_write_byte(dat); } /****************************************************************************** 函数说明:LCD写入命令 入口数据:dat 写入的命令 返回值: 无 ******************************************************************************/ void LCD_WR_REG(uint8_t dat) { LCD_DC_CLR();//写命令 hdl_lcd_write_byte(dat); } /****************************************************************************** 函数说明:设置起始和结束地址 入口数据:x1,x2 设置列的起始和结束地址 y1,y2 设置行的起始和结束地址 返回值: 无 ******************************************************************************/ void LCD_Address_Set(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2) { LCD_WR_REG(0x2a);//列地址设置 LCD_WR_DATA(x1); LCD_WR_DATA(x2); LCD_WR_REG(0x2b);//行地址设置 LCD_WR_DATA(y1); LCD_WR_DATA(y2); LCD_WR_REG(0x2c);//储存器写 } void hdl_lcd_fill(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2, uint8_t *color) { LCD_Address_Set(x1,y1,x2,y2);//设置显示范围 hdl_lcd_send(color, (x2-x1+1)*(y2-y1+1)*2); } void LCD_DrawPoint(uint16_t x,uint16_t y,uint16_t color) { LCD_Address_Set(x,y,x,y);//设置光标位置 LCD_WR_DATA(color); } void hdl_lcd_init(void) { hdl_lcd_config(); hdl_lcd_timer_config(); LCD_RES_CLR();//复位 hdl_delay_ms(100); LCD_RES_SET(); hdl_delay_ms(100); LCD_WR_REG(0xEF); LCD_WR_REG(0xEB); LCD_WR_DATA8(0x14); LCD_WR_REG(0xFE); LCD_WR_REG(0xEF); LCD_WR_REG(0xEB); LCD_WR_DATA8(0x14); LCD_WR_REG(0x84); LCD_WR_DATA8(0x40); LCD_WR_REG(0x85); LCD_WR_DATA8(0xFF); LCD_WR_REG(0x86); LCD_WR_DATA8(0xFF); LCD_WR_REG(0x87); LCD_WR_DATA8(0xFF); LCD_WR_REG(0x88); LCD_WR_DATA8(0x0A); LCD_WR_REG(0x89); LCD_WR_DATA8(0x21); LCD_WR_REG(0x8A); LCD_WR_DATA8(0x00); LCD_WR_REG(0x8B); LCD_WR_DATA8(0x80); LCD_WR_REG(0x8C); LCD_WR_DATA8(0x01); LCD_WR_REG(0x8D); LCD_WR_DATA8(0x01); LCD_WR_REG(0x8E); LCD_WR_DATA8(0xFF); LCD_WR_REG(0x8F); LCD_WR_DATA8(0xFF); LCD_WR_REG(0xB6); LCD_WR_DATA8(0x00); LCD_WR_DATA8(0x20); LCD_WR_REG(0x36); if(USE_HORIZONTAL==0)LCD_WR_DATA8(0x08); else if(USE_HORIZONTAL==1)LCD_WR_DATA8(0xC8); else if(USE_HORIZONTAL==2)LCD_WR_DATA8(0x68); else LCD_WR_DATA8(0xA8); LCD_WR_REG(0x3A); LCD_WR_DATA8(0x05); LCD_WR_REG(0x90); LCD_WR_DATA8(0x08); LCD_WR_DATA8(0x08); LCD_WR_DATA8(0x08); LCD_WR_DATA8(0x08); LCD_WR_REG(0xBD); LCD_WR_DATA8(0x06); LCD_WR_REG(0xBC); LCD_WR_DATA8(0x00); LCD_WR_REG(0xFF); LCD_WR_DATA8(0x60); LCD_WR_DATA8(0x01); LCD_WR_DATA8(0x04); LCD_WR_REG(0xC3); LCD_WR_DATA8(0x13); LCD_WR_REG(0xC4); LCD_WR_DATA8(0x13); LCD_WR_REG(0xC9); LCD_WR_DATA8(0x22); LCD_WR_REG(0xBE); LCD_WR_DATA8(0x11); LCD_WR_REG(0xE1); LCD_WR_DATA8(0x10); LCD_WR_DATA8(0x0E); LCD_WR_REG(0xDF); LCD_WR_DATA8(0x21); LCD_WR_DATA8(0x0c); LCD_WR_DATA8(0x02); LCD_WR_REG(0xF0); LCD_WR_DATA8(0x45); LCD_WR_DATA8(0x09); LCD_WR_DATA8(0x08); LCD_WR_DATA8(0x08); LCD_WR_DATA8(0x26); LCD_WR_DATA8(0x2A); LCD_WR_REG(0xF1); LCD_WR_DATA8(0x43); LCD_WR_DATA8(0x70); LCD_WR_DATA8(0x72); LCD_WR_DATA8(0x36); LCD_WR_DATA8(0x37); LCD_WR_DATA8(0x6F); LCD_WR_REG(0xF2); LCD_WR_DATA8(0x45); LCD_WR_DATA8(0x09); LCD_WR_DATA8(0x08); LCD_WR_DATA8(0x08); LCD_WR_DATA8(0x26); LCD_WR_DATA8(0x2A); LCD_WR_REG(0xF3); LCD_WR_DATA8(0x43); LCD_WR_DATA8(0x70); LCD_WR_DATA8(0x72); LCD_WR_DATA8(0x36); LCD_WR_DATA8(0x37); LCD_WR_DATA8(0x6F); LCD_WR_REG(0xED); LCD_WR_DATA8(0x1B); LCD_WR_DATA8(0x0B); LCD_WR_REG(0xAE); LCD_WR_DATA8(0x77); LCD_WR_REG(0xCD); LCD_WR_DATA8(0x63); LCD_WR_REG(0x70); LCD_WR_DATA8(0x07); LCD_WR_DATA8(0x07); LCD_WR_DATA8(0x04); LCD_WR_DATA8(0x0E); LCD_WR_DATA8(0x0F); LCD_WR_DATA8(0x09); LCD_WR_DATA8(0x07); LCD_WR_DATA8(0x08); LCD_WR_DATA8(0x03); LCD_WR_REG(0xE8); LCD_WR_DATA8(0x34); LCD_WR_REG(0x62); LCD_WR_DATA8(0x18); LCD_WR_DATA8(0x0D); LCD_WR_DATA8(0x71); LCD_WR_DATA8(0xED); LCD_WR_DATA8(0x70); LCD_WR_DATA8(0x70); LCD_WR_DATA8(0x18); LCD_WR_DATA8(0x0F); LCD_WR_DATA8(0x71); LCD_WR_DATA8(0xEF); LCD_WR_DATA8(0x70); LCD_WR_DATA8(0x70); LCD_WR_REG(0x63); LCD_WR_DATA8(0x18); LCD_WR_DATA8(0x11); LCD_WR_DATA8(0x71); LCD_WR_DATA8(0xF1); LCD_WR_DATA8(0x70); LCD_WR_DATA8(0x70); LCD_WR_DATA8(0x18); LCD_WR_DATA8(0x13); LCD_WR_DATA8(0x71); LCD_WR_DATA8(0xF3); LCD_WR_DATA8(0x70); LCD_WR_DATA8(0x70); LCD_WR_REG(0x64); LCD_WR_DATA8(0x28); LCD_WR_DATA8(0x29); LCD_WR_DATA8(0xF1); LCD_WR_DATA8(0x01); LCD_WR_DATA8(0xF1); LCD_WR_DATA8(0x00); LCD_WR_DATA8(0x07); LCD_WR_REG(0x66); LCD_WR_DATA8(0x3C); LCD_WR_DATA8(0x00); LCD_WR_DATA8(0xCD); LCD_WR_DATA8(0x67); LCD_WR_DATA8(0x45); LCD_WR_DATA8(0x45); LCD_WR_DATA8(0x10); LCD_WR_DATA8(0x00); LCD_WR_DATA8(0x00); LCD_WR_DATA8(0x00); LCD_WR_REG(0x67); LCD_WR_DATA8(0x00); LCD_WR_DATA8(0x3C); LCD_WR_DATA8(0x00); LCD_WR_DATA8(0x00); LCD_WR_DATA8(0x00); LCD_WR_DATA8(0x01); LCD_WR_DATA8(0x54); LCD_WR_DATA8(0x10); LCD_WR_DATA8(0x32); LCD_WR_DATA8(0x98); LCD_WR_REG(0x74); LCD_WR_DATA8(0x10); LCD_WR_DATA8(0x85); LCD_WR_DATA8(0x80); LCD_WR_DATA8(0x00); LCD_WR_DATA8(0x00); LCD_WR_DATA8(0x4E); LCD_WR_DATA8(0x00); LCD_WR_REG(0x98); LCD_WR_DATA8(0x3e); LCD_WR_DATA8(0x07); LCD_WR_REG(0x35); LCD_WR_REG(0x21); LCD_WR_REG(0x11); hdl_delay_ms(120); LCD_WR_REG(0x29); hdl_delay_ms(20); }