{"id":1415,"date":"2022-12-18T04:43:09","date_gmt":"2022-12-18T04:43:09","guid":{"rendered":"https:\/\/blog.embeddedexpert.io\/?p=1415"},"modified":"2022-12-18T04:43:10","modified_gmt":"2022-12-18T04:43:10","slug":"getting-started-with-stm32f103-uart-receiver-in-interrupt-mode","status":"publish","type":"post","link":"https:\/\/blog.embeddedexpert.io\/?p=1415","title":{"rendered":"Getting Started with STM32F103: UART Receiver in interrupt mode"},"content":{"rendered":"\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img decoding=\"async\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/AdobeStock_316544570-2048x1448.jpeg\" alt=\"\" \/><\/figure><\/div>\n\n\n\n<p>In the previous guide (<a rel=\"noreferrer noopener\" href=\"https:\/\/blog.embeddedexpert.io\/?p=1395\" data-type=\"URL\" data-id=\"https:\/\/blog.embeddedexpert.io\/?p=1395\" target=\"_blank\">here<\/a>), we took a look at how to receive a character using polling mode. In this guide, we shall use interrupt to receive the data.<\/p>\n\n\n\n<p>In this guide, we shall cover the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Enable RX in interrupt mode.<\/li><li>Interrupt handler.<\/li><li>Code.<\/li><li>Demo.<\/li><\/ul>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">1. Enable RX in interrupt mode:<\/h2>\n\n\n\n<p>In order to enable the RX in interrupt mode, we need the following two steps:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Enable RXNEIE in Control Register 1 (CR1).<\/li><li>Enable UART2 interrupt in NVIC.<\/li><\/ul>\n\n\n\n<p>To enable the RXNEIE for the UART, we need to set the RXNEIE bit in CR1 to 1:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"260\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/Screenshot-2022-12-18-at-7.34.30-AM-1024x260.png\" alt=\"\" class=\"wp-image-1416\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/Screenshot-2022-12-18-at-7.34.30-AM-1024x260.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/Screenshot-2022-12-18-at-7.34.30-AM-300x76.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/Screenshot-2022-12-18-at-7.34.30-AM-768x195.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/Screenshot-2022-12-18-at-7.34.30-AM-1536x390.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/Screenshot-2022-12-18-at-7.34.30-AM-2048x521.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/Screenshot-2022-12-18-at-7.34.30-AM-1150x292.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/Screenshot-2022-12-18-at-7.34.30-AM-750x191.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/Screenshot-2022-12-18-at-7.34.30-AM-400x102.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/Screenshot-2022-12-18-at-7.34.30-AM-250x64.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\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;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">\/*Enable RXNIE interrupt*\/\nUSART2-&gt;CR1|=USART_CR1_RXNEIE;<\/pre><\/div>\n\n\n\n<p>Then enable USART2 interrupt in NVIC:<\/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;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">\t\/*Enable USART2 interrupt in NVIC*\/\n\tNVIC_EnableIRQ(USART2_IRQn);<\/pre><\/div>\n\n\n\n<p>Thats all to enable interrupt.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2. Interrupt handler:<\/h2>\n\n\n\n<p>Within the interrupt handler, we shall implement the following sequence:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Check if the interrupt source is RXNE.<\/li><li>If it is, Read the register.<\/li><li>Echo back the character.<\/li><li>Print new line and return the cursor.<\/li><li>Clear the status register.<\/li><\/ul>\n\n\n\n<p><\/p>\n\n\n\n<p>For the main Interrupt handler, the function 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;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">void USART2_IRQHandler(void)<\/pre><\/div>\n\n\n\n<p>Within the function:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Check if the interrupt source is RXNE as following:<\/li><\/ul>\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;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">\t\/*Check the interrupt source*\/\n\tif((USART2-&gt;SR&amp;USART_SR_RXNE)) \/*Received a character*\/\n\t{<\/pre><\/div>\n\n\n\n<p>Read the character:<\/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;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">rx_char=USART2-&gt;DR; \/\/Read the character<\/pre><\/div>\n\n\n\n<p>Echo back the character:<\/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;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">uart2_write(rx_char); \/\/echo back the character<\/pre><\/div>\n\n\n\n<p>Print newline and return the cursor:<\/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;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">\/*print new line and return the cursor*\/\n\t\tuart2_write('\\r');\n\t\tuart2_write('\\n');<\/pre><\/div>\n\n\n\n<p>Clear the pending flag:<\/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;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">\t\tUSART2-&gt;SR&amp;=~USART_SR_RXNE;\n\n\t}<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3. Code:<\/h2>\n\n\n\n<p>Hence, the entire code as following:<\/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;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#include &quot;stm32f1xx.h&quot;\n\n\n\n#define Perpher_CLK 8000000\n#define Baudrate\t115200\n\n\n\nstatic uint16_t compute_uart_bd(uint32_t PeriphClk, uint32_t BaudRate)\n{\n\treturn ((PeriphClk + (BaudRate\/2U))\/BaudRate);\n}\n\n\nstatic void uart_set_baudrate(USART_TypeDef *USARTx, uint32_t PeriphClk,  uint32_t BaudRate)\n{\n\tUSARTx-&gt;BRR =  compute_uart_bd(PeriphClk,BaudRate);\n}\n\n\n\n\n\nvoid uart2_write(char ch)\n{\n  \/*Make sure the transmit data register is empty*\/\n\twhile(!(USART2-&gt;SR &amp; USART_SR_TXE)){}\n\n  \/*Write to transmit data register*\/\n\tUSART2-&gt;DR\t=  (ch &amp; 0xFF);\n}\n\n\n\n\n\nvolatile char rx_char;\n\n\n\nint main(void)\n{\n\n\t\/*UART2 Pin configures*\/\n\n\t\/\/enable clock access to GPIOA\n\tRCC-&gt;APB2ENR|=RCC_APB2ENR_IOPAEN;\n\t\/\/Enable clock access to alternate function\n\tRCC-&gt;APB2ENR|=RCC_APB2ENR_AFIOEN;\n\n\t\/*Confgiure PA2 as output maximum speed to 50MHz\n\t * and alternate output push-pull mode*\/\n\tGPIOA-&gt;CRL|=GPIO_CRL_MODE2;\n\n\tGPIOA-&gt;CRL|=GPIO_CRL_CNF2_1;\n\tGPIOA-&gt;CRL&amp;=~GPIO_CRL_CNF2_0;\n\n\n\t\/*Configure PA3 as Input floating*\/\n\n\t\/*Set mode to be input*\/\n\tGPIOA-&gt;CRL &amp;=~(GPIO_CRL_MODE3);\n\tGPIOA-&gt;CRL|=GPIO_CRL_CNF3_0;\n\tGPIOA-&gt;CRL&amp;=~GPIO_CRL_CNF3_1;\n\n\n\n\n\t\/*Don't remap the pins*\/\n\tAFIO-&gt;MAPR&amp;=~AFIO_MAPR_USART2_REMAP;\n\n\n\t\/*USART2 configuration*\/\n\n\t\/\/enable clock access to USART2\n\n\tRCC-&gt;APB1ENR|=RCC_APB1ENR_USART2EN;\n\n\t\/\/Transmit Enable\n\tUSART2-&gt;CR1 |= USART_CR1_TE;\n\n\t\/\/Enable receiver\n\tUSART2-&gt;CR1 |= USART_CR1_RE;\n\n\n\t\/*Enable RXNIE interrupt*\/\n\n\tUSART2-&gt;CR1|=USART_CR1_RXNEIE;\n\n\t\/*Enable USART2 interrupt in NVIC*\/\n\tNVIC_EnableIRQ(USART2_IRQn);\n\n\t\/*Set baudrate *\/\n\tuart_set_baudrate(USART2,Perpher_CLK,Baudrate);\n\t\/\/Enable UART\n\tUSART2-&gt;CR1 |= USART_CR1_UE;\n\n\n\n\twhile(1)\n\t{\n\n\n\n\t}\n}\n\n\nvoid USART2_IRQHandler(void)\n{\n\t\/*Check the interrupt source*\/\n\tif((USART2-&gt;SR&amp;USART_SR_RXNE)) \/*Received a character*\/\n\t{\n\t\trx_char=USART2-&gt;DR; \/\/Read the character\n\t\tuart2_write(rx_char); \/\/echo back the character\n\t\t\/*print new line and return the cursor*\/\n\t\tuart2_write('\\r');\n\t\tuart2_write('\\n');\n\t\t\/*Clear the pending RXNE flag*\/\n\t\tUSART2-&gt;SR&amp;=~USART_SR_RXNE;\n\n\t}\n\n}\n\n<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">4. Demo:<\/h2>\n\n\n\n<p>Open you favourite serial terminal and set the buadrate to be 115200 and send any character and you should receive the same sent character:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"600\" height=\"434\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/ezgif-5-8176dddb77.gif\" alt=\"\" class=\"wp-image-1398\" \/><\/figure>\n\n\n\n<p>Happy coding \ud83d\ude42 <\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the previous guide (here), we took a look at how to receive a character using polling mode. In this guide, we shall use interrupt to receive the data. In this guide, we shall cover the following: Enable RX in interrupt mode. Interrupt handler. Code. Demo. 1. Enable RX in interrupt mode: In order to [&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-1415","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\/1415"}],"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=1415"}],"version-history":[{"count":1,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/1415\/revisions"}],"predecessor-version":[{"id":1417,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/1415\/revisions\/1417"}],"wp:attachment":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1415"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1415"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1415"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}