AI 编程课
完整教案
自学课件
5 课 · 共 5/48

点亮一个点 ——坐标、画点和屏幕总线

课时
待定
器材
ESP32-S3 触摸屏板 + USB 线
前置知识
配套代码
见项目 demo 目录

自学读本:跟着读、照着做,卡住就问 AI

你好,我是吴老师。

这份是给你自己读的——不用等我讲,你一段一段往下看,看到让你停下来的地方,就照着做一遍。看不懂的整段复制给 AI,加一句"请一次只解释一个概念,讲完问我一个小问题"。

读完之后,你应该能:说出屏幕上任意一个点的坐标;用画线、画方框、画圆拼出一幅简单的图;解释为什么"只改一小块"比"整屏重画"快;说出 SPI 那几根线各自干什么。

用时:60–90 分钟。准备:板子、数据线、已经接入板卡 Skill 的 WorkBuddy。


一、今天只做一件很小的事

第 3 课,我们让整块屏幕变成一种颜色。你按一下 BOOT,七万六千八百个小点全都换了色,挺痛快的。

今天反过来,我们只做一件很小的事:点亮其中的一个点。

你可能会说,这有什么难的?整屏都变了,变一个点还不是小菜一碟?

那我就要问你了:屏幕上有七万六千八百个点,你要点亮哪一个?

"最中间那个。"——不行,板子听不懂"中间"。

板子只认数字。你得给它一个号码,这个号码叫坐标

所以今天真正的问题不是"怎么画",而是——怎么说清楚我要哪一个。

二、坐标:就像电影院找座位

屏幕坐标系示意图

怎么给七万多个点编号?总不能一个一个起名字吧。

你可以把它想成一张电影票:上面写着"第几排、第几座"。两个数一确定,座位就唯一了。

屏幕也一样,只是这两个数有自己的名字:

  • X:从左边开始数。最左边是 0,往右挪一格加 1,一直数到 239
  • Y:从上边开始数。最上边是 0,往下挪一格加 1,一直数到 319

原点 (0, 0) 就在左上角

位置XY像电影票上的
左上角00第 1 排第 1 座
右上角2390第 1 排最后一座
左下角0319最后一排第 1 座
右下角239319最后一排最后一座
正中间120160中间靠前一点

⚠️ 这里有个坑,几乎每个人都会踩

屏幕的 Y 是往下增长的,Y 越大越靠屏幕下方。这和你数学课上的坐标系正好相反。

数学课上,Y 往上是正方向;屏幕上,Y 往下才是正方向。

是不是谁写错了?不是。这只是约定不同

屏幕为什么要这么定?你想想画面是怎么送过去的:从左上角那个点开始,一个一个数过去,第一行数完数第二行——数数的顺序,就决定了 Y 的方向

你可以这样记:屏幕不是一张坐标纸,是一篇从左上角开始读的文章。

(顺带一提:正中间为什么是 (120, 160) 而不是 (120, 159.5)?因为点的编号是从 0 开始的整数,没有"半个点"这种东西。)

三、板子不会提醒你画到外面去了

我们做个小实验。假如我让板子在 (239, 319) 画一个边长 8 的方块。

这个方块要占横向 239 到 246、纵向 319 到 326。可是——屏幕最右边只到 239,最下边只到 319

结果是什么?

方块缺了一大角。

而且板子不报错,不提醒,不闪灯。它只是把屏幕外面那部分安安静静地丢掉了。

这像什么?像你在作业本的最后一格写了个很大的字,超出纸边的那一半,本子上不会出现,老师也不会提醒你——它就那么没了。

所以在我们这门课上,检查的标准不只要看"有没有画出来",还要看"是不是和你预想的一模一样"。

你可能会遇到的情况先怀疑什么
方块缺了一角坐标加上宽高以后,超出 240×320 了吗?
东西出现在上下颠倒的位置Y 的方向是不是记反了?
左右反了屏幕方向和 Skill 里的配置一致吗?
什么都没出来是不是先用整屏黑色把它盖住了?顺序对吗?

四、不只是点:还能画线、方框和圆

会画点了,就能画更多东西。有意思的是:画的东西不一样,你要告诉板子的数字个数也不一样。

四种图形需要的参数

一条线:给板子两个点

画一个点要给 2 个数,画一条线要给 4 个数——起点一对,终点一对。

中间那些点呢?不用你操心。你给了两头,板子自己算出中间该点亮哪些点。就像你在一张纸上点了两个点,然后用尺子一连。

一个圆:只用圆规就够了

这里有个地方值得你想一想:为什么画圆只要 3 个数?

你想想圆规是怎么用的:把针尖扎在一个点上(圆心),把铅笔腿张开到某个宽度(半径),转一圈——圆就出来了。

圆规不需要你告诉它"第 10 行第 20 列要画、第 10 行第 21 列要画……"。它只需要圆心 + 半径

板子也一样。圆的定义就是"到一个点的距离等于某个长度的所有点"。规则一定,圆就唯一了。

这个比喻有个地方要修正:圆规是"画"出来的,板子是"判断"出来的。它会拿每一个点去算:这个点到圆心的距离等于半径吗?等于就点亮,不等于就放过。板子手里只有加减乘除,它并不"懂"什么是圆。

把规则交给板子,它替你把点算出来——这是编程里特别省力的一个思路。

一张表收好

要画什么要给板子几个数分别是函数
一个点2X、YdrawPixel
一条线4起点 X/Y、终点 X/YdrawLine
空心方框4起点 X/Y、宽、高drawRect
实心方块4起点 X/Y、宽、高fillRect
3圆心 X/Y、半径drawCircle / fillCircle

(别忘了,这几个数之外,每次都还要再给一个颜色。)

五、描边和填充:看起来一样大,干的活差 10 倍

描边与填充的数据量对比

drawRect 只画四条边(描边),fillRect 把里面全填上(填充)。

它们要的数一样多,画出来的点却差很多。边长 40 的方框:

画法像什么要画多少个点要送多少字节
描边 drawRect用彩笔勾个边框约 156 个约 312 字节
填充 fillRect把里面全涂满1,600 个3,200 字节

就像画画:勾个轮廓几秒钟,把里面涂满要花好几分钟。屏幕上看起来差不多大,板子干的活差了约 10 倍

六、所以,改多少就送多少

要做的事要送的数据打个比方
给一颗 RGB 灯换色3 字节递一张三个字的纸条
改屏幕上 1 个2 字节比给灯换色还少
改 10×10 的小块200 字节抄一小段话
整块屏幕换色153,600 字节抄一本厚厚的书

第 3 课我们算过 15 万字节,你可能会以为"屏幕就是这么重"。不是的。

15 万是因为我们当时要求改整块屏幕。今天只改一个点,板子就只送 2 个字节。

**改多少,就送多少。**这句话你先记住,第 6 课它会变成一条硬规矩。

七、数据走哪条路:SPI

好,现在知道要送什么了。接下来的问题是:这些东西是怎么从主控跑到屏幕上来的?

这条通道叫 SPI。你可以把它想成工厂里的一条传送带

线的名字GPIO在传送带上扮演什么
SCLK 时钟12节拍器。它每响一下,带子往前推一格
MOSI 数据11传送带本身,一个字节一个字节往屏幕那头运
CS 片选10点名员。叫到谁,谁才接货
DC 命令/数据46贴在包裹上的标签:这是"指令"还是""

DC 这根线最巧

请你想一想:同一条传送带上运过去的字节,屏幕怎么知道它们是什么意思?

"准备接收"、"从第 120 列开始"、"这个点是红色"——这些都是不同的意思,可它们走的是同一条线。

所以每个包裹都要贴张标签。DC 就是这张标签:

  • 标签写命令 → 屏幕把它当指令,比如"从第几行开始"
  • 标签写数据 → 屏幕把它当颜色本身

这就是工程师常说的取舍:用一根线省下一根 GPIO,代价是每次发货都要先说一句"接下来是什么"。

还有一个坑:这条路只能往外走

SPI 本来还有一条反向的线叫 MISO(屏幕往主控送数据)。我们这块板上接是接了,但没打通

这意味着:我们能给屏幕送东西,却不能把屏幕上的画面读回来。

就像一个只能往外寄信、收不到回信的邮筒。

所以以后你想把屏幕画面截个图存下来,不能指望"把屏幕上的点读出来",只能自己记住画了什么。这个坑以后做"你画我猜"的时候还会再遇到一次。

八、动手做

任务 1:点亮五个点

请新建一个屏幕坐标实验:
开机后整屏填黑,然后在下面五个位置各画一个亮黄色方块(边长 8):
左上角 (0,0)、右上角 (239,0)、左下角 (0,319)、右下角 (239,319)、正中间 (120,160)。
颜色亮度不超过 80。请说明你用的画方块函数叫什么、坐标是怎么传进去的。
编译烧录前先核对目标端口,保留旧程序。

**先猜再烧。**五个都出现以后,重点看右下角那个——它是不是缺了一角?

任务 2:把四种图形都画一遍

请新建一个图形实验,黑底上画出这些图形方便对比:
1. 从 (0,0) 到 (239,319) 画一条青色对角线;
2. 在 (60,60) 画一个 40×40 的红色方框,只画边框;
3. 在 (60,140) 画一个 40×40 的红色方块,填满;
4. 在 (170,80) 画一个半径 30 的黄色圆,只画边框;
5. 在 (170,220) 画一个半径 30 的黄色圆,填满。
亮度都不超过 80。请用中文注释,保留旧程序。

凑近看一眼那个空心圆的边:是不是有点毛糙?

为什么?因为屏幕上的点是一格一格的,它画不出行云流水的曲线——只能给你一条锯齿状的"差不多是圆的线"。

任务 3:测一测,谁更快

请加上计时,分别测出:
1. 整屏填充红蓝交替 100 次,用了多少毫秒;
2. 只填充中间 40×40 的小方块,红蓝交替 100 次,用了多少毫秒。
结果同时显示在屏幕上、并通过串口打印出来。按 BOOT 可以重测一轮。

**先预测再烧录。**整屏 76,800 个点,小方块 1,600 个点——点数是 48 倍,那时间也会是 48 倍吗?

如果差得没那么多,想一想:这 100 次里,除了"送数据",还有什么在花时间?(提示:下命令、算颜色,也都要时间。)

挑战:坐标寻宝图

请做一个坐标寻宝游戏:
开机后随机藏一个 8×8 的方块(不显示)。我在串口输入 "x y"(如 "50 200"),
板子在我猜的位置画一个灰色标记,并按距离回答:
小于 20 回答"烫!",小于 60 回答"热",小于 120 回答"温",否则回答"冷"。
猜中(距离小于 8)时把宝藏显示成亮黄色,串口回答"找到了!你一共猜了__次"。
按 BOOT 开始新一轮。

玩完想一想这个:板子理解你在找东西吗?

不。它只是做了几次减法和比较。所有的"聪明"都来自你写下的规则——规则是你给的,不是它自己想出来的。

九、自检小测

先自己想,再点开对答案。

1. 屏幕的坐标原点在哪里?X 和 Y 各朝哪个方向增长?

原点在左上角。X 向右增长到 239,Y 向下增长到 319。

2. 在 (239, 319) 画一个边长 8 的方块,会完整显示吗?

不会。方块要占 239–246,超出屏幕的部分被丢掉,你会看到一个缺角的方块,而且板子不会报错。

3. 画一条线、一个方框、一个圆,分别要给板子几个数?

线 4 个(起点 X/Y + 终点 X/Y),方框 4 个(起点 X/Y + 宽高),圆 3 个(圆心 X/Y + 半径)。都还要再加一个颜色。

4. 画圆为什么只要圆心和半径?

因为圆的定义就是"到一个点距离等于半径的所有点"。规则一定,圆就唯一了。这就像用圆规:扎住一点、张开固定宽度、转一圈。

5. 40×40 的方框,描边和填充送的数据差多少?

描边约 156 个点 / 312 字节,填充 1,600 个点 / 3,200 字节,相差约 10 倍

6. DC 这根线是干什么的?

告诉屏幕接下来送过去的字节是命令(比如"从第几行开始画")还是数据(颜色本身)。像包裹上的标签。

7. 为什么不能把屏幕上的画面读回来?

SPI 负责反向传输的 MISO(GPIO13)在这块板上没有真正打通,只能给屏幕送,不能从屏幕读。

十、还想玩点什么

方向可以描述给 AI 的效果值得继续想
像素画用方块拼出一个笑脸或房子你要怎样把"图案"翻译成一串坐标?
星空随机位置点亮几十个白点每次重画整屏,和只在旧点上盖黑色,哪种更好?
进度条底部长条按进度从左往右填充从 30% 涨到 31%,这一帧要改几个点?
心电图一条线从左到右移动,到头回到最左每一帧要擦掉什么、画上什么?

最后那道题留给下一课:让画面动起来,真正的难点不是"画",而是只改该改的地方


本课的配套资源

本节配套的演示程序源码与可烧录固件,已整合到课程页面底部的「配套资源 · 在线烧录」区——插上你的 ESP32-S3 触摸屏板(Chrome / Edge 浏览器),点「在线烧录」即可直接写入,无需安装软件。

给 AI 的第一句话(每次新开对话都先说这句):

请使用课程的 esp32s3-touchboard-hardware-dev Skill,
我现在做第 5 课(屏幕坐标与图形),需要你帮我____。
改动前先说清依据的项目文件路径,烧录前先运行 arduino-cli board list 确认端口。

本节配套资源 · 在线烧录

查看全部固件 →

下列演示程序已编译为可烧录固件。把你的 ESP32-S3 触摸屏板 用 USB 接上电脑(需 Chrome / Edge 浏览器),点「在线烧录」即可直接写入,无需安装任何软件。

风景画动画
可烧录

竖屏风景动画(蓝天、白云、草地、树木,加上走动的小羊和偶尔飞过的小鸟)。纯本地动画,不联网,适合作为 UI 动画模板学习。

动画 风景 非阻塞
✓ 可在线烧录
第 5 课 · 点亮一个点
可烧录

在屏幕四角和中心点亮 5 个方块,右下角那个是缺角的。用来理解坐标从 0 开始、最大是 239 和 319。

05 坐标 入门
第 5 课 · 画线和图形
可烧录

对角线、空心方框、实心方框、空心圆、实心圆。体会描边只画边上一圈,填充要画满里面。

05 图形 描边填充
第 5 课 · 局部改画 vs 整屏重画
可烧录

整屏、小方块、空心圆、实心圆各画 100 次,屏幕和串口报出毫秒数与相差倍数,按 BOOT 重测。

05 计时 实验
第 5 课 · 坐标寻宝图
可烧录

屏幕里藏了宝贝,在串口输入坐标,板子回答烫 / 热 / 温 / 冷,直到你找到它。按 BOOT 重新藏。

05 坐标 串口 游戏