TraSH/sim/simple/driver/Driver_tftspi.c

630 lines
11 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
******************************************************************************
*
* TFT 1.14寸显示屏驱动文件目前使用SPI
*
* 版本修订:
* 修改时间 版本号 修改内容
* 2022-12-07 v1.0 开始构建本文件;
*
* Create 2016年09月09日
* Update 2022年12月07日
* Author dengchow
*
******************************************************************************
***/
#include "Driver_tftspi.h"
#define LCD_MODE 2
// 0 // 竖屏
// 1
// 2 // 横屏
// 3
uint16_t POINT_COLOR = 0x0000;//画笔颜色
uint16_t BACK_COLOR = 0xFFFF;//背景色
_TFTCmdTypeStruct TFTCmd;//管理LCD重要参数
/**
* @brief :模拟SPI发送数据
* @note :--
* @param :dat待发送的数据
* @return :void
*
* @data :2023/01/21
* @design :
**/
static void _spi_write_data(uint8_t dat)
{
#ifdef LCD_SPI_SOFT
for (uint8_t i=0; i<8; i++)
{
LCD_SCL_L;
if (dat & 0x80) {
LCD_SDA_H;
} else {
LCD_SDA_L;
}
LCD_SCL_H;
dat <<= 1;
}
#endif
}
/**
* @brief :写寄存器地址
* @note :--
* @param :reg, 寄存器地址
* @return :void
*
* @data :2017/03/04
* @design :
**/
void TFT_WR_REG(uint16_t reg)
{
TFT_DC_CMD();
_spi_write_data(reg);
TFT_DC_DATA();
}
/**
* @brief :写数据
* @note :--使用此函数前先调用TFT_WR_REG(),即写寄存器函数!
* @param :dat, 要写入的值
* @return :void
*
* @data :2017/03/04
* @design :
**/
void TFT_WR_DATA8(uint8_t dat)
{
_spi_write_data(dat);
}
void TFT_WR_DATA(uint16_t dat)
{
_spi_write_data(dat>>8);
_spi_write_data(dat);
}
/**
* @brief :读数据
* @note :--读数据前先写寄存器地址!
* @param :void
* @return :uint16_t, 读到的值
*
* @data :2017/03/04
* @design :
**/
uint16_t TFT_RD_DATA(void)
{
return BACK_COLOR; // NO USED!
}
/**
* @brief :选择lcd设备
* @note :--
* @param :idx, lcd序号
en, 1选中/0未选中
* @return :void
*
* @data :2017/03/04
* @design :
**/
void TFT_Select(uint8_t idx, uint8_t en)
{
if (0 == en)
{
switch (idx)
{
case 0: LCD_CS0_DIS; break;
default: {
LCD_CS0_DIS;
break;
}
}
} else {
switch (idx)
{
case 0: LCD_CS0_EN; break;
default: {
LCD_CS0_EN;
break;
}
}
}
}
/**
* @brief :向寄存器写数据
* @note :--
* @param :reg, 寄存器地址
dat, 要写入的值
* @return :void
*
* @data :2017/03/04
* @design :
**/
void TFT_WriteReg(uint16_t reg, uint16_t dat)
{
TFT_WR_REG(reg);
TFT_WR_DATA(dat);
}
/**
* @brief :从寄存器读数据
* @note :--
* @param :Reg, 寄存器地址
* @return :uint16_t, 读到的数据
*
* @data :2017/03/04
* @design :
**/
uint16_t TFT_ReadReg(uint16_t reg)
{
return 0xFFFF; // NO USED!
}
/**
* @brief :开始写GRAM
* @note :--
* @param :void
* @return :void
*
* @data :2017/03/04
* @design :
**/
void TFT_StartWriteRAM(void)
{
TFT_WR_REG(0x2C);
}
/**
* @brief :写GRAM
* @note :--
* @param :color, 颜色值
* @return :void
*
* @data :2017/03/04
* @design :
**/
void TFT_WriteRAM(uint16_t color)
{
TFT_WR_DATA(color);
}
/**
* @brief :tft开启显示
* @note :
* @param :void
* @return :void
*
* @data :2017/03/04
* @design :
**/
void TFT_DisplayOn(void)
{
// NO USED!
}
/**
* @brief :tft关闭显示
* @note :--
* @param :void
* @return :void
*
* @data :2017/03/04
* @design :
**/
void TFT_DisplayOff(void)
{
// NO USED!
}
/**
* @brief :设置光标位置
* @note :--
* @param :X1, 横坐标(0~TFTCmd.width)
Y1, 纵坐标(0~TFTCmd.height)
X2, 横坐标(0~TFTCmd.width)
Y3, 纵坐标(0~TFTCmd.height)
* @return :void
*
* @data :2017/03/04
* @design :
**/
void TFT_SetCursor(uint16_t X1, uint16_t Y1, uint16_t X2, uint16_t Y2)
{
#if (LCD_MODE == 0)
const uint16_t _k_x_base = 52;
const uint16_t _k_y_base = 40;
#endif
#if (LCD_MODE == 1)
const uint16_t _k_x_base = 53;
const uint16_t _k_y_base = 40;
#endif
#if (LCD_MODE == 2)
const uint16_t _k_x_base = 40;
const uint16_t _k_y_base = 53;
#endif
#if (LCD_MODE == 3)
const uint16_t _k_x_base = 40;
const uint16_t _k_y_base = 52;
#endif
TFT_WR_REG(0x2A); //列地址设置
TFT_WR_DATA(X1+_k_x_base);
TFT_WR_DATA(X2+_k_x_base);
TFT_WR_REG(0x2B); //行地址设置
TFT_WR_DATA(Y1+_k_y_base);
TFT_WR_DATA(Y2+_k_y_base);
}
/**
* @brief :设置tft的自动扫描方向
* @note :--ILI9341的其他函数可能会受到此函数设置的影响所以一般设置为L2R_U2D
--针对ILI9341进行修改修复无法横屏的bug
--设置ILI9341默认为RGB格式
* @param :direct, 扫描方向(_TFTScanDir枚举类型中定义)
* @return :void
*
* @data :2018/01/24
* @design :
**/
void TFT_SetScanDir(_TFTScanDir direct)
{
// NO USED!
}
/**
* @brief :设置tft显示方向
* @note :--
* @param :direct, 显示方向(_TFTDispDir枚举类型定义)
* @return :void
*
* @data :2017/03/04
* @design :
**/
void TFT_SetDisplayDir(_TFTDispDir direct)
{
if(direct == DISP_PORTRAIT)//竖屏
{
TFTCmd.dir = DISP_PORTRAIT;
TFTCmd.width = CFG_LCD_Y_SIZE;
TFTCmd.height = CFG_LCD_X_SIZE;
}else{//横屏
TFTCmd.dir = DISP_HORIZON;
TFTCmd.width = CFG_LCD_X_SIZE;
TFTCmd.height = CFG_LCD_Y_SIZE;
}
TFTCmd.wramcmd = 0; // NO USED!
TFTCmd.setxcmd = 0; // NO USED!
TFTCmd.setycmd = 0; // NO USED!
}
/**
* @brief :设置tft窗口大小
* @note :--窗体大小width*height
* @param :XS , 窗口起始横坐标
YS , 窗口起始纵坐标
width , 窗口宽度,必须大于0!
height, 窗口高度,必须大于0!
* @return :void
*
* @data :2017/03/04
* @design :
**/
void TFT_SetWindowSize(uint16_t XS, uint16_t YS, uint16_t width, uint16_t height)
{
// NO USED!
}
/**
* @brief :tft初始化设置
* @note :--
* @param :void
* @return :void
*
* @data :2017/03/04
* @design :
**/
void TFT_InitConfig(void)
{
TFT_BACK_LED_CLOSE();
TFT_Select(0xff, 1); // SELECT ALL DEVICE!
TFT_RST_HIGH();
delay_ms(1);
TFT_RST_LOW();
delay_ms(10);
TFT_RST_HIGH();
delay_ms(120);
TFT_WR_REG(0x36);
#if (LCD_MODE == 0)
TFT_WR_DATA8(0x00);
#endif
#if (LCD_MODE == 1)
TFT_WR_DATA8(0xC0);
#endif
#if (LCD_MODE == 2)
TFT_WR_DATA8(0x70);
#endif
#if (LCD_MODE == 3)
TFT_WR_DATA8(0xA0);
#endif
TFT_WR_REG(0x3A);
TFT_WR_DATA8(0x05);
TFT_WR_REG(0xB2);
TFT_WR_DATA8(0x0C);
TFT_WR_DATA8(0x0C);
TFT_WR_DATA8(0x00);
TFT_WR_DATA8(0x33);
TFT_WR_DATA8(0x33);
TFT_WR_REG(0xB7);
TFT_WR_DATA8(0x35);
TFT_WR_REG(0xBB);
TFT_WR_DATA8(0x19);
TFT_WR_REG(0xC0);
TFT_WR_DATA8(0x2C);
TFT_WR_REG(0xC2);
TFT_WR_DATA8(0x01);
TFT_WR_REG(0xC3);
TFT_WR_DATA8(0x12);
TFT_WR_REG(0xC4);
TFT_WR_DATA8(0x20);
TFT_WR_REG(0xC6);
TFT_WR_DATA8(0x0F);
TFT_WR_REG(0xD0);
TFT_WR_DATA8(0xA4);
TFT_WR_DATA8(0xA1);
TFT_WR_REG(0xE0);
TFT_WR_DATA8(0xD0);
TFT_WR_DATA8(0x04);
TFT_WR_DATA8(0x0D);
TFT_WR_DATA8(0x11);
TFT_WR_DATA8(0x13);
TFT_WR_DATA8(0x2B);
TFT_WR_DATA8(0x3F);
TFT_WR_DATA8(0x54);
TFT_WR_DATA8(0x4C);
TFT_WR_DATA8(0x18);
TFT_WR_DATA8(0x0D);
TFT_WR_DATA8(0x0B);
TFT_WR_DATA8(0x1F);
TFT_WR_DATA8(0x23);
TFT_WR_REG(0xE1);
TFT_WR_DATA8(0xD0);
TFT_WR_DATA8(0x04);
TFT_WR_DATA8(0x0C);
TFT_WR_DATA8(0x11);
TFT_WR_DATA8(0x13);
TFT_WR_DATA8(0x2C);
TFT_WR_DATA8(0x3F);
TFT_WR_DATA8(0x44);
TFT_WR_DATA8(0x51);
TFT_WR_DATA8(0x2F);
TFT_WR_DATA8(0x1F);
TFT_WR_DATA8(0x1F);
TFT_WR_DATA8(0x20);
TFT_WR_DATA8(0x23);
TFT_WR_REG(0x21);
TFT_SetDisplayDir(DISP_HORIZON);
TFT_SetWindowSize(0, 0, TFTCmd.width, TFTCmd.height);
TFT_WR_REG(0x11);
delay_ms(120);
TFT_WR_REG(0x29);
TFT_WR_REG(0x2C);
TFT_ClearScreen(WHITE);
TFT_Select(0xff, 0); // UNSELECT ALL DEVICE!
TFT_BACK_LED_OPEN();
}
/**
* @brief :tft清屏
* @note :--以特定的颜色填充整块屏幕!
* @param :color, 要清屏的填充色
* @return :void
*
* @data :2017/03/04
* @design :
**/
void TFT_ClearScreen(uint16_t color)
{
TFT_FillSingleColor(0, 0, TFTCmd.width, TFTCmd.height, color);
}
/**
* @brief :特殊延时
* @note :--当mdk -O1时间优化时需要设置一般不涉及
* @param :t, 特殊延时
* @return :void
*
* @data :2017/03/04
* @design :
**/
//static void opt_delay(uint32_t t)
//{
// while(t--);
//}
/**
* @brief :tft读点
* @note :--
* @param :X, 横坐标(0~TFTCmd.width)
Y, 纵坐标(0~TFTCmd.height)
* @return :uint16_t, RGB格式的颜色值
*
* @data :2017/03/04
* @design :
**/
uint16_t TFT_ReadPoint(uint16_t X, uint16_t Y)
{
return BACK_COLOR; // NO USED!
}
/**
* @brief :tft画点
* @note :--
* @param :X , 横坐标(0~TFTCmd.width)
Y , 纵坐标(0~TFTCmd.height)
color, 颜色(取自调色板定义的颜色或者其他颜色!)
* @return :void
*
* @data :2017/03/04
* @design :
**/
void TFT_DrawPoint(uint16_t X, uint16_t Y, uint16_t color)
{
if ((X >= TFTCmd.width) || (Y >= TFTCmd.height))
return;
TFT_SetCursor(X, Y, X, Y);
TFT_StartWriteRAM();
TFT_WR_DATA(color);
}
/**
* @brief :tft快速画点
* @note :--本函数需要Driver_tft.c支持
* @param :X , 横坐标(0~TFTCmd.width)
Y , 纵坐标(0~TFTCmd.height)
color, 颜色
* @return :void
*
* @data :2017/03/04
* @design :
**/
void TFT_FastDrawPoint(uint16_t X, uint16_t Y, uint16_t color)
{
TFT_DrawPoint(X, Y, color);
}
/**
* @brief :在指定区域内填充单个颜色
* @note :--填充矩形区域,大小为:(XE-XS)*(YE-YS)
* @param :XS , 起点横坐标
YS , 起点纵坐标
XE , 终点横坐标
YE , 终点纵坐标
Color, 要填充的颜色
* @return :void
*
* @data :2017/03/04
* @design :
**/
void TFT_FillSingleColor(uint16_t XS, uint16_t YS, uint16_t XE, uint16_t YE, uint16_t color)
{
uint16_t height, width;
width = XE - XS;
height = YE - YS;
TFT_SetCursor(XS, YS, XE-1, YE-1);
TFT_StartWriteRAM();
for (uint16_t i=0; i<width*height; i++ ) {
TFT_WR_DATA(color);
}
}
/**
* @brief :在指定区域内填充指定颜色块
* @note :--填充矩形区域,大小为:(XE-XS)*(YE-YS)
* @param :XS , 起点横坐标
YS , 起点纵坐标
XE , 终点横坐标
YE , 终点纵坐标
*color, 要填充的颜色
* @return :void
*
* @data :2017/03/04
* @design :
**/
void TFT_FillBlockColor(uint16_t XS, uint16_t YS, uint16_t XE, uint16_t YE, uint16_t *color)
{
uint16_t height, width;
width = XE - XS;
height = YE - YS;
TFT_SetCursor(XS, YS, XE-1, YE-1);
TFT_StartWriteRAM();
for (uint16_t i=0; i<width*height; i++ ) {
TFT_WR_DATA(color[i]);
}
}
/* ******************** Copyright (C), 2017-2017, TYUT TSS-plan by SERI.LJI ******************** */