cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L problem with USART --> DR empty after writing to it :(

irekguzik
Associate II
Posted on January 11, 2012 at 01:31

It's strange, I don't have a transmission with this function and I don't know why. State of registers after USART_Cmd

(

USART1

,

ENABLE

)

is:

SR -> 0x000000C0 (OK)

DR -> 0

BRR -> 0x00000683 (for HSI = 16 [MHz] -> OK)

CR1 -> 0x0000200C (OK)

CR2 -> 0

CR3 -> 0x00000300 (OK)

GTPR -> 0

In step-by-step working (debug in keil) i see that for example 'A' isn't written to DR(DR is still 0) I tried change USART1 for USART2 but problem wasn't solved.

void

USART1forFUN

(

void

)

{

USART_InitTypeDef USART_InitStructure

;

GPIO_InitTypeDef GPIO_InitStructure

;

 

/* Enable GPIOA and USART1 clock */

RCC_AHBPeriphClockCmd

(

RCC_AHBPeriph_GPIOA

,

ENABLE

)

;

RCC_APB2PeriphClockCmd

(

RCC_APB2Periph_USART1

,

ENABLE

)

;

 

/* Connect P9 to USART1_Tx

* Connect P10 to USART1_Rx

* Connect P11 to USART1_CTS

* Connect P12 to USART1_RTS

*/

GPIO_PinAFConfig

(

GPIOA

,

GPIO_PinSource9

,

GPIO_AF_USART1

)

;

GPIO_PinAFConfig

(

GPIOA

,

GPIO_PinSource10

,

GPIO_AF_USART1

)

;

GPIO_PinAFConfig

(

GPIOA

,

GPIO_PinSource11

,

GPIO_AF_USART1

)

;

GPIO_PinAFConfig

(

GPIOA

,

GPIO_PinSource12

,

GPIO_AF_USART1

)

;

 

/* Configure USART Tx and Rx as alternate function push-pull */

GPIO_InitStructure.

GPIO_Mode

=

GPIO_Mode_AF

;

GPIO_InitStructure.

GPIO_Speed

=

GPIO_Speed_2MHz

;

GPIO_InitStructure.

GPIO_OType

=

GPIO_OType_PP

;

GPIO_InitStructure.

GPIO_PuPd

=

GPIO_PuPd_UP

;

GPIO_InitStructure.

GPIO_Pin

=

GPIO_Pin_9

|

GPIO_Pin_10

|

GPIO_Pin_11

|

GPIO_Pin_12

;

GPIO_Init

(

GPIOA

,

&

GPIO_InitStructure

)

;

 

/* USARTx configured as follow:

- BaudRate = 9600 baud

- Word Length = 8 Bits

- One Stop Bit

- No parity

- Hardware flow control enabled (RTS and CTS signals)

- Receive and transmit enabled

*/

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_RTS_CTS

;

USART_InitStructure.

USART_Mode

=

USART_Mode_Rx

|

USART_Mode_Tx

;

USART_Init

(

USART1

,

&

USART_InitStructure

)

;

 

/* Odblokowanie USART1 */

USART_Cmd

(

USART1

,

ENABLE

)

;

 

USART_SendData

(

USART1

,

'A'

)

;

while

(

USART_GetFlagStatus

(

USART1

,

USART_FLAG_TXE

)

==

RESET

)

;

USART_SendData

(

USART1

,

'B'

)

;

while

(

USART_GetFlagStatus

(

USART1

,

USART_FLAG_TXE

)

==

RESET

)

;

USART_SendData

(

USART1

,

'C'

)

;

while

(

USART_GetFlagStatus

(

USART1

,

USART_FLAG_TXE

)

==

RESET

)

;

USART_SendData

(

USART1

,

'D'

)

;

while

(

USART_GetFlagStatus

(

USART1

,

USART_FLAG_TXE

)

==

RESET

)

;

}

5 REPLIES 5
Posted on January 12, 2012 at 13:56

The read/write of DR go to different internal registers, ie you can't see what you wrote in. You could loop-back externally and wait for it to clock over.

Try disabling flow control (CTS/RTS), and see if the data is emitted. Use a scope on the pin to observed data.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
irekguzik
Associate II
Posted on January 12, 2012 at 16:15

Thanks for help ~clive1, it was very good idea with loop-back :).

Now USART is working but I have another problem :\ when I clean [1] flag USART_FLAG_RXNE only before SECOND LED ON-OFF (after received 'O' from terminal), the 'K' can't be identified. Letter 'K' is recognized when I clean that flag additionaly in [2] (after SECOND LED ON-OFF).       

       

USART_SendData(USART2, 'A');

    while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);

    USART_SendData(USART2, 'T');    

    while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);

    USART_SendData(USART2, 0x0D);

    while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);

    USART_SendData(USART2, 0x0A);

    while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);

    /*FIRST LED ON-OFF */

    GPIO_WriteBit(GPIOB, GPIO_Pin_6, Bit_SET);

    Delay(50);

    GPIO_WriteBit(GPIOB, GPIO_Pin_6, Bit_RESET);

   

    /* WAIT FOR 'O' */

    while(USART_GetFlagStatus(USART2, USART_FLAG_RXNE) != RESET);

    while(USART_ReceiveData(USART2)!= 'O');

    USART_ClearFlag(USART2, USART_FLAG_RXNE);  //[1]

   

    /*SECOND LED ON-OFF */

    GPIO_WriteBit(GPIOB, GPIO_Pin_7, Bit_SET);

    Delay(50);

    GPIO_WriteBit(GPIOB, GPIO_Pin_7, Bit_RESET);

    USART_ClearFlag(USART2, USART_FLAG_RXNE);  //[2]

    /* WAIT FOR 'K' */

    while(USART_GetFlagStatus(USART2, USART_FLAG_RXNE) != RESET);

    while(USART_ReceiveData(USART2)!= 'K');

    USART_ClearFlag(USART2, USART_FLAG_RXNE);

I would be very thankful for help.

Posted on January 13, 2012 at 02:00

You need to wait for RXNE before reading each character, you do not need to clear RXNE, it is cleared by reading the data.

/*FIRST LED ON-OFF */
GPIO_WriteBit(GPIOB, GPIO_Pin_6, Bit_SET);
Delay(50);
GPIO_WriteBit(GPIOB, GPIO_Pin_6, Bit_RESET);
/* WAIT FOR 'O' */
do
{
while(USART_GetFlagStatus(USART2, USART_FLAG_RXNE) == RESET);
} while(USART_ReceiveData(USART2)!= 'O');
/*SECOND LED ON-OFF */
GPIO_WriteBit(GPIOB, GPIO_Pin_7, Bit_SET);
Delay(50);
GPIO_WriteBit(GPIOB, GPIO_Pin_7, Bit_RESET);
/* WAIT FOR 'K' */
do
{
while(USART_GetFlagStatus(USART2, USART_FLAG_RXNE) == RESET);
} while(USART_ReceiveData(USART2)!= 'K');

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
irekguzik
Associate II
Posted on January 13, 2012 at 13:01

It's strange when delete line [1] and [2] program doesn't work good in normal mode . STM32L can receive 'O' but no 'K'. There is one exception: when I'm working in keil debug mode and stop program after receiving 'O' and then resume, STM32L receive 'K' :\

I think that the problem is with Delay() function. When I comment this line project works good. But I don't have idea how Delay() have impact on USART. Delay() is standard implementation from STM32L Discovery Demo:

void Config_Systick(void)

{

  RCC_ClocksTypeDef RCC_Clocks;

 

  RCC_GetClocksFreq(&RCC_Clocks);

  SysTick_Config(RCC_Clocks.HCLK_Frequency / 100);

}

void Delay(uint32_t nTime)

{

  TimingDelay = nTime;

  while(TimingDelay != 0);

 

}

void TimingDelay_Decrement(void)

{

  if (TimingDelay != 0x00)

  {

    TimingDelay--;

  }

}

void SysTick_Handler(void)

{

    disableInterrupts();

    TimingDelay_Decrement();

    enableInterrupts();

Posted on January 13, 2012 at 14:10

I hope you figure it out, I'm not good with incomplete code fragments.

Look carefully at the code I provided, consider not using interrupts/delays, consider toggling the LEDs as characters arrive, not pulsing them.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..