cancel
Showing results for 
Search instead for 
Did you mean: 

Problem using UART

soumaya BEN MANSOUR
Associate II
Posted on May 05, 2017 at 16:11

Hi community,

I'm using stm32f769i-disco to make a serial communication with a Vacuum Transducer (925 MicroPirani).The 925 transducer can provide pressure mesurement output as RS232 digital value.

Pressure request :

Query: @253PR1?;FF

Query reply: 

@253ACK9.00E+2;FF

The discovery card transmit the request bufftr[30] = @253PR1?;FF via the HAL_UART_Transmit(&UartHandle, bufftr, 30, 100)

and the 925 transducer send the pressure value that is to say that the discovery card receive the reply for her request via HAL_UART_Receive(&UartHandle, buffrec, 30, 100); buffrec[30]=@253ACK9.00E+2;FF 

Then I use double pression to get just the bit 7,12,13 of the buffrec and finally I display this value in the LCD.

Here is my code:

int main(void)

{

  MPU_Config();

CPU_CACHE_Enable();

 HAL_Init();

SystemClock_Config();

/* Enalbe clock for USART6 and GPIOC */

__HAL_RCC_GPIOC_CLK_ENABLE();

__HAL_RCC_USART6_CLK_ENABLE();

__HAL_UART_ENABLE(&UartHandle);

/* Initialize GPIOC */

MX_GPIOC_Init();

/* Initialize USART6 */

MX_USART6_UART_Init();

/*♯♯-2- Configure the LCD peripheral ♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯*/

LCD_Config();

uint8_t bufftr[30] = '@253PR1?;FF';

uint8_t buffrec[30];

double pression;

char pressbuf [20];

/* Infinite loop */

while (1)

{

/*Transmitting and receiving data */

HAL_UART_Transmit(&UartHandle, bufftr, 30, 100);

HAL_UART_Receive(&UartHandle, buffrec, 30, 100);

HAL_Delay(1000);

if (buffrec[12]==43)

{

pression = (buffrec[7]-48)*pow(10,(buffrec[13]-48));// buffrec7 en ascii c'est 57 - 48 = 9

}

if (buffrec[12]==45)

{

pression = (buffrec[7]-48)*pow(10,-(buffrec[13]-48));

}

/* Display the Pression Value on the LCD */

snprintf(pressbuf, 17, 'Vacuum : %fmBar',pression);

BSP_LCD_DisplayStringAt(0, BSP_LCD_GetYSize()/2 + 45, (uint8_t *)pressbuf, CENTER_MODE);

BSP_LCD_ClearStringLine(30);

}

}

Finally I don't get my presion value, I only get Vacuum : 0.00000 mBar.

I tried to understand what is wrong with my code I use breakpoint but when I click in step over my code doesn't respect the steps , it is supposed to transmit the request then receive the reply then get the pression then display it on the lcd. 

Can anyone help me to know what I'm missing?

thanks in advance

#uart #uart-rx #uart-tx #stm32 #debug-mode
1 ACCEPTED SOLUTION

Accepted Solutions
Posted on May 23, 2017 at 14:04

Hi Elkin,

Finally I find the solution and now Ican transmit and receive data from the pc via the hyperterminal.

Thank you very much for your help.

Here is the code:

int main(void)

{

/* Enable GPIO TX/RX clock */

__HAL_RCC_GPIOC_CLK_ENABLE();

__USART6_CLK_ENABLE();

__HAL_UART_ENABLE_IT(&UartHandle, UART_IT_RXNE);

/* Initialize GPIOC */

MX_GPIOC_Init();

/* Initialize USART6 */

MX_USART6_UART_Init();

/* Buffer used for reception */

uint8_t aRxBuffer[RXBUFFERSIZE] ;

uint8_t bufftr[] = '@253PR1?;FF\n\r';

while (1)

{

HAL_UART_Transmit(&UartHandle, bufftr, (sizeof(bufftr)-1), 100);

HAL_UART_Receive_IT(&UartHandle, (uint8_t *)aRxBuffer, RXBUFFERSIZE);

}

}

void MX_GPIOC_Init(void)

{

GPIO_InitStruct.Pin = USARTx_TX_PIN;

GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;

GPIO_InitStruct.Pull = GPIO_PULLUP;

GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;

GPIO_InitStruct.Alternate = USARTx_TX_AF;

HAL_GPIO_Init(USARTx_TX_GPIO_PORT, &GPIO_InitStruct);

/* UART RX GPIO pin configuration */

GPIO_InitStruct.Pin = USARTx_RX_PIN;

GPIO_InitStruct.Alternate = USARTx_RX_AF;

HAL_GPIO_Init(USARTx_RX_GPIO_PORT, &GPIO_InitStruct);

/* Configure USARTx Tx as alternate function */

HAL_GPIO_DeInit(USARTx_TX_GPIO_PORT, USARTx_TX_PIN);

/* Configure USARTx Rx as alternate function */

HAL_GPIO_DeInit(USARTx_RX_GPIO_PORT, USARTx_RX_PIN);

}

void MX_USART6_UART_Init(void)

{

UartHandle.Instance = USARTx;

UartHandle.Init.BaudRate = 115200 ;

UartHandle.Init.WordLength = UART_WORDLENGTH_8B;

UartHandle.Init.StopBits = UART_STOPBITS_1;

UartHandle.Init.Parity = UART_PARITY_NONE;

UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;

UartHandle.Init.Mode = UART_MODE_TX_RX;

if(HAL_UART_DeInit(&UartHandle) != HAL_OK)

{

Error_Handler();

}

if(HAL_UART_Init(&UartHandle) != HAL_OK)

{

Error_Handler();

}

}

View solution in original post

9 REPLIES 9
Posted on May 05, 2017 at 19:52

Hi soumaya BEN MANSOUR,

Some times when I'm working with devices with RS232 interface the first thing that I do is to test it with an USB-RS232 DB9 serial adapter and a terminal program (I'm using Hercules), in the terminal you can check if the sensor is working right sending the query and waiting that the sensor query reply appear in the terminal (just for be sure!).

I check transducer datasheet, by default comes with a serial baudrate of 9600, are you setting the right baudrate of the uart port in you discovery board?

In the code, when you declare an char array, for me, the best way to do it is:

uint8_t bufftr[] = '@253PR1?;FF';

Keep the 

[] in blank, so the array will have a size of the number of characters plus one (the last position of the array when you declare it on this way is a null or 0x00). Declaring the buffer on this way you assure that won't send useless characters to the transducer, and the best way to me for using the transmit function is the following:

HAL_UART_Transmit(&UartHandle, bufftr, (sizeof(bufftr)-1), 100);

sizeof returns array size then subtracts 1 to avoid send the null char.

If in the argument of the buffer size you put 30, you will send the characters and the data that is stored in the followings array positions, may be the transducer is affected for this.

To receive the data, if the query reply have always the same size, is better to declare the array with the fixed size, I see that have 17 characters, so I suggest to declare:

uint8_t buffrec[17];

and call the receive function:

HAL_UART_Receive(&UartHandle, buffrec, sizeof(buffrec), 100);

Another thing that you could use is to declare a Hal Status variable, I usually call it error:

HAL_StatusTypeDef error;

And equal this variable to the received and maybe also to the transmit function, is the functions returs HAL_OK means that the data have been send or received well, doing that maybe allows to you also make a better debug (sometimes have worked to me), and example code could be:

error = HAL_UART_Receive(&UartHandle, buffrec,

sizeof(

buffrec)

, 100);

if(error == HAL_OK){

   //write LCD

}

else{

   //i.e. toogle a led to indicate that the data wasn't received

}

When you debug, put the breakpoint in the if line, so you can check the function return status.

To finish, I have never used the snprintf function, instead I use the sprintf and have worked well to me. Hope to be useful, have a nice day!

Posted on May 09, 2017 at 18:00

Hi Elkin Grandos,

Thank you very much for your response.

I tested the sensor with an hyperterminal, I send my request

@253PR1?;FF and I receive correctly the reply so the sensor is woring right.

I make some changes in my code, here is the new code :

HAL_StatusTypeDef error_transmission;

HAL_StatusTypeDef error_reception;

uint8_t bufftr[] = '@253PR1?;FF';

uint8_t buffrec[17];

double pression;

char pressbuf [20];

/* Infinite loop */

while (1)

error_transmission = HAL_UART_Transmit(&UartHandle, bufftr, (sizeof(bufftr)-1), 100);

if(error_transmission == HAL_OK){

error_reception = HAL_UART_Receive(&UartHandle, buffrec, sizeof(buffrec), 100);

}

else{

//i.e. toogle a led to indicate that the data wasn't transmitted

BSP_LED_Toggle(LED1);

}

if(error_reception == HAL_OK){

if (buffrec[12]=='+')

{

pression = (buffrec[7]-48)*pow(10,(buffrec[13]-48));// buffrec7 en ascii c'est 57 - 48 = 9

}

else if (buffrec[12]=='-')

{

pression = (buffrec[7]-48)*pow(10,-(buffrec[13]-48));

}

 /* Display the Pression Value on the LCD */

snprintf(pressbuf, 17, 'Vacuum : %fmBar',pression);

BSP_LCD_DisplayStringAt(0, BSP_LCD_GetYSize()/2 + 45, (uint8_t *)pressbuf, CENTER_MODE);

BSP_LCD_ClearStringLine(30);

}

else{

//i.e. toogle a led to indicate that the data wasn't received

BSP_LED_Toggle(LED2);

}

}

Finally the Led 2 toggle so I have a problem in the reception of the pression from the 

Vacuum Transducer (925 MicroPirani); 

Can you help me to know what I'm missing exactly?

Can you explain me why my function 

HAL_UART_Receive(&UartHandle, buffrec, sizeof(buffrec), 100) doesn't work correctly?

Thanks in advance

Posted on May 10, 2017 at 16:19

Hi soumaya BEN MANSOUR,

Hi have just check the code and I didn't see anything wrong except for the missing { in while(1) line, just a couple of questions, what IDE are you using?, are you using CubeMX to generate the peripheral inicialization? Could you post your peripheral 

inicialization code?

, again just for be sure, remember that the uart must be configurated to 9600 bps, no parity and one stop bit. Another thing, how do you have the hardware interface between the nucleo board and the sensor? could you post an image of the scheme. Hope to keep helping you, have a nice day!
Posted on May 10, 2017 at 17:14

The original post was too long to process during our migration. Please click on the provided URL to read the original post. https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I6s5&d=%2Fa%2F0X0000000bx0%2FoVoDOjR6YLgne1CHiEgAR6fGQ20xRNcHOHSaMzW64hk&asPdf=false
Posted on May 10, 2017 at 20:02

Hi soumaya BEN MANSOUR,

I checked the code and the only strange thing that I found was the commented lines:

//GPIO_InitDef_Tx.Alternate = GPIO_AF8_USART6;

//GPIO_InitDef_Rx.Alternate = GPIO_AF8_USART6;

//USARTx_RX_GPIO_CLK_ENABLE();

If the pins are not configurated in the alternate function those won't be able to work as uart Tx and Rx.

With the CubeMX you can also generate the peripheral initialization for Keil, so I did the test and generate the following code:

For the GPIOS:

__HAL_RCC_USART6_CLK_ENABLE();

/**USART6 GPIO Configuration

PC7 ------> USART6_RX

PC6 ------> USART6_TX

*/

GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_6;

GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;

GPIO_InitStruct.Pull = GPIO_PULLUP;

GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;

GPIO_InitStruct.Alternate = GPIO_AF8_USART6;

HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

and for the UART:

huart6.Instance = USART6;

huart6.Init.BaudRate = 115200;

huart6.Init.WordLength = UART_WORDLENGTH_8B;

huart6.Init.StopBits = UART_STOPBITS_1;

huart6.Init.Parity = UART_PARITY_NONE;

huart6.Init.Mode = UART_MODE_TX_RX;

huart6.Init.HwFlowCtl = UART_HWCONTROL_NONE;

huart6.Init.OverSampling = UART_OVERSAMPLING_16;

huart6.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;

huart6.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;

if (HAL_UART_Init(&huart6) != HAL_OK)

{

Error_Handler();

}

Try to replace your code for this, maybe it works!, other question, the system clock frequency is 216Mhz?

Attached to this reply is the Keil Project, if you want to check it, it's going with the Cube file.

________________

Attachments :

F769INIH_TEST.zip : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006HycH&d=%2Fa%2F0X0000000bAm%2Fn9PAyMCInIrs.gpm7yyYyfMqdxNSYHomwmCI.V7m3wA&asPdf=false
raptorhal2
Lead
Posted on May 11, 2017 at 01:41

The sensor's RS232 output is compatible with your PC RS232 port, but not compatible with the mcu's UART peripheral which has TTL logic levels. You need to use a converter chip such as a Maxim 232, or an RS232 to TTL UART adapter cable.

Cheers, Hal

Posted on May 19, 2017 at 15:02

Hi Elkin Granados,

Thank you very much for your help. Yes 

the system clock frequency is 216Mhz.

I replaced the code part of the gpio and uart configuration by the code you sent to me.

Now I try to test with the hyperterminal to validate the rs232. If I can receive all the character that I will write in the hyperteminal so I can receive the reply of the 

Vacuum Transducer.

The stm32f769i-disco transmit to the pc the data : uint8_t bufftr[] = '@253PR1?;FF\n\r'; it works perfectly I can see 

@253PR1?;FF in the hyperterminal.

When the pc send data to the 

stm32f769i-disco I receive just the first character even if I write several characters. I use the watch window in the debug mode to check if I receive all the data sent or not .

The stm32f769i-disco must receive the data in the uint8_t buffrec[17] so normally I must receive all the data from 0 to 16. 

Here is my code :

int main(void)

{

/* Enalbe clock for USART6 and GPIOC */

__HAL_RCC_GPIOC_CLK_ENABLE();

/* Initialize GPIOC */

MX_GPIOC_Init();

/* Initialize USART6 */

MX_USART6_UART_Init();

uint8_t buffrec[17];

uint8_t bufftr[] = '@253PR1?;FF\n\r';

while (1)

{

error_transmission = HAL_UART_Transmit(&UartHandle, bufftr, (sizeof(bufftr)-1), 100);

if(error_transmission != HAL_OK)

{

BSP_LED_Toggle(LED1);

}

HAL_Delay(1000);

error_reception = HAL_UART_Receive(&UartHandle, buffrec, sizeof(buffrec), 100);

if(error_reception!= HAL_OK)

{

BSP_LED_Toggle(LED2);

}

HAL_Delay(1000);

}

}

void MX_GPIOC_Init(void)

{

/* GPIOC PIN6 alternative function Tx */

/* GPIOC PIN7 alternative function Rx */

GPIO_InitDef_Tx.Pin = GPIO_PIN_7|GPIO_PIN_6;

GPIO_InitDef_Tx.Mode = GPIO_MODE_AF_PP;

GPIO_InitDef_Tx.Pull = GPIO_PULLUP;

GPIO_InitDef_Tx.Speed = GPIO_SPEED_FREQ_VERY_HIGH;

GPIO_InitDef_Tx.Alternate = GPIO_AF8_USART6;

HAL_GPIO_Init(GPIOC, &GPIO_InitDef_Tx);

}

void MX_USART6_UART_Init(void)

{

/*♯♯-1- Configure the UART peripheral ♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯*/

/* Put the USART peripheral in the Asynchronous mode (UART Mode) */

/* UART configured as follows:

- Word Length = 8 Bits

- Stop Bit = One Stop bit

- Parity = None

- BaudRate = 9600 baud

- Hardware flow control disabled (RTS and CTS signals) */

UartHandle.Instance = USART6;

UartHandle.Init.BaudRate = 9600;

UartHandle.Init.WordLength = UART_WORDLENGTH_8B;

UartHandle.Init.StopBits = UART_STOPBITS_1;

UartHandle.Init.Parity = UART_PARITY_NONE;

UartHandle.Init.Mode = UART_MODE_TX_RX;

UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;

UartHandle.Init.OverSampling = UART_OVERSAMPLING_16;

UartHandle.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;

UartHandle.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;

USARTx_RX_GPIO_CLK_ENABLE();

if (HAL_UART_Init(&UartHandle) != HAL_OK)

{

Error_Handler_1();

}

}

Can anyone tell me what's wrong with my code?

Thanks in advance

Posted on May 22, 2017 at 17:48

Hi,

I see the code and think that is right, but I suggest to you a couple of things:

error_transmission = HAL_UART_Transmit(&UartHandle, bufftr, (sizeof(bufftr)-1), 100);

if(error_transmission != HAL_OK)

{

BSP_LED_Toggle(LED1);

}

HAL_Delay(1000); <----- REMOVE

In this part of the code remove the 

HAL_Delay(1000);, as the sensor reply immediately, if you put a delay after you send the command, just the first character will be received and will keep in the uart buffer until it is read, the 

HAL_UART_Receive function have to be called right after the command is sent in order to process all incoming characters.

Posted on May 23, 2017 at 14:04

Hi Elkin,

Finally I find the solution and now Ican transmit and receive data from the pc via the hyperterminal.

Thank you very much for your help.

Here is the code:

int main(void)

{

/* Enable GPIO TX/RX clock */

__HAL_RCC_GPIOC_CLK_ENABLE();

__USART6_CLK_ENABLE();

__HAL_UART_ENABLE_IT(&UartHandle, UART_IT_RXNE);

/* Initialize GPIOC */

MX_GPIOC_Init();

/* Initialize USART6 */

MX_USART6_UART_Init();

/* Buffer used for reception */

uint8_t aRxBuffer[RXBUFFERSIZE] ;

uint8_t bufftr[] = '@253PR1?;FF\n\r';

while (1)

{

HAL_UART_Transmit(&UartHandle, bufftr, (sizeof(bufftr)-1), 100);

HAL_UART_Receive_IT(&UartHandle, (uint8_t *)aRxBuffer, RXBUFFERSIZE);

}

}

void MX_GPIOC_Init(void)

{

GPIO_InitStruct.Pin = USARTx_TX_PIN;

GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;

GPIO_InitStruct.Pull = GPIO_PULLUP;

GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;

GPIO_InitStruct.Alternate = USARTx_TX_AF;

HAL_GPIO_Init(USARTx_TX_GPIO_PORT, &GPIO_InitStruct);

/* UART RX GPIO pin configuration */

GPIO_InitStruct.Pin = USARTx_RX_PIN;

GPIO_InitStruct.Alternate = USARTx_RX_AF;

HAL_GPIO_Init(USARTx_RX_GPIO_PORT, &GPIO_InitStruct);

/* Configure USARTx Tx as alternate function */

HAL_GPIO_DeInit(USARTx_TX_GPIO_PORT, USARTx_TX_PIN);

/* Configure USARTx Rx as alternate function */

HAL_GPIO_DeInit(USARTx_RX_GPIO_PORT, USARTx_RX_PIN);

}

void MX_USART6_UART_Init(void)

{

UartHandle.Instance = USARTx;

UartHandle.Init.BaudRate = 115200 ;

UartHandle.Init.WordLength = UART_WORDLENGTH_8B;

UartHandle.Init.StopBits = UART_STOPBITS_1;

UartHandle.Init.Parity = UART_PARITY_NONE;

UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;

UartHandle.Init.Mode = UART_MODE_TX_RX;

if(HAL_UART_DeInit(&UartHandle) != HAL_OK)

{

Error_Handler();

}

if(HAL_UART_Init(&UartHandle) != HAL_OK)

{

Error_Handler();

}

}