STM32G030驱动一款TFT屏,图片浏览,使用SPI + DMA + flash , 触摸按键 ucGUI , 请写相关代码
时间: 2024-05-01 19:23:43 浏览: 131
STM32 驱动TFT 横屏 移植ucGUI
5星 · 资源好评率100%
由于代码比较长,我将分为多个部分来介绍。
1. 引脚定义和初始化
首先需要定义TFT屏幕的引脚,并初始化SPI和DMA的相关配置。
```c
#define TFT_RST_PIN GPIO_Pin_0
#define TFT_DC_PIN GPIO_Pin_1
#define TFT_CS_PIN GPIO_Pin_2
#define TFT_SPI SPI1
#define TFT_DMA DMA1_Channel3
#define TFT_WIDTH 240
#define TFT_HEIGHT 320
void TFT_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = TFT_RST_PIN | TFT_DC_PIN | TFT_CS_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_SetBits(GPIOA, TFT_RST_PIN | TFT_DC_PIN | TFT_CS_PIN);
}
void TFT_SPI_Init(void)
{
SPI_InitTypeDef SPI_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
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_4;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(TFT_SPI, &SPI_InitStructure);
SPI_Cmd(TFT_SPI, ENABLE);
}
void TFT_DMA_Init(void)
{
DMA_InitTypeDef DMA_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
DMA_DeInit(TFT_DMA);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&(TFT_SPI->DR);
DMA_InitStructure.DMA_MemoryBaseAddr = 0;
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(TFT_DMA, &DMA_InitStructure);
DMA_ITConfig(TFT_DMA, DMA_IT_TC, ENABLE);
NVIC_EnableIRQ(DMA1_Channel3_IRQn);
}
```
2. TFT屏幕驱动
接下来是TFT屏幕的驱动代码,包括写命令、写数据等。
```c
void TFT_WriteCmd(uint8_t cmd)
{
GPIO_ResetBits(GPIOA, TFT_DC_PIN);
GPIO_ResetBits(GPIOA, TFT_CS_PIN);
SPI_I2S_SendData(TFT_SPI, cmd);
while (SPI_I2S_GetFlagStatus(TFT_SPI, SPI_I2S_FLAG_BSY) == SET);
GPIO_SetBits(GPIOA, TFT_CS_PIN);
}
void TFT_WriteData(uint8_t data)
{
GPIO_SetBits(GPIOA, TFT_DC_PIN);
GPIO_ResetBits(GPIOA, TFT_CS_PIN);
SPI_I2S_SendData(TFT_SPI, data);
while (SPI_I2S_GetFlagStatus(TFT_SPI, SPI_I2S_FLAG_BSY) == SET);
GPIO_SetBits(GPIOA, TFT_CS_PIN);
}
void TFT_WriteWord(uint16_t data)
{
uint8_t byte1 = (uint8_t)(data >> 8);
uint8_t byte2 = (uint8_t)(data & 0xFF);
TFT_WriteData(byte1);
TFT_WriteData(byte2);
}
void TFT_SetAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1)
{
TFT_WriteCmd(0x2A);
TFT_WriteWord(x0);
TFT_WriteWord(x1);
TFT_WriteCmd(0x2B);
TFT_WriteWord(y0);
TFT_WriteWord(y1);
TFT_WriteCmd(0x2C);
}
```
3. DMA传输
接下来是DMA传输的代码,用于将图片数据从flash中读取并传输到TFT屏幕中。
```c
void TFT_DMA_Transfer(uint16_t *data, uint32_t count)
{
DMA_Cmd(TFT_DMA, DISABLE);
while (DMA_GetFlagStatus(DMA1_FLAG_TC3) == RESET);
DMA_ClearFlag(DMA1_FLAG_TC3);
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)data;
DMA_InitStructure.DMA_BufferSize = count;
DMA_Init(TFT_DMA, &DMA_InitStructure);
DMA_Cmd(TFT_DMA, ENABLE);
}
void TFT_DMA_TransferImage(uint32_t addr)
{
uint32_t size = TFT_WIDTH * TFT_HEIGHT * 2;
uint16_t *data = (uint16_t *)addr;
for (uint32_t i = 0; i < size; i += 1024) {
TFT_DMA_Transfer(&data[i], 1024);
}
}
```
4. UC GUI
最后是使用UC GUI的代码,用于处理触摸按键和显示图片。
```c
#include "GUI.h"
#include "DIALOG.h"
#define ID_BUTTON_EXIT 1
static void _cbDialog(WM_MESSAGE * pMsg)
{
WM_HWIN hItem;
int NCode;
int Id;
switch (pMsg->MsgId) {
case WM_INIT_DIALOG:
hItem = BUTTON_CreateEx(200, 280, 40, 40, pMsg->hWin, WM_CF_SHOW, 0, ID_BUTTON_EXIT);
BUTTON_SetFont(hItem, GUI_FONT_16B_ASCII);
BUTTON_SetText(hItem, "X");
break;
case WM_NOTIFY_PARENT:
Id = WM_GetId(pMsg->hWinSrc);
NCode = pMsg->Data.v;
switch (Id) {
case ID_BUTTON_EXIT:
switch (NCode) {
case WM_NOTIFICATION_CLICKED:
GUI_EndDialog(pMsg->hWin, 0);
break;
}
break;
}
break;
default:
WM_DefaultProc(pMsg);
break;
}
}
void TFT_ShowImage(uint32_t addr)
{
GUI_Init();
WM_SetCallback(WM_HBKWIN, &WM_DefaultProc);
WM_HWIN hWin = GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), _cbDialog, 0, 0, 0);
WM_SetFocus(hWin);
TFT_SetAddrWindow(0, 0, TFT_WIDTH - 1, TFT_HEIGHT - 1);
TFT_DMA_TransferImage(addr);
while (GUI_Exec()) {
// 处理触摸按键
}
}
```
以上是整个驱动TFT屏幕的代码,其中还需要根据具体情况进行一些调整和修改。
阅读全文