cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F100 UART problem

sumanth
Associate II
Posted on September 25, 2012 at 09:06

Hello,

I'm currently trying to implement a UART driver with interrupt handling for the STM32F100x6 on my Discovery board.

but I am unable to receive or send data and even the interrupts are not getting generated.

check my code and help me out..

void UART_ConfigIni()

{

 

 

 

  /*enable the USART1 peripheral clock */

RCC->APB2ENR = RCC->APB2ENR | RCC_APB2ENR_USART1EN;

/*enable the clock for GPIO port A */

RCC->APB2ENR = RCC->APB2ENR | RCC_APB2ENR_IOPAEN;

/* set the TX as push - pull mode with 50MHz and RX as pull - up mode */

GPIOA->CRH = GPIOA->CRH | GPIO_CRH_MODE9 ;    /* Alternate function output Push-pull*/

GPIOA->CRH = GPIOA->CRH | GPIO_CRH_CNF9_1 ;   /* Output mode, max speed 50 MHz.*/

GPIOA->CRH = GPIOA->CRH | GPIO_CRH_MODE10_1 ; /*Input with pull-up.*/

/* setting the USART_CR1 register*/

USART1->CR1 = USART1->CR1 | USART_CR1_RE;     /* reciever enable*/

USART1->CR1 = USART1->CR1 | USART_CR1_TE ;    /*Transmitter Enable*/

USART1->CR1 = USART1->CR1 | USART_CR1_RXNEIE; /*RXNE Interrupt Enable*/

USART1->CR1 = USART1->CR1 | USART_CR1_TCIE;   /*Transmission Complete Interrupt Enable */

USART1->CR1 = USART1->CR1 | USART_CR1_UE;     /*USART Enable */

USART1->CR1 = USART1->CR1 | USART_CR1_OVER8;  /*USART Oversmapling 8-bits */

USART1->CR1 = USART1->CR1 | USART_CR1_OVER8;

/* by deafult it takes 1 start bit and 8 data bits */

/* USART_CR2 is not set, by default we have 1 stop bit */

/* setting one sample bit method in USART_CR3*/

USART1->CR3 = USART1->CR3 | USART_CR3_ONEBIT ;  /*One Bit method*/

}

void   UART_BaudConfig (uint32 u32_baudUART_bps)

{

 real32 r64_uart_div, r64_uart_fraction;

  uint u32_mantissa,u32_fraction;

 

   r64_uart_div = (real32) 8000000 / ( u32_baudUART_bps * 16 );

   u32_mantissa = (int) (r64_uart_div);

  r64_uart_fraction =  r64_uart_div - (uint)(r64_uart_div);

   r64_uart_fraction =  r64_uart_fraction * 8;

   u32_fraction =  ceil (r64_uart_fraction);

   if ( u32_fraction >=16 )

   u32_mantissa++;

   

   u32_mantissa = u32_mantissa << 4;

   u32_fraction = u32_fraction & 0x07;

   

   USART1->BRR = u32_mantissa | u32_fraction;

}  

uint8 UART_TxData(const uint8* tx_data, uint16 u16_txlen)

{

  uint8 i, Tx_sucess;

 

 for (i=0;i<u16_txlen;i++)

  {

    Tx_sucess = UART_TxByte(*tx_data);

    tx_data++;

    if (Tx_sucess)

      {

        

      }

  }

   return 1;

 

}

uint8 UART_RxData(uint8* rx_data, uint16 u16_rxlen)

{

 extern bool b_rx_flag;

 uint8 rx_success;

 

 

 while(*rx_data != 10)

 {   

    if(b_rx_flag == 1)

    {

      rx_success = UART_RxByte (rx_data);

      b_rx_flag = 0;

    }

 }

 b_rx_flag = 0;

 return 1;

 

   

}

uint8 UART_TxByte(const uint8 u8_byteTx)

{

  extern bool b_tx_flag;

  USART1->DR = u8_byteTx;

  while (!b_tx_flag);

    b_tx_flag=0;

        

    return 1;

}

uint8  UART_RxByte (uint8* pu8_byteRx)

{

 *pu8_byteRx =  USART1->DR & 0x01ff;

 return 1;

}

void USART1_IRQHandler(void)

{  

  extern bool b_tx_flag;

  extern bool b_rx_flag;

   

  if ( USART1->SR & 0x0040)

    {

      b_tx_flag = 1;

    }

  else if (  USART1->SR & 0x0020)

    {

      b_rx_flag = 1;       

    }

}

in my main function I am checking by transmitting a single byte.

bool b_tx_flag=0;

bool b_rx_flag=0;

int main(void)

{

uint8 sucess,a=0x23;

UART_ConfigIni();

UART_BaudConfig (9600);

  while (1)

  {

     

     UART_TxEnbl (1);

    sucess = UART_TxByte ('a');

     if (sucess)

      {

         USART1->SR=0x0000;

        GPIOC->CRH = 0x3;

       GPIOC->ODR = 0xFFFF;

      }

     

  }

}

this is my code.

I am not getting any interrupt.

whats wrong in my code help me out.

#uart.stm32-uart #usart
6 REPLIES 6
Posted on September 25, 2012 at 14:05

whats wrong in my code help me out.

 

Well there are a bunch of things going on, I'm not interested in digging into the register level bit minutia, if you discard the library you own those issues.

What I can see is :

You don't initialize the NVIC.

You don't use volatile for appropriate variables.

You don't service and clear the interrupt sources, this will cause serious issues when you do get an interrupt.

You check SR flags as if they are mutually exclusive.

If you don't have data to supply for TX you must turn off the interrupts.

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

I initialised the NVIC registers.

Can u give some working code.

Posted on September 25, 2012 at 17:37

Recommend downloading and reviewing the sample/example code within the firmware library.

The following example might be helpful, but there are others.

STM32F10x_StdPeriph_Lib_V3.5.0\Project\STM32F10x_StdPeriph_Examples\USART\Interrupt

I've posted some polled mode examples before, interrupt code starts to get into more architected solutions where how I solve problems may differ from what fits into your model. Plus it falls outside the time window.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on September 25, 2012 at 20:56

// STM32 USART IRQ TX/RX Loop (USART1 TX PA.09, RX PA.10) VLDiscovery - sourcer32@gmail.com
#include ''stm32F10x.h''
#include ''STM32vldiscovery.h''
volatile char StringLoop[] = ''The quick brown fox jumps over the lazy dog

'';
/**************************************************************************************/
void RCC_Configuration(void)
{
/* Enable GPIO clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
/* Enable UART clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
}
/**************************************************************************************/
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Configure USART Tx as alternate function push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; // PA.09 USART1.TX
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Configure USART Rx as input floating */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; // PA.10 USART1.RX
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
/**************************************************************************************/
void USART_Configuration(void)
{
USART_InitTypeDef USART_InitStructure;
/* USART resources configuration (Clock, GPIO pins and USART registers) ----*/
/* USART 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 configuration */
USART_Init(USART1, &USART_InitStructure);
/* Enable the USART1 */
USART_Cmd(USART1, ENABLE);
USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
}
/**************************************************************************************/
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* Configure the NVIC Preemption Priority Bits */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
/* Enable the USART1 Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/**************************************************************************************/
void USART1_IRQHandler(void)
{
static int tx_index = 0;
static int rx_index = 0;
if (USART_GetITStatus(USART1, USART_IT_TXE) != RESET) // Transmit the string in a loop
{
USART_SendData(USART1, StringLoop[tx_index++]);
if (tx_index >= (sizeof(StringLoop) - 1))
tx_index = 0;
}
if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) // Received characters modify string
{
StringLoop[rx_index++] = USART_ReceiveData(USART1);
if (rx_index >= (sizeof(StringLoop) - 1))
rx_index = 0;
}
}
/**************************************************************************************/
int main(void)
{
RCC_Configuration();
GPIO_Configuration();
NVIC_Configuration();
USART_Configuration();
while(1);
}
/**************************************************************************************/
#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..
sumanth
Associate II
Posted on September 27, 2012 at 07:13

I some how modified my code.

enabled the interrupts now the control flow is working correctly.

but when I check the recieved and transmitted data on the termite I am getting some junk values.

by reading to some posts on this forum I came to know that we need to set the IDE to 8mhz.

my stm32 discovery board is using 8MHz, how can set my IAR IDE to 8 MHz

please help me out.

thank you.

Posted on September 27, 2012 at 15:37

Well probably in the Target/CPU window for one.

What's generally more important, is to ensure that HSE_VALUE is set appropriately (used in the rate math), and the PLL is configured correctly (system_stm32f4xx.c, PLL_M)
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..