{"id":8887,"date":"2014-12-07T23:34:07","date_gmt":"2014-12-08T04:34:07","guid":{"rendered":"http:\/\/embedded-lab.com\/blog\/?p=8887"},"modified":"2023-04-20T23:03:33","modified_gmt":"2023-04-21T03:03:33","slug":"stm32-serial-communication","status":"publish","type":"post","link":"https:\/\/embedded-lab.com\/blog\/stm32-serial-communication\/","title":{"rendered":"STM32 Serial Communication"},"content":{"rendered":"<p>STM32 micros just like any other micro provide hardware for serial communication. As we all know serial communication is a very important tool for debugging, connecting with external hardware like RFID, GPS, GSM modems, etc. and for performing other communication-related tasks. STM32s have several hardware serial (USART) ports. The number of ports available in a STM32 micro is dependent on device family type and the device itself. Typically there are at least 5 serial ports. Apart from the basic serial communication needs, STM32\u2019s USART hardware also have support for LIN, one-wire, smart card protocols, SPI and IrDA. We can even utilize STM32\u2019s DMA controller with USART hardware to achieve high speed automated data communication. Thus these hardware are truly universal synchronous-asynchronous receiver-transmitters.<\/p>\n<p>In any standard serial communication, we need three wires \u2013 <b><i>TX, RX<\/i><\/b> and <b><i>GND<\/i><\/b>. TX pin is an output pin and transmits data serially to another device\u2019s RX pin. RX pin is an input pin and is responsible for receiving data from another device\u2019s TX pin. The two devices connected in this way must have same ground (GND). There are other pins like<b><i> CTS<\/i><\/b> and <b><i>RTS <\/i><\/b>which are used for hardware flow control. Additionally there\u2019s also another pin called <b><i>CK<\/i><\/b>. It is transmitter\u2019s clock output and used usually in SPI and other modes.<\/p>\n<p>Depending on package, USART pins are arranged in the following pattern:<\/p>\n<table border=\"1\" width=\"639\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td valign=\"bottom\"><b><i>BGA100<\/i><\/b><b><i><\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>LQFP100<\/i><\/b><b><i><\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>LQFP48<\/i><\/b><b><i><\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>LQFP64<\/i><\/b><b><i><\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>Pin Name<\/i><\/b><b><i><\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>USART\/UART<\/i><\/b><b><i><\/i><\/b><\/td>\n<\/tr>\n<tr>\n<td valign=\"bottom\"><b><i>D9<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>67<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>29<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>41<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>PA8<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>USART1_CK<\/i><\/b><\/td>\n<\/tr>\n<tr>\n<td valign=\"bottom\"><b><i>C10<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>70<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>32<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>44<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>PA11<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>USART1_CTS<\/i><\/b><\/td>\n<\/tr>\n<tr>\n<td valign=\"bottom\"><b><i>B10<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>71<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>33<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>45<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>PA12<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>USART1_RTS<\/i><\/b><\/td>\n<\/tr>\n<tr>\n<td valign=\"bottom\"><b><i>C9<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>68<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>30<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>42<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>PA9<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>USART1_TX<\/i><\/b><\/td>\n<\/tr>\n<tr>\n<td valign=\"bottom\"><b><i>D10<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>69<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>31<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>43<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>PA10<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>USART1_RX<\/i><\/b><\/td>\n<\/tr>\n<tr>\n<td valign=\"bottom\"><b><i>G3<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>29<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>14<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>20<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>PA4<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>USART2_CK<\/i><\/b><\/td>\n<\/tr>\n<tr>\n<td valign=\"bottom\"><b><i>G2<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>23<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>10<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>14<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>PA0<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>USART2_CTS<\/i><\/b><\/td>\n<\/tr>\n<tr>\n<td valign=\"bottom\"><b><i>H2<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>24<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>11<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>15<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>PA1<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>USART2_RTS<\/i><\/b><\/td>\n<\/tr>\n<tr>\n<td valign=\"bottom\"><b><i>J2<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>25<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>12<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>16<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>PA2<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>USART2_TX<\/i><\/b><\/td>\n<\/tr>\n<tr>\n<td valign=\"bottom\"><b><i>K2<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>26<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>13<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>17<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>PA3<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>USART2_RX<\/i><\/b><\/td>\n<\/tr>\n<tr>\n<td valign=\"bottom\"><b><i>K8<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>51<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>25<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>33<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>PB12<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>USART3_CK<\/i><\/b><\/td>\n<\/tr>\n<tr>\n<td valign=\"bottom\"><b><i>J8<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>52<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>26<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>34<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>PB13<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>USART3_CTS<\/i><\/b><\/td>\n<\/tr>\n<tr>\n<td valign=\"bottom\"><b><i>H8<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>53<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>27<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>35<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>PB14<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>USART3_RTS<\/i><\/b><\/td>\n<\/tr>\n<tr>\n<td valign=\"bottom\"><b><i>J7<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>47<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>21<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>29<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>PB10<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>USART3_TX<\/i><\/b><\/td>\n<\/tr>\n<tr>\n<td valign=\"bottom\"><b><i>K7<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>48<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>22<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>30<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>PB11<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>USART3_RX<\/i><\/b><\/td>\n<\/tr>\n<tr>\n<td valign=\"bottom\"><b><i>B8<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>79<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>&#8211;<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>52<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>PC11<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>UART4_RX<\/i><\/b><\/td>\n<\/tr>\n<tr>\n<td valign=\"bottom\"><b><i>B9<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>78<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>&#8211;<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>51<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>PC10<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>UART4_TX<\/i><\/b><\/td>\n<\/tr>\n<tr>\n<td valign=\"bottom\"><b><i>B7<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>83<\/i><\/b><\/td>\n<td valign=\"bottom\"><\/td>\n<td valign=\"bottom\"><b><i>54<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>PD2<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>UART5_RX<\/i><\/b><\/td>\n<\/tr>\n<tr>\n<td valign=\"bottom\"><b><i>C8<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>80<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>&#8211;<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>53<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>PC12<\/i><\/b><\/td>\n<td valign=\"bottom\"><b><i>UART5_TX<\/i><\/b><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Personally I&#8217;m interested in LQFP packages, particularly 48 and 64 packages as they are mostly used in the most common STM32 development boards. I suggest locating USART\/UART pins before working with them.<\/p>\n<p><!--more--><\/p>\n<p><b><i>Things to keep in mind<\/i><\/b><\/p>\n<ul>\n<li>Only USART1 can operate with clocks up to 72 MHz while the rest can operate at 36 MHz maximum. This is because USART1 can get full system clock while the others get half of that.<\/li>\n<li>USART1 is connected to the high speed APB2 bus while rest are connected to the lower speed APB1 bus. Most communication peripherals are connected with APB1 bus.<\/li>\n<li>GPIO pins associated with USART hardware must be set as alternate function I\/Os and it should be enabled before the hardware modules\u2019 use.<\/li>\n<li>TX pins should be set as low speed (2 MHz) AFIO push-pull outputs while RX pins should be set as floating inputs. RX pins can also be set as inputs with pull-ups or pull-downs if needed.<\/li>\n<li>If flow control is not used then the associated flow control pins can be left as GPIO pins. For instance PA8, PA11 and PA12 of USART1 can be used as GPIO pins if flow control is not needed.<\/li>\n<li>USART\/UART pins can be remapped using <b><i>AFIO_MAPR<\/i><\/b> register. By default, the default pins like PA9 and PA10 for USART1 are used and not remapped elsewhere because this register is by default cleared and hardware remapping is not enabled.<\/li>\n<li>In exception conditions, <b><i>APB1RSTR<\/i><\/b> and <b><i>APB2RSTR<\/i><\/b> registers can be used reset USART\/UART hardware.<\/li>\n<\/ul>\n<p>This is USART register map:<br \/>\n<a href=\"http:\/\/embedded-lab.com\/blog\/stm32-serial-communication\/usart-register-map\/\" rel=\"attachment wp-att-8888\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-8888\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2014\/07\/USART-Register-Map.png\" alt=\"USART Register Map\" width=\"705\" height=\"424\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2014\/07\/USART-Register-Map.png 705w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2014\/07\/USART-Register-Map-550x330.png 550w\" sizes=\"auto, (max-width: 705px) 100vw, 705px\" \/><\/a><br \/>\nFor better view check STM32F10x Reference Manual\u2019s (RM) page 799. These registers are all that are related to USART\/UART hardware. Although the registers are 32 bit wide, the upper nibbles are left unused and so they should be written 0s. This is done by hardware too.<\/p>\n<p>It should also be noted that STM32s operate at 3.3V and so avoid using 5V devices directly. Although some STM32 pins are 5V tolerant I would suggest avoiding 5V device interfacing. I will recommend using popular MAX232-based circuit for interfacing with RS232-level ports or USB-TTL converters like FT232, CP2102, PL2303, etc. for connecting with PCs and laptops. I\u2019m using a FT232R breakout board here.<\/p>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/stm32-serial-communication\/usart-hardware\/\" rel=\"attachment wp-att-8890\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-8890\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2014\/07\/USART-Hardware-1024x771.png\" alt=\"USART Hardware\" width=\"860\" height=\"647\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2014\/07\/USART-Hardware-1024x771.png 1024w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2014\/07\/USART-Hardware-550x414.png 550w\" sizes=\"auto, (max-width: 860px) 100vw, 860px\" \/><\/a><\/p>\n<p>If needed a logic level converter may also be used.<\/p>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/stm32-serial-communication\/logic-level-converters\/\" rel=\"attachment wp-att-8889\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-8889\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2014\/07\/Logic-Level-Converters-1024x639.png\" alt=\"Logic Level Converters\" width=\"860\" height=\"536\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2014\/07\/Logic-Level-Converters-1024x639.png 1024w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2014\/07\/Logic-Level-Converters-550x343.png 550w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2014\/07\/Logic-Level-Converters.png 1632w\" sizes=\"auto, (max-width: 860px) 100vw, 860px\" \/><\/a><\/p>\n<p><strong><em>Baud Rate Calculation<\/em><\/strong><\/p>\n<p>In most 8 bit micros when calculating baud rates for serial communication, baud rates are usually programmed to the nearest integer values, ignoring the fractional portions. This is completely the opposite in STM32s. One can also program the rounded fractional values too. It is not a complex process in any way. In any floating point number there are two parts \u2013 an integer part (before decimal) and a fractional part (after decimal). STM32\u2019s RM calls these parts in a mathematical literature as DIV_Mantissa and DIV_fraction.<\/p>\n<p>USART_BRR Register is responsible for keeping baud rate-related values.<\/p>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/stm32-serial-communication\/usart_brr-register\/\" rel=\"attachment wp-att-8891\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-8891\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2014\/07\/USART_BRR-Register.png\" alt=\"USART_BRR Register\" width=\"623\" height=\"220\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2014\/07\/USART_BRR-Register.png 623w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2014\/07\/USART_BRR-Register-550x194.png 550w\" sizes=\"auto, (max-width: 623px) 100vw, 623px\" \/><\/a><\/p>\n<p>As can be seen the lower four nibbles store the fractional part of baud calculation while the upper bits till reserved locations keep the integer part. The reserved portion should always be cleared (set as 0s).<\/p>\n<p>According to RM:<\/p>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/stm32-serial-communication\/formula\/\" rel=\"attachment wp-att-8892\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-8892\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2014\/07\/Formula.png\" alt=\"Formula\" width=\"276\" height=\"97\" \/><\/a><\/p>\n<p>For instance, suppose fCK is set to 8MHz and the baud rate for serial communication is set to 9600. In this case USART_BRR should be:<\/p>\n<p>USART_BRR = 8,000,000 \/ (9,600 x 16) = 52.083.<\/p>\n<p>Thus the mantissa will be 52 or 0x34 and the fractional part will be (16 x 0.083) = 1.3 approximately, after rounding it becomes 1 or 0x01;<\/p>\n<p>Now in the code we&#8217;ll have to shift the mantissa part four times or multiply by 16 as the mantissa starts from 4<sup>th<\/sup> position of USART_BRR register and then add 1 (fractional part) with it. Thus the USART_BRR will be loaded with (52 x \u00a0+ 1) = 833 or 0x341. We&#8217;ll be setting USART1 with this baud rate value in our code.<\/p>\n<p><strong><em>The Other Stuffs<\/em><\/strong><\/p>\n<p>Fortunately right after reset all USART\/UART registers have favorable default values as such that there\u2019s no parity and one stop bit. This is what we usually use. The <b><i>USART_DR<\/i><\/b> register is buffer that is responsible for data transmission and reception. Data to be sent to another device is written here while data to be received is also buffered here. However we need to know if there\u2019s a transmission or reception going one. To know this we can either use interrupt methods or read USART status register, <b><i>USART_SR <\/i><\/b>flags<b><i>.<\/i><\/b><\/p>\n<p><strong><em>The Software Part<\/em><\/strong><\/p>\n<p>Setting up registers for USART is very easy. Just as always we need to enable the required I\/O peripherals and hardware. Since we are dealing with USART1 only and it is connected with APB2 bus, we will have to set <b><i>RCC_APB2ENRbits.USART1EN<\/i><\/b> bit. We\u2019ll also need to enable GPIOA pins as USART1, by default, uses PA9 and PA10 pins. We\u2019ll have to set PA9 and PA10 in AFIO mode too as I already stated. Before enabling the USART hardware completely we should first set the baud rate value for <b><i>BRR<\/i><\/b> register. This is followed by setting the USART hardware and its TX and RX options.<\/p>\n<p><i>void setup()<\/i><\/p>\n<p><i>{<\/i><\/p>\n<p><i>\u00a0\u00a0\u00a0\u00a0 RCC_APB2ENRbits.IOPAEN = 1;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/Enable GPIOA<\/i><\/p>\n<p><i>\u00a0\u00a0\u00a0\u00a0 RCC_APB2ENRbits.USART1EN = 1;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/Enable USART1<\/i><\/p>\n<p><i>\u00a0\u00a0\u00a0\u00a0 GPIOA_CRH = 0x4A0;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/Set PA9 and PA10 as AFIO pins<\/i><\/p>\n<p><i>\u00a0\u00a0\u00a0\u00a0 USART1_BRR = 0x341;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/Set value for required baud rate<\/i><\/p>\n<p><i>\u00a0\u00a0\u00a0\u00a0 USART1_CR1bits.UE = 1;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/Set USART1<\/i><\/p>\n<p><i>\u00a0\u00a0\u00a0\u00a0 USART1_CR1bits.RE = 1;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/Set USART1 RX to receive incoming data<\/i><\/p>\n<p><i>\u00a0\u00a0\u00a0\u00a0 USART1_CR1bits.TE = 1;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/Set USART1 TX to send data<\/i><\/p>\n<p><i>}<\/i><\/p>\n<p>Transmitting and receiving data needs only a few lines of code.<\/p>\n<p><i>unsigned char USART1_receive()\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/i><\/p>\n<p><i>{<\/i><\/p>\n<p><i>\u00a0\u00a0\u00a0\u00a0 while(USART1_SRbits.RXNE == 0);\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/wait until data is available for reading<\/i><\/p>\n<p><i>\u00a0\u00a0\u00a0\u00a0 return (0xFF &amp; USART1_DR);\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/return read data<\/i><\/p>\n<p><i>}<\/i><\/p>\n<p><i>\u00a0<\/i><\/p>\n<p><i>void USART1_send(unsigned char value)<\/i><\/p>\n<p><i>{<\/i><\/p>\n<p><i>\u00a0\u00a0\u00a0\u00a0 USART1_DR = value;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/transfer data to DR register<\/i><\/p>\n<p><i>\u00a0\u00a0\u00a0\u00a0 while(USART1_SRbits.TXE == 0);\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/wait until data transmission is complete<\/i><\/p>\n<p><i>}\u00a0\u00a0\u00a0\u00a0 <\/i><\/p>\n<p>As stated earlier, the <b><i>DR (Data Register) <\/i><\/b>register actually deals with incoming and outgoing data. It is like a temporary data buffer. The code example above is self-explanatory. We wait until data is received or transmitted successfully. This is done by monitoring <b><i>SR (Status Register) <\/i><\/b>hardware flags set by the hardware peripherals responsible. Thus the above code is based on polling method. I have also included examples with interrupt and MikroC\u2019s built-in library in the compressed folder and I leave them for readers to explore should they understand my explanation.<\/p>\n<p><strong><em>Last Few Words<\/em><\/strong><\/p>\n<p>One more thing to note &#8211; MikroC\u2019s libraries are good and easy to use but they are resource expensive and have limited functionalities. For instance the serial communication codes without MikroC\u2019s library assistance took only about 1% of STM32F103C8\u2019s space, i.e. 1% of 64kB = 0.64kb or 640 bytes while with USART library this figure becomes 5% of 64kB or 3.2kB. ARM chips typically have large memory resources and so using library for fast development or testing is not a big deal. It\u2019s up to the coder to decide what to do. Personally I use library functions for rapid prototyping and testing. I also use them in professional works when their usage doesn\u2019t cause any problem. I only go down to every bits-and-bytes when desperately needed.<\/p>\n<p>I have also made a USART_BRR calculator software which will calculate the <b><i>BRR<\/i><\/b> register value for a given clock frequency and required baud rate. It&#8217;ll greatly relieve from tiresome calculations.<\/p>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/stm32-serial-communication\/gui\/\" rel=\"attachment wp-att-8895\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-8895\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2014\/07\/GUI.png\" alt=\"GUI\" width=\"338\" height=\"250\" \/><\/a><\/p>\n<p><strong><em><strong><em>Demo<\/em><\/strong><\/em><\/strong><\/p>\n<p>All of the code examples are just USART loops and so whatever we write to STM32 is returned to PC USART terminal program. MikroC like many other IDEs have USART terminal support and we can use it very easily. Usually the USART1 hardware is also the hardware we use for bootloader mode and provided that the usual USART pins are not remapped elsewhere, we can use it for USART code checks without wiring extra stuffs. We wire it for uploading codes before tests. This is what I did in my examples.<\/p>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/stm32-serial-communication\/20140707_040115\/\" rel=\"attachment wp-att-8894\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-8894\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2014\/07\/20140707_040115-1024x695.jpg\" alt=\"20140707_040115\" width=\"860\" height=\"583\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2014\/07\/20140707_040115-1024x695.jpg 1024w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2014\/07\/20140707_040115-550x373.jpg 550w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2014\/07\/20140707_040115.jpg 1369w\" sizes=\"auto, (max-width: 860px) 100vw, 860px\" \/><\/a> <a href=\"http:\/\/embedded-lab.com\/blog\/stm32-serial-communication\/20140707_040043\/\" rel=\"attachment wp-att-8893\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-8893\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2014\/07\/20140707_040043-1024x657.jpg\" alt=\"20140707_040043\" width=\"860\" height=\"551\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2014\/07\/20140707_040043-1024x657.jpg 1024w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2014\/07\/20140707_040043-550x353.jpg 550w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2014\/07\/20140707_040043.jpg 1369w\" sizes=\"auto, (max-width: 860px) 100vw, 860px\" \/><\/a> <a href=\"http:\/\/embedded-lab.com\/blog\/stm32-serial-communication\/test\/\" rel=\"attachment wp-att-8896\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-8896\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2014\/07\/test.png\" alt=\"test\" width=\"887\" height=\"709\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2014\/07\/test.png 887w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2014\/07\/test-550x439.png 550w\" sizes=\"auto, (max-width: 887px) 100vw, 887px\" \/><\/a><\/p>\n<p>Video Link:\u00a0<a href=\"https:\/\/www.youtube.com\/watch?v=vjzGVh5HHhQ\">https:\/\/www.youtube.com\/watch?v=vjzGVh5HHhQ<\/a><\/p>\n<p>Download link for the GUI and the demo codes:\u00a0<a title=\"here\" href=\"http:\/\/embedded-lab.com\/blog\/stm32-serial-communication\/stm32-usart\/\" rel=\"attachment wp-att-8897\">STM32 USART<\/a>.<\/p>\n<p>Last but not least I will suggest readers going through the STM32F10x Reference Manual\u2019s USART section. It\u2019ll surely help building vital concepts.<\/p>\n<p><span style=\"font-size: 0.95em;line-height: 1.6em\">Happy playing with STM32.<\/span><\/p>\n<p>Repository: <a href=\"https:\/\/github.com\/sshahryiar\/STM32-Tutorials\">https:\/\/github.com\/sshahryiar\/STM32-Tutorials<\/a><\/p>\n<p><i>Author: Shawon M. Shahryiar<br \/>\n<\/i><\/p>\n<p><a href=\"https:\/\/www.youtube.com\/c\/sshahryiar\">https:\/\/www.youtube.com\/c\/sshahryiar<\/a><\/p>\n<p><a href=\"https:\/\/github.com\/sshahryiar\">https:\/\/github.com\/sshahryiar<\/a><\/p>\n<p><a href=\"mailto:sshahryiar@gmail.com\"><i>sshahryiar@gmail.com<\/i><\/a><i><\/i><i>\u00a0 \u00a0 \u00a0 \u00a0 <\/i><\/p>\n","protected":false},"excerpt":{"rendered":"<p>STM32 micros just like any other micro provide hardware for serial communication. As we all know serial communication is a very important tool for debugging, connecting with external hardware like RFID, GPS, GSM modems, etc. and for performing other communication-related tasks. STM32s have several hardware serial (USART) ports. The number of ports available in a STM32 micro is dependent on device family type and the device itself. Typically there are at least 5 serial ports. Apart from the basic serial communication needs, STM32\u2019s USART hardware also have support for LIN, one-wire, smart card protocols, SPI and IrDA. We can even<\/p>\n","protected":false},"author":5,"featured_media":8888,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[733,1474,1466],"tags":[415,734,143,1319],"class_list":["post-8887","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-stm32","category-stm32-tutorials","category-tutorials","tag-advanced-microcontrollers","tag-arm","tag-serial-communication","tag-stm32"],"_links":{"self":[{"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/posts\/8887","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/comments?post=8887"}],"version-history":[{"count":10,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/posts\/8887\/revisions"}],"predecessor-version":[{"id":15156,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/posts\/8887\/revisions\/15156"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/media\/8888"}],"wp:attachment":[{"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/media?parent=8887"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/categories?post=8887"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/tags?post=8887"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}