STM8 interrupt serial receive

user3824211 picture user3824211 · Nov 1, 2016 · Viewed 7.7k times · Source

I am new to STM8, and trying to use a STM8S103F3, using IAR Embedded Workbench. Using C, I like to use the registers directly. I need serial on 14400 baud, 8N2, and getting the UART transmit is easy, as there are numerous good tutorials and examples on the net. Then the need is to have the UART receive on interrupt, nothing else will do. That is the problem. According to iostm8s103f3.h (IAR) there are 5 interrupts on 0x14 vector UART1_R_IDLE, UART1_R_LBDF, UART1_R_OR, UART1_R_PE, UART1_R_RXNE

According to Silverlight Developer: Registers on the STM8,

Vector 19 (0x13) = UART_RX

According to ST Microelectronics STM8S.h

#define UART1_BaseAddress       0x5230
#define UART1_SR_RXNE  ((u8)0x20) /*!< Read Data Register Not Empty mask */
#if defined(STM8S208) ||defined(STM8S207) ||defined(STM8S103)     ||defined(STM8S903)
#define UART1 ((UART1_TypeDef *) UART1_BaseAddress)
#endif /* (STM8S208) ||(STM8S207)  || (STM8S103) || (STM8S903)  */

According to STM8S Reference manual RM0016 The RXNE flag (Rx buffer not empty) is set on the last sampling clock edge, when the data is transferred from the shift register to the Rx buffer. It indicates that a data is ready to be read from the SPI_DR register. Rx buffer not empty (RXNE) When set, this flag indicates that there is a valid received data in the Rx buffer. This flag is reset when SPI_DR is read. Then I wrote:

#pragma vector = UART1_R_RXNE_vector //as iostm8s103f3 is used, that means 0x14
__interrupt void UART1_IRQHandler(void)
{ unsigned character recd;
  recd = UART1_SR;
  if(1 == UART1_SR_RXNE) recd = UART1_DR;

etc. No good, I continually get interrupts, UART1_SR_RXNE is set, but UART1_DR is empty, and no UART receive has happened. I have disabled all other interrupts I can see that can vector to this, and still no good. The SPI also sets this flag, presumably the the UART and SPI cannot be used together. I sorely need to get this serial receive interrupt going. Please help. Thank you

Answer

user3824211 picture user3824211 · Nov 3, 2016

The problem was one bit incorrectly set in the UART1 setup. The complete setup for the UART1 in the STM8S103F3 is now(IAR):

  void InitialiseUART()
{       
    unsigned char tmp = UART1_SR;
    tmp = UART1_DR;
    //  Reset the UART registers to the reset values.
    UART1_CR1 = 0;
    UART1_CR2 = 0;
    UART1_CR4 = 0;
    UART1_CR3 = 0;
    UART1_CR5 = 0;
    UART1_GTR = 0;
    UART1_PSCR = 0;
    //  Set up the port to 14400,n,8,2.
    UART1_CR1_M    = 0;         //  8 Data bits.
    UART1_CR1_PCEN = 0;         //  Disable parity.
    UART1_CR3      = 0x20;      //  2 stop bits     
    UART1_BRR2     = 0x07;      //  Set the baud rate registers to 14400
    UART1_BRR1     = 0x45;      //  based upon a 16 MHz system clock.
    //  Disable the transmitter and receiver.
    UART1_CR2_TEN   = 0;        //  Disable transmit.
    UART1_CR2_REN   = 0;        //  Disable receive.
    //  Set the clock polarity, clock phase and last bit clock pulse.
    UART1_CR3_CPOL  = 0;
    UART1_CR3_CPHA  = 0;
    UART1_CR3_LBCL  = 0;
    //  Set the Receive Interrupt RM0016 p358,362
    UART1_CR2_TIEN  = 0;     // Transmitter interrupt enable
    UART1_CR2_TCIEN = 0;     // Transmission complete interrupt enable
    UART1_CR2_RIEN  = 1;     //  Receiver interrupt enable
    UART1_CR2_ILIEN = 0;     //  IDLE Line interrupt enable

    //  Turn on the UART transmit, receive and the UART clock.
    UART1_CR2_TEN    = 1;
    UART1_CR2_REN    = 1;
    UART1_CR1_PIEN   = 0;
    UART1_CR4_LBDIEN = 0;
    }
    //-----------------------------
    #pragma vector = UART1_R_RXNE_vector
    __interrupt void UART1_IRQHandler(void)
    {
      byte recd;
      recd = UART1_DR;
      //send the byte to circular buffer;
    }