AS5045磁旋转编码器使用以及STM32接收学习心得(另modbus协议、RS485接口、RS485转TTL说明)


作者:瓴(L)
时间:2021.05.13
说明:部分文章内容引用,若有侵权联系删除


一、电气接口

在这里插入图片描述
在这里插入图片描述

1、5V供电,1:VDD5;2:A;3: B;4:GND
2、板子上没有配终端电阻,需要自己根据应用需要配电阻
3、板子外径30mm,安装孔内径2.7mm,可配2.5的螺钉,两孔中心间距21mm.

二、RS485接口通信协议

编码器485波特率范围:1200-57600,可以根据具体实际请款设置波特率,默认设率9600,8,n,1。

三、modbus通信协议格式

(1)、moubus协议概要
1、Modbus协议是一种单主/多从的通信协议,其特点是在同一时间,总线上只能有一个主设备,但可以有一个或者多个(最多247个)从设备。
2、Modbus通信总是由主设备发起,当从设备没有收到来自主设备的请求时,不会主动发送数据。
3、从设备之间不能相互通信,主设备同时只能启动一个Modbus访问事务处理。

(2)、modbus寄存器
1、四种寄存器
在这里插入图片描述

注:1)采用保持寄存器传递信息;
2)默认节点号1(可修改);

2、寄存器地址以及命令

寄存器地址0001020304050607
寄存器功能角度符号角度圈数符号圈数波特率波特率(备用)地址1置零2
注:1)如果要修改编码器的设备地址,只要按照modbus协议修改该处值即可
2) 对于置零操作,只要修改该寄存器值为1即可完成置零。新设零点位置掉电后不丢失。
3) 波特率(备用)寄存器用于以后提高波特率用。
4) 符号寄存器均设定为:0为正,1为负;
5) 红色寄存器代表后续添加功能。

(3)、Modbus功能码

1、modbus功能码表

功能码名称作用
01读取线圈状态取得一组逻辑线圈的当前状态(ON/OFF)
02读取输入状态取得一组开关输入的当前状态(ON/OFF)
03读取保持寄存器在一个或多个保持寄存器中取得当前的二进制值
04读取输入寄存器在一个或多个输入寄存器中取得当前的二进制值
05强置单线圈强置一个逻辑线圈的通断状态
06预置单寄存器把具体二进值装入一个保持寄存器
07读取异常状态取得8个内部线圈的通断状态,这8个线圈的地址由控制器决定,用户逻辑可以将这些线圈定义,以说明从机状态,短报文适宜于迅速读取状态
08回送诊断校验把诊断校验报文送从机,以对通信处理进行评鉴
09编程(只用于484)使主机模拟编程器作用,修改PC从机逻辑
10控询(只用于484)可使主机与一台正在执行长程序任务从机通信,探询该从机是否已完成其操作任务,仅在含有功能码 9 的报文发送后,本功能码才发送
11读取事件计数可使主机发出单询问,并随即判定操作是否成功,尤其是该命令或其它应答产生通信错误时
12读取通信事件记录可使主机检索每台从机的ModBus事务处理通信事件记录。如果某项事务处理完成,记录会给出有关错误
13编程(184/384 484 584 )可使主机模拟编程器功能修改PC从机逻辑
14探询(184/384 484 584)可使主机与正在执行任务的从机通信,定期控询该从机是否已完成其程序操作,仅在含有功能13的报文发送后,本功能码才得发送
15强置多线圈强置一串连续逻辑线圈的通断
16预置多寄存器把具体的二进制值装入一串连续的保持寄存器
17报告从机标识可使主机判断编址从机的类型及该从机运行指示灯的状态
18884 和MICRO 84可使主机模拟编程功能,修改PC状态逻辑
19重置通信链路发生非可修改错误后,是从机复位于已知状态,可重置顺序字节
20读取通用参数(584L)显示扩展存储器文件中的数据信息
21写入通用参数(584L)把通用参数写入扩展存储文件,或修改
22~64保留作扩展功能备用
65~72保留以备用户功能所用留作用户功能的扩展编码
73~119非法功能
120~127保留留作内部作用
128~255保留用于异常应答
2、常用modbus功能码
1)读线圈状态功能码 01
2)读(离散)输入状态功能码 02
3)读保持寄存器功能码 03
4)读输入寄存器功能码 04
5)写单个线圈功能码 05
6)写单个保持寄存器功能码 06
7)写多个线圈功能码 15
8)写多个保持寄存器功能码 16

四、modbus调试软件说明

Modbus调试精灵无需安装,打开软件界面如下。
在这里插入图片描述

1、插入485模块后,电脑会自动分配串口号,根据设备管理器中显示的串口选择。
2、点击打开串口,绿色显示连接成功
3、在右边寄存器区进行操作,我们只需要输入的是寄存器地址和数值,然后点击写入或者读出。
4、当我们点击写入或者读出后,发送区域会显示发送出去的十六进制数(发送命令),接收区域会显示接收到的十六进制数据。

五、STM32读取modbus磁旋转编码器方法

(1)、硬件部分

1、该编码器使用的是RS485通信协议,属于串口的一种协议。RS485是电压差分信号传输,而stm32根据电平分辨0和1。所以需要RS485转TTL模块。
在这里插入图片描述

2、RS485转TTL模块硬件连接图,根据下图红色框对应进行连接。
在这里插入图片描述

可根据正点原子STM32库函数版本中文手册进行理解。

//模式控制
#define RS485_TX_EN		PDout(7)	//485模式控制.0,接收;1,发送.

(注:根据硬件图,应该将RE、DE从背面焊接起来,然后与我们定义的引脚相接,如上代码这里定义了PD7引脚控制)

(2)软件部分

1、需要向该编码器发送命令,编码器才会发送返回数据。
2、发送命令即为我们根据寄存器区操作时,发送区域自动生成的十六进制数,直接复制过来使用即可。
如下代码,我通过定时器周期发送命令,从而磁旋转编码器周期返回数据。

u8 order[8]={0x01,0x03,0x00,0x01,0x00,0x02,0x95,0xCB};
//定时器3中断服务程序
void TIM3_IRQHandler(void)   //TIM3中断
{
	if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)  //检查TIM3更新中断发生与否
		{
			RS485_Send_Data(order,8);//发送5个字节 
		TIM_ClearITPendingBit(TIM3, TIM_IT_Update  );  //清除TIMx更新中断标志 
		LED1=!LED1;
		}
}

3、经过转接模块之后我们就可以适用普通给串口接收方式进行接收,但要注意由于RS485是半双工通信,所以RE、DE引脚是控制RS485处于接收或者发送模式,因此stm32控制程序还要定义一个gpio引脚进行控制。通过正点原子485库函数源码也不难发现,485相比串口接收只是多一个引脚控制,接收函数还是基于普通串口接收函数。
如下是485接收和发送代码

//RS485发送len个字节.
//buf:发送区首地址
//len:发送的字节数(为了和本代码的接收匹配,这里建议不要超过64个字节)
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);		
	RS485_RX_CNT=0;	  
	RS485_TX_EN=0;				//设置为接收模式	
}
//RS485查询接收到的数据
//buf:接收缓存首地址
//len:读到的数据长度
void RS485_Receive_Data(u8 *buf,u8 *len)
{
	u8 rxlen=RS485_RX_CNT;
	u8 i=0;
	*len=0;				//默认为0
	delay_ms(10);		//等待10ms,连续超过10ms没有接收到一个数据,则认为接收结束
	if(rxlen==RS485_RX_CNT&&rxlen)//接收到了数据,且接收完成了
	{
		for(i=0;i<rxlen;i++)
		{
			buf[i]=RS485_RX_BUF[i];	
		}		
		*len=RS485_RX_CNT;	//记录本次数据长度
		RS485_RX_CNT=0;		//清零
	}
}

可以发现RS485基于普通串口接收数据填充到485数据接收缓冲区,这里为什么接收8个数据就等待处理呢,是因为我从01寄存器起始读取两个寄存器,接收数据长度就8个字节。所以这里的接收字节数取决于你想接收的数据长度。

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

主函数处理数据,然后输出记录转角值

 int main(void)
 {
u8 len1=8;		 
u8 rs485buf[8]; 	 
// 	u16 t;
  u16 date1,date2;  
//	u16 times=0;
	delay_init();	    	 //延时函数初始化	  
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
	uart_init(9600);	 //串口初始化为115200
 	LED_Init();			     //LED端口初始化
	KEY_Init();          //初始化与按键连接的硬件接口
	RS485_Init(9600);	//初始化RS485
	TIM3_Int_Init(4999,7199);//计数频率10KHZ,500ms
 	while(1)
	{
		if(RS485_RX_CNT>=8)//接收数据完成
		{	
  			RS485_Receive_Data(rs485buf,&len1);
//			for(t=0;t<8;t++) //将接收到的数据发送到串口助手显示
//						{	USART_SendData(USART1, rs485buf[t]);//向串口1发送数据
//							while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
//						}			
					if  (rs485buf[2]==0x04)
					{							
						date1=(rs485buf[4])|(rs485buf[3]<<8);
						date1=(int)( ((double)date1/4096)*360 ) ;				
						printf("\r\n angle=:%d ",date1);//读取磁编码器旋转角度					
					}					         			    
	   }

	}	 
 
}

(3)、使用举例说明

1、写寄存器
如果我们要把01写到一个地址是0000的寄存器地址里,点一下“写入”,就会出现发送指令:01 06 00 00 00 01 48 0A。我们来分析一下这帧数据,其中01是设备地址,06是功能码,代表写寄存器这个功能,后边跟00 00表示的是要写入的寄存器的地址,00 01就是要写入的数据,48 0A就是CRC校验码,这是软件自动算出来的。而根据Modbus协议,当写寄存器的时候,从机成功完成该指令的操作后,会把主机发送的指令直接返回,我们的调试精灵会接收到这样一帧数据:01 06 00 00 00 01 48 0A。
2、读寄存器
假如我们现在要从寄存器地址0002开始读取寄存器,并且读取的数量是2个。点一下“读出”,就会出现发送指令:01 03 00 02 00 02 65 CB。其中01是设备地址,03是功能码,代表读寄存器这个功能,00 02就是读寄存器的起始地址,后一个00 02就是要从寄存器起始地址读取2个寄存器的数值,65 CB就是CRC校验。而接收到的数据是:01 03 04 00 00 00 00 FA 33。其中01是设备地址,03是功能码,04代表的是后边读到的数据字节数是4个,00 00 00 00分别是地址为00 02和00 03的寄存器内部的数据,而FA 33就是CRC校验了。
3、CRC校验说明
CRC校验:CRC校验是一种数据算法,是用来校验数据对错的。CRC校验函数把一帧数据除最后两个字节外,前边所有的字节进行特定的算法计算,计算完后生成了一个16bit的数据,作为CRC校验码,添加在一帧数据的最后。接收方接收到数据后,同样会把前边的字节进行CRC计算,计算完了再和发过来的16bit的CRC数据进行比较,如果相同则认为数据正常,没有出错,如果比较不相同,则说明数据在传输中发生了错误,这帧数据将被丢弃,就像没收到一样,而发送方会在得不到回应后做相应的处理错误处理。
注:校验码算法比较复杂,需要了解可自行搜索,发送时的校验码软件已经自动生成了,所以我们不用考虑,直接复制适用。

  • 8
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值