0
\$\begingroup\$

I have a NUCLEO-F303RE board and try to send some data by one-wire UART with 57600 baudrate. But frames are sent broken (see images below):

How must to be: enter image description here

What I get: enter image description here

I've tried to use different clocks (HSE 32MHz and internal HSI 8MHz), change baud rate to 9600, but nothing helps and frames are broken the same way. I suppose I have a bad configuration of something, but I have no idea what is wrong. I have another UART connected which is used for debug and it works fine on 57600 baud rate (not in half-duplex mode) with same clock.

My UART configuration:

#define SERVO_PORT GPIOB #define SERVO_PIN GPIO_PIN_10 #define SERVO_GPIO_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE() #define UART_INSTANCE USART3 #define UART_CLK_ENABLE() __HAL_RCC_USART3_CLK_ENABLE() #define UART_AF GPIO_AF7_USART3 #define UART_IRQ USART3_IRQn #define UART_IRQ_HANDLER USART3_IRQHandler static UART_HandleTypeDef huart = { .Instance = UART_INSTANCE, .Init.BaudRate = 57600, .Init.WordLength = UART_WORDLENGTH_8B, .Init.StopBits = UART_STOPBITS_1, .Init.Mode = UART_MODE_TX_RX, .Init.Parity = UART_PARITY_NONE, }; /* Called later in HAL_UART_MspInit */ void Servo_UART_MspInit(UART_HandleTypeDef* h) { if (h == &huart) { SERVO_GPIO_ENABLE(); UART_CLK_ENABLE(); GPIO_InitTypeDef pin = { .Pin = SERVO_PIN, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_NOPULL, .Speed = GPIO_SPEED_FREQ_HIGH, .Alternate = UART_AF, }; HAL_GPIO_Init(SERVO_PORT, &pin); } } void initUART() { HAL_TIM_PWM_DeInit(&htim); HAL_HalfDuplex_Init(&huart); HAL_NVIC_SetPriority(UART_IRQ, 0, 0); HAL_NVIC_EnableIRQ(UART_IRQ); HAL_HalfDuplex_EnableReceiver(&huart); } bool servoSend(uint8_t* data, uint8_t size) { HAL_HalfDuplex_EnableTransmitter(&huart); return HAL_OK == HAL_UART_Transmit(&huart, data, size, HAL_MAX_DELAY); } 

And I send data like this:

... uint8_t d[5] = {0x2B, 0x0, 0xD5, 2, 0xB1}; bool ret = servoSend(d, 5); if (!ret) return DITEX_SERVO_CALLBACK_FAILED; ... 

My clock initialization:

static void initSystemClock() { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; /** Initializes the RCC Oscillators according to the specified parameters * in the RCC_OscInitTypeDef structure. */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL4; RCC_OscInitStruct.PLL.PREDIV = RCC_PREDIV_DIV2; /** Initializes the CPU, AHB and APB buses clocks */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2|RCC_PERIPHCLK_USART3 |RCC_PERIPHCLK_TIM2; PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_SYSCLK; PeriphClkInit.Usart3ClockSelection = RCC_USART3CLKSOURCE_SYSCLK; PeriphClkInit.Tim2ClockSelection = RCC_TIM2CLK_HCLK; } 
\$\endgroup\$
6
  • \$\begingroup\$ Well the first problem I see is that your signal is inverted. That, of course, will confuse the receiver and cause a framing error. \$\endgroup\$ Commented Jan 7, 2021 at 19:27
  • \$\begingroup\$ @jwh20 I've tried invert data logic or tx active level but then data is completely incorrect. Invertion of rx active level changes nothing \$\endgroup\$ Commented Jan 7, 2021 at 19:34
  • \$\begingroup\$ Well it's inverted and that's wrong. Fix that and move to next problem. \$\endgroup\$ Commented Jan 7, 2021 at 19:52
  • 1
    \$\begingroup\$ What does "one-wire UART" mean? You are using a common ground, aren't you? \$\endgroup\$ Commented Jan 7, 2021 at 21:35
  • 1
    \$\begingroup\$ Are you checking that the content of your UART TX data register have been successfully shifted by for example while(!(USART1->ISR & USART_ISR_TXE)) checking that the TX register is empty. Otherwise this smells like a clock/baud mismatch, show us your clock tree, the clock source for your USART is the system clock and not the APB where I assume the USART is connected to \$\endgroup\$ Commented Jan 8, 2021 at 7:02

2 Answers 2

2
\$\begingroup\$

Problem was in UART pin configuration: it needed to be pulled up instead of open drain:

GPIO_InitTypeDef pin = { .Pin = SERVO_PIN, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_FREQ_HIGH, .Alternate = UART_AF, }; HAL_GPIO_Init(SERVO_PORT, &pin); 
\$\endgroup\$
0
\$\begingroup\$

I believe that you have problem in configuring the system clock. You can use ST's STM32CubeIDE to get the right configuration.

If you are using crystal, use

 RCC_OscInitStruct.HSEState = RCC_HSE_ON; 

You specified RCC_HSE_BYPASS, unless you have clock source (not crystal).

(sorry, I have to put this as answer as I do not have enough reputation)

\$\endgroup\$

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.