仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
- #include <reg52.h>
- #include <intrins.h>
- /* ========== 引脚定义(按接线修改) ========== */
- sbit TFT_CS = P1^0; // 片选(低有效)
- sbit TFT_DC = P1^1; // 数据/命令:1=数据 0=命令
- sbit TFT_RST = P1^2; // 复位(低有效)
- sbit TFT_SCK = P1^3; // SPI时钟
- sbit TFT_MOSI = P1^4; // SPI主出从入(DIN)
- /* ========== 公用延时 ========== */
- static void tiny_delay(void) { _nop_(); _nop_(); _nop_(); _nop_(); }
- void delay_ms(unsigned int ms){
- unsigned int i,j;
- for(i=0;i<ms;i++) for(j=0;j<125;j++);
- }
- /* ========== SPI位打发送 ========== */
- static void spi_write8(unsigned char v){
- unsigned char i;
- for(i=0;i<8;i++){
- TFT_SCK = 0;
- TFT_MOSI = (v & 0x80) ? 1 : 0; // 发送高位
- tiny_delay();
- TFT_SCK = 1; // 上升沿采样
- tiny_delay();
- v <<= 1;
- }
- TFT_SCK = 0;
- }
- /* ========== ILI9341 基本写接口 ========== */
- static void tft_write_cmd(unsigned char cmd){
- TFT_CS = 0;
- TFT_DC = 0; // 命令
- spi_write8(cmd);
- TFT_CS = 1;
- }
- static void tft_write_data8(unsigned char dato){
- TFT_CS = 0;
- TFT_DC = 1; // 数据
- spi_write8(dato);
- TFT_CS = 1;
- }
- static void tft_write_data16(unsigned int dato){
- TFT_CS = 0;
- TFT_DC = 1;
- spi_write8((unsigned char)(dato >> 8)); // 高字节
- spi_write8((unsigned char)(dato & 0xFF));// 低字节
- TFT_CS = 1;
- }
- /* 连续写数据流(提升效率) */
- static void tft_begin_stream(void){
- TFT_CS = 0;
- TFT_DC = 1;
- }
- static void tft_stream_data16(unsigned int dato){
- spi_write8((unsigned char)(dato >> 8));
- spi_write8((unsigned char)(dato & 0xFF));
- }
- static void tft_end_stream(void){
- TFT_CS = 1;
- }
- /* ========== 参数与颜色 ========== */
- #define TFT_W 240
- #define TFT_H 320
- /* RGB888→RGB565 */
- #define RGB565(r,g,b) ( ((r&0xF8)<<8) | ((g&0xFC)<<3) | ((b)>>3) )
- /* 常用色 */
- #define COLOR_BLACK 0x0000
- #define COLOR_WHITE 0xFFFF
- #define COLOR_RED 0xF800
- #define COLOR_GREEN 0x07E0
- #define COLOR_BLUE 0x001F
- #define COLOR_YELLOW 0xFFE0
- #define COLOR_CYAN 0x07FF
- #define COLOR_MAGENTA 0xF81F
- #define COLOR_GRAY 0x8410
- /* ========== 设置窗口 & 基础绘图 ========== */
- static void tft_set_window(unsigned int x0, unsigned int y0, unsigned int x1, unsigned int y1){
- // Column Address Set
- tft_write_cmd(0x2A);
- tft_write_data8(x0 >> 8); tft_write_data8(x0 & 0xFF);
- tft_write_data8(x1 >> 8); tft_write_data8(x1 & 0xFF);
- // Page Address Set
- tft_write_cmd(0x2B);
- tft_write_data8(y0 >> 8); tft_write_data8(y0 & 0xFF);
- tft_write_data8(y1 >> 8); tft_write_data8(y1 & 0xFF);
- // Memory Write
- tft_write_cmd(0x2C);
- }
- void tft_draw_pixel(unsigned int x, unsigned int y, unsigned int color){
- if(x>=TFT_W || y>=TFT_H) return;
- tft_set_window(x, y, x, y);
- tft_write_data16(color);
- }
- void tft_fill_rect(unsigned int x, unsigned int y, unsigned int w, unsigned int h, unsigned int color){
- unsigned long count;
- unsigned int i;
- if(x>=TFT_W || y>=TFT_H) return;
- if(x+w-1 >= TFT_W) w = TFT_W - x;
- if(y+h-1 >= TFT_H) h = TFT_H - y;
- tft_set_window(x, y, x+w-1, y+h-1);
- count = (unsigned long)w * h;
- tft_begin_stream();
- while(count--) tft_stream_data16(color);
- tft_end_stream();
- }
- void tft_fill_screen(unsigned int color){
- tft_fill_rect(0, 0, TFT_W, TFT_H, color);
- }
- /* 画线(Bresenham) */
- void tft_draw_line(int x0,int y0,int x1,int y1,unsigned int color){
- int dx = (x1>x0) ? (x1-x0) : (x0-x1);
- int sx = (x0<x1) ? 1 : -1;
- int dy = (y1>y0) ? (y0-y1) : (y1-y0);
- int sy = (y0<y1) ? 1 : -1;
- int err = dx + dy, e2;
- for(;;){
- tft_draw_pixel(x0,y0,color);
- if(x0==x1 && y0==y1) break;
- e2 = 2*err;
- if(e2 >= dy){ err += dy; x0 += sx; }
- if(e2 <= dx){ err += dx; y0 += sy; }
- }
- }
- /* 画矩形(边框) */
- void tft_draw_rect(unsigned int x, unsigned int y, unsigned int w, unsigned int h, unsigned int color){
- if(w==0 || h==0) return;
- tft_draw_line(x, y, x+w-1, y, color);
- tft_draw_line(x, y+h-1, x+w-1, y+h-1, color);
- tft_draw_line(x, y, x, y+h-1, color);
- tft_draw_line(x+w-1, y, x+w-1, y+h-1, color);
- }
- /* ========== ILI9341 初始化(常用序列) ========== */
- void tft_reset(void){
- TFT_RST = 1; TFT_CS = 1; TFT_SCK = 0; TFT_MOSI = 0;
- delay_ms(5);
- TFT_RST = 0; delay_ms(20);
- TFT_RST = 1; delay_ms(120);
- }
- void tft_init(void){
- tft_reset();
- // ILI9341 init (通用稳定序列)
- tft_write_cmd(0xEF); tft_write_data8(0x03); tft_write_data8(0x80); tft_write_data8(0x02);
- tft_write_cmd(0xCF); tft_write_data8(0x00); tft_write_data8(0xC1); tft_write_data8(0x30);
- tft_write_cmd(0xED); tft_write_data8(0x64); tft_write_data8(0x03); tft_write_data8(0x12); tft_write_data8(0x81);
- tft_write_cmd(0xE8); tft_write_data8(0x85); tft_write_data8(0x00); tft_write_data8(0x78);
- tft_write_cmd(0xCB); tft_write_data8(0x39); tft_write_data8(0x2C); tft_write_data8(0x00); tft_write_data8(0x34); tft_write_data8(0x02);
- tft_write_cmd(0xF7); tft_write_data8(0x20);
- tft_write_cmd(0xEA); tft_write_data8(0x00); tft_write_data8(0x00);
- tft_write_cmd(0xC0); tft_write_data8(0x23); // Power control VRH[5:0]
- tft_write_cmd(0xC1); tft_write_data8(0x10); // Power control SAP[2:0];BT[3:0]
- tft_write_cmd(0xC5); tft_write_data8(0x3E); tft_write_data8(0x28); // VCM
- tft_write_cmd(0xC7); tft_write_data8(0x86); // VCM control2
- // 内存访问控制:0x48 竖屏,BGR=1;如需横屏可改 0x28/0xE8 等
- tft_write_cmd(0x36); tft_write_data8(0x48);
- // 像素格式:16bpp RGB565
- tft_write_cmd(0x3A); tft_write_data8(0x55);
- tft_write_cmd(0xB1); tft_write_data8(0x00); tft_write_data8(0x18); // Frame rate
- tft_write_cmd(0xB6); tft_write_data8(0x08); tft_write_data8(0x82); tft_write_data8(0x27); // Display Function
- tft_write_cmd(0xF2); tft_write_data8(0x00); // 3Gamma off
- tft_write_cmd(0x26); tft_write_data8(0x01); // Gamma curve
- // Gamma设置(可按需调整)
- tft_write_cmd(0xE0);
- tft_write_data8(0x0F); tft_write_data8(0x31); tft_write_data8(0x2B); tft_write_data8(0x0C);
- tft_write_data8(0x0E); tft_write_data8(0x08); tft_write_data8(0x4E); tft_write_data8(0xF1);
- tft_write_data8(0x37); tft_write_data8(0x07); tft_write_data8(0x10); tft_write_data8(0x03);
- tft_write_data8(0x0E); tft_write_data8(0x09); tft_write_data8(0x00);
- tft_write_cmd(0xE1);
- tft_write_data8(0x00); tft_write_data8(0x0E); tft_write_data8(0x14); tft_write_data8(0x03);
- tft_write_data8(0x11); tft_write_data8(0x07); tft_write_data8(0x31); tft_write_data8(0xC1);
- tft_write_data8(0x48); tft_write_data8(0x08); tft_write_data8(0x0F); tft_write_data8(0x0C);
- tft_write_data8(0x31); tft_write_data8(0x36); tft_write_data8(0x0F);
- // 退出睡眠、开显示
- tft_write_cmd(0x11); delay_ms(120);
- tft_write_cmd(0x29); delay_ms(20);
- tft_fill_screen(COLOR_BLACK);
- }
- /* ========== 6×8 点阵字体(精简版) ========== */
- /* 说明:为控制篇幅,此处提供数字'0'~'9'、大写'A'~'Z'、空格及符号".:-/"等
- 未覆盖字符显示为空白。你可按需扩展完整ASCII表。 */
- typedef struct { char ch; unsigned char cols[6]; } glyph_t;
- unsigned char code GLYPH_SPACE[6] = {0,0,0,0,0,0};
- const glyph_t code font6x8[] = {
- {' ',{0,0,0,0,0,0}},
- {'0',{0x3E,0x51,0x49,0x45,0x3E,0x00}},
- {'1',{0x00,0x42,0x7F,0x40,0x00,0x00}},
- {'2',{0x62,0x51,0x49,0x49,0x46,0x00}},
- {'/',{0x40,0x30,0x0C,0x03,0x00,0x00}}
- };
- #define FONT_COUNT (sizeof(font6x8)/sizeof(font6x8[0]))
- /* 查找字模;未找到返回空白 */
- static const unsigned char* font_lookup(char ch){
- unsigned char i;
- for(i=0;i<FONT_COUNT;i++){
- if(font6x8[i].ch == ch) return font6x8[i].cols;
- }
- return GLYPH_SPACE;
- }
- /* 在(x,y)绘制6×8字符(前景/背景色),左上为起点 */
- void tft_draw_char6x8(unsigned int x, unsigned int y, char ch, unsigned int fg, unsigned int bg){
- unsigned char col, row;
- const unsigned char* p = font_lookup(ch);
- if(x+6 > TFT_W || y+8 > TFT_H) return;
- tft_set_window(x, y, x+5, y+7);
- tft_write_cmd(0x2C); // RAMWR
- tft_begin_stream();
- for(row=0; row<8; row++){
- for(col=0; col<6; col++){
- if( (p[col] >> row) & 0x01 ) tft_stream_data16(fg);
- else tft_stream_data16(bg);
- }
- }
- tft_end_stream();
- }
- /* 打印字符串,等宽间隔=6像素 */
- void tft_print6x8(unsigned int x, unsigned int y, const char* s, unsigned int fg, unsigned int bg){
- unsigned int cx = x;
- while(*s){
- if(*s=='\n'){ y += 8; cx = x; s++; continue; }
- tft_draw_char6x8(cx, y, *s, fg, bg);
- cx += 6;
- s++;
- if(cx+6 > TFT_W){ y+=8; cx = x; }
- if(y+8 > TFT_H) break;
- }
- }
- /* ========== 示例:主程序 ========== */
- void main(void){
- unsigned int i;
- tft_init();
- // 彩条测试
- tft_fill_rect(0, 0, TFT_W, 40, COLOR_RED);
- tft_fill_rect(0, 40, TFT_W, 40, COLOR_GREEN);
- tft_fill_rect(0, 80, TFT_W, 40, COLOR_BLUE);
- tft_fill_rect(0, 120, TFT_W, 40, COLOR_CYAN);
- tft_fill_rect(0, 160, TFT_W, 40, COLOR_MAGENTA);
- tft_fill_rect(0, 200, TFT_W, 40, COLOR_YELLOW);
- tft_fill_rect(0, 240, TFT_W, 40, COLOR_GRAY);
- tft_fill_rect(0, 280, TFT_W, 40, COLOR_WHITE);
- // 文本与图形
- tft_print6x8(10, 10, "TFT LCD ILI9341", COLOR_WHITE, COLOR_RED);
- tft_print6x8(10, 26, "SPI 4-WIRE DEMO", COLOR_WHITE, COLOR_GREEN);
- tft_print6x8(10, 42, "RES 240x320", COLOR_WHITE, COLOR_BLUE);
- tft_draw_rect(20, 100, 200, 120, COLOR_WHITE);
- for(i=0;i<50;i++){
- tft_draw_line(20,100+i, 219,100+119-i, COLOR_WHITE);
- }
- // 简单计数刷新(避开全屏,以免过慢)
- {
- unsigned int cnt = 0;
- char buf[20];
- while(1){
- // 覆盖区域清背景
- tft_fill_rect(20, 230, 200, 16, COLOR_BLACK);
- // 构造字符串(只用到数字/大写)
- buf[0]='C';buf[1]='N';buf[2]='T';buf[3]=':';buf[4]=' '; // "CNT:
复制代码 仿真程序下载:
TFT9341_SPI.rar
(133.21 KB, 下载次数: 0)
|