最近做项目要用到esp32s3,所以在网上找了和很多资料去学习,但发现好像都堆初学者不是很友好。因为我之前学习和用的都是stm32这类需要自己写驱动的单片机,用到esp32s3这种直接调用驱动一时间会有点不习惯,但反应过来后会发现用起来很方便。
然后我购买的是官方的开发板——ESP32-S3-DevKitC-1。官方给的资料很全,很详细,所以需要长时间去学习沉淀。官网链接https://mp.csdn.net/mp_blog/creation/editor?spm=1011.2124.3001.6217
如果有和我一样购买了官方的开发板 ESP32-S3-DevKitC-1,你会发现和我们之前学习的单片机不一样,像stm32、51这类单片机第一步一般都是配置gpio口去点亮一个led灯,而ESP32-S3-DevKitC-1,没有led!!!只有一个rgb led。
而这篇文章就是为了方便让和我一样有点灯困惑的小伙伴快速熟悉如何点灯。
1.SK68XX
首先,我们要先知道连接的这个rgbled是什么型号,如何驱动,驱动代码在哪里。我们先看原理图(下图为新版开发板,旧版开发版的驱动引脚是GPIO48) rgbled的型号是SK68XX,然后我们去找到对应的芯片数据手册。发现每一个rgbled灯可以看成是一个像素点,除了电源和地引脚外,就只用一个DIN引脚驱动,同时我们看手册会发现这个rgbled同一时间需要24bit数据才能实现红、绿、蓝等多种颜色的切换但是就一个驱动引脚如何传输24位数据呢,高低电平如何区分呢,这就是它的驱动原理了可以看出,它是需要先确定一个固定的周期,然后在这个固定的周期里高低电平不同的保持时间来区分“0”码和“1”码。相信到这里,学过单片机的都知道如何点亮这个rgbled了。但如我前文所说,esp32已经有写好的driver了,我们只需看懂和直接调用就好,省去了自己写驱动的时间。
2.红外遥控 (RMT)
作为一个初学者,我们并不熟悉esp32的驱动该如何调用,在哪里调用,所以最好的方法是从例程入手,我们在安装esp-idf时其实吧例程也下载好了,而rgb灯的例程在这里打开例程会发现,rgbled的·驱动并不是直接用GPIO进行驱动的,而是用到了红外遥控RMT,了解过红外遥控的都知道,红外遥控也是单线驱动的,和SK68XX异曲同工,所以在配置时注意周期和“0”码“1”码的高低电平占空比就可实现SK68XX的驱动,具体可看代码。
led_strip_t *led_strip_new_rmt_ws2812(const led_strip_config_t *config)
{
led_strip_t *ret = NULL;
STRIP_CHECK(config, "configuration can't be null", err, NULL);
// 24 bits per led
uint32_t ws2812_size = sizeof(ws2812_t) + config->max_leds * 3;
ws2812_t *ws2812 = calloc(1, ws2812_size);
STRIP_CHECK(ws2812, "request memory for ws2812 failed", err, NULL);
uint32_t counter_clk_hz = 0;
STRIP_CHECK(rmt_get_counter_clock((rmt_channel_t)config->dev, &counter_clk_hz) == ESP_OK,
"get rmt counter clock failed", err, NULL);
// ns -> ticks
float ratio = (float)counter_clk_hz / 1e9;
ws2812_t0h_ticks = (uint32_t)(ratio * WS2812_T0H_NS);
ws2812_t0l_ticks = (uint32_t)(ratio * WS2812_T0L_NS);
ws2812_t1h_ticks = (uint32_t)(ratio * WS2812_T1H_NS);
ws2812_t1l_ticks = (uint32_t)(ratio * WS2812_T1L_NS);
// set ws2812 to rmt adapter
rmt_translator_init((rmt_channel_t)config->dev, ws2812_rmt_adapter);
ws2812->rmt_channel = (rmt_channel_t)config->dev;
ws2812->strip_len = config->max_leds;
ws2812->parent.set_pixel = ws2812_set_pixel;
ws2812->parent.refresh = ws2812_refresh;
ws2812->parent.clear = ws2812_clear;
ws2812->parent.del = ws2812_del;
return &ws2812->parent;
err:
return ret;
}
3.点亮
了解完驱动方式后,便可点亮rgbled了,调用代码esp32也已经包装好了,话不多说,直接上代码
struct led_strip_s {
/**
* @brief Set RGB for a specific pixel
*
* @param strip: LED strip
* @param index: index of pixel to set
* @param red: red part of color
* @param green: green part of color
* @param blue: blue part of color
*
* @return
* - ESP_OK: Set RGB for a specific pixel successfully
* - ESP_ERR_INVALID_ARG: Set RGB for a specific pixel failed because of invalid parameters
* - ESP_FAIL: Set RGB for a specific pixel failed because other error occurred
*/
esp_err_t (*set_pixel)(led_strip_t *strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue);
/**
* @brief Refresh memory colors to LEDs
*
* @param strip: LED strip
* @param timeout_ms: timeout value for refreshing task
*
* @return
* - ESP_OK: Refresh successfully
* - ESP_ERR_TIMEOUT: Refresh failed because of timeout
* - ESP_FAIL: Refresh failed because some other error occurred
*
* @note:
* After updating the LED colors in the memory, a following invocation of this API is needed to flush colors to strip.
*/
esp_err_t (*refresh)(led_strip_t *strip, uint32_t timeout_ms);
/**
* @brief Clear LED strip (turn off all LEDs)
*
* @param strip: LED strip
* @param timeout_ms: timeout value for clearing task
*
* @return
* - ESP_OK: Clear LEDs successfully
* - ESP_ERR_TIMEOUT: Clear LEDs failed because of timeout
* - ESP_FAIL: Clear LEDs failed because some other error occurred
*/
esp_err_t (*clear)(led_strip_t *strip, uint32_t timeout_ms);
/**
* @brief Free LED strip resources
*
* @param strip: LED strip
*
* @return
* - ESP_OK: Free resources successfully
* - ESP_FAIL: Free resources failed because error occurred
*/
esp_err_t (*del)(led_strip_t *strip);
};
调用
static led_strip_t *pStrip_a;
static void blink_led(void)
{
/* If the addressable LED is enabled */
if (s_led_state) {
/* Set the LED pixel using RGB from 0 (0%) to 255 (100%) for each color */
pStrip_a->set_pixel(pStrip_a, 0, 0, 51, 51);
/* Refresh the strip to send data */
pStrip_a->refresh(pStrip_a, 100);
} else {
/* Set all LED off to clear all pixels */
pStrip_a->clear(pStrip_a, 50);
}
}
我也是初次接触esp32s3,如有不对的地方欢迎大家指正。