USART1 problem to setup without configurator
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-05-13 7:26 AM - last edited on ‎2025-05-13 9:50 AM by mƎALLEm
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
}
}
- Labels:
-
STM32C0 Series
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-05-13 7:38 AM - edited ‎2025-05-13 7:38 AM
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...
A complex system designed from scratch never works and cannot be patched up to make it work.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-05-13 8:04 AM
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
Up vote any posts that you find helpful, it shows what's working..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-05-13 8:23 AM
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-05-13 8:36 AM
0x4000 would be PC14
0x8000 is PC15, ie (1 << 15)
Up vote any posts that you find helpful, it shows what's working..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-05-13 8:43 AM
@VSimo.18 wrote:yes I tryed with configurator and works,
So compare & contrast what your code does against what the conifgurator's code does.
Or just take the configurator's code, and cut it down to your requirements.
A complex system designed from scratch never works and cannot be patched up to make it work.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-05-13 8:43 AM
Yes I use UART1_TX on PC14.
I try to follow your previous advises.
Valter
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-05-13 8:54 AM
Yes I thinked to do in this way, but it is the first time that I use a STM and the CUBE, and it is not frendly for me, instede I use to use directly the registers (on Renesas, Microchip and Motorola, in the past, 32 bits MCU).
In the project builded with the configurator I send all the registers value to the USART, and seem are the same that I set "manually".
But as I said into the polling procedure seem to works correctly, as the clock is preset and the registers are correct. That is very strange is that the TX pin, connected to the oscilloscope, not show anyting, rather if touched by finger show as it is high impedenze. As if it is not connected to the peripheral.
Valter
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-05-14 12:47 AM
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
