欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

485通信——驱动 MX64/MX28 舵机

程序员文章站 2022-06-09 09:29:20
...

背景:在使用STM32调试MX64舵机时,由于控制该舵机需要采用RS485通信协议,因此需要从单片机的串口经过一个TTL转485通信的模块再与舵机进行通信。

485通信特点:

485通信采用差分信号:可以抑制共模干扰。尤其当工业现场环境比较复杂,干扰比较多时,采用差分方式可以有效的提高通信可靠性。RS485 采用两根通信线,通常用 A 和 B 或者 D+和 D-来表示。逻辑“1”以两线之间的电压差为+(0.2~6)V 表示,逻辑“0”以两线间的电压差为-(0.2~6)V 来表示,是一种典型的差分通信。

485通信距离与速度:传输距离最远可以达到 1200 米左右,但是它的传输速率和传输距离是成反比的,只有在 100Kb/s 以下的传输速度,才能达到最大的通信距离,如果需要传输更远距离可以使用中继。

485多设备通信:可以在总线上进行联网实现多机通信,总线上允许挂多个收发器,从现有的 RS485芯片来看,有可以挂 32、64、128、256 等不同个设备的驱动器。

485通信方式:半双工模式,因此通讯时需要切换收发状态。

 

485通信常用电路:

1、手动收发控制的485通信:

485通信——驱动 MX64/MX28 舵机

MAX485 是美信(Maxim)推出的一款常用 RS485 转换器。

5 脚和 8 脚是电源引脚;

6脚和 7 脚就是 RS485 通信中的 A 和 B 两个引脚;

1 脚和 4 脚分别接到单片机的 RXD 和 TXD引脚上,直接使用单片机 UART 进行数据接收和发送;

2 脚和 3 脚是方向引脚,其中 2 脚是低电平使能接收器,3 脚是高电平使能输出驱动器,我们把这两个引脚连到一起,平时不发送数据的时候,保持这两个引脚是低电平,让 MAX485 处于接收状态,当需要发送数据的时候,把这个引脚拉高,发送数据,发送完毕后再拉低这个引脚就可以了。

 

手动收发控制的485通信电路:

485通信——驱动 MX64/MX28 舵机

实现自动收发功能:

发送数据过程:

发送数据,用的是单片机的TXD引脚,也就是说,在TXD引脚上表现数据。

例:要发送的数据转化为二进制,TXD引脚上就会依次的用高低电平体现1和0。

当TXD发送0时,三极管不导通,DE接高电平,进入发送模式,485芯片会把DI上的电平反应到AB引脚上输出,因为DI已经接地,所以AB引脚会传输0。

当TXD发送1时,三极管导通,RE接低电平,进入接收模式,485芯片的AB引脚进入高阻状态,因为上拉电阻把A拉高,下拉电路把B拉低,所以,AB传输的是1。

总结,TXD发1,AB就发1;TXD发0,AB就发0。

接收数据过程:

接收数据,用的是单片机引脚RXD,也就是说,在RXD引脚上表现数据。

在接收数据的过程中,TXD引脚是一直保持高电平的,当TXD是高电平时,RE是低电平,正好调理成了接收状态,然后485芯片的RO引脚(也就是接RXD的引脚)就会反应AB传输过来的数据。

电路阻值选取:

上下拉电阻R9、R10 —— 1k , 4.7k , 10k

双绞线并联电阻 —— 一般120Ω

 

MX64舵机驱动:

MX64舵机官网通信接口实例原理图:

485通信——驱动 MX64/MX28 舵机

 通过串口TTL转485模块实现数据电平转换,然后使用STM32的串口驱动舵机。

平台:STM32F405RGT6

舵机:MX64T —— 固件版本1.0

舵机通信串口配置:

/* UART2 for MX64 */
void vUart2Config(void)
{
	USART_InitTypeDef usart2;
	GPIO_InitTypeDef  gpio;

	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);
	GPIO_PinAFConfig(GPIOA,GPIO_PinSource2,GPIO_AF_USART2);
	GPIO_PinAFConfig(GPIOA,GPIO_PinSource3,GPIO_AF_USART2);

	gpio.GPIO_Pin = GPIO_Pin_2;
	gpio.GPIO_Mode = GPIO_Mode_AF;
	gpio.GPIO_OType = GPIO_OType_PP;
	gpio.GPIO_Speed = GPIO_Speed_100MHz;
	gpio.GPIO_PuPd = GPIO_PuPd_NOPULL;
	GPIO_Init(GPIOA,&gpio);

	gpio.GPIO_Pin = GPIO_Pin_3;
	gpio.GPIO_Mode = GPIO_Mode_IN;
	gpio.GPIO_Speed = GPIO_Speed_100MHz;
	gpio.GPIO_PuPd = GPIO_PuPd_NOPULL;
	GPIO_Init(GPIOA,&gpio);

	usart2.USART_BaudRate = 115200;
	usart2.USART_WordLength = USART_WordLength_8b;
	usart2.USART_StopBits = USART_StopBits_1;
	usart2.USART_Parity = USART_Parity_No;
	usart2.USART_Mode = USART_Mode_Rx|USART_Mode_Tx;
	usart2.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_Init(USART2,&usart2);

//	USART_ITConfig(USART1,USART_IT_IDLE,ENABLE);
	USART_Cmd(USART2,ENABLE);
//	USART_DMACmd(USART1,USART_DMAReq_Rx,ENABLE);	
	
//	{
//		DMA_InitTypeDef	dma;
//		RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1,ENABLE);
//		DMA_DeInit(DMA1_Stream6);
//		dma.DMA_Channel= DMA_Channel_4;
//		dma.DMA_PeripheralBaseAddr = (uint32_t)&(USART2->DR);
//		dma.DMA_Memory0BaseAddr = (uint32_t)sbus_rx_buffer;
//		dma.DMA_DIR = DMA_DIR_MemoryToPeripheral;
//		dma.DMA_BufferSize = TX_USART2_BUFFER;
//		dma.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
//		dma.DMA_MemoryInc = DMA_MemoryInc_Enable;
//		dma.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
//		dma.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
//		dma.DMA_Mode = DMA_Mode_Circular;
//		dma.DMA_Priority = DMA_Priority_VeryHigh;
//		dma.DMA_FIFOMode = DMA_FIFOMode_Disable;
//		dma.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull;
//		dma.DMA_MemoryBurst = DMA_Mode_Normal;
//		dma.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
//		DMA_Init(DMA2_Stream5,&dma);
//		DMA_ITConfig(DMA2_Stream5,DMA_IT_TC,ENABLE);
//		DMA_Cmd(DMA2_Stream5,ENABLE);
//	}
}

舵机EEPROM及RAM地址:

485通信——驱动 MX64/MX28 舵机

485通信——驱动 MX64/MX28 舵机

485通信——驱动 MX64/MX28 舵机

舵机驱动函数:

这里由于仅需要使用舵机的最基本功能:单圈的位置模式,因此在此只实现了两个控制函数。如有其它需求,仿照一下函数即可。但是关于舵机的控制模式切换以及一些高级的设置,需要使用舵机的编程卡配合上位机配置。

/* MX64 action commend */
void send_MX64_action(void)
{
	uint8_t i = 0;
	uint8_t MX64_buffer[6];
	
	MX64_buffer[0]=0xFF;	
	MX64_buffer[1]=0xFF;	
	MX64_buffer[2]=0xFE;	
	MX64_buffer[3]=0x02;	
	MX64_buffer[4]=0x05;	
	MX64_buffer[5]=0xFA;	//ACTION COMMAND
	
	for(i=0;i<=5;i++)
	{
		USART_SendData(USART2,MX64_buffer[i]);
		while( USART_GetFlagStatus(USART2,USART_FLAG_TC)!= SET);
	}
}

/* MX64 position set commend */
void send_MX64_position(unsigned short Control_Angle)
{
	uint8_t j = 0;
	uint8_t MX64_buffer[15];
	
	MX64_buffer[0]=0xFF;	//header byte 
	MX64_buffer[1]=0xFF;	//header byte
	MX64_buffer[2]=0xFE;	//motor id
	MX64_buffer[3]=0x05;	//length
	MX64_buffer[4]=0x04;	//read and write:0x04 
												//write: 0x03 
	MX64_buffer[5]=0X1E;	//goal position reg address
	/* goal position */
	MX64_buffer[6]=(Control_Angle<<8)>>8;
	MX64_buffer[7]=Control_Angle>>8;
	/* check */
	MX64_buffer[8]=~(MX64_buffer[2]+MX64_buffer[3]+MX64_buffer[4]+MX64_buffer[5]+MX64_buffer[6]+MX64_buffer[7]);
	
	for(j=0;j<=8;j++)
	{
		USART_SendData(USART2,MX64_buffer[j]);
		while( USART_GetFlagStatus(USART2,USART_FLAG_TC)!= SET);
	}
}

注意:在使用位置模式控制舵机时,需要先设置目标位置,目标位置设定成功后,舵机并不会动,而是还需要发送一条ACTION指令(即send_MX64_action()函数),舵机才会运动。每次设定一个新的目标位置都需要调用该函数,使舵机开始运动。

                                                                                                                                                                 ——cloud over sky

                                                                                                                                                                 ——2020/1/14
 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

相关标签: STM32基础 驱动