01_点亮LED

news2025/6/28 11:37:36

        这节课的标题是点亮 LED,虽然任务很简单,但是需要大家了解的单片机基础知识的内容却很多,特别是对于初学者,刚开始要在头脑中建立一个单片机的概念,课程最后通过点亮一个 LED 小灯来增加初学者对单片机的兴趣和自信。

1. 单片机的内部资源

        在这里我所讲到的单片机内部资源,和传统单片机书籍中讲单片机内部结构不同,我这里讲到的内部资源,是指作为单片机用户,单片机提供给我们可使用的东西。总结起来,主要是三大资源:

        Flash——程序存储空间,早期单片机是 OTPROM。

        RAM——数据存储空间。

        SFR——特殊功能寄存器。

        在早期的单片机中,主要是用 OTPROM(One Time Programmable Read-Only Memory,即一次可编程只读存储器)来存储单片机的程序,程序只能写入一次,如果发现错了,没办法,只能换一片,重新写入了。随着技术的发展,Flash 以其可重复擦写且容量大成本低的优点成为现在绝大多数单片机的程序存储器。对于单片机来说 Flash 最大的意义是断电后数据不丢失,这个概念类似于我们电脑的硬盘,我们保存了电影、文档、音乐等文件,把电源关掉后,下次重新开电脑,所有的文件都还照样存在。

        RAM 是单片机的数据存储空间,用来存储程序运行过程中产生的和需要的数据,跟电脑的内存是相似的概念,其实最典型的比喻是我们的计算器,我们用计算器计算个加减法,一些中间的数据都会保存在 RAM 里边,关电后数据丢失,所以我们每次打开计算器,都是从归零开始计算。但是它的优点,第一是读写速度非常快,第二是理论上是可无限次写入的,即寿命无限,不管程序怎么运行怎么读写它都不会坏。

        第三个资源是 SFR,特殊功能寄存器。这个概念大家可能刚开始理解不了,但是一定要记住。单片机有很多很多功能,每个功能都会对应一个或多个 SFR,我们就是通过对 SFR 的读写来实现单片机的多种多样的功能的。

        讲到这里,我们来了解一下 51 单片机。通常我们一说到 51 单片机,指的都是兼容 Intel MCS-51 体系架构的一系列单片机,而 51 是它的一个通俗的简称。全球有众多的半导体厂商推出了无数款这一系列的单片机,比如 Atmel 的 AT89C52,NXP(Philips)的 P89V51,宏晶科技的 STC89C52……具体型号千差万别,但他们的基本原理和操作都是一样的,程序开发环境也是一样的。这里我们要分清楚 51 这个统称和具体的单片机型号之间的关系。

        单片机内部资源的三个主要部分我们清楚了,那么我们选择 STC89C52 这款单片机来进行学习。STC89C52 是宏晶科技出品的一款 51 内核的单片机,具有标准的 51 体系结构,全部的 51 标准功能,程序下载方式简单,方便学习,我们就用它来学习单片机。它的资源情况:Flash 程序空间是 8K 字节(1K=1024,1 字节= 8 位),RAM 数据空间是 512 字节,SFR我们后边会逐一提到并且应用。

2. 单片机最小系统

        为什么称之为单片机最小系统呢?单片机最小系统,也叫做单片机最小应用系统,是指用最少的原件组成单片机可以工作的系统。单片机最小系统的三要素就是电源、晶振、复位电路,如图 2-1 所示。

        这张最小系统的电路图节选自我们的 KST-51 开发板原理图,下面我们就照这张电路图来具体分析最小系统的三要素。

2.1 电源

        这个很好理解,电子设备都需要供电,就连我们的家用电器(手电筒^_^)也不例外。目前主流单片机的电源分为 5V 和 3.3V 这两个标准,当然现在还有对电压要求更低的单片机系统,一般多用在一些特定场合,在学习中我们不做过多的关注。

        我们所选用的 STC89C52,它需要 5V 的供电系统,我们的开发板是使用 USB 口输出的5V 直流直接供电的。从图 2-1 可以看到,供电电路在 40 脚和 20 脚的位置上,40 脚接的是+5V,通常也称为 VCC 或 VDD,代表的是电源正极,20 脚接的是 GND,代表的是电源的负极。+5V 和 GND 之间还有个电容,作用我们下节课介绍。

        这个地方我们还要普及一个看原理图的知识。电路原理图是为了表达这个电路的工作原理而存在的,很多器件在绘制的时候更多考虑的是方便原理分析,而不是表达各个器件实际位置。比如原理图中的单片机引脚图,引脚的位置我们是可以随意放的,但是每个引脚上有一个数字标号,这个数字标号代表的才是单片机真正的引脚位置。一般情况下,这种双列直插封装的芯片,左上角是 1 脚,逆时针旋转引脚号依次增加,一直到右上角是最大脚位,我们现在选用的单片机一共是 40 个引脚,因此右上角就是 40(在表示芯片的方框的内部),如图 2-2 所示,大家要分清原理图引脚标号和实际引脚位置的区别。

2.2 晶振

        晶振,又叫晶体振荡器,从这个名字我们就可以看出来,它注定一生都要不停振荡的。他起到的作用是为单片机系统提供基准时钟信号,类似于我们部队训练时喊口令的人,单片机内部所有的工作都是以这个时钟信号为步调基准来进行工作的。STC89C52 单片机的 18 脚和 19 脚是晶振引脚,我们接了一个 11.0592M 的晶振(它每秒钟振荡 11,059,200 次),外加两个 20pF 的电容,电容的作用是帮助晶振起振,并维持振荡信号的稳定。

2.3 复位电路

        在图 2-1 左侧是一个复位电路,接到了单片机的 9 脚 RST(Reset)复位引脚上,这个复位电路如何起作用我们后边再讲,现在着重讲一下复位对单片机的作用。单片机复位一般是3种情况:上电复位、手动复位、程序自动复位。

        假如我们的单片机程序有 100 行,当某一次运行到第 50 行的时候,突然停电了,这个时候单片机内部有的区域数据会丢失掉,有的区域数据可能还没丢失。那么下次打开设备的时候,我们希望单片机能正常运行,所以上电后,单片机要进行一个内部的初始化过程,这个过程就可以理解为上电复位,上电复位保证单片机每次都从一个固定的相同的状态开始工作。这个过程跟我们打开电脑电源开电脑的过程是一致的。

        当我们的程序运行时,如果遭受到意外干扰而导致程序死机,或者程序跑飞的时候,我们就可以按下一个复位按键,让程序重新初始化重新运行,这个过程就叫做手动复位,最典型的就是我们电脑的重启按钮。

        当程序死机或者跑飞的时候,我们的单片机往往有一套自动复位机制,比如看门狗,具体应用以后再了解。在这种情况下,如果程序长时间失去响应,单片机看门狗模块会自动复位重启单片机。还有一些情况是我们程序故意重启复位单片机。

        电源、晶振、复位构成了单片机最小系统的三要素,也就是说,一个单片机具备了这三个条件,就可以运行我们下载的程序了,其他的比如 LED 小灯、数码管、液晶等设备都是属于单片机的外部设备,即外设。最终完成我们想要的功能就是通过对单片机编程来控制各种各样的外设实现的。

3. LED小灯

        LED(light-emitting diode),即发光二极管,俗称 LED 小灯,它的种类很多,参数也不尽相同,我们板子上用的是普通的贴片发光二极管。这种二极管通常的正向导通电压是 1.8V到 2.2V 之间,工作电流一般在 1mA~20mA 之间。其中,当电流在 1mA~5mA 之间变化时,随着通过 LED 的电流越来越大,我们的肉眼会明显感觉到这个小灯越来越亮,而当电流从5mA~20mA 之间变化时,我们看到的发光二极管的亮度变化就不是太明显了。当电流超过20mA 时,LED 就会有烧坏的危险了,电流越大,烧坏的也就越快。所以我们在使用过程中应该特别注意它在电流参数上的设计要求。

        那么下面我们来看一下这个发光二极管在开发板上的设计应用。首先来看图 2-3。

        图 2-3 是我们开发板上的 USB 接口电路,通过 USB 线,电脑给我们的开发板供电和下载程序以及实现电脑和开发板之间的通信。从图上可以看出,USB 座共有 6 个接口,其中 2脚和 3 脚是数据通信引脚,1 脚和 4 脚是电源引脚,1 脚是 VCC 正电源,4 脚是 GND 即地线。5 脚和 6 脚是外壳,我们直接接到了 GND 上,大家可以观察一下开发板上的这个 USB座的 6 个引脚。

        我们现在主要来看 1 脚 VCC 和 4 脚 GND。1 脚通过 F1(自恢复保险丝)接到右侧,在正常工作的情况下,保险丝可以直接看成导线,因此左右两边都是 USB 电源+5V,自恢复保险丝的作用是,当你后级电路哪个地方有发生短路的时候,保险丝会自动切断电路,保护开发板以及电脑的 USB 口,当电路正常后,保险丝会恢复畅通,正常工作。

        右侧有 2 条支路,第一条是在+5V 和 GND 接了一个 470uF 的电容,电容是隔离直流的,所以这条支路是没有电流的,电容的作用,我们下节课再介绍,这节课我们主要看第二条支路。我们把第二条支路摘取出来就是如图 2-4 这个样子。

        发光二极管是二极管中的一种,因此和普通二极管一样,这个二极管也有阴极和阳极,习惯上也称之为负极和正极。原理图里的 LED 画成这样方便在电路上观察,方向必须接对了才会有电流通过让 LED 小灯发光。刚才提到了我们接入的 VCC 电压是 5V,发光二极管自身压降大概是 2V,那么在右边 R34 这个电阻上承受的电压就是 3V。那么现在我们要求电流范围是 1~20mA 的话,就可以根据欧姆定律 R=U/I,把这个电阻的上限和下限值求出来。

        U=3V,当电流是 1mA 的时候,电阻值是 3K;当电流是 20mA 的时候,电阻值是 150欧,也就是 R34 的取值范围是 150~3K 欧姆。这个电阻值大小的变化,直接可以限制整条通路的电流的大小,因此这个电阻我们通常称之为“限流电阻”。在图 2-3 中,我们用的电阻是1K,这条支路电流的大小,我想大家可以轻松计算出来了,而这个发光二极管在这里的作用,是作为电源指示灯的,使用 USB 线将开发板和电脑连起来,这个灯就会亮了。

        同理,我们在板子后级开关控制的地方,又添加了一个 LED10 发光二极管,作用就是当我们打开开关时,这个二极管才会亮起,如图 2-5 所示。

        大家注意,这里的开关虽然只有一个,但是是 2 路的,2 路开关并联能更好的确保给后级提供更大的电流。电容 C19 和 C10,都是隔离断开直流的,作用我们下节课介绍,这里大家可以忽略。

        那么下面呢,我们把图 2-4 进行一下变化,把右侧的 GND 去掉,改成一个单片机的 IO口,如图 2-6 所示。

        图 2-4 由于电源从正极到负极有电压差,并且电路是导通的,所以就会有电流通过,LED小灯因为有了电流通过,所以就会直接发光。我们把右侧的原 GND 处接到单片机 P0.0 引脚上,那么如果我们单片机输出一个低电平,也就是跟 GND 一样的 0V 电压,就可以让 LED小灯和图 2-4 一样发光了。

        因为我们的单片机是可以编程控制的,我们可以让 P0.0 这个引脚输出一个高电平,就是跟 VCC 一样的 5V 电压,那么这个时候,左侧 VCC 电压和右侧的 P0.0 的电压是一致的,那就没有电压差,没有电压差就不会产生电流,没有电流 LED 小灯就不会亮,也就是会处于熄灭状态。下面,我们就用我们的编程软件来实现控制小灯的亮和灭。

4. 程序代码编写

        这是我们的第一个实验程序,因此请大家一定要耐心,我们先来了解一些 51 单片机特有的程序语法以及 Keil 软件的基本操作步骤。

4.1 特殊功能寄存器和位定义

        我们主要是用 C 语言来对单片机编程,而有的单片机有那么几条很特殊的独有的编程语句,51 单片机就有,先介绍 2 条。

        第一条语句是:sfr P0 = 0x80;

        sfr 这个关键字,是 51 单片机特有的,他的作用是定义一个单片机特殊功能寄存器(special function register)。51 单片机内部有很多个小模块,每个模块居住在拥有唯一房间号的房间内,同时每个模块都有 8 个控制开关。P0 就是一个功能模块,就住在了 0x80 这个房间里,我们就是通过设置 P0 内部这个模块的 8 个开关,来让单片机的 P0 这 8 个 IO 口输出高电平或者低电平的。而 51 单片机内部有很多寄存器,如果我们想使用的话必须提前进行 sfr 声明。不过 Keil 软件已经把所有这些声明都预先写好并保存到一个专门的文件中去了,我们要用的话只要文件开头添加一行#include即可,这个在后边有用法详解。

        第二条语句是:sbit LED = P0^0;

        这个 sbit,就是对刚才所说的 SFR 里边的 8 个开关其中的一个进行定义。经过上边第二条语句后,以后只要在程序里写 LED,就代表了 P0.0 口(“^”这个符号在数字键 6 上边),注意这个 P 必须大写,也就是说我们给 P0.0 又取了一个更形象的名字叫做 LED。

        了解了这两个语句后,我们来大概看一下单片机的特殊功能寄存器。请注意,每个型号的单片机都会配有生产厂商所编写的数据手册(Datasheet),所以我们来看一下 STC89C52 的数据手册,从 21 页到 24 页,全部是对特殊功能寄存器的介绍以及地址映射列表。我们在使用这个寄存器之前,必须对这个寄存器的地址进行说明。是不是花花绿绿的太多了,记不住啊,这个没关系的,不需要你记住,了解一下,后边大部分我会慢慢给大家解释,少部分需要用到的时候,自己过来查手册就可以了,做技术不是为了应付考试,你可以随时翻阅手册查找你需要的资料。

        如图 2-7,是截取的手册中第 22 页最下边的一个表格。

        我们来看一下这个表,其中 P4 口 STC89C52 对标准 51 的扩展,我们先忽略它,只看前边的 P0、P1、P2、P3 这 4 个,每个 P 口本身又有 8 个控制端口。大家可以结合我们的开发板原理图或者图 2-1 来看,那么这样就确定了我们的单片机一共有 32 个 IO 口(IO,Input和 Output,分别是输入和输出)。

        其中 P0 口所在的地址是 0x80,一共有从 7 到 0 这 8 个 IO 口控制位,后边有个 Reset Value(复位值),这个很重要,是我们看寄存器必看的一个参数,8 个控制位复位值全部都是 1。这就是告诉我们,每当单片机上电复位的时候,所有的引脚的值默认是都是 1,即高电平,我们在设计电路的时候也要充分的考虑这个问题。

        那么上边那 2 条语句,我们写 sfr 的时候,必须要根据手册里的这个地址(Add)去写,写sbit 的时候,就可以直接将一个字节其中某一位取出来。我们编程的时候,也有现成的写好寄存器地址的头文件,我们直接包含该头文件就可以了,不需要逐一去写了。

4.2 新建一个工程

        对于单片机程序来说,每个功能程序,都必须要有一个配套的工程(Project),即使是点亮 LED 这样简单的功能程序也不例外,因此我们首先要新建一个工程,打开我们的 Keil 软件后,点击:Project-->New uVision Project...然后会出现一个新建工程的界面,如图 2-8 所示。

        现在讲到了第一章,所以我们在硬盘上建立一个 lesson2 的目录,然后把 LED 这个工程的路径指定到这里,这样方便今后管理程序,不同的功能程序放到不同的文件夹下,并且给这个工程起一个名字叫做 LED,软件会自动添加扩展名.uvproj。如图 2-9 所示。

        我们直接点保存就可以了,工程会自动保存成 LED.uvproj 文件,下次要打开 LED 这个工程时,可以直接找到文件夹,双击这个.uvproj 文件就可以直接打开了。

        保存之后会弹出一个对话框,这个对话框让我们选择单片机型号。因为 Keil 软件是外国人开发的,所以我们国内的 STC89C52 并没有上榜,但是只要选择同类型号就可以了。因为51 内核是由 Intel 公司创造的,所以这里我们直接选择 Intel 公司名下的 80/87C52 来代替,这个选项的选择对于后边的编程没有任何的不良影响。如图 2-10 所示。

        点击 OK 之后,会弹出一个对话框,如图 2-11 所示,每个工程都需要一段启动代码,如果点“否”编译器会自动处理这个问题,如果点“是”,这部分代码会提供给我们用户,我们就可以按需要自己去处理这部分代码,那这部分代码在我们初学 51 的这段时间内,一般是不需要去修改的,但是随着技术的提高和知识的扩展,我们就有可能会需要了解这块内容,因此这个地方我们选一下“是”,让这段代码出现,但是我们暂时不需要修改它,大家知道这么回事就可以了。

        这样工程就建立好了,如图 2-12 所示,如果我们点击 Target 1 左边的加号,会出现我们刚才加入的初始化文件 STARTUP.A51,这个我们先不管。

        工程有了之后,我们要建立编写代码的文件,点击 File-->New,如图 2-13,新建一个文件,也就是我们编写程序的平台。然后点 File-->Save 或者直接点击那个 Save 的快捷键,可以保存文件,保存时我们把它命名为 LED.c,这个地方必须加上.c,因为如果写汇编语言,这个地方的扩展名是.asm,头文件就是.h 等等,我们编写的是 C 语言程序,这个地方必须自己添加文件的扩展名.c,如图 2-14 所示。

        现在我们就可以在我们建立好的文件中输入我们的程序代码了,在编写之前还有个工作要做。我们每做一个功能程序,必须要新建一个工程,一个工程代表了单片机要实现的一个功能。但是一个工程,有时候我们可以把我们的程序分多个文件写,所以每写一个文件,我们都要添加到我们所建立的工程中去,鼠标右键点 Source Group 1,点 Add Files to Group ‘Source Group 1’...,如图 2-15 所示。

        在弹出的对话框中,单击 LED.c 选中它,然后点 Add,或者直接双击 LED.c 都可以将文件加入到这个工程下,然后单击 Close,关闭添加。这个时候大家会看到在 Source Group 1下边又多了一个 LED.c 文件。

4.3 编写点亮小灯的程序

        忙活了半天,准备工作做了那么多,终于要编写我们的程序代码了。如果学过 C 语言的话,你应该很轻松的跟着我的编程自己写出来,如果没学过 C 语言也没关系,你先照着我的抄,我会在合适的位置写出来对 C 语言语法的解释,这样抄几次后再看看解释,就应该很明白了,抄的时候一定要认真,尤其标点符号不可以搞错。

#include <reg52.h>     //包含特殊功能寄存器定义的头文件

sbit LED = P0^0;     //位地址声明,注意:sbit 必须小写、P 大写!

void main()         //任何一个 C 程序都必须有且仅有一个 main 函数
{                     //{}是成对存在的,在这里表示函数的起始和结束
    LED = 0;         //分号表示一条语句结束
}

        先从程序语法上来分析一下。

1、main 是主函数的函数名字,每一个 C 程序都必须有且仅有一个 main 函数。

2、void 是函数的返回值类型,本程序没有返回值,用 void 表示。

3、{}在这里是函数开始和结束的标志,不可省略。

4、每条 C 语言语句以;结束的。

        逻辑上来看,程序这样写就可以了,但是在实际单片机应用中,存在一个问题。比如我们的程序空间可以容纳 100 行代码,但是我们实际上的程序只用了 50 行代码,当运行完了50 行,再继续运行时,第 51 行的程序不是我们想运行的程序,而是不确定的未知内容,一旦执行下去程序就会出错从而可能导致单片机自动复位,所以我们通常在程序中加入一个死循环,让程序停留在我们希望的这个状态下,不要乱运行,有以下两种写法可以参考:

参考程序一:                    参考程序二:

#include                            #include

sbit LED = P0^0;               sbit LED = P0^0;

void main()                         void main()

{                                         {

        while(1)                               LED = 0;

        {                                           while(1);

                LED = 0;            }

        }

}

        程序一的功能是程序在反复不断的无限次执行 LED = 0;这条语句,而程序二的功能是执行一次,然后程序直接停留下来等待,相对程序一来说程序二更加简洁一些。针对于图 2-6,我们这个程序能够把小灯点亮,但是这个程序却点不亮我们板子上的小灯,这是为什么呢?

        这里大家就要培养一个意识了,我们做单片机编程,实际上算是硬件底层驱动程序开发,这种程序的开发,是离不开电路图的,必须根据我们的电路图来进行程序的编写。如果我们设计电路板的电路图和图 2-6 一样的话,程序可以成功点亮小灯,但是如果不一样,就可能点不亮。

        我们的开发板上,还有一个 74HC138 作为 8 个 LED 小灯的总开关,而 P0.0 仅仅是个分开关。如同我们家里总是有一个供电总闸,然后每个电灯又有一个专门的开关,我们刚才的程序仅仅打开了那个电灯的开关,但是没有打开那个总电闸,所以程序需要加上这部分代码。

        因为这节课要介绍的内容比较多,所以我们把 74HC138 的原理以及为什么要加额外的代码在下节课统一介绍,这节课我们直接加上这部分代码,大家知道有这么一回事就可以了。

#include <reg52.h>      //包含特殊功能寄存器定义的头文件

sbit LED = P0 ^ 0;      //位地址声明,注意,sbit必须小写、P大写
sbit ADDR0 = P1 ^ 0;
sbit ADDR1 = P1 ^ 1;
sbit ADDR2 = P1 ^ 2;
sbit ADDR3 = P1 ^ 3;
sbit ENLED = P1 ^ 4;

void main()
{
    ENLED = 0;
    ADDR3 = 1;
    ADDR2 = 1;
    ADDR1 = 1;
    ADDR0 = 0;
    LED = 0;    //点亮小灯
    while(1);   //程序停止在这里
}

        写了这么多啰嗦的语句,刚开始大家可能觉得很麻烦,为什么有的书上程序很简单就可以点亮小灯,我们这里却这么麻烦呢。大家要了解一点,就是我们做这个学习板,虽然仅仅提供给大家简单学习使用,但是我们也得按照实际产品的开发模式去设计,所以综合考虑因素很多,大家学到后边就会明白它的设计价值了,这里大家只要跟着我们去做就可以了。

        程序编好了,我们要对我们的程序进行编译,生成我们需要的可以下载到单片机里的文件,在编译之前,我们先要勾选一个选项,Project-->Options for Target ‘Target1’...,或者直接点图 2-17 中红框内的快捷图标:

        在弹出的对话框中,点击 Output 选项页,勾选其中的“Create HEX File”复选框,然后点 OK,如图 2-18 所示。

        设置好以后呢,点击“Project-->rebuild all target files”,或者鼠标点击图 2-19 中红框内的快捷图标,就可以对程序进行编译了。

        编译完成后,在我们的 Keil 下方的 Output 窗口会出现相应的提示,大家注意看图 2-20,这个窗口告诉我们编译完成后的情况,data=9.0,指的是我们的程序使用了单片机内部的 256字节 RAM 资源中的 9 个字节,code=29 的意思是使用了 8K 代码 Flash 资源中的 29 个字节。当提示“0 Error(s), 0 warning(s)”表示我们的程序没有错误和警告,就会出现“creating hex file from “LED”...,意思是从当前工程生成了一个 HEX 文件,我们要下载到单片机上的就是这个HEX 文件。如果出现有错误和警告提示的话,就是 Error 和 warning 不是 0,那么我们就要对程序进行检查,找出问题,解决好了再进行编译产生 HEX 才可以。

        到此为止,程序就编译好了,下边我们就要把编译好的程序文件下载到单片机里了。

5. 程序下载

        首先,我们要把硬件连接好,把板子插到我们的电脑上,打开设备管理器查看所使用的是哪个 COM 口,如图 2-21 所示,找到“USB-SERIAL CH340(COM5)”这一项,这里最后的数字就是开发板目前所使用的 COM 端口号。

        然后 STC 系列单片的下载软件——STC-ISP,如图 2-22 所示。

  下载软件列出了 5 个步骤:第一步,选择单片机型号,我们现在用的单片机型号STC89C52RC,这个一定不能选错了;第二步,点击“打开程序文件”,找到我们刚才建立工程的那个 lesson2 文件夹,找到 LED.hex 这个文件,点击打开;第三步,选择刚才查到的 COM口,波特率使用默认的就行;第四步,这里的所有选项都使用默认设置,不要随便更改,有的选项改错了以后可能会产生麻烦。第五步,因为 STC 单片机要冷启动下载,就是先点下载,然后再给单片机上电,所以我们先关闭板子上的电源开关,然后点击“Download/下载”按钮,等待软件提示你请上电后,如图 2-23 所示,然后再按下板子的电源开关,就可以将程序下载到单片机里边了。当软件显示“已加密”就表示程序下载成功了,如图 2-24 所示。

        程序下载完毕后,就会自动运行,大家可以在板子上看到那一排 LED 中最右侧的小灯已经发光了。那现在如果我们把 LED = 0 改成 LED = 1,再重新编译程序下载进去新的 HEX 文件,灯就会熄灭。至此,点亮一个 LED 的实验已经完成,终于迈出了第一步,是不是还挺好玩的呢。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1822499.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

GLS-3004K 端子排静态双位置继电器 AC115V 导轨安装约瑟 JOSEF

系列型号&#xff1a; GLS-3002K端子排静态双位置继电器&#xff1b; GLS-3204K端子排静态双位置继电器&#xff1b; GLS-3220端子排静态双位置继电器; GLS-3004K端子排静态双位置继电器; 一、用途 GLS系列端子排静态双位置继电器用于交直流操作的各种保护与自动控制系统中,作为…

Dubbo-使用zookeeper作为注册中心时节点的概述

本文内容很容易理解&#xff0c;会阐述当dubbo使用zookeeper作为注册中心时候&#xff0c;zookeeper节点是什么样子的 本文的代码使用的dubbo版本是2.7.x&#xff0c;几年前的版本了&#xff0c;但是不影响探究 首先我们创建一个简单的maven项目&#xff0c;然后写出一段dubb…

分布式事务的八种方案解析(1)

针对不同的分布式场景业界常见的解决方案有2PC、TCC、可靠消息最终一致性、最大努力通知等方案&#xff0c;以下总结8 种常见的解决方案&#xff0c;帮助大家在实际的分布式系统中更好地运用事务。 1.2PC 二阶段提交协议&#xff08;Two-phase commit protocol&#xff09;&…

Tensorflow入门实战 T04-猴痘识别

本篇文章主要&#xff1a;tensorflow 运行环境&#xff1a;本地cpu 运行epoch&#xff1a;50 1、tensorflow官网 tensorflow的官网教程。初学者的 TensorFlow 2.0 教程 | TensorFlow Core 官网上有图像分类的相关详细描述还有代码示例。 2、完整代码展示 from tensorflo…

进阶篇04——视图

简介及基本语法 视图的检查选项 可以通过视图进行数据的增删改查操作&#xff0c;但由于视图是一张虚拟表&#xff0c;所以操作的实际上是视图的基表&#xff0c;即创建视图时select语句操作的表 cascaded 自己还测试了一下这种情况&#xff1a;当V1和V2都没有加检查选项&…

华三HCL模拟器安装及华三防火墙配置

0、前言 最近跟模拟器杠上了&#xff0c;主要是需要运行防火墙&#xff0c;目前已经成功模拟出华为、山石防火墙&#xff0c;而且模拟出来的设备能与物理网络环境进行互联。现在我又盯上华三防火墙了。 首先下载模拟器&#xff1a; 下载地址&#xff1a;H3C网络设备模拟器官方免…

EasyExcel文件导出,出现有文件但没有数据的问题

一开始由于JDK版本过高&#xff0c;我用的17&#xff0c;一直excel没有数据&#xff0c;表头也没有&#xff0c;后来摸索了好久&#xff0c;找了资料也没有&#xff0c;后来改了代码后报了一个错误&#xff08;com.alibaba.excel.exception.ExcelGenerateException: java.lang.…

进程状态及其转换

0号进程(idle):在linux系统启动的时候最先运行的进程就是0号进程&#xff0c;0号进程又叫空闲进程。如果系统上没有其他进程执行那么0号进程就执行。0号进程是1号进程和2号进程的父进程 1号进程(init):init进程是由0号进程创建得到的&#xff0c;它的主要工作是系统的初始化。…

Spring Security 与 JWT、OAuth 2.0 整合详解:构建安全可靠的认证与授权机制

Spring Security 与 OAuth 2.0 整合详解&#xff1a;构建安全可靠的认证与授权机制 将 JWT&#xff08;JSON Web Token&#xff09;与 OAuth 2.0 整合到 Spring Security 中可以为应用程序提供强大的认证和授权功能。以下是详细的整合步骤和代码示例。 1. 引入依赖 首先&am…

【开源项目】重庆智慧城市案例~实景三维数字孪生城市CIM/BIM

飞渡科技数字孪生重庆管理平台&#xff0c;以实景三维平台为支撑&#xff0c;以城市数据库对接为核心&#xff0c;利用数字孪生技术&#xff0c;结合云计算、物联网IOT等技术&#xff0c;对接城市规划、智能交通、和公共安全等系统。 利用平台强大的国产自研渲染引擎&#xff0…

怎么压缩视频大小

在数字时代&#xff0c;视频已成为我们日常生活和工作中不可或缺的一部分。然而&#xff0c;视频文件的大小也越来越大&#xff0c;这给存储和传输带来了不小的挑战。因此&#xff0c;学会如何有效地压缩视频文件&#xff0c;就显得尤为重要。本文将详细介绍一种常用的视频压缩…

vscode中模糊搜索和替换

文章目录 调出搜索&#xff08;快捷键&#xff09;使用正则&#xff08;快捷键&#xff09;替换&#xff08;快捷键&#xff09;案例假设给定文本如下目标1&#xff1a;查找所有函数名目标2&#xff1a;替换所有函数名为hello目标3&#xff1a;给url增加查询字符串参数 调出搜索…

Coursera耶鲁大学金融课程:Financial Markets 笔记Week 01

Financial Markets 本文是学习 https://www.coursera.org/learn/financial-markets-global这门课的学习笔记 这门课的老师是耶鲁大学的Robert Shiller https://en.wikipedia.org/wiki/Robert_J._Shiller Robert James Shiller (born March 29, 1946)[4] is an American econ…

如何用Xcode创建你的第一个项目?学起来

前言 上一期&#xff0c;咱们已经有安装XCode的教程了。有小伙伴说建议跳过&#xff0c;嗯。。。如果你对开发很熟悉&#xff0c;那可以。但如果不熟悉&#xff0c;建议还是按照教程一步步来哦&#xff01; 毕竟统一了开发工具&#xff0c;咱们后续讲的内容学习起来也会简单一…

U-Mail反垃圾邮件网关助力企业抵御垃圾邮件,守护邮箱安全

在数字化时代&#xff0c;电子邮件已成为企业沟通不可或缺的工具&#xff0c;它在促进信息流通和提高工作效率方面扮演着关键角色。然而&#xff0c;随着电子邮件使用的普及&#xff0c;垃圾邮件问题也日益凸显&#xff0c;特别是那些携带恶意软件或钓鱼链接的邮件&#xff0c;…

2024 年最新 Python 调用 OpenAi 详细教程实现问答、图像合成、图像理解、语音合成、语音识别(详细教程)

OpenAi 环境安装 首先确保您的计算机上已经安装了 Python。您可以从 Python 官方网站下载并安装最新版本 Python。安装时&#xff0c;请确保勾选 “Add Python to PATH” &#xff08;添加环境变量&#xff09;选项&#xff0c;以便在 cmd 命令行中直接使用 Python。 安装 Op…

如何将ai集成到项目中,方法二

上一篇文章&#xff1a;如何将ai集成到radsystems项目中&#xff0c;在项目中引入ai-CSDN博客 上一篇文章内容主要针对于未实现权限分离的项目&#xff0c;这篇文章主要来说一下权限分离的项目怎么做&#xff0c;以及注意的细节。 一、编写前端router.js 二、编写前端askai.vu…

qemu microvm 测试运行记录

[v3] Introduce the microvm machine type | Patchew 下载获取rootfs wget http://dl-cdn.alpinelinux.org/alpine/v3.10/releases/x86_64/alpine-minirootfs-3.10.2-x86_64.tar.gz qemu-img create -f raw alpine-rootfs-x86_64.raw 1G losetup /dev/loop0 alpine-rootfs-x86…

服务器哪些因素会影响到网站SEO优化?

您是否曾想过&#xff0c;您的 SEO 性能下降&#xff0c;可能是网站服务器出了问题?鉴于此&#xff0c;在本文中&#xff0c;我们将探讨哪些服务器因素会影响您网站的 SEO&#xff0c;并提供可行的建议。 页面速度 搜索引擎非常看重您网站的加载速度。加载缓慢的网站会给用户体…

jenkins使用注意问题

1.在编写流水线时并不知道当前处在哪个目录&#xff0c;导致名使用不当&#xff0c;以及文件位置不清楚 流水线任务默认路径是&#xff0c;test4_mvn为jenkins任务名 [Pipeline] sh (hide)pwd /var/jenkins_home/workspace/test4_mvn maven任务也是&#xff0c;看来是一样的…