La recepción de UART no funciona en STM8S

Soy nuevo en stm8 (stm8s003f3p). He realizado el siguiente código, pero no pude encontrar el problema. La transmisión UART está funcionando pero no pudo recibir nada.

#include <iostm8s003f3.h>
#include <intrinsics.h>
#include <stdio.h>

void InitialiseSystemClock()
{
    CLK_ICKR = 0;                       //  Reset the Internal Clock Register.
    CLK_ICKR_HSIEN = 1;                 //  Enable the HSI.
    CLK_ECKR = 0;                       //  Disable the external clock.
    while (CLK_ICKR_HSIRDY == 0);       //  Wait for the HSI to be ready for use.
    CLK_CKDIVR = 0;                     //  Ensure the clocks are running at full speed.
    CLK_PCKENR1 = 0xff;                 //  Enable all peripheral clocks.
    CLK_PCKENR2 = 0xff;                 //  Ditto.
    CLK_CCOR = 0;                       //  Turn off CCO.
    CLK_HSITRIMR = 0;                   //  Turn off any HSIU trimming.
    CLK_SWIMCCR = 0;                    //  Set SWIM to run at clock / 2.
    CLK_SWR = 0xe1;                     //  Use HSI as the clock source.
    CLK_SWCR = 0;                       //  Reset the clock switch control register.
    CLK_SWCR_SWEN = 1;                  //  Enable switching.
    while (CLK_SWCR_SWBSY != 0);        //  Pause while the clock switch isbusy.
}

void InitialiseUART()
{
    unsigned char tmp = UART1_SR;
    tmp = UART1_DR;
    UART1_CR1 = 0;
    UART1_CR2 = 0;
    UART1_CR4 = 0;
    UART1_CR3 = 0;
    UART1_CR5 = 0;
    UART1_GTR = 0;
    UART1_PSCR = 0;
    UART1_CR1_M = 0;        //  8 Data bits.
    UART1_CR1_PCEN = 0;     //  Disable parity.
    UART1_CR3_STOP = 0;     //  1 stop bit.
    UART1_BRR2 = 0x02;      //  Set the baud rate registers to 9600 baud
    UART1_BRR1 = 0x68;      //  based upon a 16 MHz system clock.
    UART1_CR2_TEN = 0;      //  Disable transmit.
    UART1_CR2_REN = 0;      //  Disable receive.
    UART1_CR3_CPOL = 1;
    UART1_CR3_CPHA = 1;
    UART1_CR3_LBCL = 1;
    UART1_CR2_TEN = 1;
    UART1_CR2_REN = 1;
    UART1_CR3_CKEN = 1;
}

void UARTPrintF(char *message)
{
    char *ch = message;
    while (*ch)
    {
        UART1_DR = (unsigned char) *ch;     //  Put the next character into the data transmission register.
        while (UART1_SR_TXE == 0);          //  Wait for transmission to complete.
        ch++;                               //  Grab the next character.
    }
}

unsigned char RecUART1(void)
{
    while (!(UART1_SR_RXNE));    // USART_SR[5]:RXNE   Read data register not empty
    PD_ODR |= (1<<2);                                      //   0: Data is not received, 1: Received data is ready to be read.
    return UART1_DR;
}

int main( void )
{
    unsigned char out;
    char dis[25];
    // PD_DDR = (1<<5)|(1<<2);
    //PD_CR1 |= (1<<2);
    //*out ='l';
    //in=out;
    __disable_interrupt();
    InitialiseSystemClock();
    InitialiseUART();
    __enable_interrupt();
    while (1)
    {
        out = RecUART1();

        //for (long counter = 0; counter < 250000; counter++);
        sprintf(dis,"this is %c\n",out);
        UARTPrintF(dis);
    }
}
¿No funciona significa que se está atascando while (!(UART1_SR_RXNE)); ?
No, no se queda atascado allí. En cambio, el valor en el registro de DATOS UART no se actualiza.
Gracias por la pregunta y la respuesta, eso me salvó la vida... Encontré que en el manual de referencia oficial (RM0016), página 81, capítulo 9.1.2, hay una nota que dice: 'Al inicio, la fuente del reloj maestro se selecciona automáticamente como salida de reloj HSI RC dividida por 8 (fHSI/8).'. Una vez que cualquier carácter recibido o transmitido a través de UART fue 0x00, después de agregar los códigos de yogesh singh, UART funcionó bien. Los baudios se calculan a partir de fMatser (en BBR1 y BBR2), ya que los fMaster se dividieron entre 8, los baudios son incorrectos en mi caso.

Respuestas (1)

El problema se resuelve comentando HSI

#include <iostm8s003f3.h>
#include <intrinsics.h>
#include <stdio.h>

void InitialiseSystemClock()
{
 CLK_ICKR = 0;                       //  Reset the Internal Clock Register.
 //CLK_ICKR_HSIEN = 1;                 //  Enable the HSI.
 CLK_ECKR = 0;                       //  Disable the external clock.
 //while (CLK_ICKR_HSIRDY == 0);       //  Wait for the HSI to be ready for     use.
CLK_CKDIVR = 0;                     //  Ensure the clocks are running at full speed.
CLK_PCKENR1 = 0xff;                 //  Enable all peripheral clocks.
CLK_PCKENR2 = 0xff;                 //  Ditto.
CLK_CCOR = 0;                       //  Turn off CCO.
CLK_HSITRIMR = 0;                   //  Turn off any HSIU trimming.
CLK_SWIMCCR = 0;                    //  Set SWIM to run at clock / 2.
CLK_SWR = 0xe1;                     //  Use HSI as the clock source.
CLK_SWCR = 0;                       //  Reset the clock switch control register.
CLK_SWCR_SWEN = 1;                  //  Enable switching.
while (CLK_SWCR_SWBSY != 0);        //  Pause while the clock switch isbusy.
}

mientras que el resto del programa es el mismo.

¿Alguien podría explicarme esto? Funcionó, pero no sé cómo y por qué?

¿Deshabilitaste el Oscilador Interno? ¿Y funcionó? ¿qué clase de brujería es esta?
No sé, tal vez por defecto, stm8s funciona a 16 mhz y no lo deshabilité, simplemente no lo habilité. Si está destinado a ejecutarse de forma predeterminada a 16 MHz, debe habilitarse. No entiendo qué problema ocurrió cuando lo habilitó específicamente en mi código.
Bueno. Comentó la línea del reloj interno y deshabilitó el reloj externo; por lo que tomó oscilador interno por defecto.
No estoy seguro, ya que nada de esto está escrito en la hoja de datos o en el manual de referencia.