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