52单片机LED实验
文章目录
- 前言
- 点亮一个LED
- LED闪烁 LED灯亮灭交替
- LED流水灯
前言
我所用的板子是普中的STC89C52RC,创建文件的过程中如果你发现keil文件找不到单片机依赖,那怎么办呢
下面从创建新项目讲起
首先打开keil软件,点击project
new一个新的project在这里插入图片描述
随便取个名字点击保存进入选择依赖的界面
如果你的下拉框有第二个选项,那么直接在搜索框进行搜索选择对应的依赖
如果你的下拉框没有别的选项,那么还需要去官网下载对应的依赖
进去之后
对应着自己的版本下载或者直接把你自己的卸载了重新安装新下的也可以,我是嫌麻烦直接卸载了重新安装的下载的安装包
安装完成后的下拉框应该就有选项了,如果你有选项但是搜索不到你想要的依赖
还是进入这个mdk官网
依次选择上方的Download->Product Downloads 进入到这个页面
点击C51下载安装就可以搜索到了
选择对应依赖后点击确认,生成对应文件夹,在target1文件上右键,add group,展开文件夹,在刚刚新建的new group文件夹,右键 ,选择add new item…
选择新建C,起个名字,从左侧树形菜单栏双击这个文件,就可以在这个文本内写代码了
关于keil如何打包.HEX文件
先点击最上方红框内的按钮,然后出现2的文件框
如果你的ISIS仿真图内有晶振那么将选中部分值改为你的晶振值
如果没有则进入第三步,点击 OUTPUT
勾选红框圈起的部分点击OK
然后从左到右依次执行三个按钮打开(只点第二个也行)
这句话就表示.hex文件已经生成
做实验之前,我们首先得分析原理图,如图
1
RP9、RP10就是电阻,不过是4个电阻并联在一起,再给封装起来。连电阻主要是为了限流,如果直接连接LED,电流过大的话,会对LED有损害,也就是防止电流过大
2 二进制只有1和0这两个数字,单片机只能读懂二进制,1表示高电平,0表示低电平;
3 VCC:表示电源正极,高电平(其实就是高电压)。我们可以看见图上绿色三角形,那个就是LED(也叫发光二极管),图上三角形左边(也就是宽的那一边连接电源正极),三角形右边(有个竖线那一边连接电源负极)
所以P20-P27连接的是电源负极(这是控制LED关键的一个点),如果给P20-P27高电平,又VCC为高电平,这样就没有电势差(没有电流),LED就不会亮;相反,如果给P20-P27低电平,又VCC为高电平,这样就会有电势差(有电流),LED就会亮。那怎么给P20-P27高低电平呢,以下部分为详细说明。
CPU通过控制寄存器来控制硬件电路,硬件电路执行我们想要的功能。如图所示,驱动器只是起到加大控制力度的作用。图中控制过程:CPU->寄存器->驱动器->P20-P27
具体来说,在LED这节课中,通过CPU控制寄存器的值(1/0,1对应高点平,0对应低电平),又通过驱动器加大控制力度,控制P20-P27输出高电平还是低电平,刚好和前面的图形成闭环,原理解释完毕。
寄存器(相当于存储器):每个寄存器含8个二进制位,一般每个寄存器是8位整体读写操作的(也就是说这8个二进制位是一个整体)
点亮一个LED
有了上面的思路,CPU控制寄存器的值(1/0),控制P20-P27输出高电平还是低电平二进制
如果想控制第一个一个灯亮,C语言编码:P2=1111 1110;//控制P2引脚电平,也就是P20-P27
但是C语言识别不了二进制,因此,把二进制转变成十六进制,如图
1 二进制转变成十进制的方法在本节最后面;
2 十进制、十六进制:数字1-9没区别,数字10开始,10-A,11-B,12-C,13-D,14-E,15-F;本节课只需要记住前15数字就行了。另外,十六进制,还要加前缀0x,比如:十进制7,对应十六进制0x7;十进制15,对应十六进制0xF
写法一
#include <REGX52.H>void main()
{P2=0xFE; //FE 1111 1110 /* */ 55 0101 0101
}写法二
#include <REGX52.H>void main()
{while(1){P2=0xFE; //FE 1111 1110 /* */ 55 0101 0101}
}写法三
#include <REGX52.H>void main()
{P2=0xFE; //FE 1111 1110 /* */ 55 0101 0101while(1){}
}
1)通过PCB原理图可以知道控制LED灯亮灭的是P2口的,并且接入+VCC5V即高电平1,LED灯要那个亮的话那个线,P2端要设置为0,不亮就设置为1,有电势差,即有电流流过灯亮;
2)P2=11111110,即第一个灯亮其他灯不亮,但是我们读取是从下面的,所以不是(P2=01111111)这样写;
3)用到P2口,所有要导入头文件#…鼠标右键点击就可以加进来;
4)不能识别P2=11111110这样的类型,所有将它转为16进制,开头用0x表示16进制的数
P2=0xFE;//11111110转换可以网上搜索,计算器也可以直接算;
5)一个亮一个灭P2=0x55;//01010101
如果你跟我一样,按下的时候左边两颗闪一下,把芯片型号切换成我上图这个,至于什么原因我也不就丢暂时,另外选型的时候你要是找不到STC89C52,AT89C52也是一样的,不过AT被MIcrochip收购了,要去那个里面找哦
LED闪烁 LED灯亮灭交替
1)用STC可以生成延迟函数:根据晶振改系统频率(我们这个是12MHZ,还有其他信息(定时长度;
2)复制生成代码到主函数上面,如下图代码:(void:无返回值,这里(可以设置参数);while、do…while都表示循环;
要在主函数,及程序入口调用才可以实现延迟:如下
闪烁图片看不出来实物,我就不放了
_ nop_
表示空语句,什么都不做,这个函数要加头文件如下:
#include <INTRINS.H>
LED流水灯
流水灯,也是跟闪烁大同小异,也是在while循环中加入延时函数。具体来说,八个LED灯,在while循环中,设置每个灯亮一段时间(具体亮多少时间,也是在延时函数中设置的),这样每个灯都会亮一会再熄灭,一个接一个,就是流水灯的效果。
流水灯---->即可实现后面为–>优化
1)将上面延迟的代码复制过来;
2)在main函数里面控制P2口灯的亮灭,代码如下,如上图放在while循环里
面;
#include <STC89C5xRC.H>
#include <INTRINS.H>
void Delay500ms(void) //@12.000MHz
{unsigned char data i, j, k;_nop_();_nop_();i = 23;j = 205;k = 120;do{do{while (--k);} while (--j);} while (--i);
}void main()
{P2 = 0xFE;//1111 1110Delay500ms();P2 = 0xFD;//1111 1101Delay500ms();P2 = 0xFB;//1111 1011Delay500ms();P2 = 0xF7;//1111 0111Delay500ms();P2 = 0xEF;//1110 1111Delay500ms();P2 = 0xDF;//1101 1111Delay500ms();P2 = 0xBF;//1011 1111Delay500ms();P2 = 0x7F;//0111 1111Delay500ms();
}
3)下载到板子上测试即可
4)生成延迟1秒函数,复制到main(函数前面
5)修改生成的延迟函数,可设置控制延时时间
void Delay1ms(unsigned int xms) //@12.000MHz
{unsigned char data i, j;i = 12;j = 169;do{while (--j);} while (--i);xms--;
}
实现程序
#include <STC89C5xRC.H>
#include <INTRINS.H>void Delay1ms(unsigned int xms) //@12.000MHz
{unsigned char data i, j;i = 12;j = 169;do{while (--j);} while (--i);xms--;
}void main()
{P2 = 0xFE;//1111 1110Delay1ms(100);P2 = 0xFD;//1111 1101Delay1ms(100);P2 = 0xFB;//1111 1011Delay1ms(100);P2 = 0xF7;//1111 0111Delay1ms(100);P2 = 0xEF;//1110 1111Delay1ms(100);P2 = 0xDF;//1101 1111Delay1ms(100);P2 = 0xBF;//1011 1111Delay1ms(100);P2 = 0x7F;//0111 1111Delay1ms(100);
}
注意,每次下载程序都要重新启动板子
点灯模块就如此,写于2025/4/20