|
|
求助各位大佬们:
程序折腾一个星期了,下面这段源码在8H单片机上驱动ILI9225G,调试显示通过后,移植到8051U单片机上,高低不显示,只亮屏。屏是同一块屏,单片机硬件也没问题,用逻辑分析仪也看过波形没问题,就是不显示或显示不正常。
AI也问了几个,至今还是未能解决,恳求大佬们给掌掌眼,指点指点。
下面是部分关键程序:
//================================ILI9225.c======================================
#include "ILI9225.h"
#include "font.h"
#include <intrins.h>
void Delay1ms(void){ //@33.000MHz //适用于8H, 8051U(8位)
unsigned char data i, j;
i = 43;
j = 217;
do
{
while (--j);
} while (--i);
}
void delay_ms(unsigned int ms){
while (ms--)
{
Delay1ms();
}
}
// ------------------------- 底层写操作 ---------------------------
// 写命令
void ILI9225_WriteCmd(unsigned char cmd){
TFT_RS = 0; // 命令模式
TFT_DATAH = cmd; // 写入数据
_nop_();
TFT_RW = 0; // 写操作 WR 拉低(i8080 写有效)
_nop_(); _nop_(); _nop_(); // 建立时间
TFT_RW = 1; // 写结束
_nop_();
}
// 写数据
void ILI9225_WriteData(unsigned char dat){
TFT_RS = 1; // 数据模式
TFT_DATAH = dat; // 写入数据
_nop_();
TFT_RW = 0; // 写操作
_nop_(); _nop_(); _nop_(); // 建立时间
TFT_RW = 1; // 写结束
_nop_();
}
// 写16位数据(ILI9225使用16位数据,先写高8位再写低8位)
void ILI9225_WriteData16(unsigned int dat)
{
ILI9225_WriteData((unsigned char)(dat >> 8)); // 高8位
ILI9225_WriteData((unsigned char)(dat & 0xFF)); // 低8位
}
// 写寄存器(1个命令+16位参数)
void ILI9225_WriteReg(unsigned char reg, unsigned int val)
{
ILI9225_WriteCmd(reg);
ILI9225_WriteData16(val);
}
// 初始化ILI9225G(8位并口、i8080模式)
void ILI9225_Init(void)
{
// 硬件复位
TFT_RST = 1;
delay_ms(100);
TFT_RST = 0;
delay_ms(150);
TFT_RST = 1;
delay_ms(50);
// --- 2. 电源控制设置 (Power Control) ---
// 先关闭各电源模块,准备逐步上电
ILI9225_WriteReg(0x10, 0x0000); // POWER_CTRL1: SAP, DSTB, STB
ILI9225_WriteReg(0x11, 0x0000); // POWER_CTRL2: DC1, DC0
ILI9225_WriteReg(0x12, 0x0000); // POWER_CTRL3: VRH (GVDD)
ILI9225_WriteReg(0x13, 0x0000); // POWER_CTRL4: VC (VCI)
ILI9225_WriteReg(0x14, 0x0000); // POWER_CTRL5: VCOMH/VCOML
delay_ms(100); // 等待电源稳定
// 逐步配置电源模块
ILI9225_WriteReg (0x11, 0x1038); // Set APON,PON,AON,VCI1EN,VC
ILI9225_WriteReg (0x12, 0x200E); // Set BT,DC1,DC2,DC3
ILI9225_WriteReg (0x13, 0x0052); // Set GVDD
ILI9225_WriteReg (0x14, 0x3961); // Set VCOMH/VCOML voltage
ILI9225_WriteReg (0x10, 0x0000); // Set SAP,DSTB,STB
delay_ms(50); // Delay 30 ms
// --- 3. 显示与接口控制 ---
ILI9225_WriteReg(0x02, 0x0300); // 驱动模式: 0x0000 - 帧反转 / 0x0100 - 行反转 / 0x0200 - 列反转 / 0x0300 - 点反转驱动模式
#if USE_HORIZONTAL//如果定义了横屏
//R01H:SM=0,GS=0,SS=0 (for details,See the datasheet of ILI9225)
ILI9225_WriteReg(0x01, 0x001C); // set the display line number and display direction
//R03H:BGR=1,ID0=1,ID1=1,AM=1 (for details,See the datasheet of ILI9225)
ILI9225_WriteReg(0x03, 0x1038); // set GRAM write direction .
#else//竖屏
//R01H:SM=0,GS=0,SS=1 (for details,See the datasheet of ILI9225)
ILI9225_WriteReg(0x01, 0x011C); // set the display line number and display direction
//R03H:BGR=1,ID0=1,ID1=1,AM=0 (for details,See the datasheet of ILI9225)
ILI9225_WriteReg(0x03, 0x1030); // set GRAM write direction.
#endif
ILI9225_WriteReg(0x07, 0x0000); // Display off
ILI9225_WriteReg(0x08, 0x0808); // Blank Period Control: 消隐期控制
ILI9225_WriteReg(0x0B, 0x1100); // Frame Cycle Control: 帧周期控制
ILI9225_WriteReg(0x0C, 0x0000); // Interface Control: 接口控制
ILI9225_WriteReg(0x0F, 0x0501); // OSC Control: 振荡器控制,决定帧率
ILI9225_WriteReg(0x15, 0x0020); // Set VCI recycling
ILI9225_WriteReg(0x20, 0x0000); // RAM Address Set 1: 行地址
ILI9225_WriteReg(0x21, 0x0000); // RAM Address Set 2: 列地址
ILI9225_WriteReg(0x30, 0x0000); // Gate Scan Control: 栅极扫描控制
ILI9225_WriteReg(0x31, 0x00DB); // Vertical Scroll Control 1: 垂直滚动
ILI9225_WriteReg(0x32, 0x0000); // Vertical Scroll Control 2
ILI9225_WriteReg(0x33, 0x0000); // Vertical Scroll Control 3
ILI9225_WriteReg(0x34, 0x00DB); // Partial Driving Position 1: 局部驱动
ILI9225_WriteReg(0x35, 0x0000); // Partial Driving Position 2
ILI9225_WriteReg(0x36, 0x00AF); // Horizontal Window Address 1: 水平窗口
ILI9225_WriteReg(0x37, 0x0000); // Horizontal Window Address 2
ILI9225_WriteReg(0x38, 0x00DB); // Vertical Window Address 1: 垂直窗口
ILI9225_WriteReg(0x39, 0x0000); // Vertical Window Address 2
// --- 5. 伽马校准 (Gamma Calibration) ---
ILI9225_WriteReg(0x50, 0x0603);
ILI9225_WriteReg(0x51, 0x080D);
ILI9225_WriteReg(0x52, 0x0D0C);
ILI9225_WriteReg(0x53, 0x0205);
ILI9225_WriteReg(0x54, 0x040A);
ILI9225_WriteReg(0x55, 0x0703);
ILI9225_WriteReg(0x56, 0x0300);
ILI9225_WriteReg(0x57, 0x0400);
ILI9225_WriteReg(0x58, 0x0B00);
ILI9225_WriteReg(0x59, 0x0017);
ILI9225_WriteReg(0x0F, 0x0701);
ILI9225_WriteReg(0x07, 0x0012); // Display Control: 开启显示
delay_ms(100);
// --- 6. 开启显示 ---
ILI9225_WriteReg(0x07, 0x1017); // Display Control: 开启显示
delay_ms(50);
// 背光开启
TFT_LED = 1;
}
// 设置显示窗口(坐标范围)
void ILI9225_SetWindow(unsigned char XStart, unsigned char YStart, unsigned char XEnd, unsigned char YEnd)
{
#if USE_HORIZONTAL//横屏
ILI9225_WriteReg(0x38, XEnd);
ILI9225_WriteReg(0x39, XStart);
ILI9225_WriteReg(0x36, YEnd);
ILI9225_WriteReg(0x37, YStart);
ILI9225_WriteReg(0x21, XStart);
ILI9225_WriteReg(0x20, YStart);
#else //竖屏
ILI9225_WriteReg(0x36, XEnd);
ILI9225_WriteReg(0x37, XStart);
ILI9225_WriteReg(0x38, YEnd);
ILI9225_WriteReg(0x39, YStart);
ILI9225_WriteReg(0x20, XStart);
ILI9225_WriteReg(0x21, YStart);
#endif
// 写入内存
ILI9225_WriteCmd(0x22); // 写显存命令
}
// 绘制单个像素 通过设置一个 1×1 的窗口来绘制单点,效率较低但简单可靠。
void ILI9225_DrawPixel(unsigned int x, unsigned int y, unsigned int color)
{
ILI9225_SetWindow(x, y, x, y);//设置光标位置
ILI9225_WriteData16(color);
}
// 填充屏幕 --- 全屏填充颜色函数(清屏)
void ILI9225_FillScreen(unsigned int color){
unsigned long i;
unsigned long total;
ILI9225_SetWindow(0, 0, X_MAX_PIXEL - 1, Y_MAX_PIXEL - 1);
total = (unsigned long)X_MAX_PIXEL * Y_MAX_PIXEL;
for(i = 0; i < total; i++)
{
ILI9225_WriteData16(color);
}
}
//================================ILI9225.h======================================
#ifndef _ILI9225_H_
#define _ILI9225_H_
#include <ai8051u.h> // Ai8051U 头文件
//#include <STC8H.h>
//=================== 引脚定义 ===================
sbit TFT_RW = P4^1; // 读写控制(低电平写,高电平读,此处只用于写)
sbit TFT_RS = P4^6; // 寄存器/数据选择(0=命令,1=数据)
sbit TFT_RST = P4^5; // 复位引脚(低电平复位)
sbit TFT_LED = P4^0; // 背光控制(高电平开)
// TFT_CS 物理置低,TFT_RD 物理置高(8位并口只写不读)
//sbit TFT_RW = P4^1; // 读写控制(低电平写,高电平读,此处只用于写)
//sbit TFT_RS = P4^2; // 寄存器/数据选择(0=命令,1=数据)
//sbit TFT_RST = P4^3; // 复位引脚(低电平复位)
//sbit TFT_LED = P4^4; // 背光控制(高电平开)
#define TFT_DATAH P2 // 8位数据总线(高8位,低8位未使用,因为仅8位模式)
//=================== 屏幕尺寸 ===================
#define TFT_WIDTH 176 // 横屏宽度
#define TFT_HEIGHT 220 // 横屏高度
#define USE_HORIZONTAL 1 //使用横屏 1:使用 0:不使用.
#if USE_HORIZONTAL //如果定义了横屏
#define X_MAX_PIXEL TFT_HEIGHT
#define Y_MAX_PIXEL TFT_WIDTH
#else
#define X_MAX_PIXEL X_MAX_PIXEL
#define Y_MAX_PIXEL TFT_HEIGHT
#endif
//=================== 常用颜色 ===================
#define BLACK 0x0000
#define WHITE 0xFFFF
#define RED 0xF800
#define GREEN 0x07E0
#define BLUE 0x001F
#define YELLOW 0xFFE0
#define CYAN 0x07FF
#define MAGENTA 0xF81F
#define GRAY 0x8410
#define ORANGE 0xFD20
#define LIGHTGREEN 0X841F //浅绿色
#define LGRAY 0XC618 //浅灰色(PANNEL),窗体背景色
#define LGRAYBLUE 0XA651 //浅灰蓝色(中间层颜色)
#define LBBLUE 0X2B12 //浅棕蓝色(选择条目的反色)
//=================== 函数声明 ===================
void ILI9225_Init(void);
void ILI9225_SetWindow(unsigned char XStart, unsigned char YStart, unsigned char XEnd, unsigned char YEnd);
void ILI9225_DrawPixel(unsigned int x, unsigned int y, unsigned int color);
void ILI9225_FillScreen(unsigned int color);
void ILI9225_FillRect(unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2, unsigned int color);
void ILI9225_DrawChar(unsigned int x, unsigned int y, unsigned char ch, unsigned int fg, unsigned int bg,unsigned char sizey,unsigned char mode);
void ILI9225_DrawString(unsigned int x, unsigned int y, const char *str, unsigned int fg, unsigned int bg,unsigned char sizey,unsigned char mode);
void ILI9225_ShowIntNum(unsigned int x, unsigned int y, unsigned int num, unsigned char len, unsigned int fg, unsigned int bg, unsigned char sizey);
void ILI9225_ShowFloatNum1(unsigned int x, unsigned int y, float num, unsigned char len, unsigned int fg, unsigned int bg, unsigned char sizey);
void ILI9225_DrawLine(unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2, unsigned int color);
void ILI9225_DrawRectangle(unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2, unsigned int color);
void delay_ms(unsigned int ms);
#endif
//================================main.c======================================
#include <math.h>
#include "ILI9225.h"
#include <intrins.h>
// 端口初始化
void GPIO_Init(void)
{
P0M0 = 0xbc; P0M1 = 0x03; // P0.0、1:高阻输入;P0.6:准双向口;P0.2、3、4、5、7: 推挽输出(驱动三极管, 需要足够驱动能力)
P1M0 = 0xfe; P1M1 = 0x01; // P1.0置为高阻抗;P1.1234567置为推换口
// P2M0 = 0xFF; P2M1 = 0x00; // P2推挽 (屏幕数据线)
P3M0 = 0x00; P3M1 = 0x00; // 准双向口(弱上拉, 用于按键检测)
// P4M0 = 0x01; P4M1 = 0x00; // P4.0推挽输出;其余为准双向口
// P4M0 = 0x63; P4M1 = 0x00; //推挽输出
P2M0 = 0x00; P2M1 = 0x00; //
P4M0 = 0x00; P4M1 = 0x00; //
}
// ===================================================================
// 主函数
// ===================================================================
void main(void) {
GPIO_Init(); // GPIO初始化
// Ai8051U 系统初始化
// P_SW2 |= 0x80; // 允许访问扩展的特殊寄存器 XFR
// WTST = 0; // 设置取程序代码等待时间,0表示不等待
// CKCON = 0; // 设置访问片内 xdata 速度,0为最快
// // 启动外部晶振==========================================================
// XOSCCR = 0xc0; // 启动外部晶振 (ENXOSC=1, XITYPE=1, GAIN=0, XCFILTER=00)
// while (!(XOSCCR & 1)); // 等待时钟稳定 (查询XOSCST标志位)
// CLKDIV = 0x00; // 时钟不分频
// CLKSEL = 0x01; // 选择外部晶振作为系统时钟
// //=========================================================================
ILI9225_Init();
while(1) {
ILI9225_FillScreen(BLACK);
ILI9225_DrawChar(93, 144,'A', GREEN, BLACK, 32, 0); //显示一个字符
ILI9225_DrawString(10, 10, "Hello AI8051U!",RED, WHITE,16,0);
ILI9225_DrawString(10, 30, "12345 +-*/", YELLOW, BLACK,16,0);
ILI9225_DrawString(30, 60, "ABCDefg", GREEN, BLACK, 32, 0); //显示字符串
ILI9225_ShowIntNum(30, 90, 65467, 5, GREEN, BLACK, 16); //显示整数变量
ILI9225_ShowFloatNum1(30, 120, 3.14159, 4, GREEN, BLACK, 16); //显示两位小数变量
delay_ms(3000);
// 填充矩形
ILI9225_FillRect(100, 78, 120, 98, YELLOW);
ILI9225_DrawLine(100, 78, 120, 98, RED);
delay_ms(2000);
ILI9225_FillScreen(RED); // RGB565 纯红
delay_ms(1000);
ILI9225_DrawPixel(100, 100, WHITE); // 画点示例
ILI9225_DrawLine(10, 78, 200, 98, WHITE);
delay_ms(2000);
TFT_LED = 0;//背光闪烁测试时间
delay_ms(500);
TFT_LED = 1;
delay_ms(500);
TFT_LED = 0;
delay_ms(500);
TFT_LED = 1;
ILI9225_FillScreen(BLACK);
delay_ms(2000);
ILI9225_DrawRectangle(0, 0, 219, 175, RED);
delay_ms(100);
ILI9225_DrawRectangle(2, 2, 217, 173, MAGENTA);
delay_ms(100);
ILI9225_DrawRectangle(4, 4, 215, 171, ORANGE);
delay_ms(100);
ILI9225_DrawRectangle(8, 8, 211, 167, YELLOW);
delay_ms(100);
ILI9225_DrawRectangle(12, 12, 207, 163, WHITE);
delay_ms(2000);
}
}
|
|