中文名:发光二极管
外文名:Light Emitting Diode
简称:LED
用途:照明、广告灯、指引灯、屏幕
长脚正短脚负 左正右负
首先先打开keil5,选择project-newProject
选择好存储位置后,选择单片机的型号
选择Atmel->AT89C52,因为我们使用的是中国制造,keil5中暂时还没有STC89C52,所以选择操作方式和功能一模一样的;然后选择NO。
Source Group 1便是我们的工作台
选择添加新文件
添加C语言,并命名为main
第一个:编译;第二个:建立工程;第三个:所有的文件都编译建立一遍。
再如图设置好c和c++的字体
先写出主函数
int main()
{
}
打开开关后,单片机会给LED两边通上电,LED两边都处于高电平状态,即LED两边电势差为0,则LED不会亮,当LED的一边处于低电平状态时,LED就会亮。
所以把LED亮灭问题转化为转换LED的一边的高电平与低电平状态问题。
这是MCU,引脚链接着LED模块的如图右侧的引脚。
MCU可以通过控制CPU给寄存器写值(1和0),寄存器再通过驱动器控制引脚输出高电平和低电平,1为高电平,0为低电平。
则可以把调整高低电平问题转化为配置寄存器P2的值。
知道原理后,写出
注意:
一、1111 1110是二进制,要转化为16进制,且带有前缀0x
二、P2的P要大写,要引入头文件,右键头文件可以查询芯片里面的寄存器
编写好程序后,点击编译,确定没有报错
然后打开STP-ISP,选择单片机的型号:SCT89C52RC(选择自己的单片机型号)
然后点击打开程序文件,选择存储代码的文件夹,会发现找不到相应的代码文件。
这是因为keil5默认不生成代码文件,所以要进行一下操作:
点击下面的按钮
然后选择output——》勾选Create HEX File——》ok——》再次编译
再次编译后会出现creating hex file~~~~~
这时候再接着之前的操作:打开STP-ISP——》打开程序文件——》选择相应的文件——》下载/编程
会出现操作成功的字样
实物图展示:
但是由于代码过于简单,在执行完指令后会重新回到主函数,再执行,以此循环下去,所以要阻止其再次重复主函数,可以加一个while(1)语句,让其一直执行while,而不是主函数。
#include
void main()
{
P2 = 0xFE;
while(1)
{
}
}
然后再下载即可。
还可以改为:
#include
void main()
{
P2 = 0x24;
//0010 0100
while(1)
{
}
}
效果如图:
2-2LED的闪烁
写入如下代码:
#include
void main()
{
while(1)
{
P2 = 0xFE;
P2 = 0xFF;
}
}
按照之前的步骤,打开Create······,然后编译,再然后用STC打开程序文件,之后下载,运行
结果如图:
会发现LED根本不会闪烁,这是因为P2=0xFE和P2=0xFF之间执行没有间隔,因为单片机每秒可以运行一百万次,所以间隔太小,执行得很快,观察不出区别。
所以要让其延时一段时间,那该如何写代码呢。
#include
void Delay500ms() //@11.0592MHz
{
unsigned char i, j, k;
_nop_();
i = 4;
j = 129;
k = 119;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void main()
{
while(1)
{
P2 = 0xFE;
P2 = 0xFF;
}
}
但是编译会报错:
_nop_()函数错误,此时需要添加一个新的头文件 #include
在这之后还要在主函数中调用Delay500ms函数,结果如下:
#include
#include
void Delay500ms() //@11.0592MHz
{
unsigned char i, j, k;
_nop_();
i = 4;
j = 129;
k = 119;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void main()
{
while(1)
{
P2 = 0xFE;
Delay500ms();
P2 = 0xFF;
Delay500ms();
}
}
按照之前的经验,可写出简易的流水灯代码:
#include
#include
void Delay500ms() //@11.0592MHz
{
unsigned char i, j, k;
_nop_();
i = 4;
j = 129;
k = 119;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void main()
{
while(1)
{
P2=0xFE;//1111 1110
Delay500ms();
P2=0xFD;//1111 1101
Delay500ms();
P2=0xFB;//1111 1011
Delay500ms();
P2=0xF7;//1111 0111
Delay500ms();
P2=0xEF;//1110 1111
Delay500ms();
P2=0xDF;//1101 1111
Delay500ms();
P2=0xBF;//1011 1111
Delay500ms();
P2=0x7F;//0111 1111
Delay500ms();
}
}
还可以使用for循环简化代码
#include
#include
void Delay1ms(unsigned int xms) //@11.0592MHz
{
unsigned char i, j;
while(xms)
{
_nop_();
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
xms--;
}
}
void main()
{
int a[8]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F};
int i;
while(1)
{
for(i=0; i<8; i++){
P2=a[i];
Delay1ms(500);
}
}
}
但是,还可以再升级一下代码——实现只靠输入数字可以自由设定每个灯之间的间隔时间,可以给间隔函数添加参数来实现。
先用STC-ISP生成一个一毫秒延迟的代码
#include
void Delay1ms(unsigned int xms) //@11.0592MHz
{
unsigned char i, j;
_nop_();
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
}
再给这个函数添加一个参数unsigned int xms;已知原函数执行一次,间隔就是1ms,那每重复执行函数里的内容50次,间隔就是50ms,500次就是500ms。
则可以给原函数添加一个循环,且循环次数是xms。
#include
void Delay1ms(unsigned int xms) //@11.0592MHz
{
unsigned char i, j;
while(xms)
{
_nop_();
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
xms--;
}
}
再写出全部代码:
#include
#include
void Delay1ms(unsigned int xms) //@11.0592MHz
{
unsigned char i, j;
while(xms)
{
_nop_();
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
xms--;
}
}
void main()
{
while(1)
{
P2=0xFE;//1111 1110
Delay1ms(50);
P2=0xFD;//1111 1101
Delay1ms(50);
P2=0xFB;//1111 1011
Delay1ms(50);
P2=0xF7;//1111 0111
Delay1ms(50);
P2=0xEF;//1110 1111
Delay1ms(50);
P2=0xDF;//1101 1111
Delay1ms(50);
P2=0xBF;//1011 1111
Delay1ms(50);
P2=0x7F;//0111 1111
Delay1ms(50);
}
}
甚至可以调整不同的间隔时间:
#include
#include
void Delay1ms(unsigned int xms) //@11.0592MHz
{
unsigned char i, j;
while(xms)
{
_nop_();
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
xms--;
}
}
void main()
{
while(1)
{
P2=0xFE;//1111 1110
Delay1ms(500);
P2=0xFD;//1111 1101
Delay1ms(500);
P2=0xFB;//1111 1011
Delay1ms(50);
P2=0xF7;//1111 0111
Delay1ms(50);
P2=0xEF;//1110 1111
Delay1ms(50);
P2=0xDF;//1101 1111
Delay1ms(50);
P2=0xBF;//1011 1111
Delay1ms(500);
P2=0x7F;//0111 1111
Delay1ms(500);
}
}