USART2实现Motbus485通信

news2024/11/23 13:44:05

本文用的单片机是原子的战舰V4

1. 先来驱动一下usart2

USART驱动配置一般步骤:

STEP1:使能相关时钟,这块板子usart2用到了A2A3分别为TX脚、RX脚,D7的作用是发送接收模式控制。下面开启GPIO与USART2时钟:

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOD, ENABLE);

STEP2:初始化GPIO,A2A3D7三个IO口都要去初始化,其中TX功能IO要设置为复用推挽输出,RX功能IO要设置为浮空,D7作为发送接收控制要设为推挽输入。

/*GPIO初始化--Ck*/
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_7;//CK
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOD, &GPIO_InitStruct);
    /*GPIO初始化--TX*/
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2;//TX
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStruct);
    /*GPIO初始化--RX*/
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_3; //RX
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
    GPIO_Init(GPIOA, &GPIO_InitStruct);

STEP3:接下来是USARTNVIC的初始化,串口初始化主要设置波特率、控制流、校验、停止位等,初始化完之后记得开启一下串口中断;NVIC初始化则需要设置中断通道使能、优先级等。我们默认设置为接收模式

	USART_InitStruct.USART_BaudRate = bound;
    USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStruct.USART_Mode = USART_Mode_Rx|USART_Mode_Tx;
    USART_InitStruct.USART_Parity = USART_Parity_No;
    USART_InitStruct.USART_StopBits = USART_StopBits_1;
    USART_InitStruct.USART_WordLength = USART_WordLength_8b;
    USART_Init(USART2, &USART_InitStruct);
    /*开启串口中断*/
    USART_ITConfig(USART2, USART_IT_RXNE,ENABLE); //接收中断,当接收到1个字节,会产生USART_IT_RXNE中断
    /*使能串口*/
    USART_Cmd(USART2,ENABLE);
    /*NVIC初始化*/
    NVIC_InitStruct.NVIC_IRQChannel = USART2_IRQn; //USART2通道使能
    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1; //抢占优先级
    NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1; //子优先级
    NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStruct);

STEP4:接着去写中断服务函数即可,这里先写一个简单的,下载程序后可实现“串口助手发什么就能接收到什么”。

void USART2_IRQHandler(void){
    u8 res;	    
 	if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) //接收到数据
	{	 		 
		res =USART_ReceiveData(USART2); 
		USART_SendData(USART2,res);
	}  
}

最后不要忘记在主程序中配置中断优先级分组NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

这样我们一个简单的串口通信就完成了。

2. Motbus485通信在USART基础上又应该怎么实现

首先这边是我们的h文件,只是一些定义和声明,不详细介绍。

#ifndef __USART2_H
#define __USART2_H
#include "sys.h"

#define RS485_REC_LEN  			64  	//定义最大接收字节数 200

//模式控制
#define RS485_TX_EN		PDout(7)	//485模式控制.0,接收;1,发送.
#define EN_USART2_RX 			1		//使能(1)/禁止(0)串口1接收
	  	
extern u8  RS485_RX_BUF[RS485_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.末字节为换行符 
extern u16 USART_RX_CNT;         		//接收状态标记	

void usart2_init(u32 bound);

void RS485_Receive_Data(u8 *buf,u8 *len);
void RS485_Send_Data(u8 *buf,u8 len);
#endif

中断服务函数修改:我们将接收到的数据放到一个数组中存起来。这里我们做了一个条件编译#ifdef EN_USART2_RX...#endif。可以看到相对于前面写的中断服务函数并没有什么改变,我们并没有直接将接收到的数据发出来,而实现存到一个数组里面。

#ifdef EN_USART2_RX   	//如果使能了接收
u8 RS485_RX_BUF[RS485_REC_LEN]; //定义接收缓冲200字节
u16 USART_RX_CNT=0;       //接收状态标记

void USART2_IRQHandler(void){
    u8 res;	    
 	if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) //接收到数据
	{	 		 
		res =USART_ReceiveData(USART2); 	//读取接收到的数据
		if(USART_RX_CNT<64)
		{
			RS485_RX_BUF[USART_RX_CNT]=res;		//记录接收到的值
			USART_RX_CNT++;						//接收数据增加1 
		} 
	}  
}
#endif

接着写一下485接收程序,这边要做的事情其实就是将usart接收到的数据存到buf中。相当于是将数据从RS485_RX_BUF转到buf中,之后要做数据处理,我们直接对这个buf做数据处理即可。

void RS485_Receive_Data(u8 *buf,u8 *len){
    u8 rxlen = USART_RX_CNT;
    u8 i = 0;
    *len = 0;
    delay_ms(10);//等待10ms,连续超过10ms没有接收到一个数据,则认为接收结束
    if(rxlen == USART_RX_CNT&&rxlen){//接收到了数据,且接收完成了
        for(i = 0; i < rxlen; i++){
            buf[i] = RS485_RX_BUF[i];
        }
        *len = USART_RX_CNT;
        USART_RX_CNT = 0; //清0
    }  
}

写一下485发送数据的程序,我们要判断数据是否发完了,没有发完就用USART_SendData去发

先了解一下USART_FLAG_TC这个标志是干嘛的
当发送移位寄存器中的1字节数据已经通过TX脚一位一位的移出去后,该标志位就会被置1,从而引发该事件的中断。所以,其实USART_FLAG_TC就是用来标志 “发送移位寄存器中的数据有没有全部发送出去” 这件事的。

void RS485_Send_Data(u8 *buf,u8 len){
    u8 t;
    RS485_TX_EN=1;			//设置为发送模式
    for(t=0;t<len;t++)		//循环发送数据
	{		   
		while(USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET);	  
		USART_SendData(USART2,buf[t]);
	}	 
	while(USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET);		
	USART_RX_CNT=0;	  
	RS485_TX_EN=0;				//设置为接收模式	
}

我们定义了一个要发送的数据数组与数据接收数组,接着发送、接收。

u8 TR_Read[8]={0x01,0x03,0x00,0x00,0x00,0x02,0xC4,0x0B}; 
u8 rs485buf[20]={0}; 
RS485_Send_Data(TR_Read,8);
delay_ms(300);
RS485_Receive_Data(rs485buf,&len);

实验现象:接着打开串口进行测试,指令就发出来了。
在这里插入图片描述

一般情况下,我们只要向485传感器发送相关指令,就可以驱动这种传感器了。比如你要获取传感器数据,你就发送数据获取指令;需要修改地址,就发送修改地址的指令。485收发你都会了,传感器驱动哪里还是什么问题呢。

创作不易!希望收获你的点赞与关注👍🤝🤝

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot中打印 sql 语句

系列文章目录 文章目录 系列文章目录前言一、在配置文件中 application.yml 配置即可二、#Log4g打印SqL语句三、配置Logback总结 前言 在SpringBoot中&#xff0c;我们可以使用日志框架来打印SQL语句&#xff0c;常用的日志框架有Logback和Log4j2。下面以Logback为例&#xff…

35:考虑virtual函数以外的其他选择

假设你正在写一个视频游戏软件&#xff0c;你打算为游戏内的人物设计一个继承体系&#xff0c;剧中人物被伤害或因其他因素而降低健康状态的情况并不罕见。你因此决定提供一个成员函数healthValue&#xff0c;它会返回一个整数&#xff0c;表示人物的健康程度。 由于不同的人物…

Linux x86_64平台同时编译x86_64和arm64两个架构的Qt应用程序出现XRes库无法找到

一 背景 在ubuntu x86_64平台上需要同时编译x86_64和arm64两个架构的Qt应用程序。在实践过程中&#xff0c;发现XRes库只能安装在其中一个平台。 二 根因 安装amd64版本的XRes库会删除arm64版本的库&#xff0c;反之亦然。 在安装amd64版本时&#xff0c;会删除arm64版本&a…

内部员工有没有在线帮助文档可以使用呢

当今企业中&#xff0c;内部员工的工作内容变得越来越复杂&#xff0c;需要不断学习新的知识和技能。在这种情况下&#xff0c;企业需要给员工提供一种便捷的在线帮助文档&#xff0c;使员工能够更加高效地完成工作任务。本文将介绍企业内部员工在线帮助文档的重要性以及如何建…

区块链如何助力价值互联网?这些专家有话说

6月13日&#xff0c;由开放原子开源基金会主办&#xff0c;XuperCore开源项目承办的2023开放原子全球开源峰会区块链分论坛在北京举办。来自区块链领域内的专家、行业代表汇聚一堂&#xff0c;分别以主题演讲、圆桌论坛等形式&#xff0c;阐述了全球区块链行业的新理念、新发展…

Opencv仿射函数getAffineTransform底层实现原理

推导 三角形ABC仿射成为三角形DEF的变换矩阵M 猜测矩阵M [ [a1,b1,c1], [a2,b2,c2] ] 仿射变换的数学联系 对于A点和D点 AX*a1AY*b1c1DX AX*a2AY*b2c1DY 对于B点和E点 BX*a1BY*b1c1EX BX*a2BY*b2c2EY 对于C点和F点 CX*a1CY*b1c1FX CX*a2CY*b2c2FY 求解 对以上数…

seqkit 两种拆分方法的比较

seqkit拆分fastq&#xff0c;fasta等文件有两种方式&#xff1a;split和split2&#xff0c; 二者的逻辑并不一样。 split 是将原文件拆分&#xff0c;写满第一个文件&#xff0c;再写第二个文件 split2是将原文件的内容&#xff0c;挨个写到各个拆分文件里面去&#xff1f; 比…

拓尔微技术干货 | get 5个知识点,了解细分驱动技术

本期我们对步进电机驱动原理、五线的步进电机和四线的步进电机、2-2相励磁和1-2相励磁、步进电机驱动的优化方案、拓尔微TMI8150B细分驱动技术的原理进行详细的介绍&#xff0c;共分为5个知识点&#xff0c;全是技术干货&#xff0c;赶紧get下来~ ✔get 1&#xff1a;步进电机…

datax安装部署使用 windows

Datax在win10中的安装_windows安装datax_JMzz的博客-CSDN博客 DataX/userGuid.md at master alibaba/DataX GitHub 环境准备&#xff1a; 1.JDK(1.8以上&#xff0c;推荐1.8) 2.①Python(推荐Python2.7.X) ②Python(Python3.X.X的可以下载下面的安装包替换) python3.0需…

Docker安装——CentOS7.6(详细版)

ps:docker官网 在 CentOS 上安装 Docker 引擎 |官方文档 &#xff08;&#xff09; 一、确定版本&#xff08;必须是7以上版本&#xff09; cat /etc/redhat-release 二、卸载旧版本&#xff08;或者之前装过&#xff0c;没有安装过就不用管了&#xff09; &#xff08;root用…

OpenCV 项目开发实战--实现填充图像中的孔( Python / C++ ) 代码实现

文末附分别基于C++和python实现的相关测试代码下载链接 图 1. 左:原始的图像。中心:阈值和倒置。右:孔被填充。 在本教程中,我们将学习如何填充二值图像中的孔洞。考虑图 1 中左侧的图像。假设我们想要找到一个将硬币与背景分开的二进制掩码,如右图所示。在本教程中,包含…

2.0C++继承

C继承概述 C 中的继承是指一个类可以从另一个类中继承属性和方法&#xff0c;这个被继承的类称为基类或父类&#xff0c;继承它的类称为派生类或子类。 C三种继承 1、公有继承 public 在公有继承中&#xff0c;基类的公有成员和保护成员都可以被派生类访问&#xff0c;而基…

【ROS】ROS2导航Nav2:简介、安装、测试效果、错误处理

1、简介 在ROS2中自动导航使用Nav2来实现。 Nav2 使用几个独立的模块化服务&#xff0c;通过 ROS 2接口&#xff08;例如动作服务器或服务&#xff09;与行为树 (BT) 通信。 Nav2 输入包括&#xff1a;TF转换、一个地图源、一个行为树 (BT) XML 文件和相关的传感器数据源; Nav…

【数字图像处理】2.几何变换

目录 2.1 仿射变换&#xff08;二维&#xff09; 2.2 投影变换&#xff08;三维&#xff09; 2.3 极坐标变换 2.3.1 将笛卡尔坐标转化为极坐标 2.3.2 将极坐标转换为笛卡尔坐标 2.3.3 利用极坐标变换对图像进行变换 几何变换&#xff1a;放大、缩小、旋转等&#xff0c;改…

[游戏开发]Unity中随机位置_在圆/椭圆/三角形/多边形/内随机一个点

[ 目录 ] 0. 前言1. 矩形内随机2. 圆形内随机3. 三角形内随机4. 多边形内随机&#xff08;1&#xff09;多边形分割为三角形&#xff08;2&#xff09;三角形面积计算&#xff08;3&#xff09;数据缓存&#xff08;4&#xff09;按权重随机&#xff08;5&#xff09;实现随机 …

理论【8】TCPUDP彻底搞懂了吗?

1 概述 对于TCP协议和UDP协议&#xff0c;大家应该都有所耳闻。TCP协议和UDP协议都工作在传输层&#xff0c;他们的目标都是在应用之间传输数据。我们常用的网络通信&#xff0c;比如浏览网页、查看邮件、电话通信等&#xff0c;都是通过这两种协议来进行数据传输的。 2 TCP…

面试---如何发现Redis热点Key,有哪些解决方案?

目录 热点问题概述热点问题的危害常见解决方案阿里云数据库解热点之道热点key的处理两种方案对比总结 热点问题概述 产生原因 热点问题产生的原因大致有以下两种&#xff1a; 用户消费的数据远大于生产的数据&#xff08;热卖商品、热点新闻、热点评论、明星直播&#xff09;…

【AI绘画】本地部署Stable Diffusion Web UI

近几年AI发展迅猛&#xff0c;今年更是大爆发&#xff0c;除了爆火的大模型ChatGPT以外&#xff0c;AI绘画也有很大的进步&#xff0c;目前&#xff0c;Stable Diffusion图像生成效果相当惊人&#xff0c;可以生成逼真的人像、风景、物品图片&#xff0c;还可以将图片转换为不同…

提示学习soft prompt浅尝,启发了p-tuing

一、前言 在高质量标注数据稀缺的工业界来说&#xff0c;少样本学习或者零样本学习的方法特别受欢迎&#xff0c;后面出现过一些少样本和零样本的方法&#xff0c;例如对比学习和prompt等&#xff0c;主流prompt的工作分为离散型和连续型模板。离散型主要还是插入bert特殊的tok…

分享AI绘画的方法

曾经&#xff0c;在一个神奇的编程国度里&#xff0c;住着一个名叫小花的程序员。小花喜欢创造和探索新奇的技术&#xff0c;她有一个惊人的能力&#xff1a;她能够根据文字生成相应的图片。这项技术让她成为了这个国度里的传奇人物。人们纷纷向她寻求帮助&#xff0c;希望能够…