I am writing register level code for STM32F4 & in my code there is a timer for calculation of the frequency of an input signal.
I am trying to implement a UART for sending calculated data to another MCU.
The other MCU is an Arduino and it has the desired program in it for receiving a value (in code there is a start and finish bits for every taken value, for example Frequency is 10kHz, sending value should be like that "/10000*".
The Arduino program is written with libraries. There is just serial.read, serial.being stuff in here. I want to write my STM code in register level and without libraries.
I know details of UART and I set the required bits for config of the UART. I am stuck with the part of how STM convert the data to bits of the UART, like using ASCII or something I can't find.
For example sending "hello world" since there is no parallel communication in here, sending everything singularly like sending 'h' after that 'e' goes like this? Thank you for reading.
NOTE: I am not using interrupt or DMA. sending a data in loop for now.
NOTE2: I am planning to use RS232 between MCUs.
-
\$\begingroup\$ It is difficult to understand what is the question or problem. Are you simply looking for sprintf or something like that to convert a number variable to text string to send it one digit at a time over UART as text? That has almost nothing to do with STM32, UART or electrical engineering, not even if RS232 is used between MCUs, it does not change things. \$\endgroup\$– JustmeCommented Feb 2 at 21:10
-
\$\begingroup\$ Since uart sending bunch of zero and one. I am confused how the stuff works on the back. The data bits on uart how they are written with sprintf. Is it mentioned on STMs manuals i can't see. \$\endgroup\$– MSBCommented Feb 2 at 21:21
2 Answers
UART sends bytes.
You need to use any generic C programming constructs to convert an integer variable into text string, which is a completely separate problem unrelated to MCUs, STM32 manuals, UART, or RS-232.
In plain C language, use sprintf which is a standard C library function, or feel free to roll your own function, which could use modulo 10 and division by 10 to extract each digit (0..9) and convert the resulting digit to ASCII symbols ('0'..'9').
Since you seem familiar with Arduino, you can read Arduino source code how it prints numbers, but I already described it above.
Blocking transmit using the UART register interface works something like this (after everything like baud rate is configured):
- Loop reading the UART status byte, until the "transmit empty" flag is set.
- Write one character to the data holding register
- Repeat steps 1 and 2 until the end of the message is reached.
Code example
for( const char* p = msg; *p; ++p ) {
while ((USARTn->SR & USART_SR_TXE) == 0) {}
USARTn->DR = *p;
}
A more complete solution would limit the time spent waiting for the UART to become ready, in case it wasn't correctly configured or was stopped by flow control.
-
\$\begingroup\$ The problem wasn't how to send individual characters of a string one at a time. The problem was how to convert an integer variable into a string of printable digits. \$\endgroup\$– JustmeCommented Feb 2 at 23:42
-
\$\begingroup\$ @Justme: Could be. The question wasn't clear. The actual wording was about creating the serial bitstream, and the answer is you don't, you supply one byte at a time and the USART module clocks out the bits. \$\endgroup\$ Commented Feb 4 at 0:03
-
\$\begingroup\$ Yes but both answers are inform me about things i don't know. Thanks \$\endgroup\$– MSBCommented Feb 4 at 22:59
-
\$\begingroup\$ In my application Frequency measurement is used via input capture mode timer. I am worried about what happens if timer triggers while UART interrupt middle of sending bytes. The founding Frequency value wouldn't be dalayed or corrupted (wrong). Maybe I need to write a condition for to wait until Frequency measured send it know after transmit complated you can calculate New Frequency value. \$\endgroup\$– MSBCommented Feb 4 at 23:07
-
1\$\begingroup\$ @MSB: The input capture will store the timer value without needing any CPU time, so that isn't affected by UART interrupt. Being busy with a higher priority interrupt could affect whether you read the timer register before it gets overwritten (more or less likely, depending on how fast the input frequency you're measuring is). Interrupt priorities are configurable, and it's often a good idea to set a higher interrupt priority on data collection than data transmission. \$\endgroup\$ Commented Feb 5 at 15:49