本文主要讲使用STM32F767和绝对式多摩川TS5700N8501编码器通信的流程和注意事项。
首先使用STM32CubeMX生成RS485驱动部分功能代码,注意该款编码器的波特率是2.5Mbps。
注意使能的GPIO可以使用其他管脚,我们的主控板使用的是PA8。前期可以这么配置。
配置时钟,这里配置的是48MHz。
接下来,生成对应的项目工程,MDK-ARM就是生成对应的Keil工程。
接下来是接线:注意编码器正确接4根线即可。黑色接地,红色接5V电源。编码器的SD是蓝色,对应接的是控制板上面的管脚。编码器的是蓝黑色,对应接的是控制板上面的SD管脚。
注意编码器要保证5V供电,并且编码器的线比较细要注意保证连接可靠。 测试中遇到供电电压达不到5V,以及黑色接地线接触不好的情况,都会导致无法正常通信。
void MX_UART4_Init(void)
{
/* USER CODE BEGIN UART4_Init 0 */
/* USER CODE END UART4_Init 0 */
/* USER CODE BEGIN UART4_Init 1 */
/* USER CODE END UART4_Init 1 */
huart4.Instance = UART4;
huart4.Init.BaudRate = 2500000;
huart4.Init.WordLength = UART_WORDLENGTH_8B;
huart4.Init.StopBits = UART_STOPBITS_1;
huart4.Init.Parity = UART_PARITY_NONE;
huart4.Init.Mode = UART_MODE_TX_RX;
huart4.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart4.Init.OverSampling = UART_OVERSAMPLING_16;
huart4.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
huart4.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_RS485Ex_Init(&huart4, UART_DE_POLARITY_HIGH, 0, 0) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN UART4_Init 2 */
// HAL_UART_Receive_IT(&huart4, rs485RxData, 1);
/* USER CODE END UART4_Init 2 */
}
void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
if(uartHandle->Instance==UART4)
{
/* USER CODE BEGIN UART4_MspInit 0 */
/* USER CODE END UART4_MspInit 0 */
/** Initializes the peripherals clock
*/
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_UART4;
PeriphClkInitStruct.Uart4ClockSelection = RCC_UART4CLKSOURCE_PCLK1;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
{
Error_Handler();
}
/* UART4 clock enable */
__HAL_RCC_UART4_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/**UART4 GPIO Configuration
PA0/WKUP ------> UART4_TX
PA1 ------> UART4_RX
PA8 ------> UART4_DE
*/
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF8_UART4;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_8;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF8_UART4;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* UART4 DMA Init */
/* UART4_RX Init */
hdma_uart4_rx.Instance = DMA1_Stream2;
hdma_uart4_rx.Init.Channel = DMA_CHANNEL_4;
hdma_uart4_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_uart4_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_uart4_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_uart4_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_uart4_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_uart4_rx.Init.Mode = DMA_NORMAL;
hdma_uart4_rx.Init.Priority = DMA_PRIORITY_LOW;
hdma_uart4_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_uart4_rx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(uartHandle,hdmarx,hdma_uart4_rx);
/* UART4 interrupt Init */
HAL_NVIC_SetPriority(UART4_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(UART4_IRQn);
/* USER CODE BEGIN UART4_MspInit 1 */
/* USER CODE END UART4_MspInit 1 */
}
}
测试程序:
void RS485_SendData(uint8_t *data, uint16_t size)
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_SET);
HAL_UART_Transmit(&huart4, data, size, 1000);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET);
}
void RS485_RecvData(uint8_t *data, uint16_t size)
{
HAL_UART_Receive(&huart4, data, size, 1000);
}
void RS485_Test(void)
{
uint8_t Sendbuf[1] = {0x02};
uint8_t Recvbuf[10] = {0x00};
RS485_SendData(Sendbuf, sizeof(Sendbuf));
RS485_RecvData(Recvbuf, 6);
for(int i = 0; i < 6; i++)
{
Usart_Printf("%02x", Recvbuf[i]);
}
Usart_Printf("\n\r");
}
测试程序运行结果: