1、使用vscode开发
搭建开发环境这里就不记录了,之前的文章有讲过,可以参考
vscode搭建esp32开发记录
2、idf点灯
新建工程
选择路径和芯片
选一个空的工程
打开工程
新建驱动用的文件夹,basic可以省略
一般要准备一个Cmakelist.txt,这个可以当作一个模版使用
内容如下:
idf_component_register(SRCS "led_driver.c"
INCLUDE_DIRS include
REQUIRES driver)
leddriver内容如下:
#include "led_driver.h"
void led_init(gpio_num_t gpio_num)
{
gpio_config_t cfg = {
.pin_bit_mask = (1ull << gpio_num),
.mode = GPIO_MODE_OUTPUT,
.pull_up_en = 0,
.pull_down_en = 1,
.intr_type = 0,
};
gpio_config(&cfg);
}
头文件引用这个库
上面关于led的驱动可以参考官方说明
GPIO & RTC GPIO
详情如下所示:
这里也提到了需要链接这个库
点灯的方式有很多种,这里分别试一下,
直接在while循环里面执行
while (1)
{
gpio_set_level(LED_IO_NUM, 1);
vTaskDelay(500/portTICK_PERIOD_MS);
gpio_set_level(LED_IO_NUM, 0);
vTaskDelay(500/portTICK_PERIOD_MS);
}
使用里面的任务来实现
xTaskCreate(led_task,
"led_task",
1024 * 2,
NULL,
1,
&LED_Handle);
void led_task(void *param)
{
gpio_set_direction(LED_IO_NUM, GPIO_MODE_DEF_OUTPUT);
while (1)
{
gpio_set_level(LED_IO_NUM, 1);
vTaskDelay(500 / portTICK_PERIOD_MS);
gpio_set_level(LED_IO_NUM, 0);
vTaskDelay(500 / portTICK_PERIOD_MS);
printf("running \r\n");
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
使用定时器实现
Timer0_Handle = xTimerCreate("timer0", (1000 / portTICK_PERIOD_MS), pdFAIL, NULL, Timer0_callback);
xTimerStart(Timer0_Handle, 0);
void Timer0_callback(TimerHandle_t time)
{
static bool flag = 0;
if (flag == 0)
{
flag = 1;
gpio_set_level(LED_IO_NUM, 1);
}
else
{
flag = 0;
gpio_set_level(LED_IO_NUM, 0);
}
xTimerReset(Timer0_Handle, portMAX_DELAY);
}
也可以打开串口监视器查看串口状态
3、板子资源
这里我用的是最基础的一个核心板,这张图比较清晰,看这个吧
然后外设上接了一个引出了一个串口
led这块是有一个用户可以控制的GPIO2
下载的话做了自动下载
4、串口使用
其实前面的功能上已经用上串口了,这个idf好像默认的printf就是用的串口0 ,也就是那个默认的串口,前面已经可以用它来打印数据了。
还是一样,新开一个文件夹来搞串口的:
代码如下:
#include "uart_driver.h"
void uart_init(void)
{
// 串口参数配置->uart0
uart_config_t uart0_config = {
.baud_rate = 115200, // 波特率
.data_bits = UART_DATA_8_BITS, // 数据位
.parity = UART_PARITY_DISABLE, // 校验位
.stop_bits = UART_STOP_BITS_1, // 停止位
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE, // 硬件流控
};
uart_param_config(UART_NUM_0, &uart0_config); // 设置串口
// IO映射-> T:IO1 R:IO3
uart_set_pin(UART_NUM_0, TXD0_PIN, RXD0_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
// 注册串口服务即使能+设置缓存区大小
uart_driver_install(UART_NUM_0, RX0_BUF_SIZE * 2, TX0_BUF_SIZE * 2, 0, NULL, 0);
}
配置串口
esp32有三个串口,如下所示:
写一个串口回显的任务,阻塞实现
完整代码如下:
#include <stdio.h>
#include "esp_system.h"
#include "esp_spi_flash.h"
#include "esp_wifi.h"
#include "esp_event_loop.h"
#include "esp_log.h"
#include "esp_err.h"
#include "nvs_flash.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/ledc.h"
#include <stdio.h>
#include "driver/uart.h"
#include "driver/gpio.h"
#include "string.h"
#include "uart_driver.h"
#include "led_driver.h"
// 串口0接收任务
void uart0_rx_task()
{
uint8_t *data = (uint8_t *)malloc(RX0_BUF_SIZE + 1);
while (1)
{
// 获取串口0接收的数据
const int rxBytes = uart_read_bytes(UART_NUM_0, data, RX0_BUF_SIZE, 10 / portTICK_PERIOD_MS);
if (rxBytes > 0)
{
data[rxBytes] = 0;
uart_write_bytes(UART_NUM_0, "\r\n uart0 cb :\r\n", strlen("\r\n uart0 cb \r\n"));
// 将接收到的数据发出去
uart_write_bytes(UART_NUM_0, (char *)data, rxBytes);
}
}
free(data);
}
void app_main()
{
// 串口初始化
uart_init();
// 创建串口0接收任务
xTaskCreate(uart0_rx_task, "uart0_rx_task", 1024, NULL, configMAX_PRIORITIES, NULL);
// 串口0数据发送测试
uart_write_bytes(UART_NUM_0, "uart0 test OK ", strlen("uart0 test OK "));
}
最终效果: