GitHub项目下载链接:点我下载
硬件平台:stm32f103rct和1.44寸128x128 TFT屏(st7735驱动)
IDE:keil MDK
一些可能的问题:
1、首先为了驱动一款TFT屏,理所应当的应该知道屏幕的驱动芯片,比如我们这次使用的TFT屏就是ST7735R的驱动芯片,所以理所应当的要查找芯片手册,ST7735的芯片手册上网查也是一大堆,这个不赘述。
当然,一款驱动芯片不止能驱动一种分辨率,我们使用的就是128x128的屏幕,但这款驱动芯片最低支持132x132的屏幕,这会导致绘图时画面偏移,从芯片手册中可以了解到 ↓↓↓↓↓↓↓
2、ST7735有非常多的命令,对于一个 初学者来说不可能全部看完,所以在初始化代码中会有非常多的命令和参数初始化,我们一般直接使用网上各路前辈的初始化代码(因为实在太多了XD)。
BLK:背光控制
RS:就是芯片手册中的 DC(数据与命令)
RST:复位
CS:片选(低电平选中)
SC:接SCLK
DI:接MOSI
GND:地
VCC:最好接3.3v
贴代码:
tft_144.h:
#ifndef _TFT_144_H_
#define _TFT_144_H_
#include "stm32f10x_conf.h"
#include
/* parameters */
#define WIDTH 128
#define LENGTH 128
/* pins definitions */
#define LA0 GPIO_Pin_6 // GPIOC
#define LSDI GPIO_Pin_15 // GPIOB
#define LSCL GPIO_Pin_13 // GPIOB
#define LCS GPIO_Pin_12 // GPIOB
#define LA0_SET() GPIOC->BSRR = 1<<6
#define LA0_CLR() GPIOC->BRR = 1<<6
#define LCS_SET() GPIOB->BSRR = 1<<12
#define LCS_CLR() GPIOB->BRR = 1<<12
/* functions */
void TFT_GPIO ( void ); // TFT的GPIO初始化
void TFT_MEM ( void ); // 显存的分配
void TFT_INIT ( void ); // TFT初始化
#define LCMD 0 // 命令
#define LDAT 1 // 数据
void writeCmdData ( unsigned char Byte, unsigned char opt );
#define RED 0xf800
#define GREEN 0x07e0
#define BLUE 0x001f
#define YELLOW 0xffe0
#define BLACK 0x0000
#define WHITE 0xffff
void setPos( int sx, int ex, int sy, int ey ); // 设置绘图区域
void write2Byte( unsigned int twoByte ); // 写两个字节,因为color数据是16位
void writeAnColor( unsigned int color ); // 填充全屏
#endif
tft_144.c:
#include "tft_144.h"
unsigned short int* LCD_MEM;
void TFT_GPIO ( void ) {
SPI_InitTypeDef MYSPI;
GPIO_InitTypeDef TFTIO;
//时钟使能
RCC_APB1PeriphClockCmd( RCC_APB1Periph_SPI2, ENABLE );
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE );
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC, ENABLE );
//SPI配置
MYSPI.SPI_Mode = SPI_Mode_Master;
MYSPI.SPI_CPOL = SPI_CPOL_High;
MYSPI.SPI_CPHA = SPI_CPHA_2Edge;
MYSPI.SPI_FirstBit = SPI_FirstBit_MSB;
MYSPI.SPI_DataSize = SPI_DataSize_8b;
MYSPI.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;
MYSPI.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
MYSPI.SPI_NSS = SPI_NSS_Soft;
SPI_Init( SPI2, &MYSPI );
SPI_Cmd( SPI2, ENABLE );
//引脚配置
TFTIO.GPIO_Mode = GPIO_Mode_Out_PP;
TFTIO.GPIO_Speed = GPIO_Speed_50MHz;
TFTIO.GPIO_Pin = LA0;
GPIO_Init( GPIOC, &TFTIO );
TFTIO.GPIO_Mode = GPIO_Mode_AF_PP;
TFTIO.GPIO_Speed = GPIO_Speed_50MHz;
TFTIO.GPIO_Pin = LSDI|LSCL|LCS;
GPIO_Init( GPIOB, &TFTIO );
}
/* assemble the video memory */
void TFT_MEM ( void ) {
LCD_MEM = (unsigned short int*)\
malloc( sizeof(unsigned short int)*( WIDTH*LENGTH ) );
}
void TFT_INIT ( void ) {
TFT_GPIO();
//TFT_MEM();
//以下的初始化代码复制粘贴即可,不用深究
writeCmdData(0x28, LCMD);
writeCmdData(0x11, LCMD);//Sleep exit
//ST7735R Frame Rate
writeCmdData(0xB1, LCMD);
writeCmdData(0x01, LDAT);
writeCmdData(0x2C, LDAT);
writeCmdData(0x2D, LDAT);
writeCmdData(0xB2, LCMD);
writeCmdData(0x01, LDAT);
writeCmdData(0x2C, LDAT);
writeCmdData(0x2D, LDAT);
writeCmdData(0xB3, LCMD);
writeCmdData(0x01, LDAT);
writeCmdData(0x2C, LDAT);
writeCmdData(0x2D, LDAT);
writeCmdData(0x01, LDAT);
writeCmdData(0x2C, LDAT);
writeCmdData(0x2D, LDAT);
writeCmdData(0xB4, LCMD); //Column inversion
writeCmdData(0x07, LDAT);
//ST7735R Power Sequence
writeCmdData(0xC0, LCMD);
writeCmdData(0xA2, LDAT);
writeCmdData(0x02, LDAT);
writeCmdData(0x84, LDAT);
writeCmdData(0xC1, LCMD);
writeCmdData(0xC5, LDAT);
writeCmdData(0xC2, LCMD);
writeCmdData(0x0A, LDAT);
writeCmdData(0x00, LDAT);
writeCmdData(0xC3, LCMD);
writeCmdData(0x8A, LDAT);
writeCmdData(0x2A, LDAT);
writeCmdData(0xC4, LCMD);
writeCmdData(0x8A, LDAT);
writeCmdData(0xEE, LDAT);
writeCmdData(0xC5, LCMD); //VCOM
writeCmdData(0x0E, LDAT);
writeCmdData(0x36, LCMD); //MX, MY, RGB mode
writeCmdData(0xC8, LDAT); //竖屏C8 横屏08 A8
//ST7735R Gamma Sequence
writeCmdData(0xe0, LCMD);
writeCmdData(0x0f, LDAT);
writeCmdData(0x1a, LDAT);
writeCmdData(0x0f, LDAT);
writeCmdData(0x18, LDAT);
writeCmdData(0x2f, LDAT);
writeCmdData(0x28, LDAT);
writeCmdData(0x20, LDAT);
writeCmdData(0x22, LDAT);
writeCmdData(0x1f, LDAT);
writeCmdData(0x1b, LDAT);
writeCmdData(0x23, LDAT);
writeCmdData(0x37, LDAT);
writeCmdData(0x00, LDAT);
writeCmdData(0x07, LDAT);
writeCmdData(0x02, LDAT);
writeCmdData(0x10, LDAT);
writeCmdData(0xe1, LCMD);
writeCmdData(0x0f, LDAT);
writeCmdData(0x1b, LDAT);
writeCmdData(0x0f, LDAT);
writeCmdData(0x17, LDAT);
writeCmdData(0x33, LDAT);
writeCmdData(0x2c, LDAT);
writeCmdData(0x29, LDAT);
writeCmdData(0x2e, LDAT);
writeCmdData(0x30, LDAT);
writeCmdData(0x30, LDAT);
writeCmdData(0x39, LDAT);
writeCmdData(0x3f, LDAT);
writeCmdData(0x00, LDAT);
writeCmdData(0x07, LDAT);
writeCmdData(0x03, LDAT);
writeCmdData(0x10, LDAT);
writeCmdData(0xF0, LCMD); //Enable test command
writeCmdData(0x01, LDAT);
writeCmdData(0xF6, LCMD); //Disable ram power save mode
writeCmdData(0x00, LDAT);
writeCmdData(0x3A, LCMD); //65k mode
writeCmdData(0x05, LDAT);
writeCmdData(0x29, LCMD);//Display on
writeAnColor( YELLOW );
}
void writeCmdData ( unsigned char Byte, unsigned char opt ) {
//根据opt设置传入的是数据还是命令
if ( opt == LCMD ) {
LA0_CLR();
} else if ( opt == LDAT ) {
LA0_SET();
}
LCS_CLR(); //低电平使能
SPI_I2S_SendData( SPI2, Byte );
while( !( (SPI2->SR)&(SPI_I2S_FLAG_TXE) ) );
LCS_SET(); //取消片选
}
void setPos( int sx, int ex, int sy, int ey ) {
// X轴
// 注意这里的“sx+2”,就是之前所说的偏移问题的解决方法
writeCmdData( 0x2a, LCMD );
writeCmdData( 0x00, LDAT );
writeCmdData( sx+2, LDAT );
writeCmdData( 0x00, LDAT );
writeCmdData( ex+2, LDAT );
// Y轴
writeCmdData( 0x2b, LCMD );
writeCmdData( 0x00, LDAT );
writeCmdData( sy+3, LDAT );
writeCmdData( 0x00, LDAT );
writeCmdData( ey+3, LDAT );
// 很重要!最后的写入命令
writeCmdData( 0x2c, LCMD );
}
void write2Byte( unsigned int twoByte ) {
// 根据芯片手册可知先传输高8位,后传输低8位,总共16位
writeCmdData( twoByte>>8, LDAT );
writeCmdData( twoByte, LDAT );
}
void writeAnColor( unsigned int color ) {
unsigned char x = 0;
unsigned char y = 0;
setPos( 0, 127, 0, 127 );
for ( y = 0; y < LENGTH; y++ ) {
for ( x = 0; x < WIDTH; x++ ) {
write2Byte( color );
}
}
}
main.c
#include
#include "stm32f10x_conf.h"
/* User's inc */
#include "tft_144.h"
int main () {
TFT_INIT();
while ( 1 );
}