{"id":3735,"date":"2025-08-30T09:14:20","date_gmt":"2025-08-30T09:14:20","guid":{"rendered":"https:\/\/blog.embeddedexpert.io\/?p=3735"},"modified":"2025-08-30T09:14:23","modified_gmt":"2025-08-30T09:14:23","slug":"stm32-uart-part-3-receiving-data-using-polling-and-interrupt","status":"publish","type":"post","link":"https:\/\/blog.embeddedexpert.io\/?p=3735","title":{"rendered":"STM32 UART Part 3: Receiving Data using Polling and Interrupt"},"content":{"rendered":"\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/07\/ChatGPT-Image-Jul-24-2025-at-03_03_50-PM-1.png\" alt=\"\" \/><\/figure>\n\n\n\n<p>In this part, we focus on receiving data using both polling and interrupt-driven methods. Polling continuously checks the UART status flags for incoming data, while interrupt mode allows the CPU to handle other tasks and only responds when data actually arrives.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>In this guide, we shall cover the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Polling vs interrupt. <\/li>\n\n\n\n<li>Polling mode firmware development.<\/li>\n\n\n\n<li>Interrupt mode firmware development.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">1. Polling Vs Interrupt:<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Polling in STM32 UART Reception<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>How it works<\/strong>:<br>In polling mode, the CPU\u00a0<strong>actively waits<\/strong>\u00a0and continuously checks (or \u201cpolls\u201d) the UART status flags (like\u00a0<em>RXNE \u2013 Receive Data Register Not Empty<\/em>). The CPU keeps asking:\u00a0<em>\u201cHas a new byte arrived?\u201d<\/em>\u00a0until the flag is set.<\/li>\n\n\n\n<li><strong>CPU involvement<\/strong>:<br>The CPU is\u00a0<strong>fully occupied<\/strong>\u00a0during this waiting, wasting cycles if no data is arriving.<\/li>\n\n\n\n<li><strong>Data handling<\/strong>:<br>Once the flag indicates data is available, the CPU immediately reads the byte from the UART data register (USARTx-&gt;RDR). If the CPU is late, there\u2019s a risk of missing data if the buffer overflows.<\/li>\n\n\n\n<li><strong>Performance<\/strong>:<br>This method is simple but inefficient, especially if data arrives infrequently or irregularly. The CPU is locked in checking instead of doing useful work.<\/li>\n\n\n\n<li><strong>Use cases<\/strong>:<br>Useful for very\u00a0<strong>simple or low-speed communication<\/strong>, testing, or when data reception is rare and predictable.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Interrupt-based Reception in STM32<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>How it works<\/strong>:<br>In interrupt mode, the CPU is\u00a0<strong>free to execute other tasks<\/strong>\u00a0until the UART peripheral signals that a new byte has arrived. When the\u00a0<em>RXNE flag<\/em>\u00a0is set, the UART triggers an\u00a0<strong>interrupt request (IRQ)<\/strong>\u00a0to the NVIC (Nested Vectored Interrupt Controller).<\/li>\n\n\n\n<li><strong>CPU involvement<\/strong>:<br>The CPU only reacts\u00a0<strong>when needed<\/strong>. It executes the corresponding\u00a0<strong>ISR (Interrupt Service Routine)<\/strong>, where the data is read from the UART data register and processed or stored in a buffer.<\/li>\n\n\n\n<li><strong>Efficiency<\/strong>:<br>Since the CPU is not constantly polling, interrupt mode is\u00a0<strong>far more efficient<\/strong>. It allows the MCU to handle multiple peripherals or tasks concurrently.<\/li>\n\n\n\n<li><strong>Reliability<\/strong>:<br>Interrupts reduce the chance of missing data, provided the ISR is short and fast. However, if interrupts are delayed (due to higher-priority interrupts or disabled IRQs), data loss is still possible at very high baud rates.<\/li>\n\n\n\n<li><strong>Use cases<\/strong>:<br>Best for\u00a0<strong>moderate to high-speed communication<\/strong>, multitasking systems, and FreeRTOS-based applications where CPU time must be shared efficiently.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Polling vs Interrupt (STM32 perspective)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Polling<\/strong>\u00a0= CPU babysits UART \u2192 Simple but wasteful.<\/li>\n\n\n\n<li><strong>Interrupts<\/strong>\u00a0= UART babysits CPU \u2192 Efficient, event-driven, and scalable.<\/li>\n<\/ul>\n\n\n\n<p>In STM32 projects, polling is often only used for quick tests or debugging, while interrupt-driven reception is the practical choice for real-time embedded systems.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Polling vs Interrupt in STM32 UART Reception<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Aspect<\/th><th><strong>Polling<\/strong><\/th><th><strong>Interrupt<\/strong><\/th><\/tr><\/thead><tbody><tr><td><strong>How it works<\/strong><\/td><td>CPU keeps checking UART status flag (RXNE) in a loop.<\/td><td>UART peripheral triggers an interrupt when data arrives.<\/td><\/tr><tr><td><strong>CPU usage<\/strong><\/td><td>High (CPU is busy-waiting, wasting cycles).<\/td><td>Low (CPU free until interrupt occurs).<\/td><\/tr><tr><td><strong>Efficiency<\/strong><\/td><td>Inefficient, especially at low data rates.<\/td><td>Efficient, scales well with varying data rates.<\/td><\/tr><tr><td><strong>Reliability<\/strong><\/td><td>Risk of missing data if CPU is late in checking.<\/td><td>More reliable; ISR reacts immediately to incoming data.<\/td><\/tr><tr><td><strong>Response time<\/strong><\/td><td>Determined by how fast the loop checks the flag.<\/td><td>Determined by NVIC interrupt latency (very fast).<\/td><\/tr><tr><td><strong>Complexity<\/strong><\/td><td>Very simple to implement.<\/td><td>Requires interrupt configuration &amp; ISR management.<\/td><\/tr><tr><td><strong>Best for<\/strong><\/td><td>Debugging, very low-speed or simple cases.<\/td><td>Real applications, multitasking systems, moderate\/high-speed comms.<\/td><\/tr><tr><td><strong>Example STM32 flag<\/strong><\/td><td>CPU polls&nbsp;<code>USARTx-&gt;ISR &amp; RXNE<\/code>.<\/td><td>RXNE interrupt triggers ISR via NVIC.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p> In short:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Polling = wasteful babysitter<\/strong>\u00a0(CPU always watching).<\/li>\n\n\n\n<li><strong>Interrupt = efficient notifier<\/strong>\u00a0(UART tells CPU only when needed).<\/li>\n<\/ul>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2. Polling Mode Firmware Development:<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<p>We shall continue from the previous guide <a href=\"https:\/\/blog.embeddedexpert.io\/?p=3645\" data-type=\"link\" data-id=\"https:\/\/blog.embeddedexpert.io\/?p=3645\" target=\"_blank\" rel=\"noreferrer noopener\">here<\/a>.<\/p>\n\n\n\n<p>There won&#8217;t be any modification since the interrupt is already enabled from the previous guide.<\/p>\n\n\n\n<p>In main.c fine, in user begin PV (Private variable), declare the following array:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;C&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">uint8_t uart_rx_data[20]={0};<\/pre><\/div>\n\n\n\n<p>This array shall hold the received data from the UART in both, interrupt and polling modes.<\/p>\n\n\n\n<p>Next, in while loop of the main function, start the uart to receive in polling mode as follows:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;C&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\"> HAL_UART_Receive(&amp;huart2, uart_rx_data, 5, HAL_MAX_DELAY);<\/pre><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Explanation of Parameters<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong><code>&amp;huart2<\/code><\/strong>\n<ul class=\"wp-block-list\">\n<li>Handle of the UART peripheral you\u2019re using.<\/li>\n\n\n\n<li><code>huart2<\/code>\u00a0refers to\u00a0<strong>USART2<\/strong>\u00a0instance configured earlier in CubeMX or manually.<\/li>\n\n\n\n<li>Contains all settings (baudrate, word length, parity, etc.) and hardware registers mapping.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong><code>uart_rx_data<\/code><\/strong>\n<ul class=\"wp-block-list\">\n<li>Pointer to the buffer where received data will be stored.<\/li>\n\n\n\n<li>In this case, the received bytes will be written into\u00a0<code>uart_rx_data[]<\/code>.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong><code>5<\/code><\/strong>\n<ul class=\"wp-block-list\">\n<li>Number of bytes you want to receive.<\/li>\n\n\n\n<li>The function will keep receiving until\u00a0<strong>exactly 5 bytes<\/strong>\u00a0are received.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong><code>HAL_MAX_DELAY<\/code><\/strong>\n<ul class=\"wp-block-list\">\n<li>Timeout duration (in milliseconds).<\/li>\n\n\n\n<li><code>HAL_MAX_DELAY<\/code>\u00a0means it will\u00a0<strong>wait forever<\/strong>\u00a0(blocking) until all 5 bytes are received.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\">What Happens Internally<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The function\u00a0<strong>blocks the CPU<\/strong>\u00a0until either:\n<ol class=\"wp-block-list\">\n<li>All\u00a0<strong>5 bytes are received<\/strong>\u00a0into\u00a0<code>uart_rx_data<\/code>, OR<\/li>\n\n\n\n<li>Timeout expires (but here it never expires since you used\u00a0<code>HAL_MAX_DELAY<\/code>).<\/li>\n<\/ol>\n<\/li>\n\n\n\n<li>It works in\u00a0<strong>polling mode<\/strong>:\n<ul class=\"wp-block-list\">\n<li>The HAL driver keeps checking the\u00a0<strong>RXNE flag<\/strong>\u00a0(Receive Not Empty) inside USART registers.<\/li>\n\n\n\n<li>Once each byte arrives, it is copied into your buffer.<\/li>\n\n\n\n<li>After 5 bytes, the function returns\u00a0<code>HAL_OK<\/code>.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<p><\/p>\n\n\n\n<p>Once all the 5 bytes are received, we shall echo back the received characters are follows:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;C&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">HAL_UART_Transmit(&amp;huart2, uart_rx_data, 5, 20);<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>Thats all for the polling mode. Save the project and run it on your MCU as follows:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"34\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/07\/2025-07-03_17-48-35-1024x34.jpg\" alt=\"\" class=\"wp-image-3598\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/07\/2025-07-03_17-48-35-1024x34.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/07\/2025-07-03_17-48-35-300x10.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/07\/2025-07-03_17-48-35-768x25.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/07\/2025-07-03_17-48-35-1536x51.jpg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/07\/2025-07-03_17-48-35-2048x68.jpg 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/07\/2025-07-03_17-48-35-1150x38.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/07\/2025-07-03_17-48-35-750x25.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/07\/2025-07-03_17-48-35-400x13.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/07\/2025-07-03_17-48-35-250x8.jpg 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Using your favourite uart terminal and set the baud rate to 115200, send any 5 characters and you should get the transmitted characters as shown below:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"707\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-30_11-03-10-1024x707.jpg\" alt=\"\" class=\"wp-image-3736\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-30_11-03-10-1024x707.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-30_11-03-10-300x207.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-30_11-03-10-768x530.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-30_11-03-10-1536x1060.jpg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-30_11-03-10-1150x794.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-30_11-03-10-750x518.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-30_11-03-10-400x276.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-30_11-03-10-250x173.jpg 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-30_11-03-10.jpg 1866w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Notice that I am sending the data each 1 second and I am getting the characters I send back without any issue.<\/p>\n\n\n\n<p>Notice that the CPU will be spending most of its time waiting for the incoming character and store it in the buffer. This is inefficient method to receive data. <\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3. Interrupt Mode Firmware Development:<\/h2>\n\n\n\n<p>For the interrupt, in main.c in user code begin 2 in main function, start the UART reception in interrupt mode as follows:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;C&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">HAL_UART_Receive_IT(&amp;huart2, uart_rx_data, 5);<\/pre><\/div>\n\n\n\n<p>Once all 5 characters have been received,  <strong>HAL_UART_RxCpltCallback<\/strong> function shall be called.<\/p>\n\n\n\n<p>In user code begin 0:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;C&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)\n{\n\tif(huart-&gt;Instance==USART2)\n\t{\n\t\tHAL_UART_Transmit(&amp;huart2, uart_rx_data, 5, 20);\n\n\t\tHAL_UART_Receive_IT(&amp;huart2, uart_rx_data, 5);\n\n\t}\n\n}<\/pre><\/div>\n\n\n\n<p>First check which UART generate the interrupt (useful when multiple uart is involved) which is in this case USART2,  then echo the received data using polling mode and start the reception again in the interrupt mode.<\/p>\n\n\n\n<p>Note: Make sure the while loop is empty.<\/p>\n\n\n\n<p>Thats all for the interrupt mode. Save the project and run it on your MCU as follows:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"34\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/07\/2025-07-03_17-48-35-1024x34.jpg\" alt=\"\" class=\"wp-image-3598\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/07\/2025-07-03_17-48-35-1024x34.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/07\/2025-07-03_17-48-35-300x10.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/07\/2025-07-03_17-48-35-768x25.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/07\/2025-07-03_17-48-35-1536x51.jpg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/07\/2025-07-03_17-48-35-2048x68.jpg 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/07\/2025-07-03_17-48-35-1150x38.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/07\/2025-07-03_17-48-35-750x25.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/07\/2025-07-03_17-48-35-400x13.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/07\/2025-07-03_17-48-35-250x8.jpg 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Using your favourite uart terminal and set the baud rate to 115200, send any 5 characters and you should get the transmitted characters as shown below:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"707\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-30_11-09-22-1024x707.jpg\" alt=\"\" class=\"wp-image-3737\" style=\"width:840px;height:auto\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-30_11-09-22-1024x707.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-30_11-09-22-300x207.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-30_11-09-22-768x530.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-30_11-09-22-1536x1060.jpg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-30_11-09-22-1150x794.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-30_11-09-22-750x518.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-30_11-09-22-400x276.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-30_11-09-22-250x173.jpg 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-30_11-09-22.jpg 1866w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Note that the loop shall send data each 10ms and we are receiving each character without any issue.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>In part 4, we shall start using the interrupt to receive unknown length of data using both interrupt and DMA.<\/p>\n\n\n\n<p>Stay tuned.<\/p>\n\n\n\n<p>Happy coding \ud83d\ude09<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this part, we focus on receiving data using both polling and interrupt-driven methods. Polling continuously checks the UART status flags for incoming data, while interrupt mode allows the CPU to handle other tasks and only responds when data actually arrives. In this guide, we shall cover the following: 1. Polling Vs Interrupt: Polling in [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2,11,12],"tags":[],"class_list":["post-3735","post","type-post","status-publish","format-standard","hentry","category-embedded-systems","category-peripheral-drivers","category-stm32"],"_links":{"self":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/3735"}],"collection":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3735"}],"version-history":[{"count":1,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/3735\/revisions"}],"predecessor-version":[{"id":3738,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/3735\/revisions\/3738"}],"wp:attachment":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3735"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3735"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3735"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}