找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5|回复: 0
收起左侧

51单片机ILI9341彩屏Proteus仿真程序

[复制链接]
ID:899981 发表于 2026-4-20 10:50 | 显示全部楼层 |阅读模式
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
888888888888888888888888885.png

单片机源程序如下:
  1. #include <reg52.h>
  2. #include <intrins.h>

  3. /* ========== 引脚定义(按接线修改) ========== */
  4. sbit TFT_CS   = P1^0;   // 片选(低有效)
  5. sbit TFT_DC   = P1^1;   // 数据/命令:1=数据 0=命令
  6. sbit TFT_RST  = P1^2;   // 复位(低有效)
  7. sbit TFT_SCK  = P1^3;   // SPI时钟
  8. sbit TFT_MOSI = P1^4;   // SPI主出从入(DIN)

  9. /* ========== 公用延时 ========== */
  10. static void tiny_delay(void) { _nop_(); _nop_(); _nop_(); _nop_(); }
  11. void delay_ms(unsigned int ms){
  12.     unsigned int i,j;
  13.     for(i=0;i<ms;i++) for(j=0;j<125;j++);
  14. }

  15. /* ========== SPI位打发送 ========== */
  16. static void spi_write8(unsigned char v){
  17.     unsigned char i;
  18.     for(i=0;i<8;i++){
  19.         TFT_SCK = 0;
  20.         TFT_MOSI = (v & 0x80) ? 1 : 0;  // 发送高位
  21.         tiny_delay();
  22.         TFT_SCK = 1;                    // 上升沿采样
  23.         tiny_delay();
  24.         v <<= 1;
  25.     }
  26.     TFT_SCK = 0;
  27. }

  28. /* ========== ILI9341 基本写接口 ========== */
  29. static void tft_write_cmd(unsigned char cmd){
  30.     TFT_CS = 0;
  31.     TFT_DC = 0;           // 命令
  32.     spi_write8(cmd);
  33.     TFT_CS = 1;
  34. }

  35. static void tft_write_data8(unsigned char dato){
  36.     TFT_CS = 0;
  37.     TFT_DC = 1;           // 数据
  38.     spi_write8(dato);
  39.     TFT_CS = 1;
  40. }

  41. static void tft_write_data16(unsigned int dato){
  42.     TFT_CS = 0;
  43.     TFT_DC = 1;
  44.     spi_write8((unsigned char)(dato >> 8));  // 高字节
  45.     spi_write8((unsigned char)(dato & 0xFF));// 低字节
  46.     TFT_CS = 1;
  47. }

  48. /* 连续写数据流(提升效率) */
  49. static void tft_begin_stream(void){
  50.     TFT_CS = 0;
  51.     TFT_DC = 1;
  52. }
  53. static void tft_stream_data16(unsigned int dato){
  54.     spi_write8((unsigned char)(dato >> 8));
  55.     spi_write8((unsigned char)(dato & 0xFF));
  56. }
  57. static void tft_end_stream(void){
  58.     TFT_CS = 1;
  59. }

  60. /* ========== 参数与颜色 ========== */
  61. #define TFT_W 240
  62. #define TFT_H 320

  63. /* RGB888→RGB565 */
  64. #define RGB565(r,g,b) ( ((r&0xF8)<<8) | ((g&0xFC)<<3) | ((b)>>3) )
  65. /* 常用色 */
  66. #define COLOR_BLACK   0x0000
  67. #define COLOR_WHITE   0xFFFF
  68. #define COLOR_RED     0xF800
  69. #define COLOR_GREEN   0x07E0
  70. #define COLOR_BLUE    0x001F
  71. #define COLOR_YELLOW  0xFFE0
  72. #define COLOR_CYAN    0x07FF
  73. #define COLOR_MAGENTA 0xF81F
  74. #define COLOR_GRAY    0x8410

  75. /* ========== 设置窗口 & 基础绘图 ========== */
  76. static void tft_set_window(unsigned int x0, unsigned int y0, unsigned int x1, unsigned int y1){
  77.     // Column Address Set
  78.     tft_write_cmd(0x2A);
  79.     tft_write_data8(x0 >> 8); tft_write_data8(x0 & 0xFF);
  80.     tft_write_data8(x1 >> 8); tft_write_data8(x1 & 0xFF);
  81.     // Page Address Set
  82.     tft_write_cmd(0x2B);
  83.     tft_write_data8(y0 >> 8); tft_write_data8(y0 & 0xFF);
  84.     tft_write_data8(y1 >> 8); tft_write_data8(y1 & 0xFF);
  85.     // Memory Write
  86.     tft_write_cmd(0x2C);
  87. }

  88. void tft_draw_pixel(unsigned int x, unsigned int y, unsigned int color){
  89.     if(x>=TFT_W || y>=TFT_H) return;
  90.     tft_set_window(x, y, x, y);
  91.     tft_write_data16(color);
  92. }

  93. void tft_fill_rect(unsigned int x, unsigned int y, unsigned int w, unsigned int h, unsigned int color){
  94.     unsigned long count;
  95.     unsigned int i;
  96.     if(x>=TFT_W || y>=TFT_H) return;
  97.     if(x+w-1 >= TFT_W) w = TFT_W - x;
  98.     if(y+h-1 >= TFT_H) h = TFT_H - y;

  99.     tft_set_window(x, y, x+w-1, y+h-1);
  100.     count = (unsigned long)w * h;
  101.     tft_begin_stream();
  102.     while(count--) tft_stream_data16(color);
  103.     tft_end_stream();
  104. }

  105. void tft_fill_screen(unsigned int color){
  106.     tft_fill_rect(0, 0, TFT_W, TFT_H, color);
  107. }

  108. /* 画线(Bresenham) */
  109. void tft_draw_line(int x0,int y0,int x1,int y1,unsigned int color){
  110.     int dx = (x1>x0) ? (x1-x0) : (x0-x1);
  111.     int sx = (x0<x1) ? 1 : -1;
  112.     int dy = (y1>y0) ? (y0-y1) : (y1-y0);
  113.     int sy = (y0<y1) ? 1 : -1;
  114.     int err = dx + dy, e2;

  115.     for(;;){
  116.         tft_draw_pixel(x0,y0,color);
  117.         if(x0==x1 && y0==y1) break;
  118.         e2 = 2*err;
  119.         if(e2 >= dy){ err += dy; x0 += sx; }
  120.         if(e2 <= dx){ err += dx; y0 += sy; }
  121.     }
  122. }

  123. /* 画矩形(边框) */
  124. void tft_draw_rect(unsigned int x, unsigned int y, unsigned int w, unsigned int h, unsigned int color){
  125.     if(w==0 || h==0) return;
  126.     tft_draw_line(x, y, x+w-1, y, color);
  127.     tft_draw_line(x, y+h-1, x+w-1, y+h-1, color);
  128.     tft_draw_line(x, y, x, y+h-1, color);
  129.     tft_draw_line(x+w-1, y, x+w-1, y+h-1, color);
  130. }

  131. /* ========== ILI9341 初始化(常用序列) ========== */
  132. void tft_reset(void){
  133.     TFT_RST = 1; TFT_CS = 1; TFT_SCK = 0; TFT_MOSI = 0;
  134.     delay_ms(5);
  135.     TFT_RST = 0; delay_ms(20);
  136.     TFT_RST = 1; delay_ms(120);
  137. }

  138. void tft_init(void){
  139.     tft_reset();

  140.     // ILI9341 init (通用稳定序列)
  141.     tft_write_cmd(0xEF); tft_write_data8(0x03); tft_write_data8(0x80); tft_write_data8(0x02);
  142.     tft_write_cmd(0xCF); tft_write_data8(0x00); tft_write_data8(0xC1); tft_write_data8(0x30);
  143.     tft_write_cmd(0xED); tft_write_data8(0x64); tft_write_data8(0x03); tft_write_data8(0x12); tft_write_data8(0x81);
  144.     tft_write_cmd(0xE8); tft_write_data8(0x85); tft_write_data8(0x00); tft_write_data8(0x78);
  145.     tft_write_cmd(0xCB); tft_write_data8(0x39); tft_write_data8(0x2C); tft_write_data8(0x00); tft_write_data8(0x34); tft_write_data8(0x02);
  146.     tft_write_cmd(0xF7); tft_write_data8(0x20);
  147.     tft_write_cmd(0xEA); tft_write_data8(0x00); tft_write_data8(0x00);

  148.     tft_write_cmd(0xC0); tft_write_data8(0x23);      // Power control VRH[5:0]
  149.     tft_write_cmd(0xC1); tft_write_data8(0x10);      // Power control SAP[2:0];BT[3:0]
  150.     tft_write_cmd(0xC5); tft_write_data8(0x3E); tft_write_data8(0x28); // VCM
  151.     tft_write_cmd(0xC7); tft_write_data8(0x86);      // VCM control2

  152.     // 内存访问控制:0x48 竖屏,BGR=1;如需横屏可改 0x28/0xE8 等
  153.     tft_write_cmd(0x36); tft_write_data8(0x48);

  154.     // 像素格式:16bpp RGB565
  155.     tft_write_cmd(0x3A); tft_write_data8(0x55);

  156.     tft_write_cmd(0xB1); tft_write_data8(0x00); tft_write_data8(0x18);  // Frame rate
  157.     tft_write_cmd(0xB6); tft_write_data8(0x08); tft_write_data8(0x82); tft_write_data8(0x27); // Display Function
  158.     tft_write_cmd(0xF2); tft_write_data8(0x00);  // 3Gamma off
  159.     tft_write_cmd(0x26); tft_write_data8(0x01);  // Gamma curve

  160.     // Gamma设置(可按需调整)
  161.     tft_write_cmd(0xE0);
  162.     tft_write_data8(0x0F); tft_write_data8(0x31); tft_write_data8(0x2B); tft_write_data8(0x0C);
  163.     tft_write_data8(0x0E); tft_write_data8(0x08); tft_write_data8(0x4E); tft_write_data8(0xF1);
  164.     tft_write_data8(0x37); tft_write_data8(0x07); tft_write_data8(0x10); tft_write_data8(0x03);
  165.     tft_write_data8(0x0E); tft_write_data8(0x09); tft_write_data8(0x00);

  166.     tft_write_cmd(0xE1);
  167.     tft_write_data8(0x00); tft_write_data8(0x0E); tft_write_data8(0x14); tft_write_data8(0x03);
  168.     tft_write_data8(0x11); tft_write_data8(0x07); tft_write_data8(0x31); tft_write_data8(0xC1);
  169.     tft_write_data8(0x48); tft_write_data8(0x08); tft_write_data8(0x0F); tft_write_data8(0x0C);
  170.     tft_write_data8(0x31); tft_write_data8(0x36); tft_write_data8(0x0F);

  171.     // 退出睡眠、开显示
  172.     tft_write_cmd(0x11); delay_ms(120);
  173.     tft_write_cmd(0x29); delay_ms(20);

  174.     tft_fill_screen(COLOR_BLACK);
  175. }

  176. /* ========== 6×8 点阵字体(精简版) ========== */
  177. /* 说明:为控制篇幅,此处提供数字'0'~'9'、大写'A'~'Z'、空格及符号".:-/"等
  178.    未覆盖字符显示为空白。你可按需扩展完整ASCII表。 */
  179. typedef struct { char ch; unsigned char cols[6]; } glyph_t;
  180. unsigned char code GLYPH_SPACE[6] = {0,0,0,0,0,0};
  181. const glyph_t code font6x8[] = {
  182.     {' ',{0,0,0,0,0,0}},
  183.     {'0',{0x3E,0x51,0x49,0x45,0x3E,0x00}},
  184.     {'1',{0x00,0x42,0x7F,0x40,0x00,0x00}},
  185.     {'2',{0x62,0x51,0x49,0x49,0x46,0x00}},
  186.     {'/',{0x40,0x30,0x0C,0x03,0x00,0x00}}
  187. };
  188. #define FONT_COUNT (sizeof(font6x8)/sizeof(font6x8[0]))

  189. /* 查找字模;未找到返回空白 */
  190. static const unsigned char* font_lookup(char ch){
  191.     unsigned char i;
  192.     for(i=0;i<FONT_COUNT;i++){
  193.         if(font6x8[i].ch == ch) return font6x8[i].cols;
  194.     }
  195.     return GLYPH_SPACE;
  196. }

  197. /* 在(x,y)绘制6×8字符(前景/背景色),左上为起点 */
  198. void tft_draw_char6x8(unsigned int x, unsigned int y, char ch, unsigned int fg, unsigned int bg){
  199.     unsigned char col, row;
  200.     const unsigned char* p = font_lookup(ch);
  201.     if(x+6 > TFT_W || y+8 > TFT_H) return;

  202.     tft_set_window(x, y, x+5, y+7);
  203.     tft_write_cmd(0x2C); // RAMWR
  204.     tft_begin_stream();
  205.     for(row=0; row<8; row++){
  206.         for(col=0; col<6; col++){
  207.             if( (p[col] >> row) & 0x01 ) tft_stream_data16(fg);
  208.             else                         tft_stream_data16(bg);
  209.         }
  210.     }
  211.     tft_end_stream();
  212. }

  213. /* 打印字符串,等宽间隔=6像素 */
  214. void tft_print6x8(unsigned int x, unsigned int y, const char* s, unsigned int fg, unsigned int bg){
  215.     unsigned int cx = x;
  216.     while(*s){
  217.         if(*s=='\n'){ y += 8; cx = x; s++; continue; }
  218.         tft_draw_char6x8(cx, y, *s, fg, bg);
  219.         cx += 6;
  220.         s++;
  221.         if(cx+6 > TFT_W){ y+=8; cx = x; }
  222.         if(y+8 > TFT_H) break;
  223.     }
  224. }

  225. /* ========== 示例:主程序 ========== */
  226. void main(void){
  227.     unsigned int i;
  228.     tft_init();

  229.     // 彩条测试
  230.     tft_fill_rect(0,   0, TFT_W, 40, COLOR_RED);
  231.     tft_fill_rect(0,  40, TFT_W, 40, COLOR_GREEN);
  232.     tft_fill_rect(0,  80, TFT_W, 40, COLOR_BLUE);
  233.     tft_fill_rect(0, 120, TFT_W, 40, COLOR_CYAN);
  234.     tft_fill_rect(0, 160, TFT_W, 40, COLOR_MAGENTA);
  235.     tft_fill_rect(0, 200, TFT_W, 40, COLOR_YELLOW);
  236.     tft_fill_rect(0, 240, TFT_W, 40, COLOR_GRAY);
  237.     tft_fill_rect(0, 280, TFT_W, 40, COLOR_WHITE);

  238.     // 文本与图形
  239.     tft_print6x8(10, 10,  "TFT LCD ILI9341", COLOR_WHITE, COLOR_RED);
  240.     tft_print6x8(10, 26,  "SPI 4-WIRE DEMO", COLOR_WHITE, COLOR_GREEN);
  241.     tft_print6x8(10, 42,  "RES 240x320",     COLOR_WHITE, COLOR_BLUE);

  242.     tft_draw_rect(20, 100, 200, 120, COLOR_WHITE);
  243.     for(i=0;i<50;i++){
  244.         tft_draw_line(20,100+i, 219,100+119-i, COLOR_WHITE);
  245.     }

  246.     // 简单计数刷新(避开全屏,以免过慢)
  247.     {
  248.         unsigned int cnt = 0;
  249.         char buf[20];
  250.         while(1){
  251.             // 覆盖区域清背景
  252.             tft_fill_rect(20, 230, 200, 16, COLOR_BLACK);

  253.             // 构造字符串(只用到数字/大写)
  254.             buf[0]='C';buf[1]='N';buf[2]='T';buf[3]=':';buf[4]=' '; // "CNT:            
复制代码
仿真程序下载:
TFT9341_SPI.rar (133.21 KB, 下载次数: 0)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表