内容偏简单就不详述了。
程序控制LED
点亮LED
LED
- 中文名:发光二极管
- 外文名:Light Emitting Diode
- 简称:LED
- 用途:照明、广告灯、指引灯、屏幕
查询开发板原理图:
由于LED一端接入高电平(5V),所以我们控制另一端为低电平(0V)就可以让LED点亮,反之控制另一端的电平为高电平(5V)就可以让LED熄灭。
使用代码控制硬件电路的原理:
寄存器有8位,此处连接了8个LED的P2寄存器中分别为P20, P21, ... , P27。
要使D1点亮,其他LED熄灭,将P20置0(低电平),其他引脚置1(高电平)即可。这里需要将P2寄存器设置为二进制1111 1110
(低位在后),换算为十进制254
或十六进制0xFE
。
电路中的电阻起限流作用。观察开发板上的电阻,标有102字样,表示1000欧姆。
示例:
# 末尾一位为倍率
10 2
10 * 10 ^ 2 = 10 00
47 3
47 * 10 ^ 3 = 47 000
100 1
100 * 10 ^ 1 = 100 0
编写程序:
#include <REGX52.H>
//IDE中右键即可插入此头文件,是51开发基础头文件,定义了各寄存器
void main() //单片机会反复执行main函数
{
P2 = 0xFE;
while(1); //使单片机停止运行
}
效果:
LED闪烁
按常理来说,我们只要将LED引脚反复置1置0即可使其闪烁。但由于单片机的运行速度是MHz级别的,我们实际上观察不到LED的闪烁。因此我们需要延时函数。
打开STC-ISP,它附带了软件延时计算器,可以方便地生成延时函数。这些代码都是使单片机原地兜圈子以达到指定延时的代码。
按实际情况选择需要的频率和定时长度,对于51单片机需要选择Y1指令集,随后复制代码。
注:STC-ISP软件存在bug,当其窗体被最小化或失去焦点过久,之前输入的参数会被重置,因此请在每次复制代码前检查每个参数!
注意到生成的代码中存在_nop_()
函数,它是指不做任何事,使用它需要包含头文件INTRINS.H
。
//使P2寄存器的所有LED按1s的周期闪烁
#include <REGX52.H>
#include <INTRINS.H>
void Delay500ms() //生成的延时函数,每次调用延时500ms
{
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 = 0xFF;
Delay500ms();
P2 = 0x00;
Delay500ms();
}
}
按键控制LED
轻触按键触点如下:
查询开发板原理图:
所有单片机引脚上电时默认为高电平,按下按键后会变为低电平。单片机会读取引脚上的电平。
引用了REGX52.H
头文件的情况下,如果想单独操作某IO口而不是操作整个寄存器,可以按如下方式编写代码:
P2_0 = 1;
P2_0 = 0;
C语言位运算符:
按位左移 <<
0011 1100 << 1 -> 0111 1000
按位右移 >>
0011 1100 >> 2 -> 0000 1111
按位与 &
0001 1000 & 0010 1010 -> 0000 1000
按位或 |
0001 1000 | 0010 1010 -> 0011 1010
按位异或 ^ (不同位为真)
0001 1000 ^ 0010 1010 -> 0011 0010
按位取反 ~
~ 0001 1000 -> 1110 0111
按下K1使LED0亮
#include <REGX52.H>
void main()
{
while(1)
{
if(P3_1){
P2_0 = 1;
}
else{
P2_0 = 0;
}
}
}
按下K1消除抖动并在松开后改变LED0状态
机械按键的抖动:
对于机械开关,当机械触点断开、闭合时,由于机械触点的弹性作用,一个开关在闭合时不会马上稳定地接通,在断开时也不会一下子断开,所以在开关闭合及断开的瞬间会伴随一连串的抖动。不同开关的抖动也不尽相同。
我们使用程序在抖动期间延时约20ms将其忽略即可。
#include <REGX52.H>
#include <INTRINS.H>
void Delay_ms(unsigned int xms)//@11.0592MHz延时xms毫秒
{
unsigned char i, j;
while(xms--){
_nop_();
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
}
}
void main()
{
while(1)
{
if(!P3_1){
Delay_ms(20); //刚按下的延时
while(!P3_1); //松开之后才向下执行
Delay_ms(20); //刚松开的延时
P2_0 = ~P2_0;
}
}
}
按下K1使二进制数增加并使LED显示二进制位
#include <REGX52.H>
#include <INTRINS.H>
void Delay_ms(unsigned int xms)//@11.0592MHz延时xms毫秒
{
unsigned char i, j;
while(xms--){
_nop_();
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
}
}
void main()
{
unsigned char num = 0; //保存要显示的二进制数
while(1)
{
if(!P3_1){
Delay_ms(20);
while(!P3_1);
Delay_ms(20);
num++;
P2 = ~num;
}
}
}
按下K1控制LED移位
#include <REGX52.H>
#include <INTRINS.H>
void Delay_ms(unsigned int xms)//@11.0592MHz延时xms毫秒
{
unsigned char i, j;
while(xms--){
_nop_();
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
}
}
void main()
{
unsigned char num = 0; //保存要亮的灯的位置
P2 = ~0x01; //初始化第一个LED
while(1)
{
if(!P3_1){
Delay_ms(20);
while(!P3_1);
Delay_ms(20);
num++;
if(num>=8)
num = 0;
P2 = ~(0x01 << num);
}
}
}
Comments NOTHING