内容偏简单就不详述了。


程序控制LED

点亮LED

LED

  • 中文名:发光二极管
  • 外文名:Light Emitting Diode
  • 简称:LED
  • 用途:照明、广告灯、指引灯、屏幕

file

查询开发板原理图:

file

由于LED一端接入高电平(5V),所以我们控制另一端为低电平(0V)就可以让LED点亮,反之控制另一端的电平为高电平(5V)就可以让LED熄灭。

使用代码控制硬件电路的原理:
file

寄存器有8位,此处连接了8个LED的P2寄存器中分别为P20, P21, ... , P27。

要使D1点亮,其他LED熄灭,将P20置0(低电平),其他引脚置1(高电平)即可。这里需要将P2寄存器设置为二进制1111 1110(低位在后),换算为十进制254或十六进制0xFE

电路中的电阻起限流作用。观察开发板上的电阻,标有102字样,表示1000欧姆。

file

示例:

# 末尾一位为倍率

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);   //使单片机停止运行
}

效果:

file

LED闪烁

按常理来说,我们只要将LED引脚反复置1置0即可使其闪烁。但由于单片机的运行速度是MHz级别的,我们实际上观察不到LED的闪烁。因此我们需要延时函数。

打开STC-ISP,它附带了软件延时计算器,可以方便地生成延时函数。这些代码都是使单片机原地兜圈子以达到指定延时的代码。

file

按实际情况选择需要的频率和定时长度,对于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

轻触按键触点如下:

file

file

查询开发板原理图:

file

所有单片机引脚上电时默认为高电平,按下按键后会变为低电平。单片机会读取引脚上的电平。

引用了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状态

机械按键的抖动:

对于机械开关,当机械触点断开、闭合时,由于机械触点的弹性作用,一个开关在闭合时不会马上稳定地接通,在断开时也不会一下子断开,所以在开关闭合及断开的瞬间会伴随一连串的抖动。不同开关的抖动也不尽相同。

file

我们使用程序在抖动期间延时约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);
        }
    }
}