400字范文,内容丰富有趣,生活中的好帮手!
400字范文 > 定时器控制LED灯

定时器控制LED灯

时间:2022-12-26 11:10:10

相关推荐

定时器控制LED灯

定时器控制LED灯闪烁,按钮改变闪烁频率

文章目录

定时器控制LED灯闪烁,按钮改变闪烁频率一. 实验目的二. ESP32 GPIO介绍1.GPIO的简介2. GPIO的主要特性三. ESP32定时器的介绍1. 定时器的介绍2. 定时器特性四. 实验原理及程序结构1. GPIO1.1. LED灯和按钮的初始化:1. 2 LED控制2. 软件定时器2.1 使用最简单的软件定时器2.2 按钮控制定时器五. 源码六. 总结1 实验需求:2. 实践操作2.1 定时器控制LED2.2 按钮控制LED

一. 实验目的

为了更好的了解嵌入式中的功能,以较简单的方式提升自己对嵌入式的爱好,所以在这里开展了定时器控制LED灯的实验,本章可以基本了解ESP32的GPIO和软件定时器硬件说明:本例程会用到一个软件定时器、一个按钮和一个LED灯

二. ESP32 GPIO介绍

1.GPIO的简介

ESP32具有34个物理管脚,每个管脚都可用作一个通用IO或者连接外部信号。通过 IO MUX、RTC IO MUX 和 GPIO 交换矩阵,可配置外设模块的输入信号来源于任何的 IO 管脚,并且外设模块的输出信号也可连接到任意 IO 管脚。

2. GPIO的主要特性

输出状态可选推挽、上拉和下拉。输入状态可选择悬空、上拉或下拉、模拟。可设置中断条件,可以选择上升沿触发、下降沿触发、高电平触发、低电平触发.

三. ESP32定时器的介绍

1. 定时器的介绍

ESP32 内置 4 个 64-bit 通用定时器。每个定时器包含一个 16-bit 预分频器和一个 64-bit 可自动重新加载向上/向下计数器。

ESP32 的定时器分为 2 组,每组 2 个。TIMGn_Tx 的 n 代表组别,x 代表定时器编号。具有16-bit预分频、64-bit时基计数、警报产生、MWDT(主系统看门狗)、中断等多种功能

2. 定时器特性

可配置向上/向下时基计数器暂停和恢复时基计数器电平触发中断和边沿触发中断软件控制的即时重新加载

四. 实验原理及程序结构

1. GPIO

基本原理就是利用ESP32的软件定时器特性,在周期性回调函数中控制LED灯的状态不断翻转,达到闪烁的效果。我们先来看GPIO的初始化

1.1. LED灯和按钮的初始化:

gpio_config_t led;led.pin_bit_mask = 1 << LED_R;led.mode = GPIO_MODE_OUTPUT;led.pull_up_en = GPIO_PULLUP_DISABLE;led.pull_down_en = GPIO_PULLDOWN_DISABLE;led.intr_type = GPIO_INTR_DISABLE;gpio_config(&led);gpio_config_t btn;btn.pin_bit_mask = 1 << BUTTON_PIN;btn.mode = GPIO_MODE_INPUT;btn.pull_up_en = GPIO_PULLUP_ENABLE;btn.pull_down_en = GPIO_PULLDOWN_DISABLE;btn.intr_type = GPIO_INTR_DISABLE;gpio_config(&btn);

LED灯和按钮的初始化比较简单,选择好引脚,将LED灯设为输出模式,按钮设为输入模式即可。

1. 2 LED控制

static void periodic_timer_callback(void* arg){static bool state = true;gpio_set_level (LED_R,state);state = !state;int64_t time_since_boot = esp_timer_get_time();printf("回调成功!\n");}

每次调用定时器中的一次回调函数,LED灯的状态翻转一次,只要设置好定时器中的时间就可以改变LED灯的闪烁频率

2. 软件定时器

2.1 使用最简单的软件定时器

void app_main(void){//创建了一个新的事件,便于按钮控制定时器的时间xTaskCreate(myTask, "myTask", 1024, NULL, 1, NULL);//创建一个周期性定时器const esp_timer_create_args_t periodic_timer_args = {.callback = &periodic_timer_callback, //周期定时回调//定时器名称.name = "periodic"};esp_timer_handle_t periodic_timer;/* 计时器已经创建,但还没有运行 */ESP_ERROR_CHECK(esp_timer_create(&periodic_timer_args, &periodic_timer));//创建定时器句柄,设置定时器周期为2秒,启动定时器ESP_ERROR_CHECK(esp_timer_start_periodic(periodic_timer, 2*000*000));}

这里设置的定时器为两秒,每调用一次,LED灯的状态就翻转一次,实现闪烁到这里,定时器控制LED灯已经完成了,但按钮控制还没有完成。

2.2 按钮控制定时器

在这里只要控制了定时器的时间就改变了LED灯的闪烁频率,接下来就看按钮如何控制定时器的:

void Led_Init(esp_timer_handle_t handle){int level = 0;uint32_t period = 1000;while (1){//确定按钮是否按下,消抖if (gpio_get_level(BUTTON_PIN) == 0){//再次确定按钮是否按下,防止一次按下多次触发vTaskDelay(pdMS_TO_TICKS(10));if (gpio_get_level(BUTTON_PIN) == 0){period -= 35;timer_set(handle, period);}}//防止看门狗报错vTaskDelay(pdMS_TO_TICKS(10));}}

在这里调用了定时器中的句柄,重新设置了定时器的时间,并在按钮程序中让定时器的时间逐渐减少,进而达到LED灯闪烁越来越快的效果,实现按钮控制LED灯的闪烁频率。

五. 源码

#include <stdio.h>#include <string.h>#include <unistd.h>#include "esp_timer.h"#include "esp_log.h"#include "esp_sleep.h"#include "sdkconfig.h"// gpio头文件#include "driver/gpio.h"#include "sdkconfig.h"#include "freertos/FreeRTOS.h"#include "freertos/task.h"#include "freertos/event_groups.h"// gpio文件结束// gpio宏定义#define LED_R 2#define BUTTON_PIN 14// gpio宏定义结束void myTask(void *pvParam){while (1){printf("five by five\n");vTaskDelay(60000 / portTICK_PERIOD_MS);}}//----------------------------------------------------------------------------------------------------------------------------------------// gpio开始配置static void timer_set(esp_timer_handle_t handle, uint32_t nms){/* 启动正在运行的定时器,需要先停止 */ESP_ERROR_CHECK(esp_timer_stop(handle));//将时间从微秒化成毫秒ESP_ERROR_CHECK(esp_timer_start_periodic(handle, nms * 1000));}//----------------------------------------------------------------------------------------------------------------------------------------void Led_Init(esp_timer_handle_t handle){gpio_config_t led;led.pin_bit_mask = 1 << LED_R;led.mode = GPIO_MODE_OUTPUT;led.pull_up_en = GPIO_PULLUP_DISABLE;led.pull_down_en = GPIO_PULLDOWN_DISABLE;led.intr_type = GPIO_INTR_DISABLE;gpio_config(&led);gpio_config_t btn;btn.pin_bit_mask = 1 << BUTTON_PIN;btn.mode = GPIO_MODE_INPUT;btn.pull_up_en = GPIO_PULLUP_ENABLE;btn.pull_down_en = GPIO_PULLDOWN_DISABLE;btn.intr_type = GPIO_INTR_DISABLE;gpio_config(&btn);int level = 0;uint32_t period = 1000;while (1){if (gpio_get_level(BUTTON_PIN) == 0){vTaskDelay(pdMS_TO_TICKS(10));if (gpio_get_level(BUTTON_PIN) == 0){// level = !level;// gpio_set_level(LED_R, level);period -= 35;timer_set(handle, period);}}vTaskDelay(pdMS_TO_TICKS(10));}}//----------------------------------------------------------------------------------------------------------------------------------------static void periodic_timer_callback(void *arg);static const char *TAG = "example";//打印信息配置//----------------------------------------------------------------------------------------------------------------------------------------void app_main(void){xTaskCreate(myTask, "myTask", 1024, NULL, 1, NULL);//创建一个周期性定时器const esp_timer_create_args_t periodic_timer_args = {.callback = &periodic_timer_callback, //周期定时回调//定时器名称.name = "periodic"};esp_timer_handle_t periodic_timer;/* 计时器已经创建,但还没有运行 */ESP_ERROR_CHECK(esp_timer_create(&periodic_timer_args, &periodic_timer));//创建定时器句柄,设置定时器周期为2秒,启动定时器ESP_ERROR_CHECK(esp_timer_start_periodic(periodic_timer, 4 * 000 * 000));Led_Init(periodic_timer);}//----------------------------------------------------------------------------------------------------------------------------------------static void periodic_timer_callback(void *arg){static bool state = true;gpio_set_level(LED_R, state);state = !state;int64_t time_since_boot = esp_timer_get_time();printf("回调成功!\n");}

六. 总结

1 实验需求:

不难看出这个实验的需求只有三个:LED灯、按钮和定时器,配置它们是最基础的地方,其他的只要逻辑思维不出错便没有太多的难点。

2. 实践操作

2.1 定时器控制LED
2.2 按钮控制LED

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。