Skip to main content
Visitor II
May 13, 2025
Question

USART1 problem to setup without configurator

  • May 13, 2025
  • 3 replies
  • 728 views
Hi at everyone,
I need to write a code without the Cube IDE configurator, due to save program memory. I tryed to configure the USAR1, but seem not output on the pin the data streem. Seem that the machine runs because, at the first, I tryed to transmit in polling mode cheching the TXE flag to charge the the TDR register, but not data goes to the pin, but rather, the TX pin seem on high impedence. I forgot something.
Below the USART init :
RCC_CCIPR &= 0xfffffffc; //USART1 clock on system clock
RCC_APBENR2 |= 0x00004000; //USART1 clock enable
RCC_IOPENR |= 0x00000005; //GPIOC clock enable

PORTC_MODER &= 0xefffffff; //set PC14 as alternate function
PORTC_AFRH &= 0xf0ffffff; //set PC14 as TxD function
PORTC_OTYPER &= 0xffffbfff; //PC14 PP mode

USART1_CR1 |= 0x00000001; //USART1 enabled
USART1_CR1 &= 0xefffefff; //8 bit data length
USART1_CR3 = 0x00002000; //DMA disable
USART1_BRR = 0x000001a1; //115200

USART1_CR1 |= 0x00000008; //TX enabled
// USART1_CR1 |= 0x00000004; //RX enabled

The TXD pin is on GPIOC14

then into the main program call every 1 second the follow procedure:
void uart_polling_send(const uint8_t *pData, uint16_t Size, uint16_t Timeout)
{
const uint8_t *pdata8bits;

pdata8bits = pData;

//USART1_CR1 |= 0x00000008; //TX enabled

 while(Size > 0U)
 {
PORTC_ODR ^= 0x8000;
 while((USART1_ISR & 0x00000080) == 0) //check TXE flag
 {
 //here will manage the timeout
 }

 USART1_TDR = (uint8_t)(*pdata8bits & 0xFFU);
 pdata8bits++;
 Size--;
 }
while((USART1_ISR & 0x00000040) == 0) //check TC flag
{
//here will manage the timeout
}
}
Using the "PORTC_ODR ^= 0x8000;" instuction I can check how many time execute and how is the execution time (using an oscilloscope). Seem works the flow into the procedure, but as I say the peripheral pin not work. Why?
Thank you at all!
Valter

 

    This topic has been closed for replies.

    3 replies

    Super User
    May 13, 2025

    Welcome to the forum.

    Please see How to write your question to maximize your chances to find a solution; in particular How to insert source code.

    You haven't said what chip you're using, or what board it's on.

    Please also show the complete code.

     


    @VSimo.18 wrote:
    I need to write a code without the Cube IDE configurator, due to save program memory.

    Have you tried with the configurator first ?

    You could take that as your basis, and then optimise it if required...

    VSimo.18Author
    Visitor II
    May 13, 2025

    Hi Andrew,
    yes I tryed with configurator and works, but the code to big.
    the coplete code is the main file into it is called the USART1_init, and after into the "while(1)" is called the uart_polling_send to send data out of the USART.
    could you see any mistake o maybe some lacke in the init flow. I read the data sheet more then one time and I verified to need
    enable USART cloc,.
    enable GPIOC clock,
    select USART clock on SYSClock is on default, but I forced it in any case,
    select PC14 as alternate function.
    select AF0 (USART1),
    select PC14 as push-pull (I don't know if necessary),
    enable UART1,
    set USART1 without fifo,
    enable TX.....

    but the PC14 stays on high inpedenze.
    Notice, if I comment the "select PC14 as alternate function", it possible to drive the PC14 writing on ODR register, otherwise PC14 isn't driven. Seem the select PC14 as alternate function works, bat because the fisical pin is on high inpedence? I don't understud.

    Note:

    Thank you of "Please see How to write your question to maximize your chances to find a solution; in particular How to insert source code.", and sorry.

    Valter

     

    Graduate II
    May 13, 2025

    0x4000 would be PC14

    0x8000 is PC15, ie (1 << 15)

    Graduate II
    May 13, 2025

    Dump the registers for GPIOx and RCC, so you know what's in them

    Don't use RMW on the SAME register on multiple lines, it's NOT efficient

    Use USART1_CR1 = (USART1_CR1 & ~clear_bits) | set_bits; // so the compile can fold the operation

    Don't immediately touch the peripheral who's clock you've enabled, reorder things, say enable GPIOA/GPIOC clocks, then USART1 clock, then touch GPIOC->xx registers, so you've given the pipeline/write-buffer a chance to work.

    Correctly comment the lines

    Initialize PC15 properly as a OUTPUT-PP, be aware PC13..15 have LOW CURRENT drivers

    VSimo.18Author
    Visitor II
    May 14, 2025

    Update guys,
    I tryed the change suggested from Tesla, but no effect I saw.

    	RCC_IOPENR |= 0x00000005;			//GPIOA & GPIOC clock enable
    	RCC_CCIPR &= 0xfffffffc;			//USART1 clock enable on system clock
    	RCC_APBENR2 |= 0x00004000;			//USART1 clock enable
    HAL_Delay(100);
    
    //USART1_CR1 |= 0x00000001;		//USART1 enabled
    USART1_CR1 = USART1_CR1 | 0x00000001;		//USART1 enabled
    	USART1_CR1 &= 0xefffefff;		//8 bit data length
    	USART1_CR3 = 0x00002000;		//DMA disable
    	USART1_BRR = 0x000001a1;		//115200
    
    //	USART1_CR1 |= 0x00000008;		//TX enabled
    	USART1_CR1 = USART1_CR1 | 0x00000008;		//TX enabled
    //	USART1_CR1 |= 0x00000004;		//RX enabled
    
    //USART1_TX on PC14
    //	PORTC_MODER &= 0xefffffff;		//set PC14 as alternate function
    	PORTC_MODER = PORTC_MODER & 0xefffffff;		//set PC14 as alternate function
    //	PORTC_AFRH &= 0xf0ffffff;		//set PC14 as TxD function
    	PORTC_AFRH = PORTC_AFRH & 0xf0ffffff;		//set PC14 as TxD function
    //	PORTC_OTYPER &= 0xffffbfff;		//PC14 PP mode
    	PORTC_OTYPER = PORTC_OTYPER & 0xffffbfff;		//PC14 PP mode


    Then I tryed to set another port on TxD, PB6 writing relative register and so at the pin I can see the the frame.
    Mistery.

    	//USART1_TX on PB6
    	//	PORTB_MODER &= 0xffffefff;		//set PB6 as alternate function
    		PORTB_MODER = PORTB_MODER & 0xffffefff;		//set PB6 as alternate function
    	//	PORTB_AFRL &= 0xf0ffffff;		//set PB6 as TxD function
    		PORTB_AFRL = PORTB_AFRL & 0xf0ffffff;		//set PB6 as TxD function
    	//	PORTB_OTYPER &= 0xffffffbf;		//PB6 PP mode
    		PORTB_OTYPER = PORTB_OTYPER & 0xffffffbf;		//PB6 PP mode*/


    Now I arrange my project to redirect the new pins.
    I have another different question about the name of interrupt handle procedure. I can ask here or I have to open anoter post.
    Thank you for your patience.
    Valter