Electronic – Configure Serial with registers on STM32l073RZ

configurationmbedregisterserialstm32

I'm trying to configure the Serial of my STM32L073RZ with registers to send datas on the PA_9 pin.
Currently I have this script

#include "mbed.h"

void usartSetup (void) {
    RCC->IOPENR |= RCC_IOPENR_IOPAEN;
    GPIOA->ODR |= GPIO_ODR_OD9;
    RCC->APB2ENR |= RCC_APB2ENR_USART1EN;            // enable clock for USART1
    USART1->BRR  = 160000 / 96;              // set baudrate
    USART1->CR1 |= (USART_CR1_RE | USART_CR1_TE);  // RX, TX enable
    USART1->CR1 |= USART_CR1_UE;                    // USART enable
}

void SendChar(){
    while (!(USART1->ISR & (USART1->ISR | USART_ISR_TXE)));
    char stringtosend[4];
    stringtosend[0] = 'T';
    stringtosend[1] = 'e';
    stringtosend[2] = 'x';
    stringtosend[3] = 't';
    for(int send = 0; send < 4; send++){
        USART1->TDR = stringtosend[send];
    }
}

int main() {
    usartSetup();
    SendChar();
}

You can also see my project here on the mbed website

When I display the pin state with my oscilloscope this one is always to zero.

Does anyone can help me ?

Thank you !

EDIT:

Below you can see my current script, it work fine for write and read something, I juste want to configure external clock on the PB_5 pin but it's note working. I also try to configure the UART in smart card mode

#include "mbed.h"

void board_init(void){
    RCC->IOPENR |= RCC_IOPENR_IOPBEN;
    RCC->APB2ENR |= RCC_APB2ENR_USART1EN;            // enable clock for USART1
    USART1->BRR  = 320000 / 96;              // set baudrate

    GPIOB->MODER &= ~GPIO_MODER_MODE5_0;
    GPIOB->MODER |= GPIO_MODER_MODE5_1;

    GPIOB->MODER &= ~GPIO_MODER_MODE6_0;
    GPIOB->MODER |= GPIO_MODER_MODE6_1;

    GPIOB->MODER &= ~GPIO_MODER_MODE7_0;
    GPIOB->MODER |= GPIO_MODER_MODE7_1;

    GPIOB->AFR[1] |= 0x500000;
    GPIOB->OTYPER &= ~GPIO_OTYPER_OT_5;
    GPIOB->OTYPER &= ~GPIO_OTYPER_OT_6;
    GPIOB->OTYPER |= GPIO_OTYPER_OT_7;

    USART1->CR3 |= USART_CR3_DMAT;

    //Secure element part
    USART1->CR2 &= ~USART_CR2_LINEN;
    USART1->CR3 &= ~USART_CR3_HDSEL;
    USART1->CR3 &= ~USART_CR3_IREN;
    USART1->CR3 |= USART_CR3_SCEN;
    USART1->GTPR = 32 >> 1;
    USART1->CR2 |= USART_CR2_CLKEN;
    USART1->CR3 |= SMARTCARD_NACK_ENABLE;
    USART1->CR2 |= SMARTCARD_STOPBITS_1_5;
    USART1->CR1 |= USART_CR1_PCE;


    USART1->CR1 |= (USART_CR1_UE | USART_WORDLENGTH_8B);  // RX, TX enable
    USART1->CR1 &= ~USART_CR1_RE;
    USART1->CR1 &= ~USART_CR1_TE;
}

void delay(int cnt) {
    while (cnt-- > 0) {
        asm("nop");
    }
}

int usart_rec(void) {
    /* Wait until the data is ready to be received. */
    while ((USART1->ISR & USART_ISR_RXNE) == 0);

    // read RX data, combine with DR mask (we only accept a max of 9 Bits)
    return USART1->RDR & 0x1FF;
}

void usart_rec_str(int array[], int sizeArray){
    USART1->CR1 |= USART_CR1_RE | USART_CR1_TE;
    for(;;){
        pcMain.printf("%i",usart_rec());
    }
    USART1->CR1 &= ~USART_CR1_RE;
    USART1->CR1 &= ~USART_CR1_TE;
}

void usart_snd(int data) {
    USART1->TDR = data;

    // wait for TX
    while ((USART1->ISR & USART_ISR_TXE) == 0);
}

void usart_snd_str(char *str) {
    USART1->CR1 |= USART_CR1_TE;
    int   i = 0;
    while(str[i] != 0) {
        usart_snd(str[i++]);
    }
    USART1->CR1 &= ~USART_CR1_TE;
}

void usart_snd_str(int array[], int size) {
    USART1->CR1 |= USART_CR1_TE;
    for(int j = 0; j<size; j++) {
        // read blocking form usart
        usart_snd(array[j]);
    }
    USART1->CR1 &= ~USART_CR1_TE;
}

Best Answer

There are a few apparent problems

  • TX pin is not configured for the serial port, presumably it's still in analog mode after reset. You should set it to alternate function mode in GPIOA->MODER, and assign it to USART1 in GPIOA->AFRH. The alternate function numbers are listed in the datasheet, not in the reference manual.

  • You should check USART_ISR_TXE each time before writing to TDR, waiting until it becomes 1.

  • while (!(USART1->ISR & (USART1->ISR | USART_ISR_TXE)));

This expression is nonsense.

  • GPIOA->ODR |= GPIO_ODR_OD9;

This is unnecessary. Setting ODR has no effect unless the pin is set as output.

Related Topic