1 改写原因
原例程为“uart_events”。
例程是基于从机方式的,即接收响应的,打算实现一个基于主机方式的,即发送等待应答(带超时处理,失败自动重发2次)。
2 改写内容
硬件上:将串口改为串口2,发送脚GPIO19,接收脚GPIO18。
将例程中串口内容,复制并做部分修改移植到新建的“uart_master.c”和“uart_master.h”文件中。
“uart_master.c”文件内容如下:
#include <stdio.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "driver/uart.h"
#include "esp_log.h"
#include "uart_master.h"
static const char *TAG = "uart_events";
static QueueHandle_t rx_queue;
static uint8_t send_buf[1024]={1,2,3,4,5,6,7,8};
static uint8_t ack_ok = 0;
static void uart_rx_task(void *pvParameters)
{
uart_event_t event;
uint8_t* dtmp = (uint8_t*) malloc(1024);
for(;;) {
//Waiting for UART event.
if(xQueueReceive(rx_queue, (void * )&event, (portTickType)portMAX_DELAY)) {
bzero(dtmp, 1024);
ESP_LOGI(TAG, "uart[%d] event:", UART_NUM_2);
switch(event.type) {
//Event of UART receving data
/*We'd better handler data event fast, there would be much more data events than
other types of events. If we take too much time on data event, the queue might
be full.*/
case UART_DATA:
ESP_LOGI(TAG, "[UART DATA]: %d", event.size);
uart_read_bytes(UART_NUM_2, dtmp, event.size, portMAX_DELAY);
ESP_LOGI(TAG, "[DATA EVT]:");
uart_write_bytes(UART_NUM_2, (const char*) dtmp, event.size);
ack_ok = 1;//置应答标志
break;
//Event of HW FIFO overflow detected
case UART_FIFO_OVF:
ESP_LOGI(TAG, "hw fifo overflow");
// If fifo overflow happened, you should consider adding flow control for your application.
// The ISR has already reset the rx FIFO,
// As an example, we directly flush the rx buffer here in order to read more data.
uart_flush_input(UART_NUM_2);
xQueueReset(rx_queue);
break;
//Event of UART ring buffer full
case UART_BUFFER_FULL:
ESP_LOGI(TAG, "ring buffer full");
// If buffer full happened, you should consider encreasing your buffer size
// As an example, we directly flush the rx buffer here in order to read more data.
uart_flush_input(UART_NUM_2);
xQueueReset(rx_queue);
break;
//Event of UART RX break detected
case UART_BREAK:
ESP_LOGI(TAG, "uart rx break");
break;
//Event of UART parity check error
case UART_PARITY_ERR:
ESP_LOGI(TAG, "uart parity error");
break;
//Event of UART frame error
case UART_FRAME_ERR:
ESP_LOGI(TAG, "uart frame error");
break;
// case UART_RXFIFO_TOUT_INT://串口接收超时未找到相关事件,暂不通过此方式实现帧结束的判断
// ESP_LOGI(TAG, "uart frame end");
// break;
//Others
default:
ESP_LOGI(TAG, "uart event type: %d", event.type);
break;
}
}
}
free(dtmp);
dtmp = NULL;
vTaskDelete(NULL);
}
int sendData(const uint8_t* data,uint16_t len)
{
const int txBytes = uart_write_bytes(UART_NUM_2, data, len);
// ESP_LOGI(UART_NUM_0, "Wrote %d bytes", txBytes);
return txBytes;
}
static void uart_tx_task(void *arg)
{
static const char *TX_TASK_TAG = "TX_TASK";
esp_log_level_set(TX_TASK_TAG, ESP_LOG_INFO);
while (1) {
for(int i=0;i<3;i++)//最多重发3次
{
vTaskDelay(10 / portTICK_PERIOD_MS);//发送间隔10ms
uart_write_bytes(UART_NUM_2, send_buf, 6);
ack_ok = 0;
for(int t=0;t<500;t++)//最多等待5秒
{
vTaskDelay(10 / portTICK_PERIOD_MS);
if(ack_ok) break;//每10毫秒判断收到应答则退出循环
}
if(ack_ok) break;//收到应答则退出循环不进行重发
}
//进行应答成功或失败的相关处理
if(ack_ok)
{
ESP_LOGI(TAG, "ACK: OK");
}
else
{
ESP_LOGI(TAG, "ACK: ERROR");
}
}
}
esp_err_t uart2_init(int baud,int bufSize)
{
esp_log_level_set(TAG, ESP_LOG_INFO);
/* Configure parameters of an UART driver,
* communication pins and install the driver */
uart_config_t uart_config = {
.baud_rate = baud,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.source_clk = UART_SCLK_APB,
};
//Install UART driver, and get the queue.
uart_driver_install(UART_NUM_2, bufSize * 2, bufSize * 2, 20, &rx_queue, 0);
uart_param_config(UART_NUM_2, &uart_config);
//Set UART log level
esp_log_level_set(TAG, ESP_LOG_INFO);
//Set UART pins
uart_set_pin(UART_NUM_2, 19, 18, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
//Reset the pattern queue length to record at most 20 pattern positions.
uart_pattern_queue_reset(UART_NUM_2, 20);
uart_enable_rx_intr(UART_NUM_2);
//创建发送和接收任务
xTaskCreate(uart_rx_task, "uart_rx_task", bufSize*2, NULL, configMAX_PRIORITIES-2, NULL);
xTaskCreate(uart_tx_task, "uart_tx_task", bufSize*2, NULL, configMAX_PRIORITIES-1, NULL);
return ESP_OK;
}
“uart_master.h”文件内容如下:
#pragma once
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
esp_err_t uart2_init(int baud,int bufSize);
#ifdef __cplusplus
}
#endif
修改“uart_events_example_main.c”文件
/* UART Events Example
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "driver/uart.h"
#include "esp_log.h"
#include "uart_master.h"
void app_main(void)
{
uart2_init(19200,1024);
}
版权声明:本文为CSDN博主「tslids」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/tsliuch/article/details/121690947
暂无评论