Hi
I am using UART5 interrupt handler to receive bytes in Mod-bus protocol. MCU is STM32f407VGT6. My problem is that UART ISR does not get first 4 bytes from slave. I have checked signals with scope so I am sure hardware is okay. my code is in below after a time out I read the buffer but instead of 9 bytes there is only last 5 bytes from slave.
void uart5_configuration(void) { USART_InitTypeDef USART_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5,ENABLE); GPIO_PinAFConfig(GPIOC, GPIO_PinSource12, GPIO_AF_UART5); GPIO_PinAFConfig(GPIOD, GPIO_PinSource2, GPIO_AF_UART5); /* Configure USART2 pins: Rx and Tx ----------------------------*/ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOC, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOD, &GPIO_InitStructure); USART_InitStructure.USART_BaudRate = 9600; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(UART5, &USART_InitStructure); USART_Cmd(UART5,ENABLE); /* Enable RXNE interrupt */ USART_ITConfig(UART5, USART_IT_RXNE, ENABLE); /* Enable USART5 global interrupt */ NVIC_EnableIRQ(UART5_IRQn); }
void UART5_IRQHandler(void) { /* RXNE handler */ if(USART_GetITStatus(UART5, USART_IT_RXNE) != RESET) { char data; data=USART_ReceiveData(UART5); SYS.RS485_buffer[SYS.USART5_RX_counter]=data; SYS.flag_RS485_RX=1; SYS.flag_USART5_Timeout=0; SYS.USART5_RX_counter++; SYS.flag_RX5=1; } }
void event_RS485(void) { int i;char str[100]; if(SYS.flag_USART5_Timeout==1) //if time out { SYS.RS485_buffer_size=SYS.USART5_RX_counter; print_str(USART1,"rs485"); sprintf(str,"<<BYTES:%u>>\r\n",SYS.RS485_buffer_size); uart_out_str(str); for(i=0;i<sizeof(SYS.RS485_buffer);i++) { sprintf(str,"0x%x_",SYS.RS485_buffer[i]); uart_out_str(str); } SYS.flag_RS485_RX=0; //do not execute this part more SYS.flag_USART5_Timeout=0; SYS.USART5_RX_counter=0; //after time out reset RX buffer counter } }
How do you control the Tx_Enable on both sides?
If you mean enabling RS485 TX, I do it in two ways one: by an analog circuit (a transistor and RC filter) two: by software. In both ways I have the same problem. I should note that I used method of directly waiting for incoming bytes after sending the command to slave in the same function so I could get all the bytes correctly but in other method where I used interrupt handler ISR first four bytes are not collected by ISR.