cancel
Showing results for 
Search instead for 
Did you mean: 

Recieve more then 1 Byte over USART

sam239955
Associate II
Posted on August 31, 2012 at 20:51

Hi,

at the moment I'm using the following code to recieve a byte:

char
ReceivedData = NULL;
void
main() {
.
.
.
while
(1){
/* Wait until a byte is received */
while
(USART_GetFlagStatus(USART2, USART_FLAG_RXNE) == RESET)
{
}
/* read byte and print via usart2 it */
ReceivedData = USART_ReceiveData(USART2);
printf
(
''Positionen: %d \r\n''
, ReceivedData);
//abbort if 3 received

if
(ReceivedData == 3)
break
;
}
.
.
}

I now want to recieve more then 1 byte and store it an recieve Buffer ''RXBUFF[]''. Because I want to send a byte array from my pc to the controller and then I want to deserialze the data to int16 or int32 ... How can i achieve that? how can I recieve my bytearray with the stm32f103 ? WR Alex #usart-stm32-loopback #usart-stm32
19 REPLIES 19
Posted on September 02, 2012 at 14:15

I'd probably do some of the processing under interrupt, and make some effort to validate and synchronize the incoming data.

As to books, I learned C and Assembler a very long time ago. The K&R book is the best reference for C.

For the Cortex-M3, you could start with the ARM Technical Manuals, and Joseph Yiu's fine books, anyone of his Cortex series/editions would provide a good grounding. The STM32 specific stuff is covered well in the Data Sheets and Reference Manuals.

I suspect however you're looking for something that covers more of the mechanics of how things work in general. In this regard I'd suggest looking at some of the microprocessor books of the early 80's, while they didn't consider themselves ''embedded'' back then at lot of the systems are similar and resource limited, and addressed a lot of fundamental issues.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
marjano89
Associate II
Posted on June 14, 2014 at 16:26

Hi all,

I have the same problem using interrupts with UART. Why handler is called once if I have sent 20 bytes from my PC? Should it be called every byte is in buffer? here is the handler  and initUart code:

// this is the interrupt request handler (IRQ) for ALL USART1 interrupts

void USART1_IRQHandler(void)

{

static uint8_t cnt = 0; // this counter is used to determine the string length

//Data available in the Read Register.

if( USART_GetITStatus(USART1, USART_IT_RXNE) != RESET )

{

RXBUFF[cnt++] = USART_ReceiveData(USART1); // the character from the USART1 data register is saved in t

}

if(MAX_STRLEN > cnt)

{

cnt = 0;

}

}

and here is init of UART

void initUSART1(uint32_t baudrate)

{

GPIO_InitTypeDef GPIO_InitStruct; // this is for the GPIO pins used as TX and RX

USART_InitTypeDef USART_InitStruct; // this is for the USART1 initilization

NVIC_InitTypeDef NVIC_InitStructure; // this is used to configure the NVIC (nested vector interrupt controller)

/* enable APB2 peripheral clock for USART1

* note that only USART1 and USART6 are connected to APB2

* the other USARTs are connected to APB1

*/

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

/* enable the peripheral clock for the pins used by

* USART1, PB6 for TX and PB7 for RX

*/

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);

/* This sequence sets up the TX and RX pins

* so they work correctly with the USART1 peripheral

*/

GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; // Pins 6 (TX) and 7 (RX) are used

GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; // the pins are configured as alternate function so the USART peripheral has access to them

GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; // this defines the IO speed and has nothing to do with the baudrate!

GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; // this defines the output type as push pull mode (as opposed to open drain)

GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; // this activates the pullup resistors on the IO pins

GPIO_Init(GPIOB, &GPIO_InitStruct); // now all the values are passed to the GPIO_Init() function which sets the GPIO registers

/* The RX and TX pins are now connected to their AF

* so that the USART1 can take over control of the

* pins

*/

GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_USART1 );

GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_USART1 );

/* Now the USART_InitStruct is used to define the

* properties of USART1

*/

USART_InitStruct.USART_BaudRate = baudrate; // the baudrate is set to the value we passed into this init function

USART_InitStruct.USART_WordLength = USART_WordLength_8b; // we want the data frame size to be 8 bits (standard)

USART_InitStruct.USART_StopBits = USART_StopBits_1; // we want 1 stop bit (standard)

USART_InitStruct.USART_Parity = USART_Parity_No; // we don't want a parity bit (standard)

USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // we don't want flow control (standard)

USART_InitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; // we want to enable the transmitter and the receiver

USART_Init(USART1, &USART_InitStruct); // again all the properties are passed to the USART_Init function which takes care of all the bit setting

/* Here the USART1 receive interrupt is enabled

* and the interrupt controller is configured

* to jump to the USART1_IRQHandler() function

* if the USART1 receive interrupt occurs

*/

USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); // enable the USART1 receive interrupt

NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; // we want to configure the USART1 interrupts

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // this sets the priority group of the USART1 interrupts

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; // this sets the subpriority inside the group

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // the USART1 interrupts are globally enabled

NVIC_Init(&NVIC_InitStructure); // the properties are passed to the NVIC_Init function which takes care of the low level stuff

// finally this enables the complete USART1 peripheral

USART_Cmd(USART1, ENABLE);

}

Posted on June 14, 2014 at 17:05

Why handler is called once if I have sent 20 bytes from my PC?

Because at 9600 baud, one character takes ~1ms to arrive, so figure several hundred thousand processor cycles, you interrupt so the processor can do useful work while the signal is on the wire, and it's one byte because of the silicon/power resources needed to provide larger buffers.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
marjano89
Associate II
Posted on June 14, 2014 at 17:34

I can use baud 57600. I suppose to send single bytes in a eg. loop from the sender module? I am creating a BT app on android which is a sender.

Posted on June 14, 2014 at 18:38

I can use baud 57600. I suppose to send single bytes in a eg. loop from the sender module? I am creating a BT app on android which is a sender.

You can send and transmit continuous streams of characters, they do however arrive/depart periodically depending on the transmission rate, so dozens of characters aren't all going to arrive at once. One typically handles this by buffering the data, and managing the transmission/reception in an interrupt.

You don't mention a part/board, I'll assume for my convenience that you have an STM32F4-Discovery board.

[DEAD LINK /public/STe2ecommunities/mcu/Lists/STM32Discovery/Flat.aspx?RootFolder=/public/STe2ecommunities/mcu/Lists/STM32Discovery/STM32F4%20problem%20with%20USART1%20INTERRUPT&FolderCTID=0x01200200770978C69A1141439FE559EB459D75800084C20D8867EAD444A5987D47BE638E0F&currentviews=553]https://my.st.com/public/STe2ecommunities/mcu/Lists/STM32Discovery/Flat.aspx?RootFolder=%2Fpublic%2FSTe2ecommunities%2Fmcu%2FLists%2FSTM32Discovery%2FSTM32F4%20problem%20with%20USART1%20INTERRUPT&FolderCTID=0x01200200770978C69A1141439FE559EB459D75800084C20D8867EAD444A5987D47BE638E0F¤tviews=553

[DEAD LINK /public/STe2ecommunities/mcu/Lists/STM32Discovery/Flat.aspx?RootFolder=/public/STe2ecommunities/mcu/Lists/STM32Discovery/STM32F4%20problem%20with%20USART1%20INTERRUPT&FolderCTID=0x01200200770978C69A1141439FE559EB459D75800084C20D8867EAD444A5987D47BE638E0F&currentviews=553]https://my.st.com/public/STe2ecommunities/mcu/Lists/STM32Discovery/Flat.aspx?RootFolder=%2Fpublic%2FSTe2ecommunities%2Fmcu%2FLists%2FSTM32Discovery%2FSTM32F4%20problem%20with%20USART1%20INTERRUPT&FolderCTID=0x01200200770978C69A1141439FE559EB459D75800084C20D8867EAD444A5987D47BE638E0F¤tviews=553

[DEAD LINK /public/STe2ecommunities/mcu/Lists/STM32Discovery/Flat.aspx?RootFolder=/public/STe2ecommunities/mcu/Lists/STM32Discovery/UART%20example%20code%20for%20STM32F0&FolderCTID=0x01200200770978C69A1141439FE559EB459D75800084C20D8867EAD444A5987D47BE638E0F&currentviews=12897]https://my.st.com/public/STe2ecommunities/mcu/Lists/STM32Discovery/Flat.aspx?RootFolder=%2Fpublic%2FSTe2ecommunities%2Fmcu%2FLists%2FSTM32Discovery%2FUART%20example%20code%20for%20STM32F0&FolderCTID=0x01200200770978C69A1141439FE559EB459D75800084C20D8867EAD444A5987D47BE638E0F¤tviews=12897
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
zzdz2
Associate II
Posted on June 14, 2014 at 19:03

if(MAX_STRLEN > cnt)
{
cnt = 0;
}

This looks suspicious, cnt is lower than max length and reset every time.
marjano89
Associate II
Posted on June 16, 2014 at 08:36

shahmonil93
Associate II
Posted on August 07, 2014 at 17:05


while
(1)

{

while
(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);

RXBUFF[j] = USART_ReceiveData(USART1);


if
(USART_GetFlagStatus(USART1, USART_FLAG_TXE) != RESET)

USART_SendData(USART1, RXBUFF[j]);


j++;

if
(j >= 248)

j = 0;

}

}

I have written this code, and now, I am receiving data from GPS on USART1 and now I just want to display it on the LCD. How can I do this without transmitting it anywhere? I can display strings on LCD too. I have written a function for that. Please help as to where can I place that function call??
Posted on August 07, 2014 at 18:35

Really no idea what board or STM32 you're using.

For GPS NMEA stream, you might want to look at the line buffering example, and send the string to the display after the string is NUL terminated.

[DEAD LINK /public/STe2ecommunities/mcu/Lists/STM32Discovery/Flat.aspx?RootFolder=/public/STe2ecommunities/mcu/Lists/STM32Discovery/UART%20example%20code%20for%20STM32F0&FolderCTID=0x01200200770978C69A1141439FE559EB459D75800084C20D8867EAD444A5987D47BE638E0F&currentviews=12897]https://my.st.com/public/STe2ecommunities/mcu/Lists/STM32Discovery/Flat.aspx?RootFolder=/public/STe2ecommunities/mcu/Lists/STM32Discovery/UART%20example%20code%20for%20STM32F0&FolderCTID=0x01200200770978C69A1141439FE559EB459D75800084C20D8867EAD444A5987D47BE638E0F¤tviews=12897
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
shahmonil93
Associate II
Posted on August 08, 2014 at 07:46 I am using STM32F072RB discovery board. And, I dont want to use the interrupt based USART. So what can I do to take a string of data at one go. Or maybe check every incoming byte with a particular format. Like, see i will show you my code for receiving data from a GPS module. Here ''usart_getch()'' is a function to receive one byte. Now, how do I fix this code to get it working and display all the arrays that I have made on the LCD?


unsigned 
char
value,i,lati_value[15],lati_dir, longi_value[15], longi_dir, 
time
[10], speed[10], date[6];


unsigned 
char
usart_getch()

{

/* Wait until the data is ready to be received. */

while
((USART1->ISR & USART_ISR_RXNE) == RESET){

}

return
USART1->RDR;

}



void
readgps()

{

int
q;

value=usart_getch();

if
(value==
'$'
)

{

value=usart_getch();

if
(value==
'G'
)

{

value=usart_getch();

if
(value==
'P'
)

{

value=usart_getch();

if
(value==
'R'
)

{

value=usart_getch();

if
(value==
'M'
)

{

value=usart_getch();

if
(value==
'C'
)

{

value=usart_getch();

if
(value==
','
)

{

time
[0]=usart_getch();

value=
time
[0];

for
(q=1;q<6;q++)

{

time
[q]=usart_getch();

value=
time
[q];

}

value=usart_getch();

while
(value!=
','
)

{

value=usart_getch();

}

value=usart_getch();

while
(value!=
','
)

{

value=usart_getch();

}

lati_value[0]=usart_getch();

value=lati_value[0];

for
(i=1;i<9;i++)

{

lati_value[i]=usart_getch();

value=lati_value[i];

}

while
(value!=
','
)

{

value=usart_getch();

}

lati_dir=usart_getch();

value=usart_getch();

while
(value!=
','
)

{

value=usart_getch();

}

longi_value[0]=usart_getch();

value=longi_value[0];

for
(i=1;i<10;i++)

{

longi_value[i]=usart_getch();

value=longi_value[i];

}

while
(value!=
','
)

{

value=usart_getch();

}

longi_dir=usart_getch();

value=usart_getch();

while
(value!=
','
)

{

value=usart_getch();

}

i=0;

value=usart_getch();

while
(value!=
','
)

{

speed[i]= value; 

value=usart_getch();

i++; 

}

value=usart_getch();

while
(value!=
','
)

{

value=usart_getch();

}

i=0;

while
(i<6)

{

date[i]=usart_getch();

i++;

}


}

}

}

}

}

}

}