单片机入门

2024-04-20 42 次阅读
单片机

准备材料

  • 一块 ESP8266 板子
  • 一根 android 数据线
  • 开发环境准备

本篇实现开发环境的搭建,并测试板子成功连接。

ESP8266

这是我在 某宝 花了 ¥11.70 购买的 ESP8266 CH340 串口wifi模块(升级款)



最下方是一个 android 接口

android 数据线

这个就不用过多介绍了

开发环境

严格按照下方PDF教程使用,PDF中所需要的软件及驱动在下方列出。

PDF教程

  1. 下载安装 arduino
    【百度网盘】
  2. 下载 CH341SER.EXE 驱动
    【百度网盘】

LED灯闪烁

将开发板与电脑通过 android 数据线连接后,并按照第一节所述设置端口号,再进行后续操作。

LED灯闪烁


选择此示例之后,会给出示例代码,直接上传示例代码到板子上。

arduino 复制代码
void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  // 设置led灯引脚编号,设置模式为输出
  pinMode(LED_BUILTIN, OUTPUT);
}

// the loop function runs over and over again forever
// 循环函数
void loop() {
  // 高电平亮灯
  digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  //  延迟1秒
  delay(1000);                       // wait for a second
  // 低电平亮灯
  digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
  // 延迟1秒
  delay(1000);                       // wait for a second
}


程序上传到板子之后,板子上的 led灯 将会 亮灯1秒 重新 亮灯,达到闪烁的效果。

LED灯常亮

通过上述代码我们发现,将延迟函数去掉,就能实现常亮效果。修改 loop函数 如下:

arduino 复制代码
void loop() {
  digitalWrite(LED_BUILTIN, LOW);
}

重新上传程序到板子上,就实现了常亮的效果。

OLED屏显示HelloWorld

  • 准备SPI接口的7针引脚OLED显示屏
  • 准备7跟母对母杜邦线

元件

SPI接口的7针引脚OLED显示屏

母对母杜邦线

接线

OLED针脚 连线 ESP8266针脚
GND <---> G
VCC <---> 3V
D0 <---> D5
D1 <---> D7
RES <---> D2
DC <---> D1
CS <---> D0

安装库

Arduino 的管理库中安装 U8g2U8g2_for_Adafruit_GFX 两个库。

编写代码

arduino 复制代码
// 引入U8g2图形库,用于驱动OLED显示屏
#include <U8g2lib.h> 

// 定义SPI接口上OLED模块的相关引脚
// OLED片选信号(Chip Select)连接至D0引脚
#define OLED_CS D0 
// 数据/命令选择信号(Data/Command)连接至D1引脚
#define OLED_DC D1 
// OLED复位信号(Reset)连接至D2引脚(可选,如果没有物理连接复位引脚,则不需要此定义)
#define OLED_RST D2

// 创建一个U8g2对象实例,指定OLED型号为SSD1306,分辨率为128x64,采用4线软件SPI模式及对应的引脚配置
U8G2_SSD1306_128X64_NONAME_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ D5, /* data=*/ D7, /* cs=*/ OLED_CS, /* dc=*/ OLED_DC, /* reset=*/ OLED_RST);

// 设置函数:初始化串口通信以及OLED模块相关引脚
void setup() {
    // 初始化Serial串口通信,波特率为115200
    Serial.begin(115200);

    // 将OLED的片选和数据/命令选择引脚设为输出模式
    pinMode(OLED_CS, OUTPUT);
    pinMode(OLED_DC, OUTPUT);

    // 若OLED有连接复位引脚,则对其进行初始化操作
    if (OLED_RST != NOT_A_PIN) {
        pinMode(OLED_RST, OUTPUT);
        
        // 先将复位引脚拉高,然后短暂拉低以完成OLED模块的硬件复位
        digitalWrite(OLED_RST, HIGH);
        delay(100);
        digitalWrite(OLED_RST, LOW);
        delay(100);
        digitalWrite(OLED_RST, HIGH);
    }

    // 开始初始化U8g2库与OLED显示屏之间的通信
    u8g2.begin();
}

// 循环函数:在此函数内编写循环执行的代码,如更新OLED显示内容
void loop() {
    // 清除OLED显示缓存
    u8g2.clearBuffer();

    // 设置字体为ncenB14_tr样式
    u8g2.setFont(u8g2_font_ncenB14_tr);

    // 在坐标(0, 20)处写入英文字符串"HelloWorld"
    u8g2.drawStr(0, 20, "HelloWorld");

    // 将缓冲区中的内容发送至OLED显示屏进行显示
    u8g2.sendBuffer();

    // 延迟2秒后再进行下一轮显示更新
    delay(2000);
}

最终成功显示了文字!

完整代码参考码云地址

缺陷

目前只能显示英文文字,并且不会自动换行,后续处理。。。

连接wifi并显示当前时间 + 电量图标

安装库

关键代码

arduino 复制代码
// 创建一个U8g2对象实例,指定OLED型号为SSD1306,分辨率为128x64,采用4线软件SPI模式及对应的引脚配置
U8G2_SSD1306_128X64_NONAME_F_4W_SW_SPI u8g2(
  U8G2_R0, 
  /* clock=*/ D5, 
  /* data=*/ D7, 
  /* cs=*/ OLED_CS, 
  /* dc=*/ OLED_DC, 
  /* reset=*/ OLED_RST
);
arduino 复制代码
// 绘制时间
void drawYmdhms() {
  // 设置字体为ncenB14_tr样式
  u8g2.setFont(u8g2_font_ncenB08_tr);
  // 获取当前时间  
  time_t localTime = getLocalTime(timeClient, 8);
  // 定义时间buffer
  char timeBuffer[20];
  // 格式化时间
  formatDateTime(localTime,timeBuffer,sizeof(timeBuffer), "%Y-%m-%d %H:%M:%S");
  // 绘制年月日时分秒 
  u8g2.drawStr(5, 15, timeBuffer);
}

// 绘制电量
void drawBattery() {
  // 绘制电量
  u8g2.setFont(u8g2_font_battery19_tn);
  u8g2.drawStr(110, 20, "5");
}

/**
 * 自定义格式化函数,格式化后的结果会覆盖第二个参数buffer
 * @property {time_t} t - 时间对象
 * @property {char*} buffer - 时间对象的buffer
 * @property {size_t} bufferSize - 事件对象buffer的大小
 * @property {char*} formatStr - 格式化字符串
*/
void formatDateTime(time_t t, char* buffer, size_t bufferSize, const char* formatStr) {
  struct tm timeinfo;
  // 转换为本地时间
  localtime_r(&t, &timeinfo); 
  // 时间格式化
  strftime(buffer, bufferSize, formatStr, &timeinfo);
}

/**
 * 获取本地时间
 * @property {NTPClient} ntpClient - NTP客户端
 * @property {int} timeZoneOffsetHours - 时区偏移量,中国大陆偏移8小时
 * @return {time_t} 返回时间对象
*/
time_t getLocalTime(NTPClient ntpClient, int timeZoneOffsetHours){
  // 时间更新
  ntpClient.update();
  // 获取UTC时间戳
  time_t utcTime = ntpClient.getEpochTime(); 
  // 将UTC时间转换为本地时间
  struct tm *timeInfo = gmtime(&utcTime);
  // 增加时区偏移小时数
  timeInfo->tm_hour += timeZoneOffsetHours; 
  // 转换回Unix时间戳(此时已经是调整过时区后的本地时间戳)
  return mktime(timeInfo);
}

完整代码参考码云地址

效果图

未完待续...