帮我写stm32 标准库 TFTLCD屏幕滚动显示代码
时间: 2023-08-14 11:06:05 浏览: 184
好的,下面是一个使用STM32标准库实现TFTLCD屏幕滚动显示的示例代码,仅供参考:
```c
#include "stm32f10x.h"
#include "stm32f10x_dma.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_spi.h"
#define TFTLCD_WIDTH 240
#define TFTLCD_HEIGHT 320
#define TFTLCD_DC_PIN GPIO_Pin_2
#define TFTLCD_DC_PORT GPIOA
#define TFTLCD_CS_PIN GPIO_Pin_4
#define TFTLCD_CS_PORT GPIOA
#define TFTLCD_RST_PIN GPIO_Pin_5
#define TFTLCD_RST_PORT GPIOA
uint16_t TFTLCD_Buffer1[TFTLCD_WIDTH * TFTLCD_HEIGHT];
uint16_t TFTLCD_Buffer2[TFTLCD_WIDTH * TFTLCD_HEIGHT];
uint16_t *TFTLCD_Buffer_Read = TFTLCD_Buffer1;
uint16_t *TFTLCD_Buffer_Write = TFTLCD_Buffer2;
void TFTLCD_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
SPI_InitTypeDef SPI_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1 | RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = TFTLCD_DC_PIN | TFTLCD_CS_PIN | TFTLCD_RST_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(TFTLCD_DC_PORT, &GPIO_InitStructure);
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
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(SPI1, &SPI_InitStructure);
SPI_Cmd(SPI1, ENABLE);
}
void TFTLCD_WriteData(uint8_t data)
{
GPIO_SetBits(TFTLCD_DC_PORT, TFTLCD_DC_PIN);
GPIO_ResetBits(TFTLCD_CS_PORT, TFTLCD_CS_PIN);
SPI_I2S_SendData(SPI1, data);
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == SET);
GPIO_SetBits(TFTLCD_CS_PORT, TFTLCD_CS_PIN);
}
void TFTLCD_WriteCommand(uint8_t cmd)
{
GPIO_ResetBits(TFTLCD_DC_PORT, TFTLCD_DC_PIN);
GPIO_ResetBits(TFTLCD_CS_PORT, TFTLCD_CS_PIN);
SPI_I2S_SendData(SPI1, cmd);
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == SET);
GPIO_SetBits(TFTLCD_CS_PORT, TFTLCD_CS_PIN);
}
void TFTLCD_SetCursor(uint16_t x, uint16_t y)
{
TFTLCD_WriteCommand(0x2A);
TFTLCD_WriteData(x >> 8);
TFTLCD_WriteData(x);
TFTLCD_WriteData((x + TFTLCD_WIDTH - 1) >> 8);
TFTLCD_WriteData(x + TFTLCD_WIDTH - 1);
TFTLCD_WriteCommand(0x2B);
TFTLCD_WriteData(y >> 8);
TFTLCD_WriteData(y);
TFTLCD_WriteData((y + TFTLCD_HEIGHT - 1) >> 8);
TFTLCD_WriteData(y + TFTLCD_HEIGHT - 1);
TFTLCD_WriteCommand(0x2C);
}
void TFTLCD_FillScreen(uint16_t color)
{
uint32_t i;
TFTLCD_SetCursor(0, 0);
for (i = 0; i < TFTLCD_WIDTH * TFTLCD_HEIGHT; i++) {
TFTLCD_WriteData(color >> 8);
TFTLCD_WriteData(color);
}
}
void TFTLCD_DMA_Init(void)
{
DMA_InitTypeDef DMA_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
DMA_DeInit(DMA1_Channel3);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&SPI1->DR;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)TFTLCD_Buffer_Write;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_BufferSize = TFTLCD_WIDTH * TFTLCD_HEIGHT * 2;
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(DMA1_Channel3, &DMA_InitStructure);
DMA_ITConfig(DMA1_Channel3, DMA_IT_TC, ENABLE);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void DMA1_Channel3_IRQHandler(void)
{
DMA_ClearITPendingBit(DMA1_IT_TC3);
uint16_t *temp = TFTLCD_Buffer_Read;
TFTLCD_Buffer_Read = TFTLCD_Buffer_Write;
TFTLCD_Buffer_Write = temp;
DMA_Cmd(DMA1_Channel3, DISABLE);
DMA_SetCurrDataCounter(DMA1_Channel3, TFTLCD_WIDTH * TFTLCD_HEIGHT * 2);
DMA_Cmd(DMA1_Channel3, ENABLE);
}
void TFTLCD_ScrollDisplay(int16_t yOffset)
{
uint32_t i, j;
uint16_t *src, *dst;
if (yOffset > 0) {
src = TFTLCD_Buffer_Read + yOffset * TFTLCD_WIDTH;
dst = TFTLCD_Buffer_Read;
for (i = 0; i < TFTLCD_HEIGHT - yOffset; i++) {
for (j = 0; j < TFTLCD_WIDTH; j++) {
*dst++ = *src++;
}
}
for (i = 0; i < TFTLCD_WIDTH * yOffset; i++) {
*dst++ = 0;
}
} else if (yOffset < 0) {
yOffset = -yOffset;
src = TFTLCD_Buffer_Read;
dst = TFTLCD_Buffer_Read + yOffset * TFTLCD_WIDTH;
for (i = 0; i < TFTLCD_HEIGHT - yOffset; i++) {
for (j = 0; j < TFTLCD_WIDTH; j++) {
*dst++ = *src++;
}
}
for (i = 0; i < TFTLCD_WIDTH * yOffset; i++) {
*dst++ = 0;
}
}
}
int main(void)
{
TFTLCD_Init();
TFTLCD_DMA_Init();
TFTLCD_FillScreen(0xFFFF);
while (1) {
TFTLCD_ScrollDisplay(1);
}
}
```
这段代码使用了DMA传输和双缓冲技术,实现了TFTLCD屏幕的滚动显示。其中,TFTLCD_Buffer1和TFTLCD_Buffer2分别代表两个缓冲区,TFTLCD_Buffer_Read和TFTLCD_Buffer_Write分别指向当前显示的缓冲区和即将更新的缓冲区。在TFTLCD_ScrollDisplay函数中,根据指定的偏移量和滚动方向,将当前显示的缓冲区中的数据复制到即将更新的缓冲区中,并将TFTLCD_Buffer_Read和TFTLCD_Buffer_Write指针交换,以实现滚动显示。
阅读全文