自学内容网 自学内容网

25/1/14 嵌入式笔记 学习ESP32

蜂鸣器实验

#define BUTTON 13
#define BUZZER 22

hw_timer_t * timer = NULL;

// 定义闹钟触发时间,单位为秒
int alarmSecond = 3;

// 定时器中断处理函数
void IRAM_ATTR timer_interrupt() {
  digitalWrite(BUZZER, HIGH);
}

// 外部中断处理函数
void IRAM_ATTR handle_interrupt() {
  digitalWrite(BUZZER, LOW);
}

void setup() {
  // 配置引脚模式
  pinMode(BUTTON, INPUT_PULLUP);
  pinMode(BUZZER, OUTPUT);

  // 初始化定时器
  timer = timerBegin(0, 80, true);
  if (timer == NULL) {
    Serial.println("定时器初始化失败");
    while (1);  // 定时器初始化失败,进入死循环
  }

  // 配置定时器中断
  timerAttachInterrupt(timer, &timer_interrupt, true);
  // 设置定时时间,单位为微秒
  timerAlarmWrite(timer, alarmSecond * 1000 * 1000, false);
  // 启动定时器
  timerAlarmEnable(timer);

  // 配置外部中断
  attachInterrupt(digitalPinToInterrupt(BUTTON), handle_interrupt, FALLING);
}

void loop() {
  // 主循环为空,所有功能通过中断实现
}

蜂鸣器根据乐谱发声

#define BUZZER 23
#define CHANNEL 0
#define RESOLUTION 8
#define FREQ 20000

// 定义按键数组
int button_array[6] = {25, 26, 27, 14, 12, 13};

// 定义音符频率数组
int tone_array[7] = {262, 294, 330, 349, 392, 440, 494};  // 修正了音符频率

// 乐谱
int music[] = {1, 1, 5, 5, 6, 6, 5};

// 初始化发声频率
int tone_value = 0;

void setup() {
  // 配置引脚模式
  pinMode(BUZZER, OUTPUT);

  for (int i = 0; i < 6; i++) {
    pinMode(button_array[i], INPUT_PULLUP);
  }

  // LEDC外设
  ledcSetup(CHANNEL, FREQ, RESOLUTION);
  ledcAttachPin(BUZZER, CHANNEL);
}

void loop() {
  // 检测按键是否按下
  for (int i = 0; i < 6; i++) {
    if (!digitalRead(button_array[i])) {
      tone_value = tone_array[i];
      while (!digitalRead(button_array[i]));  // 等待按键释放
    }
  }

  // 蜂鸣器发声
  if (tone_value > 0) {
    ledcWriteTone(CHANNEL, tone_value);
  } else {
    ledcWrite(CHANNEL, 0);  // 停止发声
  }

  tone_value = 0;
  delay(10);
}

4*4矩阵键盘

薄膜按键原理

按键检测原理

为什么行引脚设置为输入,列设置为输出

 矩阵键盘的工作原理

矩阵键盘通过行和列的交叉点来识别按键。每个按键位于一个行引脚和一个列引脚的交叉点上。通过控制列引脚的电平,并读取行引脚的状态,可以确定哪个按键被按下。


//定义行引脚数组
int row_pins[4] = {13,12,14,27};
//定义列引脚数组
int col_pins[4] = {26,25,33,32};

void setup(){
  //设置串口通信波特率
  Serial.begin(9600);

  //行引脚设置为输入模式
  for(int i=0;i<4;i++){
    pinMode(row_pins[i],INPUT_PULLUP);
  }

  //列引脚设置为输出模式
  for(int i=0;i<4;i++){
    pinMode(col_pins[i],OUTPUT);
    //初始化为高电平
    digitalWrite(col_pins[i],HIGH);
  }
}
char read_keypadd(){
  //定义键盘按键的布局
  char keys[4][4]={
    {'1','2','3','A'},
    {'4','5','6','B'},
    {'7','8','9','C'},
    {'*','0','#','D'},
  };
  //行列扫描法
  for(int j=0;j<4;j++){
    //将当前列设置为低电平
    digitalWrite(col_pins[j],LOW);

    for(int i=0;i<4;i++){
      //检测行输入引脚状态,检测到低电平,说明按键按下,则返回按键值
      if(!digitalRead(row_pins[i])){

        return keys[i][j];
      }
    }
    //将当前列恢复为高电平
    digitalWrite(col_pins[j],HIGH);
  }
  return NULL;
}
void loop(){
  //保存读取到的按键值
  key = read_keypad();

  if(key){
    Serial.printf("检测到按键:%c 按下\n",key);
  }
}

SD卡实验

#include<SD.h>

//初始化文件对象
File my_file;
void setup(){
  Serial.begin(9600);

  delay(1000);
  
  if(!SD.begin()){
    Serial.println("SD卡初始化失败");
    return ;
  }
  Serial.println("SD卡初始化成功");
  //创建一个新的文件并写入数据
  my_file = SD.open("/test.txt",FILE_WRITE);

  if(my_file){
    my_file.println("你好,SD卡");
    my_file.close();
  }else{
    Serial.println("无法打开文件");
  }
  delay(1000);
  //读取文件内容
  my_file = SD.open("/test.txt");
  while(my_file.available()){
    Serial.write(my_file.read());
  }
  my_file.close();
  Serial.println("\n文件读取完成");
  delay(1000);

  //追加文件内容
  my_file = SD.open("/test.txt",FILE_APPEND);
  my_file.println("修改文件内容");
  my_file.close();
  Serial.println("文件修改成功");

  delay(1000);

  //读取文件内容
  my_file = SD.open("/test.txt");
  while(my_file.available()){
    Serial.write(my_file.read());
  }
  my_file.close();
  Serial.println("\n文件读取完成");
  delay(1000);

  //删除文件
  if(SD.remove("/test.txt")){
    Serial.println("文件删除成功");
  }else{
    Serial.println("文件删除失败");
  }
}
void loop(){
}

串口通信

串行数据传输分为两种,异步和同步

异步通信:指通信的发送与接受设备使用各自的时钟控制数据的发送和接受过程,为使双方首发协调,要求发送和接受的设备的时钟尽可能一致。

异步通信的一帧字符信息

软件程序设计HardwareSerial库

void setup() {
  // 初始化串口通信波特率
  Serial.begin(9600);
  Serial2.begin(9600);
}

void loop() {
  // 从串口监视器读取输入数据
  if (Serial.available()) {
    char data = Serial.read();
    // 将数据发送到UART2
    Serial2.write(data);
    delay(1);  // 简短延时,确保数据稳定传输
  }

  // 从UART2读取输入数据
  if (Serial2.available()) {
    char data = Serial2.read();
    // 将数据发送到串口监视器
    Serial.write(data);
    delay(1);  // 简短延时,确保数据稳定传输
  }
}

原文地址:https://blog.csdn.net/yyyy2711/article/details/145141181

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!