【STC单片机学习】第六课:单片机控制第一个外设-LED灯
2022-08-19 来源:csdn
1.6.1.单片机编程的一般步骤
1.6.1.1、目标分析。我们的目标是点亮开发板上的LED灯。
1.6.1.2、原理图分析 普中51-双核-A7开发板原理图
(1)目标器件(LED)工作原理
LED的工作是有方向性的,只有当正级接到LED阳极,负极接到LED的阴极的时候才能工作,如果反接LED是不能正常工作的。
(2)相关模块电路连接
(3)控制线路分析:相关IO端口是哪些?如何控制才能亮呢?
1.6.1.3、代码编写、编译(主要工作)
1.6.1.4、下载与调试(结果和预期不一致)
1.6.2.原理图与控制方法分析
1.6.2.1、原理图概况浏览
(1)目的1:把原理图的相关部分摘录出来重点看
原理图中:LED/交通灯模块 左边是原理图,右边是实物图
这个LED亮不亮取决去什么?取决于J19和J18的电平高低:高:不亮,低:不亮
1.6.2.2、74HC245芯片介绍 数码管的一个芯片
(1)要知道这个芯片怎么工作,就要看他的数据手册 74HC245中文参考手册
(2)第一步:找到它的数据手册
(3)第二步:原理图和芯片的原理图引脚对应
(4)管脚定义说明和功能真值表
OE和DIR的状态决定了数据方向。
高阻态:指的是电路的一种输出状态,既不是高电平也不是低电平。高阻态只有电容效应,没有电阻效应;阻抗很高很高,相当于断开。如果高阻态再输入下一级电路的话,对下级电路无任何影响,和没接一样,如果用万用表测的话有可能是高电平也有可能是低电平,随它后面接的东西定。
1.6.2.3、硬件原理图分析结论
(1)原理图及开发板默认跳线帽:当我们接线(接线方式为Px端口和J19/J18用杜邦线连接起来)后,其实相当于Px端口和LED的负极直接相连了,而LED的正极接VCC了。
(2)结论是:Px端口的8个引脚输出低电平时则LED亮;输出高电平时则LED灭。
1.6.3.第一个实验:点亮LED
1.6.3.1、创建工程与文件
(1)创建空工程
(2)创建led.c并关联到工程
(3)模式化书写:头文件包含与main函数外壳
1.6.3.2、如何用C语言进行IO端口控制
(1)P0 这个符号在C语言代码中的特殊含义:在REG52.h头文件中
(2)十六进制数:一个十六进制数对应二进制4个位。 0xFF ==1111 1111
(3)位、字节、IO端口、IO口:位对应IO口,字节对应IO端口
(4)硬件接线方式对编程的影响
1.6.3.3、点亮LED
(1)点亮8颗LED
(2)点亮4颗LED(自己完成)
(3)隔一颗点亮一颗LED(自己完成)
(4)全部熄灭8颗LED(自己完成)
1.6.4.如何让LED闪烁
1.6.4.1、闪烁的本质含义:亮-延时-灭-延时
(1)由于人眼睛有视觉暂留(电影每帧1/24秒),所以亮和灭之间的延时时间选择非常重要
(2)如果延时时间太短(譬如20ms),这时候上一次灭眼睛还没反应过来就到了下一次亮,此时你会觉得灯是一直亮着的。和一直亮着的区别是亮度低一些。但是是看不到闪烁的。
(3)延时时间逐渐增大慢慢就能看到闪烁的,大到一定程序就能看到明显的一亮一灭了。
1.6.4.2、单片机如何实现延时
(1)单片机执行每条指令需要一定时间
(2)单片机开机后不能休息
(3)单片机可以“空转”来“浪费时间”(在STARTUP.A51里面有很多空转指令)。所以延时的空隙,他在做空转指令!
1.6.4.3、C语言实现延时
(1)笨办法:放多条指令实现延时
(2)正确方法:使用C语言循环语句实现延时 写delay,以后会常用!
要求:
1、能够用C语言编写一个delay函数,实现一段时间的延时,从而实现LED闪烁即可。
2、改变延时函数中的i和j的数值,去实际观察效果然后思考为什么。后面会学习,如何控制指定时间的延时!---定时器
1.6.5.C语言循环语句学习
1.6.5.1、while循环
(1)格式
条件初始化
while (条件)
{
// 循环体, 若干条代码
// 循环体中包含条件增量
}
1.6.5.2、for循环 用的最多的,嵌入式里用的少!
(1)格式
for (循环初始化; 循环条件; 循环增量)
{
// 循环体
}
1.6.5.3、do while循环 用的很少很少
1.6.6.流水灯效果实现1---延时函数
1.6.6.1、什么是流水灯
1.6.6.2、流水灯本质分析
(1)流水灯的本质其实就是不同的亮的状态相互间隔一定时间。
(2)流水灯
第1个状态等于0x7F(011111111),
第2个状态等于0xBF(101111111),
第3个状态等于0xDF(11011111),
第4个状态等于0xEF(11101111),
第5个状态等于0xF7(11110111),
第6个状态等于0xFB(11111011),
第7个状态等于0xFD(11111101),
第8个状态等于0xFE(11111110),
(3)延时时间越长流水灯就流的越慢,越短就流水越快。
(4)8个状态一次执行,完成后从头开始,其实就是一个循环
1.6.6.3、编程实现流水灯
分析就会发现:流水灯和闪烁并没有本质差别。
大家可以自己设计下,让任意的灯实现流水!C语言不能使用二进制0b
讨论!
1.6.7.流水灯效果实现2
1.6.7.1、上节程序的缺陷分析
功能实现了,但是写的太笨了,如果状态变多程序就会更长。
1.6.7.2、改进思路:通过变量运算来得到合适的端口输出值
(1)首先定义变量unsigned char a,初值等于0x80(10000000)
(2)8个状态,其实就是a依次右移0-7位
(3)我们这样就相当于是用C语言让单片机自己去运算得到每个状态的端口值,而不用自己事先去计算好。这样程序就简化了。
1.6.7.3、C语言移位运算介绍
C语言中有移位运算符,>>可以右移,<<可以左移.
(无符号数移位:移出去的位丢掉了,空出来的位用0补)
无符号:左移:低位补0;右移:高位补0;
有符号:左移:低位补0,右移:若正数,高位补0,负数,高位补1 -> 一句话概括:高位补符号位
知识链接:C语言的移位操作 无符号移位和有符号移位有差别!尽量用无符号位。
1.6.7.4、编程实践
(1)必须用到C语言的2种技巧:左移(右移)、按位取反
(2)C语言中~这个符号表示对一个数字按位取反,譬如一个数01111111按位取反后变成了10000000。而11011111按位取反后变成了00100000
思考一下,a的值发生改变吗??
如何实现灯向另一个方向移动?
1.6.8.跑马灯效果实现
1.6.8.1、什么是跑马灯
(1)跑马灯和流水灯非常像,不同的是:流水灯是8颗LED其中7灭1亮,亮的在移动;跑马灯是8颗LED7亮1灭,灭的在移动。
1.6.8.2、实现思路分析
0x7f 10000000
0xbf 01000000
0xdf 00100000
1.6.8.3、实践编程
这个直接按照逻辑实现!
1.6.8.4、总结
向另一个方向,只需修改初始值和左移右移。