Skip to main content
Visitor II
June 11, 2020
Question

STM8S UART2 Std_Periph Continuous Rx Data Reception

  • June 11, 2020
  • 1 reply
  • 772 views

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);
			
}

    This topic has been closed for replies.

    1 reply

    Visitor II
    June 13, 2020

    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!