cancel
Showing results for 
Search instead for 
Did you mean: 

Is it possible to USART6 to receive what itself has sent?

salahuddinash
Associate II
Posted on April 08, 2014 at 14:27

Hi guys, 

I'm working on STM32F4-Discovery with KEIL uVision 4

I'm trying to write a code to send a character using USART6 and then I'm trying to receive this same sent character on USART6 too

so I've short circuited PC6 with PC7 and wrote and burn this code

<b>

// STM32 USART6 (Tx PC.6, Rx PC.7) STM32F4DIS-BB - sourcer32@gmail.com

 

#include ''stm32f4_discovery.h''

//functions prototypes

int SendChar(int ch);

int GetChar(void);

/**************************************************************************************/

  

void RCC_Configuration(void)

{

  /* --------------------------- System Clocks Configuration -----------------

* enables clocks for USART6 and GPIOC

*/

  /* USART6 clock enable */

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART6, ENABLE);

  

  /* GPIOC clock enable */

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);

}

  

/**************************************************************************************/

  

void GPIO_Configuration(void)

{

/*This function configure GPIOC

- pin 6       --> USART6_TX

- pin 7       --> USART6_RX

- GPIO mode   --> alternate function (to use USART)

- output type --> push pull

- input type  --> no pull up nor pull down

- input speed --> 2 MHz

*/

  GPIO_InitTypeDef GPIO_InitStructure;

  

  /*-------------------------- GPIO Configuration ----------------------------*/

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; // PC.6 USART6_TX, PC.7 USART6_RX

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;

  GPIO_Init(GPIOC, &GPIO_InitStructure);

  

  /* Connect USART pins to AF */

  GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_USART6);

  GPIO_PinAFConfig(GPIOC, GPIO_PinSource7, GPIO_AF_USART6);

}

  

/**************************************************************************************/

void USART6_Configuration(void)

{

    USART_InitTypeDef USART_InitStructure;

  

  /* USARTx configuration ------------------------------------------------------*/

  /* USARTx configured as follow:

        - BaudRate = 115200 baud

        - Word Length = 8 Bits

        - One Stop Bit

        - No parity

        - Hardware flow control disabled (RTS and CTS signals)

        - Receive and transmit enabled

  */

  USART_InitStructure.USART_BaudRate = 115200;

  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(USART6, &USART_InitStructure);

 

  USART_Cmd(USART6, ENABLE);

}

 

/**************************************************************************************/

 

int main(void)

{

  RCC_Configuration(); /*Configure the Clock*/

  GPIO_Configuration(); /*Configure GPIO*/

  USART6_Configuration();  /*Configure USART6*/

 

  while(1) // Don't want to exit

  {

    uint16_t data = 0; /*A 16-bit variable to hold the received data*/

 

/*Send data*/

    data = SendChar(1);   //send

data++;

/*Receive sent data*/

data = 0;

data = GetChar(); //receive

data++;

  }

}

  

/**************************************************************************/

 

int SendChar(int ch)

{

/*This function checks if DR is empty, indicating that the previous sent data is sent, with checking <TXE> bit

*if so, it puts the data want to be sent in DR to send it.

*/

while(!( USART6->SR & USART_FLAG_TXE))

/*wait for data register to be empty, indicating that the privious data has been sent*/

;

USART6->DR = (ch & 0xFF);  //put the data you want to send in data register

return (ch);   //return the data sent

}

int GetChar(void)

{

/*This function checks if data is recceived or not with checking <RXNE> bit.

*if so, it get this data received and return it

*/

while(!(USART6->SR & USART_FLAG_RXNE))

/*wait until data register is not empty, indicating that there is data received*/

return ((int)(USART6->DR & 0xFF));   //return the received data 

}

#ifdef  USE_FULL_ASSERT

 

/**

  * @brief  Reports the name of the source file and the source line number

  *         where the assert_param error has occurred.

  * @param  file: pointer to the source file name

  * @param  line: assert_param error line source number

  * @retval None

  */

void assert_failed(uint8_t* file, uint32_t line)

{

  /* User can add his own implementation to report the file name and line number,

     ex: printf(''Wrong parameters value: file %s on line %d\r\n'', file, line) */

 

  while (1)

  {}

}

#endif

 

/**************************************************************************/

</b>

Now I began debugging this code and it sent the character OK and TC flag was set, but RXNE wasn't set so it paused waiting RXNE to be set.

Now why RXNE wasn't set although it's supposed that it received a character?

I hope my question is clear
7 REPLIES 7
Posted on April 08, 2014 at 16:16

If you park the debugger's peripheral viewer over the USART it will break it. The debugger can't non-invasively read the USART->DR to display it for you, in doing so it clears the SR

Toggle an LED and observe THAT (perhaps with a scope)

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
salahuddinash
Associate II
Posted on April 08, 2014 at 16:21

Ù�Excuse me, but I'll be grateful if you explained in more details because honestly, I don't understand what do you mean .. thanks 

Posted on April 08, 2014 at 16:31

Every time you iterate the loop toggle an LED, observe that changing, not whilst in the debugger. You can observe if it works without touching it, or stopping it.

Cooking example, you set your oven for 400F, as it warms up you keep opening the door to look inside, wave your hands about, and shut the door again. The oven NEVER reaches the desired temperature because you keep opening the door. Waving your hands about does not push the heat back in, it has an even more negative effect.

The debugger does not have a magic way of knowing the internal state of the peripheral, it has to access it in the same way you do. Reading the value in USART->DR clears the RXNE bit in USART->SR. If you keep trying to debug the peripheral you won't see the states you want. The debugger distorts your view of what is happening.

See also : Experimental Interference, Invasive Testing

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
salahuddinash
Associate II
Posted on April 08, 2014 at 16:59

Thanks a lot sir for your answer

Every time you iterate the loop toggle an LED, observe that changing, not whilst in the debugger. You can observe if it works without touching it, or stopping it.

Imagine what, I tried it and it worked.

with adding a snippet of code that blinks the LEDs every iteration, then running the program without debugging, then the LEDs did blinked in fixed intervals.

Reading the value in USART->DR clears the RXNE bit in USART->SR. If you keep trying to debug the peripheral you won't see the states you want. The debugger distorts your view of what is happening.

So how can I see the values sent and received? aren't there a debugging method for that or do I have to use logic analyzer or RealTerm?

frankmeyer9
Associate II
Posted on April 08, 2014 at 17:08

So how can I see the values sent and received? aren't there a debugging method for that or do I have to use logic analyzer or RealTerm?

 

You can surely debug those values.

But as said, avoid setting breakpoints BEFORE the evaluation of an interrupt flag.

The debugger will read the DR register (and clear the flag consequently), and thus change the program flow. (To make it a little more confusing, most debugger do this 'destructive' read only if you open a debug register view which includes the corresponding peripheral registers).

Setting a breakpoint AFTER the evaluation of this flags usually works fine.

(Have spent about two hours in debug cycles last week because of this effect...).

Posted on April 08, 2014 at 17:32

So how can I see the values sent and received? aren't there a debugging method for that..

Observe them indirectly, read them into variables, and look at the variable.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
salahuddinash
Associate II
Posted on April 08, 2014 at 17:56

Observe them indirectly, read them into variables, and look at the variable.

 

Yes sir, this is what I did and it worked.

Thanks a lot for your help guys