RT-Thread基于AT32单片机的485应用开发(二)

在上篇RT-Thread基于AT32单片机的485应用开发(一)中实现了RS485收发,但总觉得效率不高,函数封装也不完善。考虑到RS485总线应用都是主从式结构,比如工业领域常用的Modbus协议,都是以帧为单位进行收发,本次测试对收发函数进行了封装,并对RS485的收发控制引脚根据波特率进行了自动延时控制,降低了CPU负载。

本例中收发全部采用DMA的NON_BLOCKING方式,把接收一帧数据和发送一帧数据进行了函数封装。

测试代码如下:

#include <rtthread.h>
#include <rtdevice.h>/* 串口设备句柄 */
static rt_device_t serial;/* 485控制引脚 */
static rt_base_t rs485_ctrl_pin = -1;/* timeout receive */
static int serial_read_frame(rt_device_t dev, uint8_t *buf, int max_len, uint32_t idle_ms, int timeout_ms)
{int rx_len = 0, rc;uint32_t idle_time, timeout_time, cur_tick, last_tick;timeout_time = rt_tick_from_millisecond(timeout_ms);idle_time = rt_tick_from_millisecond(idle_ms);cur_tick = rt_tick_get();while((rt_tick_get()-last_tick<idle_time && rx_len<max_len) || rx_len<=0){rc = rt_device_read(dev, rx_len, buf, max_len-rx_len);if(rc>0){rx_len += rc;last_tick = rt_tick_get();}else{rt_thread_mdelay(1);}if(rt_tick_get()-cur_tick>timeout_time && rx_len<=0)break;}return rx_len;
}
/* transmit with auto 485 pin ctrl */
static void serial_write_frame_rs485(rt_device_t dev, uint8_t *buf, int len, int bitrate, int ctrl_pin)
{int ms = len * 10 *1000 / bitrate + 2;rt_pin_write(rs485_ctrl_pin,1);rt_hw_us_delay(10);rt_device_write(dev, 0, buf, len);rt_thread_mdelay(ms);rt_pin_write(rs485_ctrl_pin,0);
}
static void serial_thread_entry(void *parameter)
{rt_uint32_t rx_len;static unsigned char rx_buf[256];while(1){rx_len = serial_read_frame(serial, rx_buf, 255, 10, 1000);if(rx_len<=0)continue;serial_write_frame_rs485(serial, rx_buf, rx_len, 115200, rs485_ctrl_pin);/* 打印数据 */rx_buf[rx_len] = '\0';rt_kprintf("rx_len = %d\n",rx_len);}
}static int uart_485_sample(int argc, char *argv[])
{rt_err_t ret = RT_EOK;char uart_name[RT_NAME_MAX] = "uart4";if (argc == 2){rt_strncpy(uart_name, argv[1], RT_NAME_MAX);}rt_kprintf("uart_name = %s\n",uart_name);if(rt_strcmp(uart_name,"uart3")==0){rs485_ctrl_pin = rt_pin_get("PE.15");rt_pin_mode(rs485_ctrl_pin, PIN_MODE_OUTPUT);rt_pin_write(rs485_ctrl_pin,0 );}else if(rt_strcmp(uart_name,"uart4")==0){rs485_ctrl_pin = rt_pin_get("PA.15");rt_pin_mode(rs485_ctrl_pin, PIN_MODE_OUTPUT);rt_pin_write(rs485_ctrl_pin,0);}else{return RT_ERROR;}/* 查找串口设备 */serial = rt_device_find(uart_name);if (!serial){rt_kprintf("find %s failed!\n", uart_name);return RT_ERROR;}/* 以 DMA 接收及轮询发送方式打开串口设备 */rt_device_open(serial, RT_DEVICE_FLAG_RX_NON_BLOCKING | RT_DEVICE_FLAG_TX_NON_BLOCKING);/* 创建 serial 线程 */rt_thread_t thread = rt_thread_create("serial", serial_thread_entry, RT_NULL, 1024, 25, 10);/* 创建成功则启动线程 */if (thread != RT_NULL){rt_thread_startup(thread);}else{ret = RT_ERROR;}return ret;
}
/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(uart_485_sample, uart device rs485 sample);

接收函数,返回收到的字节数:

int serial_read_frame(rt_device_t dev, uint8_t *buf, int max_len, uint32_t idle_ms, int timeout_ms)

idle_ms : 收到最后一个字节数据后空闲的毫秒数

timeout_ms : 如果在这个时间内没有收到数据,则返回0;-1代表一直等待直到收到数据。

发送函数

void serial_write_frame_rs485(rt_device_t dev, uint8_t *buf, int len, int bitrate, int ctrl_pin)

bitrate : 波特率,用于计算实际需要发送的时间

ctrl_pin :485收发控制引脚号

实际测试结果:

在编辑文字的约6分钟内,总共收发了31270个字节,没有发生错误。

在此基础上,后续又实现了一个极简ModbusRTU从机,核心代码不到300行,支持01、02、03、04、05、06、15、16功能码。

RT-Thread基于AT32单片机的485应用开发(三)Modbus从机

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/337202.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

慕课热搜01

uniapp过滤器使用 创建一个过滤器&#xff1a; 在入口函数注册过滤器 // 注册过滤器 import * as filters from "./filters/index.js"Object.keys(filters).forEach(key>{Vue.filter(key,filters[key]) })使用过滤器&#xff1a; onPageScroll , uniapp监听滚动…

花为缘享奢APP震撼上线,2024奢侈品行业创业首选平台

中国是全球最大的奢侈品消费国&#xff0c;并且有着持续的消费增长潜力。普华永道在今年2月发布的《中国内地及香港地区奢侈品市场洞察》报告显示&#xff0c;随着旅游和社交活动逐渐步入正轨&#xff0c;全球奢侈品市场正稳步复苏&#xff0c;预计至2025年全球市场规模将以11%…

KVM系统虚拟化性能测试过程总结

buildroot编译 为啥要用buildroot 支持很多&#xff1a;交叉编译工具链、根文件系统生成、内核映像编译和引导加载程序编译。使用简单&#xff1a;使用类似内核的menuconfig、gconfig和xconfig配置界面&#xff0c;使用buildroot构建基本系统很容易。支持很多的包&#xff1a…

LightGBM原理和调参

背景知识 LightGBM(Light Gradient Boosting Machine)是一个实现GBDT算法的框架&#xff0c;具有支持高效率的并行训练、更快的训练速度、更低的内存消耗、更好的准确率、支持分布式可以处理海量数据等优点。 普通的GBDT算法不支持用mini-batch的方式训练&#xff0c;在每一次…

一键修复所有dll缺失的工具,dll修复工具下载使用教程

在计算机使用过程中&#xff0c;我们经常会遇到各种软件或系统错误提示&#xff0c;其中最常见的就是“找不到指定的模块”或“无法找到某某.dll文件”。Dll是动态链接库的缩写&#xff0c;它是Windows操作系统中的重要组成部分&#xff0c;负责提供各种功能和资源给应用程序使…

大模型PEFT技术原理(一):BitFit、Prefix Tuning、Prompt Tuning

随着预训练模型的参数越来越大&#xff0c;尤其是175B参数大小的GPT3发布以来&#xff0c;让很多中小公司和个人研究员对于大模型的全量微调望而却步&#xff0c;近年来研究者们提出了各种各样的参数高效迁移学习方法&#xff08;Parameter-efficient Transfer Learning&#x…

【语义解析:连接自然语言与机器智能的桥梁】

语义解析&#xff1a;连接自然语言与机器智能的桥梁 语义解析技术可以提高人机交互的效率和准确性&#xff0c;在自然语言处理、数据分析、智能客服、智能家居等领域都有广泛的应用前景。特别是在大数据时代&#xff0c;语义解析能够帮助企业更快速地从大量的数据中获取有用的…

【开源商城推荐-LGPL-3.0】ts-mall 聚惠星商城

dts-shop: 聚惠星商城 DTS-SHOP&#xff0c;基于 微信小程序 springboot vue 技术构建 &#xff0c;支持单店铺&#xff0c;多店铺入驻的商城平台。项目包含 微信小程序&#xff0c;管理后台。基于java后台语言&#xff0c;已功能闭环&#xff0c;且达到商用标准的一套项目体…

【EI会议征稿通知】第五届计算机信息和大数据应用国际学术会议(CIBDA 2024)

第五届计算机信息和大数据应用国际学术会议&#xff08;CIBDA 2024&#xff09; 2024 5th International Conference on Computer Information and Big Data Applications 第五届计算机信息和大数据应用国际学术会议&#xff08;CIBDA 2024&#xff09;将于2024年4月26-28日在…

Python pip 常用指令

前言 Python的pip是一个强大的包管理工具&#xff0c;它可以帮助我们安装、升级和管理Python的第三方库。以下是一些常用的pip指令。 1. 安装第三方库 使用pip安装Python库非常简单&#xff0c;只需要使用pip install命令&#xff0c;后面跟上库的名字即可。 # 安装virtuale…

springboot——消息中间件

消息的概念 从广义角度来说&#xff0c;消息其实就是信息&#xff0c;但是和信息又有所不同。信息通常被定义为一组数据&#xff0c;而消息除了具有数据的特征之外&#xff0c;还有消息的来源与接收的概念。通常发送消息的一方称为消息的生产者&#xff0c;接收消息的一方称为…

使用PAI-DSW搭建基于LangChain的检索知识库问答机器人

教程简述 在本教程中&#xff0c;您将学习如何在阿里云交互式建模&#xff08;PAI-DSW&#xff09;中&#xff0c;基于LangChain的检索知识库实现知识问答。旨在建立一套对中文场景与开源模型支持友好、可离线运行的知识库问答解决方案。 LangChain是一个开源的框架&#xff0c…