UART-Empfang funktioniert nicht in STM8S

Ich bin neu bei stm8 (stm8s003f3p). Ich habe den folgenden Code ausgeführt, konnte aber nicht finden, was daran falsch ist. UART-Übertragung funktioniert, konnte aber nichts empfangen.

#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);
    }
}
Funktioniert nicht bedeutet Bleibt es stecken while (!(UART1_SR_RXNE)); ?
Nein, da bleibt es nicht hängen. Stattdessen wird der Wert im UART DATA-Register nicht aktualisiert.
Danke für die Frage und die Antwort, das hat mir das Leben gerettet... Ich habe im offiziellen Referenzhandbuch (RM0016), Seite 81, Kapitel 9.1.2, einen Hinweis gefunden: 'Beim Start wird automatisch die Master-Clock-Quelle ausgewählt als HSI-RC-Taktausgang dividiert durch 8 (fHSI/8).'. Sobald jedes Zeichen, das über UART empfangen oder übertragen wurde, 0x00 war, nachdem ich die Codes von Yogesh Singh hinzugefügt hatte, funktionierte der UART einwandfrei. Die Baud werden aus fMatser berechnet (in BBR1 und BBR2), da die fMaster durch 8 geteilt wurden, sind die Baud in meinem Fall falsch.

Antworten (1)

Das Problem wird gelöst, indem HSI kommentiert wird

#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.
}

während der Rest des Programms gleich ist.

Könnte mir das jemand erklären. Es hat funktioniert, aber ich weiß nicht wie und warum?

Sie haben den internen Oszillator deaktiviert? und es hat funktioniert? was ist das für eine Zauberei?
Ich weiß nicht, vielleicht arbeiten stm8s standardmäßig mit 16 MHz und ich habe es nicht deaktiviert, ich habe es nur nicht aktiviert. Wenn es standardmäßig mit 16 MHz laufen soll, muss es aktiviert sein. Ich verstehe nicht, welches Problem aufgetreten ist, als es speziell in meinem Code aktiviert wurde.
Okay. Sie haben die Zeile Internal Clock kommentiert und die externe Clock deaktiviert; Daher wurde der interne Oszillator als Standard verwendet.
Ich weiß es nicht genau, da nichts dergleichen im Datenblatt oder Referenzhandbuch geschrieben steht.