1
\$\begingroup\$

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;
}
\$\endgroup\$
2
\$\begingroup\$

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.

\$\endgroup\$
  • \$\begingroup\$ Thanks a lot for your help ! This work fine now, I can read and write somthing on the selected Pins. I have one more question. I'm trying to configure the PB_5 pin in external clock. I'll add in few minutes my actual script but the clock is not enable at the end... Can you help me for that ? Again thank you \$\endgroup\$ – Simon NOWAK Apr 10 '17 at 13:06
  • \$\begingroup\$ Please ask separate questions for separate topics. The goal of StackExchange is the build a collection of questions and matching answers that don't just help once but many times. \$\endgroup\$ – Codo Oct 29 '17 at 9:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.