本篇内容是观看B站江科大自化协UP主的教学视频所做的笔记,对其中内容有所引用,并结合自己的单片机板块进行了更改调整。
以下笔记内容以一个视频为一个片段(内容较多,可能不适合速食,望见谅)
根据测试,目录存在没法跳转准确的可能性(可能是因为内容太多的原因,可以考虑用左下方侧的目录跳转)
目录
1-0 下载keil时找不到文件路径问题的解决方法之一
1-1 单片机及开发板介绍
单片机(英文Micro Controller Unit,简称MCU)
STC89C52单片机
命名规则
以下是几种封装类型及图片:
单片机内部结构
开发板介绍
2-1 点亮一个LED
输入代码步骤:
编译配置文件
LED模块认识
写入程序
烧录程序
改进程序
补充程序
2-2 LED闪烁
获取延时代码
写入程序
2-3 LED流水灯
写入程序
优化程序
补充:获得其他文件的代码方式
3-1 独立按键控制LED亮灭
独立按键原理图
补充:
写入代码
补充:复位按键
3-2 独立按键控制LED状态
按键的抖动
消抖方法:
写入程序
3-3 独立按键控制LED显示二进制
写入代码
原理:
注意事项:
改进:
3-4 独立按键控制LED移位
4-1 静态数码管显示
LED数码管
数码管引脚定义
一位数码管
四位一体数码管
数码管原理图
写入代码
补充:
4-2 动态数码管显示
尝试写入代码
数码管的消隐
自己尝试
链接如下:
https://mp.csdn.net/mp_blog/creation/editor/127588145
该博客是我遇到找不到下载文件路径时,处理的解决方法,希望能对同样有问题的朋友有所帮助。
结构:内部集成了CPU、RAM、ROM、定时器、中断系统、通讯接口等一系列电脑的常用硬件功能(不等于CPU,相当于小型计算机,但性能远低于计算机,能构成完整系统)
任务:信息采集(依靠传感器)、处理(依靠CPU)和硬件设备(例如电机,LED等)的控制
优点:单片机成本低、体积小、结构简单,在生活和工业控制领域大有所用
——>51单片机开发清一色使用的芯片(初学者)
所属系列:51单片机系列
(背景知识:51单片机是指与8051单片机内核相同的单片机的统称,其中8051单片机是指intel于80年代开放的单片机,有51,就叫51单片机)
公司:STC公司(中国)
位数:8位(计算机32位或64位)
RAM(random access memory,随机存储器):512字节
作用:短期存储(相当于运行内存,关机后清零,无法长期保存)
ROM(read only memory,只读存储器):8K(Flash)
—>Flash ROM比普通ROM读写速度快,擦写方便。
作用:长期存储(相当于手机内存跟电脑硬盘,能长期保存,负责存放我们烧写的程序)
工作频率:12MHZ(取决于单片机获得的时钟)
作用:知道单片机的速度
晶振图:(下图蓝色圈内)——>给单片机提供时钟
命名图参考
所用单片机图
下面是用自己的单片机数字来对应:
1、STC表示公司名;
2、89表示系列(这里表示STC的12T/6T 的8051单片机);
3、C代表工作电压(C表示5.5~3.8V);
4、52代表程序空间大小(这里的程序空间大小为8K字节);
5、RC表示RAM的空间大小(RC为512字节);
Ps:这里单出来了RC,与视频的介绍的52跟RC合并为52不同,可能存在更新。
6、40表示工作频率(最大可达40MHZ);
Ⅰ、DIP(双列直插式封装)
普及:DIP与PDIP同样指双列直插,只不过后者加入了P,强调是塑料封装。
Ⅱ、PLCC(表面贴装型封装)
Ⅲ、QFP(方型扁平式封装——表面贴装型一种)
普及:前面的L(1.4mm)或T(1.0mm)或没有(2.0-3.6mm),决定三种厚度。
Ⅳ、BGA(球栅阵列封装)
9、40表示管脚数
值得一提的是,如果前面内容相同,而封装不一样,那么只是外表不同,内部是一样的。
如下图:
内部芯片很小,而外面的部分(也就是方形铁壳)其实也属于一种外设(除芯片外的其他部件)。——(不得不说,江科大up主真的很有探索精神以及教学能力,感动)
几乎所有单片机都有兼容内核,或者说几乎一样的8051内核。(区别在外面——即除了中央方块单片机外的板子上外设不同)
看门狗:防止程序跑飞。
SRAM:静态内存(即上面说的RAM)。
闪存:即上面说的ROM。
I/O端口:即管脚(也可以叫引脚)内部接入地方,用于输入输出。
单片机管脚图:(需要记忆,如I/O口位置)
其中:1、Vcc为电源正极,Gnd为电源负极。
2、XTAL1、XTAL2外接晶振,给单片机提供时钟。
3、引脚八个为一组(从0~7),共三组(从0~3)。
详细内部图:(取图来自购买的开发板附带资料)
其中结构采取总线结构,CPU可通过总线访问各个外部设备。
单片机最小系统:
晶振电路(图中晶振):
部件解释:两个电容为启动电容,电阻上下两条线的就是晶振元件,额外并联的电阻是为了更稳定的工作。
作用:使单片机内部的指令能在晶振振动一次时进入下一条指令(如果没有,将一直停在第一条指令,无法进行下去)。
复位电路:
作用:使指令从第一条开始,或者说在进行时,让其重新开始。
复位原理:高电平复位(即图中RST为正极<高电平>时复位,为负极<低电平>时不复位),在电容充满后断开。(此时RST从高电平恢复为低电平)
原版图:
1、中央单片机
单片机可通过拉杆取出,但放回时需要按位置放回,否则可能会出现烧坏的问题。(通过上面的凹口定位放回)
2、LED模块
用途:可利用I/O口控制LED灯制作流水灯等。
3、独立按键与矩阵按键
用途:接收按键数值,从而实现一些功能。
4、红外接头
作用:接收遥控器的信号,可实现遥控(如自己制作家里的空调遥控器)。
附带遥控器:
5、USB下载模块(大致是这个部分,因为跟视频板子不一样)
作用:插上USB口后,即可进行单片机下载程序。
6、时钟芯片
作用:产生时间,读取时间,并将时间显示在其他屏幕上,可制作闹钟、小时钟。
7、复位系统
作用:手动按下复位按键(图中红色按键),程序从头开始执行。
8、AD\DA(模/数转换器)
作用:将模拟信号转换为数字信号给单片机,或者将数字信号转换为模拟信号给外部使用。
9、步进电机模块
作用:精确控制角度(不会随着电压变化而变化)。
Ps:需要自己购买配置(自带的是直流电机)。
10、蜂鸣器
作用:根据单片机所给的各种频率输出来响动(可输出各种频率的声音)。
11、138译码器(板子未分模块,但可以找到芯片上面的字)
作用:可以拓展I/O口,驱动数码管。
12、24C02
作用:也是一种ROM(电可擦除PROM),给它写数据时能掉电不丢失。
13、温度传感器
作用:检测温度,可以做室内测温度的系统。
14、74HC245芯片
作用:驱动数码管。
15、电位器、排座跟液晶屏
用法:液晶屏可插在上排排座(下排排座插更大的液晶屏,但需要自行购买)。
作用:电位器调节显示的清晰度,液晶屏可以显示数据信息,以及调试。
16、点阵屏
作用:可用单片机驱动,使其显示任意图案。
17、动态数码管模块
作用:显示数字或者图案(八字型)。
快捷键查看:按住Ctrl 不放,然后滚轮,可以控制放大缩小。
开发板原理图
每个接口有编号,可对应连接。(图示上分开模块,便于分开查看)
1、点击[project],再点击第一个的[New project],进入文档保存。
2、选择需要保存的位置,建立文件夹,并点击该文件夹,在下方输入文件名,点击[保存]。
3、在弹出来的页面选择对应的单片机型号(本人单片机匹配AT89C52,于是选择这个)
Ps:①这里可以通过Search框进行快速搜索,也可以选择找对应的栏一层层找下去(如果不清楚对应型号的话)
②由于keil对中国不太友好,因此无法找到STC的对应型号,但可以选择AT的(因为操作方式和功能是一样的)
4、弹出的对话框选择[否]。(因为点击[是]后,会添加启动文件,但是这个文件一般不需要改动,因此直接[否]即可)
5、接着点开文件夹,直到Target 1时(此时无法继续展开),右键,选择[Add New Item]。
6、在弹出的窗口选择编译的语言类型(这里是C File,即C语言),然后在[Name]处输入名字(一般推荐main,记得不要输入中文名,否则可能出错),点击[Add]即可添加。
1、工具栏中左下角的三个按键,从左到右依次为编译,编译工程,全部重新编译工程。我们一般用第二个进行编译。
2、每次编辑语言时,加入主函数main
3、可以点入扳手图标进入配置
调整Tab的缩进距离:
调整字体类型及大小:(左边window处选择哪种编辑语言,在1处点击调节)
4、点击三个堆叠方块左边的图标,点击[Output],将[Create]勾选,创建文件,点击[ok]退出。
目的:为了烧录时能找到程序文件(每次创建时都要点击)!!!!!!!!!!
1、识别连接图
①由图上可以知道单片机控制LED对应的引脚(根据字符一一对应,如LED模块的P20对应单片机模块的P20,这样找连接)。
②由P20~P27直接相接的电阻叫限流电阻(即图上的RP9和RP10),防止电流过大烧坏LED。
Ps:这里可能跟视频图不一样,是因为这里用的是购买单片机附赠的图,建议以自己的单片机附赠版图为准。
2、分辨电阻大小
这里的102,指的是10 00(即前面的数字是有效数字,后面一位是10的倍率,或者说0的个数),因此,如473,则是47 000
3、内部控制原理示意图
由图可知,CPU通过控制寄存器(八个一组),每个单元对应一个驱动器(增大驱动能力),连接导线到引脚,进行控制外设(除了内部单片机外,外面实现功能的部件都可以叫外设)。
其中,当写入1时,该对应单元给I/O口高电平,写入0时,给低电平。(通过这个方式控制模块的导通有无)
由模块图可知,LED已经连接了高电平(VCC)。因此当对应引脚是低电平时,电路导通,LED点亮,若为高电平,LED不点亮。
因此需要给它写入低电平的代码:
这里需要包含头文件REGX52(可通过右键,点击[Insert #include
根据进制转换表,我们知道十六进制的FE等于1111 1110,因此,将其赋予P2,可实现对应单元的高低电平赋值。(需要注意的是,要加入0x在前面表示十六进制,加入0在前面表示八进制,不加默认十进制)
通过下载的stc-isp软件,将写好的程序烧入单片机中。步骤如下:
1、选择单片机型号与串口号(一般做完第一次之后,后面就默认是选好的型号)。
这里串口号可以选择扫描快速查找(或者选择最长的那一条,往往是之前配置时显示的接口)。
2、选择程序文件
点击[打开程序文件],找到之前的文件夹位置,打开,这时会发现多了两个文件夹。
点击Object文件夹(或者两个都点一下,会发现第一个是空的),双击project文件,即可选定需要烧录的程序文件。
3、下载程序
点击[下载/编程],会发现右边变为“正在检测目标单片机”,此时直接点击电源给单片机上电,即可完成操作。
效果图:(灯亮的位置跟原视频不一样,因此说明要以自己的单片机板为准,可以测试一下区别)
因为上面的程序只有一条指令,在执行完后,会不断从头开始读取指令,也就是不断打开灯,因此要避免这个情况。
所以需要加入一个死循环使其不需要重新读取主函数指令。
这样就避免了需要不断重新读取main的情况。
根据上面的程序,可以实现间隔亮灭(借助上面的进制转换表)。
如下图:(与视频中显示不一样,以自己的为准进行调整即可)
根据上节步骤,将下面代码烧录到单片机中。
效果图:
点亮LED时的效果图:
可见两灯的亮度不同,说明确实起到了亮灭效果,但是由于LED闪烁速度快(兆赫兹),导致肉眼看不到闪烁,因此需要加入延时函数,达到目标效果。
1、点击烧录软件(stc-isp),在右上角的栏框中找到[软件延时计算器],点击。
2、根据自己单片机型号选择[系统频率]、[8051指令集],然后根据自己需要选择[定时长度]。(注意后面有毫秒与微秒的选择,一般用毫秒)
Ps:[8051指令集]的选择,可以根据右边框的适用系列判断。
由图可见STC89Cxx是Y1指令,因此这里选择这个。
Ps:系统频率可以在晶振上的数字中查看。
由图可见,这里的数字是11.0592MHz,因此对应系统频率也选择11.0592。
(以自己的单片机为准,这里的数字跟视频也有所区别)
3、完成上述操作后,系统会自动生成一串代码,点击下面的[复制代码],即可复制过来使用。
1、回到编写软件(keil)后,右键,选择[Paste]进行复制(或者直接Ctrl + v键粘贴)。
2、再加入头文件INTRINS,使语句 _nop_( ); 有定义。(该语句是空语句)
Ps:如果输入正确,右键是能查看该头文件的内容的,如果显示灰色,说明输入错误。
3、添加完函数后,需要进行调用(否则编译后会有warning,提示未调用函数)
4、最后正常烧录程序即可看到闪烁效果。
1、根据上节内容代码,移动到这里(手打或者复制粘贴),并对后面延迟函数及亮灯语句进行复制粘贴。
2、根据进制转换表,将相应的二进制数对应的十六进制数,改入其中代码。如图:
3、进行正常烧录进单片机即可看到流水灯效果。
Ps:可以通过在烧录软件中更改延时的定时长度,获得对应的函数代码,然后根据上节内容替换对应的函数,即可更改流水灯速度。
但是,这样的步骤显然过于繁琐。于是可以优化方式,实现一个函数吃遍所有毫秒。
1、首先获取1毫秒的延时函数,方法与上节一样。
2、接着将复制好的代码移动到编辑栏中,利用C语言的自定义函数的特性,将该1毫秒函数改写为自己的函数,添加参数。
这里采用了循环方式,这样可以通过输入xms的值,实现循环多少次一毫秒,从而达到循环想要的任意毫秒的目的。
Ps:可以看到这里并没有包含头文件INTRINS,是因为在延时函数中,将上节提到的空代码 _nop_(); 给删除了,所以可以不用包含该头文件(该语句在微秒使用,毫秒函数删除无大碍)
3、然后在主函数中,将之前的函数替换为现有的函数,并在括号内输入需要的毫秒数。
Ps:通过这种方式,可以自定义自己想要的速度,实现相邻灯速度不一样也可以。
4、正常烧录程序进单片机即可。
可以通过在[文件资源管理器]中找到需要获得的文件位置,找到里面的main文件(不要对多出来很多文件感到奇怪,暂时不用理会)。
然后右击main文件,点击[打开方式],点击[记事本],即可打开该文件代码,选择需要的内容复制即可。
独立按键图形
单片机上的独立按键,是轻触按键。
轻触按键:相当于是一种电子开关,按下时开关接通,松开时开关断开,实现原理是通过轻触按键内部的金属弹片受力弹动来实现接通和断开。
其中我们的单片机独立按键为这种类型:
江科大up主的破拆图:(敬佩ing)
其中独立按键图形:
由上图蓝色线,可以知道其实按键的一侧两个引脚是一条线连接的,始终导通,其中一侧引出两个接触点,另一侧引出一个接触点(金属弹片就在其中间)。
当按下按键时,上面破拆图的第二个金属片便会变形,使三个接触点相同,导通四点,再按时,金属片弹开,断开导通。
由上图的对接口分析,可知独立按键一端连接到单片机的P3寄存器的单元中,一端接到GND(正极、高电平)上,而单片机上的I/O口默认是高电平的,因此,当按下按键时,该口变为低电平,不按时,为高电平。
而且,寄存器除了能写值送入I/O口改变高低电平外,还能检测I/O口电平,并读回寄存器中,由此,我们可以检测按键是否被按下。
1、可以通过下划线形式,使得能精确到一个单元。(即可以单独控制寄存器的一个单元位,而不是八位一体进行操控)
原理:
首先打开REGX52的文件(右击,点击open)
下图可以看见该头文件包含了几个八位一体寄存器
以及每个寄存器的位寄存器(即使用下划线)
因此,在有命名的情况下,我们可以直接使用寄存器里的位寄存器,精确到单元。
2、REG52头文件与REGX52头文件的区别:前者(REG52)没有对位寄存器进行声明,需要用位寄存器时,需要自己输入补充。
3、编译器对头文件的检查不是很严格,因此可以在头文件中大小写字母都可以,也可混打(在< >内的内容)
Ps:要与P2之类的区分开,P2前面的P一定要严格大写,否则会出错。
4、可以通过工具栏中的缩进注释功能,对代码快速调整。(因为keil编译器没法ctrl + /进行一行快速注释,除非自己定义)
用法:选择需要调整的代码(利用左键选择),然后点击四个按键(第一个为退后一个Tab距离,第二个为减短一个Tab距离,第三个为注释,第四个为取消注释),即可完成操作。
Ps:第一个按键,如果不是多行的内容,点击会导致代码行内容消失,需要注意。
为了达成按住时点亮一个LED,放开时LED熄灭,于是有下面代码:
上面的P3_1代表单片机的第一个独立按键K1(P3_0=K2,P3_2=K3,P3_3=K4),根据上面的理论,检测按键按下时为低电平(即等于0),因此可以编写该代码,然后烧录程序即可得到效果。(注意一定要将判断语句放入循环,否则会导致程序只执行一遍,然后卡在循环中出不来)
Ps:因为接线的位置反了,因此K1按键对应了P3_1,而K2按键对应了P3_0,可能是由于接线更方便的原因,因此一定要对照开发板原理图进行仔细比对。
当按下复位按键时,系统会重新从第一条语句进行,可以通过这个方式,达成重新开始的想法。
复位按键(图中红色按键):
对于机械开关,当机械触点断开、闭合时,由于机械触点的弹性作用,一个开关在闭合时不会马上稳定地接通,在断开时也不会一下子断开,所以在开关闭合及断开的瞬间会伴随一连串的抖动。
由图可知,对于按下单片机的按键时,由于金属弹片的抖动,会导致单片机读取多个数据(因为单片机速度很快,处理速度快),导致按一下产生多下的效果,因此需要进行消抖。
1、加入硬件,使经过电路,途径触发器之类的硬件,过滤后再传输给单片机处理。
2、通过软件处理,写入延时程序,度过抖动时间后再进行操作。
1、首先添加延时函数(方法与2-3中自定义的延时函数方法相同)。
这里使用unsigned类型的int,是因为我们不需要负数,可以通过这种类型扩大写入的数字范围。
补充:测试代码是否有问题(适合自己建立项目时,测试哪一部分有问题)
这里暂时补充主函数为闪烁的效果,如果延时函数没问题,在烧录时能正常显示闪烁,如果有问题,那么就会出错,这样就能确保每个部分的内容不出错。避免了全部写完之后,出错需要一个个找的问题,可以写完一块检测一块内容。
2、根据需要添加主函数,可以得到下面的代码。
①上面利用判断语句,检测是否按下K1按键;
②然后进行消抖(延时20毫秒);
③接着利用while语句,使得只有松开按键才会点灯,按住不会执行下一步的效果;
④之后再消抖;
⑤最后利用取反符号(C语言中的按位取反符号~,使得二进制每一位的0转1,1转0),实现P2_0灯的亮灭转换。
3、正常烧录程序进单片机即可看到效果。
1、根据上节内容,获取延时函数。(消抖)
2、写入主函数。
这里利用了一个变量LEDNum,使得P2能够实现二进制的不断加一。(其中LEDNum是十进制数,但是到P2时会转换为二进制读取到单片机操作。
由上图,可见LEDNum不断++(加一),最终到255(二进制的1111 1111)时,再加一出现越位现象(即256为二进制的1 0000 0000,但由于之前说的,单片机是八位处理器,因此无法处理第九位的1,因此会直接舍弃,也就是越位),因此可以达到从头循环的目的,而无需加入判断语句。(此时的LEDNum经过一次循环后,数值对应的二进制数早已超过处理上限,但是不会影响实现效果)
由于单片机默认高电平(也就是P2的初始值为1111 1111),因此,可能会有想法通过直接P2++来达成效果(如上面的代码),但是最终实现的是目标效果的反向操作(也就是灭灯进位),而直接对P2按位取反是不能的(因为P2在不断改动,取反是它,加一还是它,最终会卡在1111 1111与0000 0000不断徘徊)。
原理如下:
可见是不断循环的,因此这样的代码无效。
因为P2++(加一)实现的是反向操作,于是我们可以通过P2--(减一)来实现正向操作。如下图:
经过测试,效果与上面利用变量的效果相同。
实现效果:按下K1按键,LED灯右移,按下K2按键,LED灯左移。
写入代码
1、首先获取延时函数(消抖)。获取方式可以复制其他文件的,也可按照之前的操作重新编写。
2、通过实现要求,编写右移LED灯的代码。(<<为C语言的左移一位符号)
加入if语句原因:由下图可知,P2是不动的,也就是一直为1111 1110,然后通过变量LEDNum进行移位,而LEDNum值到8时,移位越界,此时就需要进行调整,加入if语句判断,使得移位变量LEDNum进行复位。
3、接着编写左移LED灯的代码。(>>为C语言的右移一位符号)
先判断,再移位原因:因为会存在越界问题,即前面定义的LEDNum是unsigned类型的int,范围(0到65535)不包含正数,在减到0时,再减会导致恢复到最高为数字65535,因此需要先判断。
也可根据上面的越界到最高位数字这个原理,编写下面的方法:
根据试验,效果与要求相同。
总结:如果存在越位情况的话,可以采用先判断,再减的方法;如果不是越位,而是超出需要数值,则正常输入范围即可。
定义:数码管是一种简单、廉价的显示器,是由多个发光二极管封装在一起组成“8”字型的器件。
生活中的数码管:
单片机上的数码管:
连接方式:
共阴极连接
共阳极连接
LED灯及其命名:(顺时针记忆)
引脚定义序号:(逆时针记忆,序号与上面连接方式的序号相对应)(电路板上连接遵循就近原则)
点亮特定数字方式:
根据LED灯的字母序号,若我们想要点亮一个“6”,那么就需要点亮A、F、E、D、C、G这几个灯(除B和DP外的灯)。
于是根据连接方式的图(假设是共阴极连接)与引脚定义序号,由于一端是低电平(阴极),因此另一端高电平(赋值为1)点亮,低电平(赋值为0)不点亮,给对应的引脚赋值即可。(共阳极同理)
其中公共端称为位选,下面分开的引脚成为段选,给段选赋值的数字(如上图的红色数字)叫做段码。(这个也可应用于四位一体数码管)
(单片机上的数码管就是这个)
引脚定义序号:(逆时针记忆)
连接方式:
显示特定位置的特定数字方式:
根据上面连接方式,可见通过更改位选(即上方的12、9、8、6对应口)的数值,来控制其是否连通。
以连接方式上面图的共阴极连接方式为例,要使第三位的数字显示6,那么只需要让8赋值为0(阴极,低电平),其他三个位选赋值1(阳极,高电平),那么无论如何只能是第三个位置的数字亮。
(原因与发光二极管的单向导电性有关,公共端如果接反电极,那么无论如何都无法让发光二极管亮)
因为四个位置的发光二极管段选是共引脚的,因此即使段选允许导通(以共阴极为例,段选为0值,即低电平),最终显示的数值也是相同的。(需要不同的话,涉及动态数码管显示,下节内容)
通过这种方式,能节省单片机控制的I/O口数。
1、控制LED的I/O口
根据上面的动态数码管模块图,可知P00~P07控制LED的段选(下面的多个引脚),而位选(公共端)接在LED1~LED8。
接着看138译码器可以发现,位选端的LED1~LED8在其右侧,左侧由P22~P24控制,即所谓3个口控制8位。
这里便是利用了二进制数,将左侧三个I/O口当成三位二进制数字(CBA的排序方式),通过高电平为1,低电平为0的方式,对应右图的Y0~Y7,且二进制转换的十进制数,就是对应的LED数。如:
2、74HC245芯片(双向数据缓冲器)
①其中OE为使能控制脚,当连接低电平(接地)时工作,高电平不工作。(控制74HC245工作)
②DIR为direction,方向的意思,表明从该侧方向向另一侧方向缓存数据,且从另一侧读不回来。(下图的OE其实就是控制方向的,与VCC相连,控制方向向右输出数据,与GND相连,向左输出数据)
上图的黄色块叫跳线帽,负责将两个引线短路(可见其连接VCC高电平)。
③由于传入的驱动是高电平驱动,能力没有低电平驱动好,会导致LED灯比较暗,因此通过加入缓冲器,提高驱动能力(芯片接收到信号再处理输出)。
3、牌组电阻
从上图的动态数码管原理图中,这一部分负责保护电路,防止数码管电流过大。
接下来实现点亮数码管上特定位上的数字。(所用单片机连接方式为共阴极连接方式)
1、编写一个switch函数,调动对应的位选(即确定点亮的位置)。
代码根据原理图编写,得到上面结果。值得注意的是,单片机板上位置与LED顺序是反过来的,因此对应代码要反过来编写。
2、编写一个数组,使得能显示对应的数字(即找到对应的段选数值)。
编写后将寄存器P0等于对应的数组值(下标用变量,刚好下标数字便是需要显示的数字),使得能显示对应数字。
3、在主函数中调用函数,烧录程序进单片机即可。
可勾选STC-ISP烧录软件的自动装载选项,使得在keil编译后能直接打开单片机的电源即可看到效果,无需再点击[下载/编程]按键。(前提是之前已经将文件选择好,因为是检测目标文件变化才装载的)
目标效果:多个位置显示不同的数字。
作用:显示数据与调试程序更方便。
1、首先将上节内容的代码弄过来(推荐之前说的去文件处以记事本方式打开,复制对应代码)。
2、再获取自定义延时函数(可到之前LED流水灯的代码中拷贝过来)。
3、接着在主函数中编写。
该主函数内的代码,是为了在前三位显示123三个数字。烧录后发现,会很接近于直接显示123。因此,可以试试直接去除延时函数。
烧录后效果:
可见虽然同时显示了123,但是出现了残影,而前面加入延时函数却没有。为什么?
因为数码管的执行顺序是[位选—>段选—>位选—>段选······],加上单片机的高速运行,所以会出现上面的数据(段选)串入下面的数据(段选)的情况(即数据串位),即出现上面的情况。
因此需要进行消隐。
方法:在段选与位选中插入清零,这样即使串位,因为是清零,也对下一位没有影响。
于是可以得到下面的更新代码
烧录后,发现不会出现串位现象。
根据删除延时函数后发现,即使对数据进行了归零(即P0=0X00),依然会影响到数据,导致显示亮度不够(如下图)。
而删除了清零语句(P0=0X00),保留延时函数后,烧录依然会出现串位现象(如下图)。
因此,清零操作,需要配合延时函数与归零语句一同使用。