单片机学习(二)开发板LED灯的控制

开发板上LED灯相关的电路图

在这里插入图片描述
这是P2相关7个引脚的电路图,在默认情况下它是直接接着VCC的,即默认为高电平。
在这里插入图片描述
可以看到,8个LED灯分别是和单片机上P20~P27这8个引脚联系起来的,即一端是VCC,另一端是单片机上的端口,这样我们只需要将引脚端电平置为低电平即可将对应的LED点亮。

点灯

这里我们尝试先点亮从左到右数第一个LED灯,从电路图上看我们只需要将P20引脚的输出置为0(即设为低电平)即可,代码如下:

#include<REG52.H>

sbit led = P2^0;

int main() {
    while (1) {
        led = 0;
    }
}

代码说明:首先我们需要引入单片机的头文件REG52.H,里面包含了许多寄存器的地址:
在这里插入图片描述
我们可以使用类似sbit led = P2^0;来指定P2寄存器的某一位,例如这里我们指定P2寄存器的第一个bit。然后我们在main函数中将其的值设置为0,即可看到第一个LED灯点亮:

LED闪烁

我们先设置一个延时函数deley()

void deley(u16 x) {
    while (x--) {}
}

即在这里面一直执行x–操作,按照这个型号单片机的执行速度,大概一个基本语句的执行为10μs,则若输入参数为x,则该函数可以延时 10 μ s ∗ x = x ∗ 1 0 − 5 s 10μs*x=x*10^{-5}s 10μsx=x105s,故若我们希望延时0.5s,我们需要填入50000。

代码(约1s闪烁一次):

#include<REG52.H>

typedef unsigned int u16;
typedef unsigned char u8;

sbit led = P2^0;

void deley(u16 x) {
    while (x--) {}
}

int main() {
    while (1) {
        led = 0;
        deley(50000);
        led = 1;
        deley(50000);
    }
}

运行结果:
在这里插入图片描述

tips: 推荐一个GIF制作网站:https://www.tutieshi.com/video/,免费制作GIF,为良心网站点赞!

LED流水灯

#include<REG52.H>
#include<INTRINS.H>

typedef unsigned int u16;
typedef unsigned char u8;

#define LED P2

void deley(u16 x) {
    while (x--) {}
}

void defaultDeley() {
    deley(50000);
}

int main() {
    u8 i = 0;
    LED = 0xfe;     // 1111 1110
    defaultDeley();
    while (1) {
        for(i=0;i<7;i++){
            LED = LED << 1;
            LED+=1;
            defaultDeley();
        }
        // 0111 1111
        for(i=0;i<7;i++){
            LED >>= 1;
            LED+=0x80;
            defaultDeley();
        }
        // 1111 1110
    }
}

这里我们直接操作P2寄存器,我们希望一开始第一个灯点亮,因此设置P2的值为0b1111 1110,即0xfe,然后我们可以进行移位操作使0位不断变化,即:
1111 1110
1111 1101
1111 1011

所以循环的代码应为:

LED <<= 1;
LED += 1;

这样即可实现向左点灯。

向右点灯也是类似的,循环代码为:

LED >>= 1;
LED+=0x80;

于是这样就完全实现了流水灯。

运行效果:
在这里插入图片描述
(后面还有几秒钟,但GIF要超过csdn的限定大小了。。。)

其他效果

灯光二进制计数器

核心代码:

int main() {
    u8 full = 0xff;
    u8 cnt;
    while (1) {
        cnt = -1;
        while (1) {        
        	// cnt: 0000 0000 -> 0000 0001
        	// LED: 1111 1111 -> 1111 1110
            cnt +=1;
            LED = full - cnt;
            defaultDeley();
            if (cnt == 0xff) {
                break;
            }
        }
    }
}

思路是让一个变量从0开始计数到0xff,LED对应的bit是0发光1熄灭的,这刚好是和我们的计数变量的二进制位模式相反,因此使用LED = 0xff - cnt进行取反,进而使LED显示与计数变量的变化对应起来。

运行效果:
在这里插入图片描述
但是此时的灯光计数器最低位在最左边,看起来不太舒服,因此希望修改最低位在最右边

那么我们仍然使用cnt作为计数变量,它将从0x00变化到0xff,然后我们再思考建立cnt到LED的映射关系:
看前面的变化规律:
cnt: 0000 0000 -> 0000 0001 -> 0000 0010
LED: 1111 1111 -> 0111 1111 -> 1011 1111
可以发现,LED的值应为cnt的二进制位模式反转后的补码,
LED = 0xff - reverse(cnt);

这样,我们很容易就可以写出控制代码:

int main() {
    u8 full = 0xff;
    u8 cnt = 0;
    while (1) {
        cnt = -1;
        while (1) {
            // cnt: 0000 0000 -> 0000 0001 -> 0000 0010
	        // LED: 1111 1111 -> 0111 1111 -> 1011 1111
	        // LED = full - (reverse(cnt));
            cnt +=1;
            LED = full - (reverse(cnt));;
            defaultDeley();
            if (cnt == 0xff) {
                break;
            }
        }
    }
}

其中二进制位模式的翻转函数为(输入一个数,返回它二进制位模式反转值):

u8 reverse(u8 x) {
    int cnt = 8;
    int res = 0;
    while (cnt--) {
        res <<= 1;
        res += x % 2;
        x >>= 1;
    }
    return res;
}

运行效果:
在这里插入图片描述

进阶版流水灯

效果:
在这里插入图片描述
思路:原来的最基本的流水灯部分我们已经建立了bit为1时对应的灯亮的映射,即LED = 0xff - val;,然后为了实现这个效果,我们的val变量的变化情况应该如下所示:

0000 0000
0000 0001
0000 0010
...
1000 0000
1000 0001
1000 0010
...
...
1111 1111

这样我们操作时可以看做是两个变化的东西,一个是左边的“1”,代表已经到达终点的1,另一个是右边不断左移的“1”,因此这两个部分可以放在两个变量中分别存储,这里设为leftPart和rightPart。

这样我们设计外层循环中leftPart每次的变化为:leftPart>>=1; leftPart+=0x80;,而内层循环中rightPart变化,为:rightPart<<=1;,且循环次数用变量leftMoveTimes进行存储,一开始值为7,代表可以左移7次,然后每次外循环后-=1。

核心代码:

void showAndDeley(u8 res) {
    LED = 0xff - res;
    defaultDeley();
}

int main() {
    u8 rightPart , res, i;
    u8 leftMoveTimes;
    u8 leftPart;
start:
    LED = 0xff;
    
    leftPart = 0;
    leftMoveTimes = 7;
    rightPart = 0;
    res = leftPart | rightPart ;
    showAndDeley(res);
    while (1) {								// 外循环
        rightPart = 1;
        res = leftPart | rightPart ;
        showAndDeley(res);
        for(i = 0; i< leftMoveTimes; i++){ 	// 内循环
            rightPart <<= 1;
            res = leftPart | rightPart ;
            showAndDeley(res);
        }
        if (leftMoveTimes ==0) {
            goto start;						// 重新开始运行
        }
        leftPart>>=1;
        leftPart+=0x80;
        leftMoveTimes--;
    }
}
  • 5
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 好的,以下是使用ESP8266控制LED的步骤: 1. 确保您已经准备好以下材料: - ESP8266模块 - LED - 杜邦线(母对母,公对公,公对母各一条) 2. 连接ESP8266模块和LED。将ESP8266的GPIO2引脚与LED的正极连接,将LED的负极连接到ESP8266的GND引脚。 3. 下载并安装Arduino IDE,打开它并在“文件”菜单中选择“首选项”。在“附加开发板管理器网址”中输入http://arduino.esp8266.com/stable/package_esp8266com_index.json,然后单击“OK”。 4. 在Arduino IDE的“工具”菜单中选择ESP8266开发板,然后选择正确的端口。 5. 创建一个新的Arduino项目,将以下代码复制并粘贴到Arduino IDE中: ``` void setup() { pinMode(2, OUTPUT); } void loop() { digitalWrite(2, HIGH); delay(1000); digitalWrite(2, LOW); delay(1000); } ``` 6. 将代码上传到ESP8266模块中,等待上传完成。 7. LED应该会开始闪烁。如果没有,请检查连接并确保您已正确地连接LED。 以上就是使用ESP8266控制LED的步骤。您可以根据需要更改代码以改变LED的行为。 ### 回答2: 51单片机是一种高性能、低成本的微控制器,被广泛应用于各种嵌入式系统中。而ESP8266则是一款集成了Wi-Fi模块的芯片,也被广泛应用于物联网领域。在本题中,我们将介绍如何使用51单片机控制ESP8266模块,进而实现对LED控制。 1. 硬件搭建 首先,需要搭建相应的硬件平台,包括51单片机、ESP8266模块、LED等。具体搭建过程如下: (1) 选择一块支持串口通信的51单片机开发板,例如STC89C52或STC89C516。 (2) 将ESP8266模块连接到开发板的串口口(RXD、TXD),同时将其VCC、GND分别接到5V、GND电源上。注意:ESP8266的TXD端不应连接到单片机的TXD引脚,否则会出现冲突。 (3) 将LED连接到开发板的I/O口,例如P2.0或P2.1。 2. 软件设计 接下来,需要设计相应的软件程序,通过串口通信实现与ESP8266模块的数据交互,从而控制LED的亮灭。具体代码如下: ```c #include<STC89C5xRC.H> #include<intrins.h> #include<stdio.h> #define baud_rate 9600 //波特率为9600 /* 串口初始化函数 */ void Uart_Init() { TMOD = 0x20; //定时器1做为波特率发生器 TH1 = 0xFD; //设置波特率为9600 TL1 = 0xFD; TR1 = 1; //启动定时器1 SM0 = 0; //设置串口模式 SM1 = 1; EA = 1; //打开总中断 ES = 1; //打开串口中断 } /* 串口中断服务函数 */ void Uart() interrupt 4 { static unsigned char i = 0; static unsigned char buf[32] = {0}; if (RI) //如果接收到数据 { RI = 0; //清除标志位 buf[i++] = SBUF; //将接收到的数据存放在缓冲区中 if (i == 32) //数据长度超出范围,清空缓冲区 { i = 0; memset(buf, 0, sizeof(buf)); } } if (TI) //如果发送数据完成 { TI = 0; //清除标志位 } } /* ESP8266发送AT指令函数 */ void Send_AT(char *cmd) { while (*cmd) { SBUF = *cmd++; //向串口发送数据 while (!TI); TI = 0; } } /* 控制LED亮 */ void LED_On() { P2 &= ~0x01; //使P2.0输出0,LED亮 } /* 控制LED灭 */ void LED_Off() { P2 |= 0x01; //使P2.0输出1,LED灭 } /* 主函数 */ void main() { Uart_Init(); //初始化串口 Send_AT("AT+CWMODE=1\r\n"); //设置ESP8266为STA模式 Send_AT("AT+CWJAP=\"myssid\",\"mypassword\"\r\n"); //连接Wi-Fi热点(需要替换成真实的SSID和密码) Send_AT("AT+CIPMUX=0\r\n"); //设置ESP8266单连接模式 Send_AT("AT+CIPMODE=1\r\n"); //设置ESP8266为透传模式 while (1) { Send_AT("AT+CIPSTART=\"TCP\",\"192.168.1.100\",8080\r\n"); //连接TCP服务器(需要替换成真实的IP地址和端口号) Send_AT("AT+CIPSEND\r\n"); //开始发送数据 Send_AT("led=on\r\n"); //控制LED亮 Delay(1000); //延时1秒 Send_AT("AT+CIPCLOSE\r\n"); //关闭TCP连接 Delay(5000); //延时5秒 Send_AT("AT+CIPSTART=\"TCP\",\"192.168.1.100\",8080\r\n"); Send_AT("AT+CIPSEND\r\n"); Send_AT("led=off\r\n"); //控制LED灭 Delay(1000); Send_AT("AT+CIPCLOSE\r\n"); Delay(5000); } } ``` 3. 算法流程 在程序中,通过Uart_Init()函数初始化串口模式、波特率等参数,然后使用Send_AT()函数发送AT指令序列,连接Wi-Fi热点、设置TCP参数、进入透传模式等。在主循环中,模拟控制LED的亮灭状态,并通过ESP8266模块向TCP服务器发送数据,从而实现远程控制LED的效果。 4. 总结 本文介绍了如何使用51单片机控制ESP8266模块,进而实现对LED的远程控制,其中涉及到了串口通信、TCP/UDP协议等知识点。需要特别注意的是,在实际应用中,需要根据实际情况修改程序中的IP地址、端口号、Wi-Fi热点名称和密码等参数,以确保程序的正确性和稳定性。 ### 回答3: 51单片机是一款广泛应用于微电子领域的控制芯片,可以用来制作各种控制电路,而ESP8266则是一款高集成度的WiFi模块,可以直接连接到互联网。控制LED是一项常见的电子项目,因此许多制作者选择使用ESP8266来控制LED的开关,从而实现远程控制。 想要实现LED控制,需要进行如下步骤: 1. 确定电路图。在这个电路中,我们需要连接LED单片机的一条引脚上,确保引脚可以输出电流,从而让LED发光。 2. 编写代码。在这个项目中,我们需要使用51单片机的程序来控制LED的开关,同时需要使用ESP8266模块来实现WiFi连接和数据发送。编写代码时,需要先连接ESP8266模块,并对其进行初始化,然后再使用相应指令来实现数据传输和接收。同时,在程序中还需要编写专门的函数来控制LED的亮灭。 3. 调试测试。在编写完程序之后,需要进行调试测试,确保代码能够正常运行。在测试中,可以先使用串口连接模块,观察程序输出的信息和指令是否正确。若程序输出无误,可以尝试使用手机或电脑连接WIFI,看看能否实现遥控LED。 总的来说,通过51单片机和ESP8266模块控制LED,可以实现方便、快捷的远程控制。这个项目不仅具有实用性,而且可以帮助我们更好地了解电子硬件的工作原理和程序设计。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值