cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F0 - USART receiving only first package of data

annette
Associate II
Posted on December 14, 2013 at 22:45

I have big problem with USART transmission. Here's my simple code:

In main():

-----------------------------

while(1) {

get_data();

}

-----------------------------

And in get_data():

----------------------------

int get_data(void) {

uint8_t data[20];

uint8_t counter = 0;

while (counter < 6) { // I just want to get first 6 characters 

if ((USART1->ISR & USART_ISR_RXNE) == USART_ISR_RXNE) {

data[counter++] = USART1->RDR;

}

}

counter=0;

}

----------------------------

Everything is fine when I receive first pack of data, but then, when I'm second time in get_data function I can only get a few characters from previous pack of data (after the 6 first which I got already) but I can't get any more. I can't get a new package of data. Even if I try few times. Receiver seems to be turned of after getting only 6 first characters from longer message (about 15). Why is that? How to solve this problem?

I'm using STM32F0Discovery.

8 REPLIES 8
Posted on December 15, 2013 at 17:39

I'm not aware of any particular failure in this regard. Be aware however that your local variable is not cleared upon entry so may appear to retain the original content from call to call.

What tool chain and debugger are you using?

Also be aware that parking a peripheral view window over the USART may interfere with registers and status observed.
Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
annette
Associate II
Posted on December 15, 2013 at 18:57

I'm using CoIDE by CooCox. 

''Be aware however that your local variable is not cleared upon entry so may appear to retain the original content from call to call.'' Can you tell me how can I fix this problem?

I'll try to describe step by step. 

1. Put first breakpoint at ''uint8_t counter = 0'' and secone one at end of while(counter...)

2. Press RUN two times and program is waiting for a data (from another uC - it's sends me back my data with his response to it - it could be problem too).

3. When he gets it I have my data table with 6 characters. Counter = 0;

4. Press RUN again, I'm at ''uint8_t counter = 0'' again like in 1. 

5. Now I'm pressing ''Step Into'' to step from one instruction to another and problem is that this if -> ''if ((USART1->ISR & USART_ISR_RXNE) == USART_ISR_RXNE)'' equals to true so its starting to read older package of data. It shouldn't let me in, because I didn't send him another package but it did.

Is there any way to solve this? Maybe I should reset some flags I didn't know about?

Posted on December 15, 2013 at 23:09

In the C Language I'm familiar with you'd use

uint8_t data[20] = { 0 };

There is also memset()

I'm not sure I understand ''package'', the USART is incapable of holding more that one byte, so a) it's not going to replicate a whole stream of arbitrary bytes, b) if you jamb up the CPU waiting for human interaction in a debugger, then a stream of bytes sent by another transmitter are going to overflow the receiver, signalling an ORE error, cleared by reading the data register (RDR)

Can you successful send a string of characters from the F0 to your terminal?
Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
annette
Associate II
Posted on December 15, 2013 at 23:37

Yes, I can do it.

''b) if you jamb up the CPU waiting for human interaction in a debugger, then a stream of bytes sent by another transmitter are going to overflow the receiver, signalling an ORE error, cleared by reading the data register (RDR)''

I know that. When I run program normally, first package of data is received with no problem (then I'm sending some data to my terminal and it responds, but I don't care about that respond data) but when I want to receive another one, the while loop takes forever to execute - like it read too few characters (from first received data which I care only about first 6 characters) to go out from while loop but in the same time it don't want to read new data.

By package of data I mean string like this -> \n\rTEXT\r\n 

In my opinion, this problem can be solved by completely reseting the usart (to delete still existing data from first package) and turn the receiver on right before I send second important package (not the rest of previous one or this echo from my terminal). But I don't know how to do this...

Posted on December 16, 2013 at 00:24

I'm not convinced that resetting the USART is the approach here, the USART should be more than capable of receiving all data sent to it, if you have line demarcations it would be more effective to identify those, and resynchronize the stream as required.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
Posted on December 16, 2013 at 00:36

At this juncture it might be helpful to do a sanity check, and confirm the USART works for a sustained period of time, and thousands of characters. If it can't do that we need to look at other issues.

/* USART1 PA.9 Tx, PA.10 Rx STM32F0-Discovery sourcer32@gmail.com */
#include ''stm32f0xx.h''
#include ''stm32f0_discovery.h''
int main(void)
{
USART_InitTypeDef USART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_1);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_1);
/* Configure USART1 pins: Rx and Tx ----------------------------*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOA, &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(USART1, &USART_InitStructure);
USART_Cmd(USART1,ENABLE);
while(1)
{
int ch;
while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET); // Wait on reception
ch = USART_ReceiveData(USART1);
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); // Should drop through
USART_SendData(USART1, ch); // Echo
}
}

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
vendor
Associate II
Posted on December 24, 2013 at 04:10

Clive1,

Your example code was very helpful. I am attempting to set up the USART1 for half duplex operation, on STM32F03-Demonstration board in an attempt to read data from external 1-wire Dallas/Maxim Temp part DS18B20, this also requires external components to set up open-drain.  While I was able to follow your example I am a bit confused why you defined int ch; Inside the while loop? Wouldn't this cause a new instance of ch for every time the loop is iterated? What am I missing?

Rick43065

Andrew Neil
Chief II
Posted on December 24, 2013 at 08:45

''I am a bit confused why you defined int ch; Inside the while loop?''

Because it is not used outside the loop!

Standard ''Good Practice'' to not give anything wider scope than it actually needs - nothing specifically to do with microcontrollers or embedded.

''Wouldn't this cause a new instance of ch for every time the loop is iterated?''

In principle, yes. But, in practice, that has very little (if any) overhead in 'C' - so is unlikely to be of any concern here.

(if this were a really-tight, time-critical spot, one might forgo ''Good Practice'' in favour of maximum performance - but, as already noted, that's unlikely to be the case here).

''attempt to read data from external 1-wire Dallas/Maxim Temp part DS18B20, this also requires external components to set up open-drain.''

So that is rather different from just ''normal'' UART comms, isn't it?

As clive1 suggested earlier, problems are more likely to be in your software implementation of the Maxim/Dallas 1-WireTM protocol - incluing control of the external components - than the UART itself...

Might it not be easier to bit-bang the protocol using GPIO than try to kludge the UART...?