TT12-MCU/applications/uart_3S.c
CSSC-WORK\murmur 1a14d5b193 更新为5s一发
添加对232接收断帧数据的处理
更新对不符合帧格式数据的处理方式,改为透传
2024-01-15 18:27:37 +08:00

238 lines
6.7 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2019-04-16 misonyo first implementation.
*/
/*
* 程序清单:这是一个串口设备 DMA 接收使用例程
* 例程导出了 uart_dma_sample 命令到控制终端
* 命令调用格式uart_dma_sample uart3
* 命令解释:命令第二个参数是要使用的串口设备名称,为空则使用默认的串口设备
* 程序功能:通过串口输出字符串"hello RT-Thread!",并通过串口输出接收到的数据,然后打印接收到的数据。
*/
#include <rtthread.h>
#include <dfs_file.h>
#include <usrcfg.h>
#include <board.h>
#define LOG_TAG "RS232"
#define LOG_LVL LOG_LVL_DBG
#include <ulog.h>
#ifdef WORK_BOARD
#define SAMPLE_UART_NAME "uart1" /* 串口设备名称 */
#else
#define SAMPLE_UART_NAME "uart3" /* 串口设备名称 */
#endif
#ifndef MIN_FRAME_LEN
#define MIN_FRAME_LEN 10
#endif
/* 串口接收消息结构*/
struct rx_msg
{
rt_device_t dev;
rt_size_t size;
};
/* 串口设备句柄 */
static rt_device_t serial;
/* 消息队列控制块 */
static struct rt_messagequeue rx_mq;
/* 接收数据回调函数 */
static rt_err_t uart_input(rt_device_t dev, rt_size_t size)
{
struct rx_msg msg;
rt_err_t result;
static rt_size_t cachecnt=0;
#ifdef CHECK_LEN
cachecnt += size;
if (cachecnt < MIN_FRAME_LEN) {
LOG_W("not enough data, cached and waiting...");//处理半包
return;
}
msg.dev = dev;
msg.size = cachecnt;
#else
msg.dev = dev;
msg.size = size;
#endif
result = rt_mq_send(&rx_mq, &msg, sizeof(msg));
if ( result == -RT_EFULL)
{
/* 消息队列满 */
LOG_W("message queue full");
}
cachecnt = 0;
return result;
}
struct rx_msg msg;
//extern struct rt_event update_cfg;
//extern int time2Str(char *str);
static uint8_t is232parsing=0;
uint8_t is232Busy(void)
{
return rx_mq.entry | is232parsing;
}
static void serial_thread_entry(void *parameter)
{
// struct rx_msg msg;
rt_err_t result;
size_t rx_length=0;//单次收到的数据长度
static char rx_buffer[RT_SERIAL_RB_BUFSZ + 1];
memset(rx_buffer,0,RT_SERIAL_RB_BUFSZ + 1);//清空rx_buffer
static uint8_t p=0;
while (1)
{
rt_memset(&msg, 0, sizeof(msg));
/* 从消息队列中读取消息*/
is232parsing=0;
result = rt_mq_recv(&rx_mq, &msg, sizeof(msg), RT_WAITING_FOREVER);
is232parsing=1;
if (result == RT_EOK)
{
/* 从串口读取数据*/
rx_length = rt_device_read(msg.dev, 0, rx_buffer+p, msg.size);
if (!rx_length) {
// LOG_W("read from RS232 error,should be %d Bytes",msg.size);
continue;
}
LOG_I("%d Bytes received from RS232",rx_length);
//对于断帧数据的处理
if (rx_buffer[p+rx_length-1] != 0xed) {
p=p+rx_length;
if (p > 120*5) {//不死等
rx_length = p + rx_length;
p=0;
parseRS232(rx_buffer, rx_length);
}
continue;
}
else {
rx_length = p + rx_length;
p=0;
}
// LOG_HEX("232rx:",16,rx_buffer,rx_length);//print what received.
parseRS232(rx_buffer, rx_length);
}
}
}
static int uart_dma_sample(int argc, char *argv[])
{
rt_err_t ret = RT_EOK;
char uart_name[RT_NAME_MAX];
static char msg_pool[256*4*2];
char str[] = {0x01,0x03,0x00,0x00,0x00,0x1d,0x85,0xc3};
if (argc == 2)
{
rt_strncpy(uart_name, argv[1], RT_NAME_MAX);
}
else
{
rt_strncpy(uart_name, SAMPLE_UART_NAME, RT_NAME_MAX);
}
/* 查找串口设备 */
serial = rt_device_find(uart_name);
if (!serial)
{
rt_kprintf("find %s failed!\n", uart_name);
return RT_ERROR;
}
/* 初始化消息队列 */
rt_mq_init(&rx_mq, "rx_mq",
msg_pool, /* 存放消息的缓冲区 */
sizeof(struct rx_msg), /* 一条消息的最大长度 */
sizeof(msg_pool), /* 存放消息的缓冲区大小 */
RT_IPC_FLAG_FIFO); /* 如果有多个线程等待,按照先来先得到的方法分配消息 */
#ifdef TR485
struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; /* 初 始 化 配 置 参 数 */
/* step2 修 改 串 口 配 置 参 数 */
config.baud_rate = BAUD_RATE_9600; //修 改 波 特 率 为 9600
config.data_bits = DATA_BITS_8; //数 据 位 8
config.stop_bits = STOP_BITS_1; //停 止 位 1
config.bufsz = 128; //修 改 缓 冲 区 buff size 为 128
config.parity = PARITY_NONE; //无 奇 偶 校 验 位
/* step3 控 制 串 口 设 备。 通 过 控 制 接 口 传 入 命 令 控 制 字, 与 控 制 参 数 */
rt_device_control(serial, RT_DEVICE_CTRL_CONFIG, &config);
#endif
/* 以 DMA 接收及轮询发送方式打开串口设备 */
rt_device_open(serial, RT_DEVICE_FLAG_DMA_RX);
/* 设置接收回调函数 */
rt_device_set_rx_indicate(serial, uart_input);
/* 发送字符串 */
#ifdef TR485
rt_pin_write(TR485_RE, PIN_HIGH);
rt_device_write(serial, 0, str, sizeof(str));
rt_pin_write(TR485_RE, PIN_LOW);
#endif
/* 创建 serial 线程 */
rt_thread_t thread = rt_thread_create("RS232", serial_thread_entry, RT_NULL, 1024*10, 25-1, 10);
/* 创建成功则启动线程 */
if (thread != RT_NULL)
{
rt_thread_startup(thread);
}
else
{
ret = RT_ERROR;
}
return ret;
}
/* 导出到 msh 命令列表中 */
//MSH_CMD_EXPORT(uart_dma_sample, uart device dma sample);
//INIT_COMPONENT_EXPORT(uart_dma_sample);
INIT_APP_EXPORT(uart_dma_sample);
/**
* 发送数据到3S
* @param din
* @param len
*/
void sendTo3S(uint8_t *din, size_t len)
{
size_t rst = rt_device_write(serial, 0, din, len);
LOG_D("send %d Bytes done.",rst);
}
#ifdef DEMO
void sendData(int argc, char *argv[])
{
//待发数据
char str[][50] =
{
{0x01,0x03,0x00,0x00,0x00,0x1d,0x85,0xc3},
"hello\r\n",
{0x5A,0xA5, 0x31, 0x32, 0x19, 0x06, 0x00, 0x01, 0x01, 0x1C, 0xED }
};
size_t size[]={8,strlen(str[1]),11};//对应每一维数据长度
size_t index = 0;
if (argc == 2) {
index = atoi(argv[1]);
}
size_t rst = rt_device_write(serial, 0, str[index], size[index]);
LOG_D("send %d Bytes ok.",rst);
}
MSH_CMD_EXPORT(sendData,3)
#endif