Forum: Mikrocontroller und Digitale Elektronik UART konfiguration STM32F030XC


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von flo (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,
ich versuche gerade die UART3 des STM32F32030XC ans laufen zu kriegen 
aber es tut sich gar nichts.
Meine Vermutung ist, dass ich irgendwo in dem Code unten was vergessen 
habe und hoffe dass einer von euch mir einen Hinweis geben kann.

Vielen Dank dafür.
1
void UART3_Config(void)
2
{
3
4
    RCC->AHBENR |= RCC_AHBENR_GPIOCEN;    // Enable GPIO clock Port C
5
6
    /* Configure UART */
7
     GPIOC->MODER |= (GPIO_MODER_MODER10_1 | GPIO_MODER_MODER11_1);  // Switch to alternate function mode
8
     GPIOC->AFR[1] |= (GPIO_AFRH_AFSEL10 | GPIO_AFRH_AFSEL11);    // Select UART3 RX and TX
9
10
     RCC->APB1ENR |= RCC_APB1ENR_USART3EN;    // Enable clock UART3
11
12
     /* Clear UART Configuration */
13
     USART3->CR1 = 0x00000000;
14
     USART3->CR2 = 0x00000000;
15
     USART3->CR3 = 0x00000000;
16
17
     USART3->BRR = 2500;  // Set Baudrate to 19200
18
19
     USART3->CR1 |= (USART_CR1_TE | USART_CR1_RE);  // Enable TX and RX
20
     USART3->CR1 |= (USART_CR1_RXNEIE);    // Enable RX interrupt
21
22
     USART3->CR1 |= USART_CR1_UE;    // Enable UART
23
24
     NVIC_SetPriority(USART3_6_IRQn, 1);
25
     // Enable USART3 interrupts
26
     NVIC_EnableIRQ(USART3_6_IRQn);
27
}

von Pieter (Gast)


Bewertung
0 lesenswert
nicht lesenswert
UART3_Config..und wo ist der Rest?

von flo (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hier nochmal der IRQ Handler, main und die Clock config.
1
void USART3_6_IRQHandler(void)
2
{
3
  unsigned int test;
4
  // Test for RXNE pending interrupt
5
  if ((USART3->ISR & USART_ISR_RXNE) == USART_ISR_RXNE)
6
    {
7
      test = USART3->RDR;
8
      // RXNE flags automatically clears when reading RDR.
9
    }
10
}
11
12
13
void SystemClock_Config(void)
14
{
15
  RCC->CR |= RCC_CR_HSION;
16
17
  RCC->CFGR &= ~(RCC_CFGR_SW);
18
19
  while(!(RCC->CR & RCC_CR_HSIRDY));
20
21
  RCC->CR &= ~(RCC_CR_PLLON);
22
23
  FLASH->ACR |= FLASH_ACR_LATENCY;
24
25
  RCC->CFGR |= RCC_CFGR_PLLSRC_HSI_PREDIV;
26
27
  RCC->CFGR = (RCC_CFGR_PLLMUL12 | RCC_CFGR_PPRE_DIV1);
28
29
  RCC->CR |= RCC_CR_PLLON;
30
31
  while(!(RCC->CR & RCC_CR_PLLRDY));
32
33
  RCC->CFGR &= ~(RCC_CFGR_SW);
34
  RCC->CFGR |= RCC_CFGR_SW_PLL;
35
}
36
37
38
int main(void)
39
{
40
  SystemClock_Config();
41
  UART3_Config();
42
  Timer6_Config();
43
44
  while(1)
45
  {
46
      Delay_ms(1000);
47
      USART3->TDR = '#';
48
  }
49
}

von A. B. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
flo schrieb:
>      GPIOC->MODER |= (GPIO_MODER_MODER10_1 | GPIO_MODER_MODER11_1);  //
>      GPIOC->AFR[1] |= (GPIO_AFRH_AFSEL10 | GPIO_AFRH_AFSEL11);    //

Was sollen diese beiden Zeilen bewirken? Die machen nun nicht gerade 
das, was
in den Kommentaren steht. Ich würde mal gründlich lesen, was im RM zu 
den GPIO-Registern und im Datenblatt zu den AF steht. Und es schader 
auch nicht, in den
CMSIS Headern nachzusehen, was diese Makros eigentlich bedeuten.

UART3 liegt bei Port C auf AF01.

Das '|=' macht hier wenig Sinn, da damit ja höchstens Bits gesetzt 
werden können.
Zwar werden nach einem Reset die meisten (aber nicht alle!) Bits auf 0 
gesetzt,
aber spätestens, wenn man Pins *um*konfiguriert, fällt einem das auf die 
Füße.
Besser wäre es, mit GPIO_AFRH_AFSEL10_Msk erst alle Bits auszumaskieren 
(daher der Name _Msk) und dann die benötigten zu setzen.

Außerdem wäre es sinnvoll, erst AFR zu setzen, und erst danach den Port 
auf AF umzuschalten (sonst ist der --- wenn auch nur kurz --- eventuell 
auf eine andere AF eingestellt).

von Sergey (Gast)


Bewertung
-1 lesenswert
nicht lesenswert
Isn't it easier to use STM32CubeMX?

von Ben S. (bensch123)


Bewertung
-3 lesenswert
nicht lesenswert
Sergey schrieb:
> Isn't it easier to use STM32CubeMX?

Einfacher, aber das ist eher was für die Klicki-Bunti Fraktion.

von flo (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Danke für die Antworten, ich lese mich gerade ein und schaue was die 
Makros so bedeuten.

>Isn't it easier to use STM32CubeMX?
Es ist zwar einfacher aber die Hintergründe hat man dann noch nicht 
verstanden.

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Bewertung
0 lesenswert
nicht lesenswert
Zum Pinstatus setzen empfehle ich eine Funktion zu bauen um das nicht 
immer neu zu machen.
Das ist fehlerträchtig und nervt irgendwann ;)
Die Funktion bekommt:
- Port -> GPIOA/B/C usw, also direkt dieses Makro welches vom Typ 
"GPIO_TypeDef*" ist.
- Pinnummer
- modus (output, input, pulldown/up, alternate, etc)
- geschwindigkeit (davon gibts 4)
- alternate function als nummer (bei manchen L0 kommt ein UARt auch mal 
als verschiednene AF numemrnr aus, wodurch ein enum leider nicht geht)
Kann man auch in ein struct packen wen man will ud dann kan man den pin 
"uart3_rx" durch die Gegend schubsen im Programm.

Anstatt ein UART3_config zu schreiben wäre doch eine allgemeinere 
Funktion besser.
UART_config und es wird übergeben welcher uart da konfiguiert werden 
soll.
Beispiel:
1
void uart_init(USART_TypeDef* uart) {
2
  
3
  uart->CR1  = USART_CR1_FIFOEN | USART_CR1_TE | USART_CR1_RE;
4
  uart->CR1 |= USART_CR1_UE;
5
}

von Stefan ⛄ F. (stefanus)


Bewertung
0 lesenswert
nicht lesenswert
Die CMSIS, auf welcher auch die HAL aufbaut, enthält hilfreiche Makros 
zum Ändern einzelner Bits. Beispiel für USART1 auf dem STM32L073:
1
#include <stdio.h>
2
#include "stm32l0xx.h"
3
4
uint32_t SystemCoreClock=2097000;
5
6
// delay loop for the default 2.1 MHz CPU clock with optimizer enabled
7
void delay(uint32_t msec)
8
{
9
    for (uint32_t j=0; j < 419UL * msec; j++)
10
    {
11
        __NOP();
12
    }
13
}
14
15
// Redirect standard output to the serial port
16
int _write(int file, char *ptr, int len)
17
{
18
    for (int i=0; i<len; i++)
19
    {
20
        while(!(USART1->ISR & USART_ISR_TXE));
21
        USART1->TDR = *ptr++;
22
    }
23
    return len;
24
}
25
26
// Called after each received character
27
void USART1_IRQHandler(void)
28
{
29
    // read the received character
30
    char received=USART1->RDR;
31
32
    // send echo back
33
    while(!(USART1->ISR & USART_ISR_TXE));
34
    USART1->TDR = received;
35
}
36
37
int main(void)
38
{
39
    // Enable clock for Port A
40
    SET_BIT(RCC->IOPENR, RCC_IOPENR_GPIOAEN);
41
42
    // PA5 = Output for the LED
43
    MODIFY_REG(GPIOA->MODER, GPIO_MODER_MODE5, GPIO_MODER_MODE5_0);
44
45
    // Use system clock for USART1
46
    SET_BIT(RCC->APB2ENR, RCC_APB2ENR_USART1EN);
47
    MODIFY_REG(RCC->CCIPR, RCC_CCIPR_USART1SEL, RCC_CCIPR_USART1SEL_0);
48
49
    // PA9 (TxD) shall use the alternate function 4 (see data sheet)
50
    MODIFY_REG(GPIOA->AFR[1], GPIO_AFRH_AFSEL9, 4UL<<GPIO_AFRH_AFSEL9_Pos);
51
    MODIFY_REG(GPIOA->MODER, GPIO_MODER_MODE9, GPIO_MODER_MODE9_1);
52
53
    // PA10 (RxD) shall use the alternate function 4 (see data sheet)
54
    MODIFY_REG(GPIOA->AFR[1], GPIO_AFRH_AFSEL10, 4UL<<GPIO_AFRH_AFSEL10_Pos);
55
    MODIFY_REG(GPIOA->MODER, GPIO_MODER_MODE10, GPIO_MODER_MODE10_1);
56
57
    // Set baudrate
58
    USART1->BRR = (SystemCoreClock / 2400);
59
60
    // Enable transmitter, receiver and receive-interrupt of USART1
61
    USART1->CR1 = USART_CR1_UE + USART_CR1_TE + USART_CR1_RE + USART_CR1_RXNEIE;
62
63
    // Enable interrupt in NVIC
64
    NVIC_EnableIRQ(USART1_IRQn);
65
66
    while (1)
67
    {
68
        // LED on
69
        WRITE_REG(GPIOA->BSRR, GPIO_BSRR_BS_5);
70
        delay(500);
71
72
        puts("Hello");
73
74
        // LED off
75
        WRITE_REG(GPIOA->BSRR, GPIO_BSRR_BR_5);
76
        delay(500);
77
    }
78
}

: Bearbeitet durch User

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.