IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 每节课都是一个项目 手把手用STM32打造联网气象站-8-面子工程-学会点亮LCD屏幕 -> 正文阅读

[嵌入式]每节课都是一个项目 手把手用STM32打造联网气象站-8-面子工程-学会点亮LCD屏幕

目录

1. 游戏的秘密

2. LCD的魅力

3. 8080接口

3.1写入命令

3.2写入数据

4. RGB接口

5. FMSC接口

5.1 FMSC接口介绍

5.2 如何产生D/C信号?

5.3 具体代码中的地址转换

6. 屏幕驱动初始化

6.1 GPIO配置

6.2 FSMC配置

6.2.1 理解SetupTime

6.2.2 理解AccessMode_B

6.3 BackLed_Control

6.3.1关于枚举类型

?6.3.2关于LED背光灯

6.4 ILI9341复位

6.5 ILI9341寄存器初始化

6.6 GRAM扫描方式设置

6.6.1设置扫描方向

6.6.2 设置X Y轴方向的坐标

7. 通过工程,验证屏幕初始化

7.1 在屏幕上画直线

7.2 在屏幕上画长方形

7.2.1. 采用OpenWindow函数,设置绘制矩形的起始坐标,宽度,高度;

7.2.2 采用FillColor函数,将矩形填满;

7.2.3 填满长方形


完成了STM32基础三板斧,用这个三板斧完成一些项目,我们接下来需要开始面子工程,点亮LCD屏幕。

我们把LCD屏幕的教程提前,主要是使得教程更加有趣味性。

1. 游戏的秘密

我们每个人都会有一段时间,沉迷于某一个游戏之中,不能自拔,连续七八个小时玩游戏,熬夜到两三点,这个可能都是常态。

为何游戏有这么大的魔力?游戏的吸引力来自于哪里?我们是否可以学习,让编程也有同等吸引力呢?

游戏的魔力主要来自于这样几点:

1.及时反馈:游戏总是每隔一段时间,会有一个正反馈,比如刷到某个装备,或者得到某个奖励。玩游戏的人不需要耗费太多的精力,就能够得到一个正反馈,这种机制吸引游戏者不断玩下去。

2. 任务简化分解:每隔任务都会简化分解为多个小任务,完成一个小任务就会有明确反馈。相信玩过游戏的人,都会有这样一个体会,如果一关实在太难过了,大家就会放弃这个游戏了。

3. 难度适中:游戏一般都会设置适中的难度,过难或者过于简单,都会使得游戏变得乏味。过难很容易让人放弃,这个容易理解。过于简单也会使得游戏让人乏味。比如某些游戏,如果充值过多,或者用外挂破解之后,大大降低了游戏难度,反而使得这个游戏缺少了吸引力。

4. 结果明确:每个游戏都会有明确的结果,比如消灭一个大BOSS,或者得到某一件宝物。明确的结果使得游戏进度容易衡量,结果容易体现。明确的结果也是游戏的魅力之一。

分析了游戏的魅力,我们就可以推到出来,如何使得编程也变得非常有魅力,非常迷人。

1. 编程教程需要及时反馈:每一个教程能够及时看到结果,而且结果需要有一定吸引力;

2. 编程任务需要简化分解:编程的复杂任务需要分解为多个简单的小任务,方便学习过程中,不断检查进度,了解进度;

3. 编程难度适中:如果编程代码量较大,就需要将他分解为多个小任务,这样可以简化每一个任务的难度;

4. 编程结果明确:每个编程项目的结果是非常明确的,达到什么样的状态,实现什么样的功能,是非常清楚的,这样在学习过程中,减少很多犹疑和走弯路的过程。

2. LCD的魅力

如果把板上的LED灯看作一个像素,那么LCD就是具备了320X240=76800个LED的表达能力。因此熟练掌握LCD,对于增强设计的表现力和表达力,都是非常有帮助的。

LCD的常用接口一般包含下面这样几种:

1. SPI接口:采用SPI方式和屏幕进行通信, 其中SPI接口时Motorola 公司推出的一 种同步串行接口技术,是一种高速的,全双工,同步的 通信总线。

2. INTEL 8080接口:使用这种接口的屏幕一般是屏幕自带了驱动芯片,比如ILI9488、ILI9341、SSD1963等 。驱动芯片里面自带了显存,MCU只需要把显示数据传给驱动芯片,驱动芯片会把数据保存到显存中,最后再把显存中的数据显示到屏幕上。

3. RGB接口:大屏采用较多的接口, 屏幕不带显存,需要MCU准备充足的显存空间(因为RGB565,480*272分辨率的屏幕就需要显存480*272*2 = 255K,一般的MCU都没有这么大的RAM,所以要加外置的SRAM或SDRAM)

我们这里重点介绍的是8080接口:

液晶屏的内部结构如上图所示,其中MCU通过8080接口,控制ILI9341或SSD1963或者同类芯片。此类芯片一般内置显存GRAM。MCU将需要显示的内容,通过8080接口,写入ILI9341。ILI9341将需要显示的内容写入GRAM,并且通过RGB接口,控制液晶显示电路。

所以ILI9341这类芯片,相当于电脑中的显卡。一方面连接CPU,另一方面连接液晶屏,实现显示控制功能。

对于STM32F4系列,也和电脑类似,会内置显卡功能。对于这类内置显卡的MCU,一般需要外挂SRAM,用来存储大量的图片。

3. 8080接口

接下来我们重点了解一下8080接口,并且通过理解这个接口,进一步深入理解MCU是如何通过接口,和外部芯片进行通信的。

8080接口分成两类:数据接口和控制接口。

数据接口包含DB0~DB15,共计16位数据;

控制接口包括:CS片选,RD读信号,WR写信号,RES复位信号,D/C数据命令信号共计5根信号线;

MCU通过8080接口写入ILI9341时,会先写入地址,再写入数据。

上图为ILI9341手册,其中明确说明了,当我们需要写入ILI9341数据时,我们先将D/C设置为0,写入对应的地址信息,告诉驱动芯片,接下来的数据需要写入哪一个位置。然后再把D/C设置为1,把数据写入对应地址中。

3.1写入命令

当MCU向ILI9341写入数据时,会控制这些管脚,达到下面状态:

1. CS片选拉低,通知ILI9341,“你被选中了,马上MCU要写入数据了”

2. D/C拉低,通知ILI9341,现在写入的是命令,而不是数据。

3. WR拉低,通知ILI9341,MCU马上要写入? ? ? ? ? ? ? ? ? ? 数据;

4. 然后数据接口DB0~DB15会执行写入动作,先写入地址信息,再写入数据信息;

具体操作如上图所示。

3.2写入数据

写入数据和写入命令唯一区别是:写入数据时,D/C为高电平;而写入命令时,D/C为低电平。

完成了上面两个操作后,就可以把数据从MCU写入ILI9341驱动中。

例如,我们常常会写入2A这个地址,这时,MCU会通知ILI9341,具体在哪一列进行显示。

?我们也常常写入2B这个地址,这里就是通知ILI9341,具体在哪一行进行显示。

4. RGB接口

MCU将数据写入ILI9341之后,LCD并不会直接更新显示。ILI9341还需要通过RGB接口,更新ILI9341对应的数据信息。ILI9341和LCD之间的接口,就是对应的RGB接口。

比如我们在淘宝上搜索RGB 4.3,就可以看到很多屏幕数据。

点击进去,就可以看到更加详细的信息,其中就会介绍对应的接口是RGB40PIN。

?

RGB40PIN对应的管脚如上图,包含了R,G,B和水平同步,垂直同步等信息。

液晶屏有一个显示指针, 它指向将要显示的像素。显示指针的扫描方向方向从左到右、从上到下,一个像素点一个 像素点地描绘图形。这些像素点的数据通过 RGB 数据线传输至液晶屏,它们在同步时钟 CLK 的驱动下一个一个地传输到液晶屏中,交给显示指针,传输完成一行时,水平同步信 号 HSYNC 电平跳变一次,而传输完一帧时 VSYNC 电平跳变一次。所以HSYNC的频率明显高于VSYNC。

液晶屏中的每个像素点都是数据,在实际应用中需要把每个像素点的数据缓存起来, 再传输给液晶屏,一般会使用 SRAM 或 SDRAM 性质的存储器,而这些专门用于存储显示 数据的存储器,则被称为显存。显存一般至少要能存储液晶屏的一帧显示数据,如分辨率 为 800x480 的 液 晶 屏 , 使 用 RGB888 格 式 显 示 , 它 的 一 帧 显 示 数 据 大 小 为 : 3x800x480=1152000 字 节 ; 若 使 用 RGB565 格 式 显 示 , 一 帧 显 示 数 据 大 小 为 : 2x800x480=768000 字节。其中RGB565把红色和蓝色的显示位数减少了,这样减少了整体显存的消耗。

在本期教程中,ILI9341将自动完成RGB接口通信,因此,我们只需要大致了解RGB接口的概念即可。

5. FMSC接口

5.1 FMSC接口介绍

第四节提到了8080接口的访问方式,然而,在现实中,我们使用的MCU并不具备8080接口,它具备的是FMSC接口。FMSC接口全称为:Flexible Static Memory Controller 的缩写,意思为:灵活的静态存储控制器,它可以用于驱动包括 SRAM、 NOR FLASH 以及 NAND FLSAH 类型的存储器。不能驱动SDRAM这类动态存储器。(备注:静态存储和动态存储的区别是:静态存储不需要刷新,而动态存储需要不断刷新内容,因此动态存储往往需要一些专用的带有自动刷新的接口)

FMSC接口时灵活通用接口,它支持多种不同外部存储的访问操作,其中就包括了8080接口。

FMSC分为多组信号,当把FMSC用作8080接口时,信号对应关系如下:

FMSC接口读操作时序图

FMSC接口写操作时序图

8080接口操作时序图

把上面3个图放在一起,就可以看出:FMSC和8080基本上一一对应。

信号名FMSC8080
片选NECS
写信号WEWR
读信号NOERD
数据DATADATA
数据/命令D/C?

比如我们像FMSC的地址,写入一个数据,就会产生类似8080接口的时序。我们通过这个方式,将数据按照写入FMSC的方式写入8080接口。按照从FMSC读取数据的方式,从8080接口读取数据。

但是这里还有一个问题:ILI9341的8080接口中,有一个D/C信号,如何通过FMSC来产生呢?

5.2 如何产生D/C信号?

FSMC对应NOR/SRAM访问地址为6000 0000 ~6FFFF FFFF这个范围。

下面捋一下地址线和访问地址之间关系:

地址

地址二进制

高电平地址线

0x6000 0001

0001

A0

0x6000 0010

0001 0000

A4

0x6000 0100

0001 0000 0000

A8

0x6000 1000

0001 0000 0000 0000

A12

0x6001 0000

0001 0000 0000 0000 0000

A16

?当我们访问地址0x6000 0001时,对应的A0地址线为高位;

当我们访问地址0x6000 0010时,对应的A4地址线为高位;

以此类推;

当我们访问地址0X6001 0000时,对应的A16地址线为高位。

通过上面规律,就可以找到实现D/C命令访问的方式:

我们把D(数据)对应的地址和C(命令)对应的地址分开,这样写入D的时候,对应的地址线为高电平,写入C的时候,对应地址线为低电平,这样可以用地址线来模拟D/C线的控制。

当 FSMC 外设被配置成正常工作,并且外部接了 NOR FLASH 时,若向 0x60000000 地 址写入数据如 0xABCD,FSMC 会自动在各信号线上产生相应的电平信号,写入数据。 FSMC 会控制片选信号 NE1 选择相应的 NOR 芯片,然后使用地址线 A[25:0]输出 0x60000000,在 NWE 写使能信号线上发出低电平的写使能信号,而要写入的数据信号 0xABCD 则从数据线 D[15:0]输出,然后数据就被保存到 NOR FLASH 中了。

5.3 具体代码中的地址转换

在FSMC驱动中,我们定义了两个地址:0x60000000 和0x60020000;这样,按照前面讨论内容,当FMSC往60020000中写入数据时,对应A17将变为高电平,因此,可以用A17来替代D/C信号,控制DATA写入。

不对啊,根据原理图来看,明明原理图上连接的时A16而不是A17啊?

?是的,其中还有一个核心秘密:

在本工程中使用的是 16位的数据访问方式,所以 HADDR与 FSMC_A的地址线连接关 系会左移一位,如 HADDR1 与 FSMC_A0 对应、HADDR2 与 FSMC_A1 对应。因此, 当 FSMC_A0地址线为 1时,实际上内部地址的第 1位为 1,FSMC_A1地址线为 1时, 实际上内部地址的第 2 位为 1。同样地,当希望 FSMC_A16 地址输出高电平或低电平 时,实质是访问内部 HADDR 地址的第(16+1)位为 1 即可。

因此,我们通过访问0X6002 0000这个地址,使得A16被设置为高电平,从而用A16来控制8080接口的D/C管脚,实现数据访问。

我们经过上面完整的分析,主要是让你掌握地址线和地址之间计算的逻辑:

当我们需要访问特定地址时,是通过特定地址线的高低电平来实现的。

6. 屏幕驱动初始化

下面重点讲解一下ILI9341的初始化过程。其他屏幕驱动芯片的初始化过程也非常类似。

6.1 GPIO配置

GPIO配置中,需要完成8080接口的16根数据线和6根控制线的初始化,把他们都初始化为输出。

这里需要注意,其中CS, DC, RD, WR设置为GPIO_Mode_AF_PP,而不是我们通常使用的GPIO_Mode_Out_PP,这是什么原因呢?

这时因为这几个IO是带有内部功能的IO,当我们采用这些带有内部功能的IO作为输出时,需要配置为AF_PP,也就是推挽复用输出。

6.2 FSMC配置

?FSMC初始化步骤比较复杂,这里进行简单说明,但不会详细讲解。对于大部分嵌入式软件工程师而言,是很难得去修改这里的代码的。对于驱动工程师而言,才有机会真正修改这里的代码。

6.2.1 理解SetupTime

其中AddressSetupTime和DataSetupTime是设置地址线和数据线的建立时间。所谓建立时间,就是为了确保信号能够被准确采集到,需要在采集点之前的x 纳秒,就需要把信号准备好,这样当读写操作开始时,能够把信号稳定在0或者1的数值,避免读写失误。

上图中,tdst就是写入数据的建立时间。WRX的上升沿(上图红色箭头处),MCU完成数据写入。但是在这个上升沿之前至少tdst这个时间,就需要把数据准备好,这样在上升沿写数据的时候,才能够稳定写入数据。

类似的参数时tdht,也就是数据保持时间,在WRX的上升沿之后,数据还需要保持至少tdht这个时间,这样才能够确保上升沿能够稳定的写入数据。?

这里设置AddressSetupTime和DataSetupTime就是根据ILI9341芯片的数据手册里面描述的setuptime,设置FMSC的参数,使得FSMC模拟出来的8080接口,能够稳定可靠的写入ILI9341。

我们理解这里的原理即可,不需要在这里扣的太细。

但是当我们实际需要在这里深挖的时候,我们应该具有这样的能力,能够深度挖掘这里的技术细节,并且完成相应的开发工作。

6.2.2 理解AccessMode_B

FSMC能够模拟不同类型的接口,而AccessMode_B则是模拟NOR FLASH 接口。 8080接口原本就是用在NOR FLASH上面,因此我们这里把他设置成为NOR FLASH 接口,是非常匹配的。

6.3 BackLed_Control

?

?点亮背光灯则非常简单,我们只需要通过GPIO,控制对应的GPIO为低电平即可。

6.3.1关于枚举类型

且慢,如何从代码中,看出这里的GPIO是需要设置为低电平呢?

我们之前跟着ST学写代码中,学习了typedef structure {}new_structure这种语句,这里我们学习类似的语句:

typedef enum{A=0,B=!A} new_state这样的语句。

首先我们复习一下枚举类型enum。我们在代码中常常用枚举类型,它的主要作用是:加强代码的可读性。比如Control(Enable), Control(Disable)这样的方式,总会比Control(0), Control(1)这样的方式更加友好,谁知道你的代码宇宙中,0表示Enable,还是1表示Enalbe (备注:在习惯的代码宇宙中,0表示disable, 1表示enable,但是也会有例外。)

?6.3.2关于LED背光灯

?我们的LED面板一般都内置背光灯。这个背光灯可以通过LCD_BK这个管脚控制点亮和熄灭,上面电路就包含了一个三极管,通过三极管,控制LED点亮或者熄灭。

这个三极管是PNP型三极管。关于如何区分NPN三极管和PNP型三极管,有这样一个小秘诀:箭头总是从P指向N; 所以如果箭头指向内部的,就是PNP管。如果箭头指向外部的,就是NPN管。根据箭头总是从P指向N这个规则,我们就可以清晰判断三极管的类型。

如果是NPN三极管,则是基极高电平导通,如果是PNP三极管,则是低电平导通。这里的记忆秘诀是:电压总是P大于N。因此对于NPN三极管,中间需要高电平,这样满足P大于N的条件,对于PNP三极管,中间需要低电平,这样才能满足P大于N的条件。

掌握上面两个记忆密码,我们就可以理解PNP和NPN三极管的工作原理。

在上面电路中,STM32的GPIO连接到LCD_BK。当GPIO设置为低电平时,LCD点亮,当GPIO设置为高电平时,LCD熄灭。

6.4 ILI9341复位

通过控制9341的RST管脚,进行相应的复位操作。

需要注意:复位后,需要Delay一段时间。由于这个Delay是在初始化的过程中,因此并不会对MCU代码运行产生影响,因为初始化只是上电短时间执行一次的操作而已。

6.5 ILI9341寄存器初始化

?9341寄存器初始化过程相对比较复杂,需要结合9341的数据手册进行查看。

比如代码中,写入0XCF,我们只需要在数据手册上,查找CF,就可以很快找到对应的内容。

从图片可以看出,代码中的设置和手册中的设置是一模一样的,这个就是芯片上电时候选择的默认设置。

?代码中ED寄存器,也就是上电寄存器,和默认值略有不同。我们这里结合手册,看看到底改了哪里。

手册中明确说了,第一参数CP1? 设置为10,对应了soft start keep 1 frame选项。CP23参数对应了3rd frame enable选项。

具体对应方式为:

0x64 对应二进制为0110 0100,也就是cp1为10, cp23为10。

从工程角度来说,我们只需要能够一一对应即可,并不需要详细理解其中的每一个细节,因为:

吾生也有涯而知也无涯以有涯随无涯殆已

因此,这里我们只要知道,需要再上电前,对ILI9341的各个寄存器,完成一系列配置即可。。

6.6 GRAM扫描方式设置

6.6.1设置扫描方向

GramScan函数用来设置LCD的扫描方式。ucOption为参数,数值为0~7,也就是LCD共计有8种扫描方式。

?

对于模式0 2 4 6 , X为240, Y为320;

对于模式1 3 5 7, X方向为320, Y方向为240;

我们先把ucOption写入0x36的地址:ucOption的数值分别为000~111,左移5位后,对应数值为0000 0000~1110 0000,这样写入0x36地址后,相当于设置了0x36地址中下面的几个寄存器数值:

MY, MX, MV设置关系如下

参数??

方向

MY=0

自下向上

MY=1????????????????

自上向下????????????????????????

MX=0

自右向左????????

MX=1????????? ?

自左向右? ? ? ? ? ??

MV=0????????????????X Y保持

MV=1

X Y互换

?因此我们就可以得出模式配置规律

参数??

方向

0 0 0

Y自下向上,X自右向左,X,Y保持

0 0 1

? Y自下向上,X自右向左,X,Y互换?????????

0 1 0

Y自下向上,X自左向右,X,Y保持

0 1 1Y自下向上,X自左向右,X,Y互换

?

1 0 0

Y自上向下,X自右向左,X,Y保持

1 0 1

? Y自上向下,X自右向左,X,Y互换?????????

1 1 0

Y自上向下,X自左向右,X,Y保持

1 1 1Y自上向下,X自左向右,X,Y互换

6.6.2 设置X Y轴方向的坐标

?

其中CoordinateX的第一个和第二个参数,对应起始坐标的高八位和第八位,这里都是0。也就是起始坐标从0开始。第三个和第四个参数,对应结束坐标的高八位和低八位,这里为前面屏幕尺寸X方向数值。

CoordinateY的参数也是类似的,第一和第二个参数为起始坐标,第三和第四个参数为结束坐标。

?

完成显示范围设置之后,就从开头,不断写入像素点,写入的方向就是按照前面ucOption设置的方向,写入的个数,就是按照前面X Y的起始点和结束点设置的个数。写入的数值,就是包含了R,G,B三元素的数值。

到这里,我们终于完成了屏幕的初始化工作。

屏幕初始化确实比较复杂,但是我们大部分时候,仅仅需要掌握如何移植这个驱动即可。而对于详细代码部分,我们需要了解,如何从Datasheet中,找到对应的数据,而不需要牢记具体的数据信息。

7. 通过工程,验证屏幕初始化

终于到了激动人心的时刻,我们来试一下屏幕的初始化功能。

7.1 在屏幕上画直线

所谓在屏幕上画直线,就是根据两个坐标,在屏幕上绘制一条连接两个点之间的直线。说起来简单,但是实际上是需要一定的算法支持的。

?因为我们的屏幕是有像素点的,所谓直线只是许多条折线的组合,只是远看起来像是一条直线而已。

假设我们起始点坐标为(0,0),结束点坐标为(50,100)我们把这个参数带进去:

1. usX1=0, usY1=0, usX2=50, usY2=100;

2. Delta_X=50, Delta_Y=100;

3. Increase_X=1, Increase_Y=1; Distance=100;

?

for循环中,?

1. 在起始点0,0画点;

2. Err_x=50, Err_Y=100;

3. 判断Err_X和Err_Y是否大于Distance;

4. Err_X=100, Err_Y=200;

5. Err_Y>Distance, Err_Y=100, y_current=1; 在(0,1)处画一个点;

7. Err_X=150, Err_Y=200, 在(1,2)处画一个点,完成后,Err_X=50, Err_Y=100;

8.继续循环在(1,3)处画一个点;

以此类推,完成从起点到终点的划线行为。

事实上,划线是一个有一定复杂度的算法,比冒泡法排序更加复杂一些。

对于有一定复杂度的算法,我们一般采用代入法,将一些特殊数值放进去,即可循序渐进,判断出对应算法逻辑。

7.2 在屏幕上画长方形

在屏幕上画长方形更加简单一些。

7.2.1. 采用OpenWindow函数,设置绘制矩形的起始坐标,宽度,高度;

下面详细看下:

?OpenWindow设置写入位置,操作的还是最初的2A和2B寄存器。具体参见6.6.2中详细描述。

7.2.2 采用FillColor函数,将矩形填满;

?首先我们需要了解一下,9341是采用RGB565的方式,控制颜色的,红色5bit 绿色6bit 蓝色5bit。

常见的RGB888和RGB565的颜色定义,可以参考下面的连接。

https://blog.csdn.net/qq_20222919/article/details/116168044

如需查看更多颜色组合,直接查看上面链接即可。

我们以黄色为例,如果需要组成黄色,就需要红色和绿色拉满,蓝色不要,这样就是FF E0,这样就可以组成黄色;如果需要组成紫色,就需要红色和蓝色拉曼,绿色不要,这就是:F8 1F,这样就把中间绿色设置为0,其他都是1,构成了紫色。

当我们需要在一个区域设置颜色时,只需要把对应的范围,直接写入上面设置的颜色信息,即可完成颜色的填充。

7.2.3 填满长方形

?先用OpenWindow设置需填充的区域,然后再往这个区域写入需要填充的颜色,即可构成填充好的长方形。

纸上得来终觉浅,绝知此事要躬行!

马上下载测试代码,看看效果。

?https://download.csdn.net/download/book_drabit/86103895

代码执行效果详细见下面GIF图片内容。

????????

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-07-17 16:39:38  更:2022-07-17 16:41:37 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 23:02:21-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码