{"id":1809,"date":"2025-10-06T00:00:00","date_gmt":"2025-10-05T15:00:00","guid":{"rendered":"https:\/\/twarelab.com\/?p=1809"},"modified":"2025-10-10T08:16:19","modified_gmt":"2025-10-09T23:16:19","slug":"stm32f4c-project-tutorial-step-4","status":"publish","type":"post","link":"https:\/\/twarelab.com\/en\/blog\/stm32f4c-project-tutorial-step-4\/","title":{"rendered":"[STM32F4]C++ \ud504\ub85c\uc81d\ud2b8 \ud29c\ud1a0\ub9ac\uc5bc &#8211; Step 4"},"content":{"rendered":"<h2 class=\"wp-block-heading\">Using the UART Peripheral in C++<\/h2>\n\n\n\n<p>UART (Universal Asynchronous Receiver\/Transmitter) is one of the most widely used communication devices in embedded systems.<\/p>\n\n\n\n<p class=\"translation-block\">It is used for various purposes such as debugging, log output, and data exchange with external devices, providing <strong>a simple yet reliable communication method<\/strong>.<\/p>\n\n\n\n<p class=\"translation-block\">In this section, we\u2019ll explore how to implement UART in a <strong>class-based structure<\/strong>.<\/p>\n\n\n\n<p class=\"translation-block\">Starting from the base class BaseUART, we\u2019ll examine how it can be extended into <strong>IntrUART (interrupt-based)<\/strong> and <strong>DmaUART (DMA-based)<\/strong> versions depending on performance requirements.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">BaseUART: The Base Class<\/h2>\n\n\n\n<p>The BaseUART class provides the fundamental features required for UART communication.\nIts main functions include:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Transmit\/Receive Queues<\/strong>\n<ul class=\"wp-block-list\">\n<li>Temporary storage for data before and after transmission.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Read\/Write Functions<\/strong>\n<ul class=\"wp-block-list\">\n<li>APIs for controlling UART data transmission and reception.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Configuration Properties<\/strong>\n<ul class=\"wp-block-list\">\n<li>Management of communication parameters such as baud rate, parity, and stop bits.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<p class=\"translation-block\">This class serves as the <strong>common foundation<\/strong> for other UART implementations.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">IntrUART: Interrupt-Based UART<\/h2>\n\n\n\n<p class=\"translation-block\">IntrUART inherits from BaseUART and operates using <strong>interrupts<\/strong>.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Suitable for small data transfers.<\/li>\n\n\n\n<li>Enables event-driven processing \u2192 saves CPU idle time.<\/li>\n\n\n\n<li>Handles data queues inside the ISR (Interrupt Service Routine).<\/li>\n<\/ul>\n\n\n\n<p>Whenever a receive event occurs, an interrupt is triggered, the incoming data is stored in the queue, and the application can easily retrieve it later.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">DmaUART: DMA-Based UART<\/h2>\n\n\n\n<p class=\"translation-block\">DmaUART also inherits from BaseUART but supports <strong>high-speed data transfer using DMA<\/strong>.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Maximizes performance by minimizing CPU involvement.<\/li>\n\n\n\n<li>Optimized for large or continuous data streams.<\/li>\n\n\n\n<li>Operates reliably in parallel with other tasks.<\/li>\n<\/ul>\n\n\n\n<p>It\u2019s particularly effective for applications that require heavy log output or high-bandwidth data exchange.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Code Examples<\/h2>\n\n\n\n<p><strong>Example 1 \u2013 Using IntrUART<\/strong><\/p>\n\n\n\n<ol class=\"wp-block-list\" start=\"1\">\n<li><strong>Include Header and Declare Object<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">#include \"IntrUART.h\"\n...\nIntrUART Uart1;\n...<\/pre>\n\n\n\n<ol class=\"wp-block-list\" start=\"2\">\n<li><strong>Initialization Function<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">void InitUarts(void);\n...\n\/*\n *\n *\/\nvoid InitUarts(void)\n{\n\tUart1 = IntrUART(USART1, &amp;CTask);\n        Uart1.InitInterrupt();\n}\n<\/pre>\n\n\n\n<ol class=\"wp-block-list\" start=\"3\">\n<li><strong>Call Initialization in main.c<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">...\n  InitUarts();\n...<\/pre>\n\n\n\n<ol class=\"wp-block-list\" start=\"4\">\n<li><strong>Interrupt ISR Handling<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">#include &lt;IntrUART.h>\n\n...\nextern IntrUART Uart1;\n\n\/**\n  * @brief This function handles USART2 global interrupt.\n  *\/\nvoid USART1_IRQHandler(void)\n{\n  \/* USER CODE BEGIN USART1_IRQn 0 *\/\n    Uart1.RxInterruptHandler();\n    Uart1.TxInterruptHandler();\n  \/* USER CODE END USART1_IRQn 0 *\/\n  \/* USER CODE BEGIN USART1_IRQn 1 *\/\n\n  \/* USER CODE END USART1_IRQn 1 *\/\n}\n<\/pre>\n\n\n\n<p><strong>Example 2 \u2013 Using DmaUART<\/strong><\/p>\n\n\n\n<ol class=\"wp-block-list\" start=\"1\">\n<li><strong>Include Header and Declare Object<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">#include \"DmaUART.h\"\n...\nDmaUART Uart1;\n...<\/pre>\n\n\n\n<ol class=\"wp-block-list\" start=\"2\">\n<li><strong>Initialization Function<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">void InitUarts(void);\n...\n\/*\n *\n *\/\nvoid InitUarts(void)\n{\n\tUart1 = DmaUART(USART1, DMA2, LL_DMA_STREAM_7, DMA2, LL_DMA_STREAM_2, &amp;CTask);\n        Uart1.DMARxEnable();\n}<\/pre>\n\n\n\n<ol class=\"wp-block-list\" start=\"3\">\n<li><strong>Call Initialization in main.c<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">...\n    InitUarts();\n...\n    while(1){\n      ...\n    }<\/pre>\n\n\n\n<ol class=\"wp-block-list\" start=\"4\">\n<li><strong>DMA ISR Handling<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">...\n#include &lt;ConsoleTask.h>\n\n...\nextern ConsoleTask CTask;\n\n...\n\/**\n  * @brief This function handles USART1 global interrupt.\n  *\/\nvoid USART1_IRQHandler(void)\n{\n  \/* USER CODE BEGIN USART1_IRQn 0 *\/\n\tCTask.uart.IDLEInterruptHandler();\n  \/* USER CODE END USART1_IRQn 0 *\/\n  \/* USER CODE BEGIN USART1_IRQn 1 *\/\n\n  \/* USER CODE END USART1_IRQn 1 *\/\n}\n...\n\/**\n  * @brief This function handles DMA2 stream2 global interrupt.\n  *\/\nvoid DMA2_Stream2_IRQHandler(void)\n{\n  \/* USER CODE BEGIN DMA2_Stream2_IRQn 0 *\/\n\tCTask.uart.RXDMAInterruptHandler();\n  \/* USER CODE END DMA2_Stream2_IRQn 0 *\/\n  \/* USER CODE BEGIN DMA2_Stream2_IRQn 1 *\/\n\n  \/* USER CODE END DMA2_Stream2_IRQn 1 *\/\n}\n...\n\/**\n  * @brief This function handles DMA2 stream7 global interrupt.\n  *\/\nvoid DMA2_Stream7_IRQHandler(void)\n{\n  \/* USER CODE BEGIN DMA2_Stream7_IRQn 0 *\/\n\tCTask.uart.TXDMAInterruptHandler();\n  \/* USER CODE END DMA2_Stream7_IRQn 0 *\/\n  \/* USER CODE BEGIN DMA2_Stream7_IRQn 1 *\/\n\n  \/* USER CODE END DMA2_Stream7_IRQn 1 *\/\n}\n<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Troubleshooting &amp; Tips<\/h2>\n\n\n\n<ol class=\"wp-block-list\" start=\"1\">\n<li class=\"translation-block\"><strong>No data received<\/strong> \u2192 Check if RXNEIE and TXEIE interrupts are enabled.<\/li>\n\n\n\n<li class=\"translation-block\"><strong>Corrupted data<\/strong> \u2192 Verify baud rate, parity, and data length settings.<\/li>\n\n\n\n<li class=\"translation-block\"><strong>ISR not triggered<\/strong> \u2192 Check NVIC configuration and vector table mapping.<\/li>\n\n\n\n<li class=\"translation-block\"><strong>Slow processing<\/strong> \u2192 Consider using DmaUART instead of IntrUART.<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p class=\"translation-block\">In this section, we <strong>designed a class hierarchy<\/strong> for UART communication consisting of:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>BaseUART<\/strong> \u2013 Common base implementation<\/li>\n\n\n\n<li><strong>IntrUART<\/strong> \u2013 Interrupt-driven UART<\/li>\n\n\n\n<li><strong>DmaUART<\/strong> \u2013 DMA-driven high-speed UART<\/li>\n<\/ul>\n\n\n\n<p>This layered design allows you to easily switch communication methods at the application level without modifying your main logic.<\/p>","protected":false},"excerpt":{"rendered":"<p>C++\uc5d0\uc11c UART Peripheral \uc0ac\uc6a9\ud558\uae30 UART(Universal Asynchronous Receiver\/Transmitter)\ub294 \uc784\ubca0\ub514\ub4dc \uc2dc\uc2a4\ud15c\uc5d0\uc11c \uac00\uc7a5 \ub110\ub9ac \uc0ac\uc6a9\ub418\ub294 \ud1b5\uc2e0 \uc7a5\uce58 \uc911 \ud558\ub098\uc785\ub2c8\ub2e4. \ub514\ubc84\uae45, \ub85c\uadf8 \ucd9c\ub825, \uc678\ubd80 \uc7a5\uce58\uc640\uc758 \ub370\uc774\ud130 \uad50\ud658 \ub4f1 \ub2e4\uc591\ud55c \ubaa9\uc801\uc73c\ub85c \ud65c\uc6a9\ub418\uba70, \ub2e8\uc21c\ud558\uba74\uc11c\ub3c4 \uc2e0\ub8b0\uc131 \ub192\uc740 \ud1b5\uc2e0 \uc218\ub2e8\uc744 \uc81c\uacf5\ud569\ub2c8\ub2e4. \uc774\ubc88 \ub2e8\uacc4\uc5d0\uc11c\ub294 UART\ub97c \ud074\ub798\uc2a4 \uae30\ubc18 \uad6c\uc870\ub85c \uad6c\ud604\ud558\ub294 \ubc29\ubc95\uc744 \ub2e4\ub8f9\ub2c8\ub2e4. \uae30\ubcf8 \ud074\ub798\uc2a4\uc778 BaseUART\ub97c \uc2dc\uc791\uc73c\ub85c, \uc131\ub2a5 \uc694\uad6c\uc5d0 \ub530\ub77c IntrUART(\uc778\ud130\ub7fd\ud2b8 [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":true,"template":"","format":"standard","meta":{"_themeisle_gutenberg_block_has_review":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[1,13,12],"tags":[87,42,32,50],"class_list":["post-1809","post","type-post","status-publish","format-standard","hentry","category-blog","category-en","category-ko","tag-c","tag-stm32f4","tag-tw100pc","tag-uart"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/twarelab.com\/en\/wp-json\/wp\/v2\/posts\/1809","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/twarelab.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/twarelab.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/twarelab.com\/en\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/twarelab.com\/en\/wp-json\/wp\/v2\/comments?post=1809"}],"version-history":[{"count":5,"href":"https:\/\/twarelab.com\/en\/wp-json\/wp\/v2\/posts\/1809\/revisions"}],"predecessor-version":[{"id":1825,"href":"https:\/\/twarelab.com\/en\/wp-json\/wp\/v2\/posts\/1809\/revisions\/1825"}],"wp:attachment":[{"href":"https:\/\/twarelab.com\/en\/wp-json\/wp\/v2\/media?parent=1809"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/twarelab.com\/en\/wp-json\/wp\/v2\/categories?post=1809"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/twarelab.com\/en\/wp-json\/wp\/v2\/tags?post=1809"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}