cancel
Showing results for 
Search instead for 
Did you mean: 

STM8S UART2 Std_Periph Continuous Rx Data Reception

JWhit.6
Associate

I have implemented the same methodology as explained in the below post:

http://embedded-lab.com/blog/continuing-stm8-microcontroller-expedition/12/

I am trying to receive data that is 6 bytes long on the Rx pin using interrupts. When calling ReceiveData8() I get the correct first byte. I then clear the UART2_FLAG_RXNE flag and the UART2_IT_RXNE ITPendingBit. When I check RXNE again the flag is not set so therefore I cannot access the rest of the data.

Is it not valid to simply call ReceiveData8() (with a clear to the flags) again in a loop until all 6 Bytes have been saved in an index of an array?

Is there a way to implement this using ST Std_Periph?

I am using the STM8S-Discovery (STM8S105C6T6) and the basic code is below. Please note that this is incomplete code and only meant to try to get the second byte of data as debug.

INTERRUPT_HANDLER(UART2_RX_IRQHandler, 21)
{		  
           rx_value[pos] = UART2_ReceiveData8();
           UART2_ClearITPendingBit(UART2_IT_RXNE);
	   UART2_ClearFlag(UART2_FLAG_RXNE);
			
            //Try to acquire next byte
	   if(UART2_GetFlagStatus(UART2_FLAG_RXNE) == SET)
	   {
                    /*never gets in here->flag not getting set?*/
		    pos++;
		    rx_value[pos] = UART2_ReceiveData8();
		    UART2_ClearITPendingBit(UART2_IT_RXNE);
	            UART2_ClearFlag(UART2_FLAG_RXNE);
	   }
			
	   if(pos > 15)
	   {
		pos = 0;
	   }
}
void clock_setup(void)
{
      CLK_DeInit();
                
      CLK_HSECmd(DISABLE);
      CLK_LSICmd(DISABLE);
      CLK_HSICmd(ENABLE);
      while(CLK_GetFlagStatus(CLK_FLAG_HSIRDY) == FALSE);
                
      CLK_ClockSwitchCmd(ENABLE);
      CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV8);
      CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV1);
                
      CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, CLK_SOURCE_HSI, 
      DISABLE, CLK_CURRENTCLOCKSTATE_ENABLE);
                
      CLK_PeripheralClockConfig(CLK_PERIPHERAL_SPI, DISABLE);
      CLK_PeripheralClockConfig(CLK_PERIPHERAL_I2C, DISABLE);
      CLK_PeripheralClockConfig(CLK_PERIPHERAL_ADC, DISABLE);
      CLK_PeripheralClockConfig(CLK_PERIPHERAL_AWU, DISABLE);
      CLK_PeripheralClockConfig(CLK_PERIPHERAL_UART2, ENABLE);
      CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER1, DISABLE);
      CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER3, ENABLE);
      CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER4, DISABLE);
}
 
 
void GPIO_setup(void)
{
      GPIO_DeInit(GPIOD);
      GPIO_Init(GPIOD, GPIO_PIN_0, GPIO_MODE_OUT_PP_HIGH_FAST);
			
			GPIO_Init(GPIOD, GPIO_PIN_5, GPIO_MODE_OUT_PP_HIGH_FAST);//Tx
			GPIO_Init(GPIOD, GPIO_PIN_6, GPIO_MODE_IN_PU_NO_IT);//Rx
}
 
 
void TIM3_setup(void)
{
      TIM3_DeInit();
      TIM3_TimeBaseInit(TIM3_PRESCALER_32, 1000);
      TIM3_OC2Init(TIM3_OCMODE_PWM1, TIM3_OUTPUTSTATE_ENABLE, 1000, 
                   TIM3_OCPOLARITY_HIGH);
      TIM3_Cmd(ENABLE);
			
}
 
void UART2_setup(void)
{
			UART2_DeInit();
			
			UART2_Init(9600, 
								 UART2_WORDLENGTH_8D, 
								 UART2_STOPBITS_1,
								 UART2_PARITY_NO,
								 UART2_SYNCMODE_CLOCK_DISABLE,
								 UART2_MODE_TXRX_ENABLE);
								 
			UART2_ITConfig(UART2_IT_RXNE, ENABLE);
			enableInterrupts();
								 
			UART2_Cmd(ENABLE);
			
}

1 REPLY 1
Cristian Gyorgy
Senior III

When the interrupt handler is executed you only have 1 byte in the USART_DR (data register). So, you cannot read a second byte or more.

I don't know why you call these 2 functions: UART2_ClearITPendingBit, UART2_ClearFlag; you don't have to clear any bits. Once the byte is read from the USART_DR, the UART2_FLAG_RXNE flag wil clear automatically.

If you want to read the next 5 bytes in the same execution of the interrupt handler, you'll have to wait for them to enter, without returning from the interrupt - not a good idea!