2020-06-10 07:12 PM
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);
}
2020-06-13 12:36 PM
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!