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 inGPIOA->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 toTDR
, 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.