2019-08-02 09:13 PM
I am new to embedded programming and trying to learn ARM with my STM32L4 board. I stick to the datasheet and stay away from HAL library to learn how the MCU and its peripherals work. Here I am trying to initiate USART3 and send a line using "printf" but fail to receive anydata from my FTDI chip. Did I miss something here?
#include <stdio.h>
#include <stdint.h>
#include "kfunction.h"
#include "kstm32l4r5xx.h"
/*--Define--------------------------------------------------------------------------------*/
/*--Global-Variable---------------------------------------------------------------------- */
/*--Function Prototypes-------------------------------------------------------------------*/
void initUSART3(void);
void initRCC(void);
void blinkBLUE(void);
void initPORT(void);
int putchar(int);
/*--Main----------------------------------------------------------------------------------*/
int main()
{
initRCC();
initPORT();
initUSART3();
while(1)
{
blinkBLUE();
printf("this is USART3");
putchar(12);
}
} // EO Main
/*--Function------------------------------------------------------------------------------*/
/************************************************/
/* Name: initUSART3 */
/*-Initiating USART3 for STM32L4R5xx */
/*-Oversampling 8 (OVER8=default/0) */
/*-Baudrate: 9600-USARTDIV=4Mhz/9600=0x1A0(416) */
/* */
/************************************************/
void initUSART3(void)
{
USART3_BRR |= 0x1A0U; //select baudrate for USART3=9600 <---edit baudrate first
USART3_CR1 |= 0x9U; // enable USART3 - Transmit Enable <---enable USART after that
}
/************************************************/
/* Name: initRCC */
/*-Initiating RCC for STM32L4R5xx */
/*-MCU run on MSI clock 4Mhz(reset value) */
/*-Open Clock Gate for USART3 */
/*-Open AHB2 clockgate */
/* */
/************************************************/
void initRCC(void)
{
RCC_APB1ENR1 |= 1U<<18; //USART3 clockgate enable
RCC_AHB2ENR |= (1<<1); // Enable PB
RCC_AHB2ENR |= (1<<3); //Enable PD
}
/************************************************/
/* Name: Blink LED */
/*-Blink LED on port B 7 with delay() */
/* */
/************************************************/
void blinkBLUE(void)
{
delay();
GIPOB_ODR ^= (1<<7); // PB7 output = 1
delay();
GIPOB_ODR |= (1<<7); // PB7 output = 1
}
/************************************************/
/* Name: initPORTB */
/*-initial PORTB */
/* */
/************************************************/
void initPORT(void)
{
GPIOB_MODER ^= (1U<<15); // Config PB7 general output
GIPOB_ODR |= (1U<<7); // PB7 output = 1
GPIOD_MODER ^= (1U<<17); // Config PD8 general output-USART3 TX
GPIOD_MODER |= (1U<<16); // Config PD8 general output-USART3 TX <---Set PORTD_8/USART3_TX as general output
}
/************************************************/
/* Name: putchar */
/*-printf() from stdlib use putchar() for output*/
/* putchar() is device specific, so we need to */
/* supply it */
/* */
/************************************************/
int putchar(int c)
{
while(!USART3_TXE); //<--define in header file
USART3_TDR = c;
return(c);
}
Solved! Go to Solution.
2019-08-04 11:16 AM
I documented all the thing I went through and the final code, for people, who happen to have a similar problem, may find it useful for them somehow someday. I known it's silly, because I am a rookie
My name is not strange.
2019-08-10 12:16 AM
Agreed that _VAL2FLD() and _FLD2VAL() macros defined in CMSIS headers can be useful. Additionally I'll share my two even more useful macros:
#define REG_MOD_FIELD(rReg, xFld, xVal) ( (rReg) = ((uint32_t)(rReg) & ~xFld##_Msk) | (((uint32_t)(xVal) << xFld##_Pos) & xFld##_Msk) )
#define REG_MOD_BITS(rReg, fClr, fSet, iPos) ( (rReg) = ((uint32_t)(rReg) & ~((uint32_t)(fClr) << (iPos))) | ((uint32_t)(fSet) << (iPos)) )
Basically these add a clearing of the previous values.