cancel
Showing results for 
Search instead for 
Did you mean: 

USART Help

definitely
Associate II
Posted on April 06, 2014 at 03:23

I'm using a STM32F3 Discovery and connecting it to labVIEW the problem is that I can't receive more than one byte. Can someone help me modifying my code to allow multiple byte reception. I'm testing it sending something and reading it in labVIEW. A problem occurs when I send more than 1 byte.

//-----------------------------------------------------Register comment format-----------------------------------------------------//

//[ Register bits ] Function name[ Function bits ] -> Value Effect explanation

//---------------------------------------------------------------------------------------------------------------------------------//

&sharpinclude <stm32f30x.h>

&sharpinclude <stdio.h>

&sharpinclude <math.h>

&sharpinclude ''lib/delay.h''

void charTX ( char ch );

void stringTX ( char *string );

uint8_t GetChar ( void );

char letra;

int main ( void ) 

{

char output[4];

delayinit();

//-----------------------------------------------------PC4 Configuration------------------------------------------------------//

RCC->AHBENR |= RCC_AHBENR_GPIOCEN; // [ 19 ] IOPCEN = 1 I/O port A clock enabled.

GPIOC->MODER |= 2 << ( 4*2 ); // [ 9:8 ] MODER4[ 1:0 ] = 10b Alternate function on 

// PIN C4

//GPIOC->OTYPER |= 1 << ( 4*1 ); // [ 4 ] OT4 = 1 Output as open drain

GPIOC->OSPEEDR |= 3 << ( 4*2 ); // [ 9:8 ] OSPEEDR4[ 1:0 ] = 11b 50 MHz High-speed on PIN C4

//GPIOC->PUPDR &= ~( 3 << ( 4*2 ) ); // [ 9:8 ] PUPDR4[ 1:0 ] = 0 No pull-up/down om PIN C4

GPIOC->AFR[ 0 ] |= 7 << ( 4*4 ); // [ 17:16 ] AFRL4[ 3:0 ] = 0111b AF7( USART1_TX ) on PIN C4

// PC5 configuration (RX)

GPIOC->MODER |= 2 << (5*2);  // GPIO_Mode_AF

GPIOC->AFR[0] |= 7 << (5*4);  //  AF7

RCC->APB2ENR |= RCC_APB2ENR_USART1EN; // Enable USART1 clock

USART1->BRR = 72000000/9600;

USART1->CR1 &= ~USART_CR1_OVER8; // Oversampling mode = 16 

USART1->CR1 &= ~USART_CR1_M;  // Word length = 8 bits

USART1->CR1 &= ~USART_CR1_PCE;  // No parity

USART1->CR1 |= USART_CR1_TE;  // Transmitter enable

USART1->CR1 |= USART_CR1_RE;  // Receiver enable

USART1->CR1 |= USART_CR1_UE;  // USART enable

USART1->CR2 &= ~(USART_CR2_STOP_1 | USART_CR2_STOP_0); // one stop bit

for( ;; )

{

letra = GetChar()

sprintf(output,''%4d\n'',letra);

stringTX(output);

delaybyms(10);

}

}

void charTX ( char ch ) 

{

while (!(USART1->ISR & USART_ISR_TXE));

USART1->TDR = (ch & 0xFF);

}

void stringTX ( char *string )

{

    do

    {

        charTX( *string );

        *string++;

    }while(*string);

}

uint8_t GetChar ( void ) 

while (!(USART1->ISR & USART_ISR_RXNE));

return ((uint8_t)(USART1->RDR & 0xFF));

#usart-stm32f3
14 REPLIES 14
Posted on April 06, 2014 at 04:09

I'm using a STM32F3 Discovery and connecting it to labVIEW the problem is that I can't receive more than one byte. Can someone help me modifying my code to allow multiple byte reception. I'm testing it sending something and reading it in labVIEW. A problem occurs when I send more than 1 byte.

So should I interpret that as a single byte is responded too in an expected manner?

While there are several aspects of your code that I find counter initiative, I think the crux of your problem is the 5:1 ratio in data generated in response. If you are sent a stream of characters back-to-back your response is going to choke. You need to add some buffering to provide some elasticity, and the buffer would need to be big enough to handle the incoming stream, as you process your way through it.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
definitely
Associate II
Posted on April 06, 2014 at 04:30

Yes when a send only one byte it responds correctly. The problem is for example if I send ''h'' it returns me ''h'' but if i send ''hola'' it crashes. How do I change the 5:1 ratio in data generated in response or how do I add that buffering you're talking about. If you have some code solutions for me would be great.

Posted on April 06, 2014 at 05:05

I'm not sure I'm up for rewriting your code, perhaps instead of doing the whole sprintf() thing you can just echo back the single character rather than generating 5 of them. Also from a C perspective, you need to understand that your output[] array is TOO small for the data you're stuffing in it, you need a character for the newline, and another for the NUL termination.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
definitely
Associate II
Posted on April 06, 2014 at 05:13

Thank you I'll try some of your advice. But do you think my 

uint8_t GetChar ( void ) 

while (!(USART1->ISR & USART_ISR_RXNE));

return ((uint8_t)(USART1->RDR & 0xFF));

is able to receive more than 1 byte? do i need to correct that part also? Or do you think that without the sprintf should work?

Posted on April 06, 2014 at 05:32

Clearly it's designed to read one character at a time, that's why you repeatedly call the function in a loop, right? The purpose of the delay is what?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on April 06, 2014 at 05:47

// STM32 USART1 LOOP (Tx PC.4, Rx PC.5) STM32F3xx - sourcer32@gmail.com
#include ''stm32f30x.h''
/**************************************************************************************/
void RCC_Configuration(void)
{
/* Enable GPIO clock */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);
/* Enable USART clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
}
/**************************************************************************************/
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Connect PC4 to USART1_Tx */
GPIO_PinAFConfig(GPIOC, GPIO_PinSource4, GPIO_AF_7);
/* Connect PC5 to USART1_Rx */
GPIO_PinAFConfig(GPIOC, GPIO_PinSource5, GPIO_AF_7);
/* Configure USART Tx as alternate function push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOC, &GPIO_InitStructure);
/* Configure USART Rx as alternate function push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_Init(GPIOC, &GPIO_InitStructure);
}
/**************************************************************************************/
void USART1_Configuration(void)
{
USART_InitTypeDef USART_InitStructure;
/* USART resources configuration (Clock, GPIO pins and USART registers) ----*/
/* USART configured as follow:
- BaudRate = 9600 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 = 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 configuration */
USART_Init(USART1, &USART_InitStructure);
/* Enable USART */
USART_Cmd(USART1, ENABLE);
}
/**************************************************************************************/
void OutString(char *s)
{
while(*s)
{
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); // Wait for Empty
USART_SendData(USART1, *s++);
}
}
/**************************************************************************************/
int main(void)
{
RCC_Configuration();
GPIO_Configuration();
USART1_Configuration();
OutString(''This is an echo back test for USART1

'');
while(1) // Don't want to exit
{
uint16_t ch;
while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET); // Wait for Char
ch = USART_ReceiveData(USART1); // Collect Char
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); // Wait for Empty
USART_SendData(USART1, ch); // Echo Char
}
}
/**************************************************************************************/
#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

'', file, line) */
/* Infinite loop */
while (1)
{
}
}
#endif

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

Man you're de best.

I adapted your code to mine and it works perfectly. Thank you very much. If there is something I can pay you with just tell me. Thank you very much

definitely
Associate II
Posted on April 06, 2014 at 07:01

Clive another question what are the variables for sending something from the usart. With the first program i could send and receive continously whatever I want, but if I want to send something that is not coming from  ch  = USART1->RDR; // Collect Char, I can't. I sent ''Hello'' and I got in labVIEW ''HelloHello'' and it disappear, what happened?

Posted on April 06, 2014 at 07:25

I don't use labView, so have no insight into it's behaviour

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