{"id":1988,"date":"2023-09-20T05:48:46","date_gmt":"2023-09-20T05:48:46","guid":{"rendered":"https:\/\/blog.embeddedexpert.io\/?p=1988"},"modified":"2023-09-20T05:48:52","modified_gmt":"2023-09-20T05:48:52","slug":"emulating-parallel-port-using-timer-and-dma-part-2-2-input-mode","status":"publish","type":"post","link":"https:\/\/blog.embeddedexpert.io\/?p=1988","title":{"rendered":"Emulating Parallel Port using Timer and DMA Part 2.2: Input mode"},"content":{"rendered":"\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"1024\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/09\/AdobeStock_92843412-2-1024x1024.jpeg\" alt=\"\" class=\"wp-image-1989\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/09\/AdobeStock_92843412-2-1024x1024.jpeg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/09\/AdobeStock_92843412-2-300x300.jpeg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/09\/AdobeStock_92843412-2-150x150.jpeg 150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/09\/AdobeStock_92843412-2-768x768.jpeg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/09\/AdobeStock_92843412-2-1536x1536.jpeg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/09\/AdobeStock_92843412-2-2048x2048.jpeg 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/09\/AdobeStock_92843412-2-1150x1150.jpeg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/09\/AdobeStock_92843412-2-750x750.jpeg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/09\/AdobeStock_92843412-2-400x400.jpeg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/09\/AdobeStock_92843412-2-250x250.jpeg 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure><\/div>\n\n\n\n<p>In the second section of part 2 of parallel port emulation, we shall see how to read the data being transmitted and display the data on LCD.<\/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\"><li>Transmitter code modification.<\/li><li>Receiver code.<\/li><li>Connection of two STM32s.<\/li><li>Code<\/li><li>Results.<\/li><\/ul>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">1. Transmitter Code Modification:<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<p>Before the code modification, take a look at <a href=\"https:\/\/blog.embeddedexpert.io\/?p=655\" data-type=\"URL\" data-id=\"https:\/\/blog.embeddedexpert.io\/?p=655\" target=\"_blank\" rel=\"noreferrer noopener\">this guide<\/a> where it explains the I2C LCD connection and the required header and source files.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>The modified transmitter 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;stm32f4xx.h&quot;\n#include &quot;stdint.h&quot;\n#include &quot;stdio.h&quot;\n#include &quot;i2c.h&quot;\n#include &quot;LiquidCrystal_PCF8574.h&quot;\n\n#define data_size \t5\n#define CH6 \t\t0x06\n\nuint32_t gpio_pattern[data_size]={200,400,100,120,150};\n\n\n#define AF01\t\t0x01\n\nchar lcd_data[60];\nuint16_t counter;\n\nint main(void)\n{\n\n\ti2c_init();\n\tlcd_init();\n\tlcd_clear();\n\t\/*GPIO Configuration*\/\n\n\t\/*Enable clock access to GPIOA*\/\n\tRCC-&gt;AHB1ENR|=RCC_AHB1ENR_GPIOCEN;\n\n\t\/*Set PC0 to PC7 as output*\/\n\tGPIOC-&gt;MODER|=GPIO_MODER_MODE0_0|GPIO_MODER_MODE1_0|GPIO_MODER_MODE2_0\n\t\t\t|GPIO_MODER_MODE3_0|GPIO_MODER_MODE4_0|GPIO_MODER_MODE5_0|\n\t\t\tGPIO_MODER_MODE6_0|GPIO_MODER_MODE7_0;\n\n\tGPIOC-&gt;MODER&amp;=~(GPIO_MODER_MODE0_1|GPIO_MODER_MODE1_1|GPIO_MODER_MODE2_1\n\t\t\t|GPIO_MODER_MODE3_1|GPIO_MODER_MODE4_1|GPIO_MODER_MODE5_1\n\t\t\t|GPIO_MODER_MODE6_1|GPIO_MODER_MODE7_1);\n\n\n\t\/*PA8 configuration*\/\n\n\t\/*Enable clock access to GPIOA*\/\n\tRCC-&gt;AHB1ENR|=RCC_AHB1ENR_GPIOAEN;\n\n\t\/*Set PA8 to AF*\/\n\tGPIOA-&gt;MODER|=GPIO_MODER_MODE8_1;\n\tGPIOA-&gt;MODER&amp;=~GPIO_MODER_MODE8_0;\n\n\t\/*Set PA8 to AF1*\/\n\n\tGPIOA-&gt;AFR[1]|=(AF01&lt;&lt;GPIO_AFRH_AFSEL8_Pos);\n\n\n\t\/*Timer configuration*\/\n\n\tRCC-&gt;APB2ENR  |=  RCC_APB2ENR_TIM1EN;\n\n\tTIM1-&gt;DIER=TIM_DIER_UDE;\n\n\tTIM1-&gt;PSC=16000-1; \/*16 000 000 \/ 16 000 =1 000*\/\n\tTIM1-&gt;ARR=1000-1; \/*1 000 \/ 1 000 = 10HZ*\/\n\n\tTIM1-&gt;CCR1=100;\n\n\tTIM1-&gt;CCMR1|=TIM_CCMR1_OC1M_2|TIM_CCMR1_OC1M_1;\n\n\tTIM1-&gt;CCER|=TIM_CCER_CC1E;\n\n\tTIM1-&gt;BDTR|=TIM_BDTR_MOE;\n\n\t\/*DMA configuration*\/\n\n\n\tRCC-&gt;AHB1ENR|=RCC_AHB1ENR_DMA2EN;\n\n\tDMA2_Stream5-&gt;CR&amp;=DMA_SxCR_EN;\n\n\twhile((DMA2_Stream5-&gt;CR)&amp;DMA_SxCR_EN){;}\n\n\tDMA2_Stream5-&gt;CR|=(CH6&lt;&lt;DMA_SxCR_CHSEL_Pos)|DMA_SxCR_MSIZE|DMA_SxCR_PSIZE|\n\t\t\tDMA_SxCR_MINC|DMA_SxCR_CIRC|DMA_SxCR_DIR_0;\n\n\tDMA2_Stream5-&gt;NDTR=(uint32_t)data_size;\n\n\tDMA2_Stream5-&gt;PAR=(uint32_t)(&amp;GPIOC-&gt;ODR);\n\n\tDMA2_Stream5-&gt;M0AR=(uint32_t)(gpio_pattern);\n\n\n\t\/*Launch DMA*\/\n\tDMA2_Stream5-&gt;CR|=DMA_SxCR_EN;\n\n\t\/*Launch Timer*\/\n\tTIM1-&gt;CR1     |= TIM_CR1_CEN;\n\n\tsrand (TIM1-&gt;CNT);\n\n\twhile(1)\n\t{\n\t\tsprintf(lcd_data,&quot;Data to be send:&quot;);\n\t\tsetCursor(0, 0);\n\t\tlcd_send_string(lcd_data);\n\t\tsetCursor(0, 1);\n\t\tcounter=5-((DMA2_Stream5-&gt;NDTR));\n\t\tsprintf(lcd_data,&quot;%d   &quot;,gpio_pattern[counter]);\n\t\tlcd_send_string(lcd_data);\n\n\t}\n\n}\n<\/pre><\/div>\n\n\n\n<p>You might noticed, we no longer randomize the data to be send and they have been fixed to certain values.<\/p>\n\n\n\n<p>Also, the LCD part is added.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Thats all for the transmitter code modification.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2. Receiver Code:<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<p>For the receiver code, we need an extra STM32F4xx board to receive the data.<\/p>\n\n\n\n<p>We start off by including these header file:<\/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;stm32f4xx.h&quot;\n#include &quot;i2c.h&quot;\n#include &quot;stdio.h&quot;\n#include &quot;LiquidCrystal_PCF8574.h&quot;<\/pre><\/div>\n\n\n\n<p>Declare characters array to handle the display:<\/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;}\">char str[40];<\/pre><\/div>\n\n\n\n<p>Declare volatile uint8_t variable for parallel data handling:<\/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;}\">volatile uint8_t parallelData;<\/pre><\/div>\n\n\n\n<p>In main function:<\/p>\n\n\n\n<p>Initialize the i2c and LCD:<\/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;}\">int main()\n{\t\n\t\/*LCD Stuff*\/\n\ti2c_init();\n\tlcd_init();\n\tlcd_clear();\n<\/pre><\/div>\n\n\n\n<p>We shall use pin0 to pin7 from portC to handle the received data.<\/p>\n\n\n\n<p>First enable clock access to GPIOC:<\/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 clock access to GPIOC*\/\n\tRCC-&gt;AHB1ENR|=RCC_AHB1ENR_GPIOCEN;<\/pre><\/div>\n\n\n\n<p>Set PC0 to PC7 as input:<\/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\/*Set PC0 to PC7 as input*\/\n\tGPIOC-&gt;MODER&amp;=~(GPIO_MODER_MODE0|GPIO_MODER_MODE1|GPIO_MODER_MODE2\n\t\t\t|GPIO_MODER_MODE3|GPIO_MODER_MODE4|GPIO_MODER_MODE5|GPIO_MODER_MODE6\n\t\t\t|GPIO_MODER_MODE7);\n<\/pre><\/div>\n\n\n\n<p>Since the transmitter has strobe signal, we shall use PA0 in falling edge interrupt to detect the new data:<\/p>\n\n\n\n<p>Start with enabling clock access to GPIOA:<\/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 Clock access to GPIOA*\/\n\tRCC-&gt;AHB1ENR|=RCC_AHB1ENR_GPIOAEN;<\/pre><\/div>\n\n\n\n<p>Set PA0 as input:<\/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\/*Set PA0 as input*\/\n\tGPIOA-&gt;MODER&amp;=~GPIO_MODER_MODE0;<\/pre><\/div>\n\n\n\n<p>For the interrupt generation on external event (EXTI), first we need to enable clock access to SYSCFG 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;}\">\t\/*Enable clock access to syscfg*\/\n\tRCC-&gt;APB2ENR|=RCC_APB2ENR_SYSCFGEN;<\/pre><\/div>\n\n\n\n<p>Set EXTI0 to be PortA 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;}\">\t\/*Set EXTI0 to be portA*\/\n\tSYSCFG-&gt;EXTICR[0]|=SYSCFG_EXTICR1_EXTI0_PA;<\/pre><\/div>\n\n\n\n<p>Unmask line 0 of the interrupt:<\/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\/*Unmask line0*\/\n\tEXTI-&gt;IMR|=EXTI_IMR_IM0;<\/pre><\/div>\n\n\n\n<p>Set the edge detection to be falling edge:<\/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\/*Set detection to falling edge*\/\n\tEXTI-&gt;FTSR|=EXTI_FTSR_TR0;<\/pre><\/div>\n\n\n\n<p>Finally enable line0 in NVIC 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;}\">\t\/*Enable the EXTI0 in NVIC*\/\n\n\tNVIC_EnableIRQ(EXTI0_IRQn);<\/pre><\/div>\n\n\n\n<p>In while (1) loop:<\/p>\n\n\n\n<p>Just print the received data:<\/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;}\">\twhile(1)\n\t{\n\t\tsetCursor(0, 0);\n\t\tsprintf(str,&quot;Received data=%d   &quot;,parallelData);\n\t\tlcd_send_string(str);\n\t}<\/pre><\/div>\n\n\n\n<p>For the interrupt handler:<\/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 EXTI0_IRQHandler (void)\n{\n\tif ((EXTI-&gt;PR &amp; EXTI_PR_PR0) == EXTI_PR_PR0)\n\t{\n\t\t\/*Get the new data*\/\n\t\tparallelData=(uint8_t)GPIOC-&gt;IDR;\n\n\t\t\/*Clear the pending flag*\/\n\t\tEXTI-&gt;PR |= EXTI_PR_PR0;\n\n\t}\n}\n<\/pre><\/div>\n\n\n\n<p>Check if the source is PR0 and if it is, read the IDR register of portc and store it in the volatile variable.<\/p>\n\n\n\n<p>Clear the pending flag by writing 1 to PR0 bit of PR register.<\/p>\n\n\n\n<p><\/p>\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;stm32f4xx.h&quot;\n#include &quot;i2c.h&quot;\n#include &quot;stdio.h&quot;\n#include &quot;LiquidCrystal_PCF8574.h&quot;\n\nchar str[40];\n\nvolatile uint8_t parallelData;\n\n\nint main()\n{\n\t\/*LCD Stuff*\/\n\ti2c_init();\n\tlcd_init();\n\tlcd_clear();\n\n\t\/*Enable clock access to GPIOC*\/\n\tRCC-&gt;AHB1ENR|=RCC_AHB1ENR_GPIOCEN;\n\t\n\t\/*Set PC0 to PC7 as input*\/\n\tGPIOC-&gt;MODER&amp;=~(GPIO_MODER_MODE0|GPIO_MODER_MODE1|GPIO_MODER_MODE2\n\t\t\t|GPIO_MODER_MODE3|GPIO_MODER_MODE4|GPIO_MODER_MODE5|GPIO_MODER_MODE6\n\t\t\t|GPIO_MODER_MODE7);\n\n\t\/*Enable Clock access to GPIOA*\/\n\tRCC-&gt;AHB1ENR|=RCC_AHB1ENR_GPIOAEN;\n\t\n\t\/*Set PA0 as input*\/\n\tGPIOA-&gt;MODER&amp;=~GPIO_MODER_MODE0;\n\n\t\/*Enable clock access to syscfg*\/\n\tRCC-&gt;APB2ENR|=RCC_APB2ENR_SYSCFGEN;\n\n\t\/*Set EXTI0 to be portA*\/\n\tSYSCFG-&gt;EXTICR[0]|=SYSCFG_EXTICR1_EXTI0_PA;\n\n\t\/*Unmask line0*\/\n\tEXTI-&gt;IMR|=EXTI_IMR_IM0;\n\n\t\/*Set detection to falling edge*\/\n\tEXTI-&gt;FTSR|=EXTI_FTSR_TR0;\n\n\t\/*Enable the EXTI0 in NVIC*\/\n\n\tNVIC_EnableIRQ(EXTI0_IRQn);\n\n\twhile(1)\n\t{\n\t\tsetCursor(0, 0);\n\t\tsprintf(str,&quot;Received data=%d   &quot;,parallelData);\n\t\tlcd_send_string(str);\n\t}\n}\n\nvoid EXTI0_IRQHandler (void)\n{\n\tif ((EXTI-&gt;PR &amp; EXTI_PR_PR0) == EXTI_PR_PR0)\n\t{\n\t\t\/*Get the new data*\/\n\t\tparallelData=(uint8_t)GPIOC-&gt;IDR;\n\n\t\t\/*Clear the pending flag*\/\n\t\tEXTI-&gt;PR |= EXTI_PR_PR0;\n\n\t}\n}\n<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3. Connection of Two STM32s:<\/h2>\n\n\n\n<p>The parallel connection as following:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"694\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/09\/Screenshot-2023-09-20-at-8.11.17-AM-1024x694.png\" alt=\"\" class=\"wp-image-1990\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/09\/Screenshot-2023-09-20-at-8.11.17-AM-1024x694.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/09\/Screenshot-2023-09-20-at-8.11.17-AM-300x203.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/09\/Screenshot-2023-09-20-at-8.11.17-AM-768x521.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/09\/Screenshot-2023-09-20-at-8.11.17-AM-1536x1042.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/09\/Screenshot-2023-09-20-at-8.11.17-AM-2048x1389.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/09\/Screenshot-2023-09-20-at-8.11.17-AM-1150x780.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/09\/Screenshot-2023-09-20-at-8.11.17-AM-750x509.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/09\/Screenshot-2023-09-20-at-8.11.17-AM-400x271.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/09\/Screenshot-2023-09-20-at-8.11.17-AM-250x170.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>For the LCD connection:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"568\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/09\/Screen-Shot-2021-12-27-at-6.22.13-AM-2048x1135-1-1024x568.png\" alt=\"\" class=\"wp-image-1991\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/09\/Screen-Shot-2021-12-27-at-6.22.13-AM-2048x1135-1-1024x568.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/09\/Screen-Shot-2021-12-27-at-6.22.13-AM-2048x1135-1-300x166.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/09\/Screen-Shot-2021-12-27-at-6.22.13-AM-2048x1135-1-768x426.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/09\/Screen-Shot-2021-12-27-at-6.22.13-AM-2048x1135-1-1536x851.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/09\/Screen-Shot-2021-12-27-at-6.22.13-AM-2048x1135-1-1150x637.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/09\/Screen-Shot-2021-12-27-at-6.22.13-AM-2048x1135-1-750x416.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/09\/Screen-Shot-2021-12-27-at-6.22.13-AM-2048x1135-1-400x222.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/09\/Screen-Shot-2021-12-27-at-6.22.13-AM-2048x1135-1-250x139.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/09\/Screen-Shot-2021-12-27-at-6.22.13-AM-2048x1135-1.png 2048w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">4. Code:<\/h2>\n\n\n\n<p>You may download the both code from here:<\/p>\n\n\n\n<p>Transmitter code:<\/p>\n\n\n\n<div class=\"wp-block-file\"><a href=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/09\/Parallel_Emulation.zip\">Parallel_Emulation<\/a><a href=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/09\/Parallel_Emulation.zip\" class=\"wp-block-file__button\" download>Download<\/a><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>Receiver code (For F446RE):<\/p>\n\n\n\n<div class=\"wp-block-file\"><a href=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/09\/Parallel_Emulation_Input.zip\">Parallel_Emulation_Input<\/a><a href=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/09\/Parallel_Emulation_Input.zip\" class=\"wp-block-file__button\" download>Download<\/a><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">5. Results:<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"Parallel Port Emulation: Input Mode\" width=\"1170\" height=\"658\" src=\"https:\/\/www.youtube.com\/embed\/IvUcSQPlTlc?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>As you can see, we have successfully transmitted the data and received it.<\/p>\n\n\n\n<p>Now the question is, when the transmitter transfer the number 400, why the receiver received 144?<\/p>\n\n\n\n<p>Share your answer in comments.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Happy coding \ud83d\ude09<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the second section of part 2 of parallel port emulation, we shall see how to read the data being transmitted and display the data on LCD. In this guide, we shall cover the following: Transmitter code modification. Receiver code. Connection of two STM32s. Code Results. 1. Transmitter Code Modification: Before the code modification, take [&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,19,11,12],"tags":[],"class_list":["post-1988","post","type-post","status-publish","format-standard","hentry","category-embedded-systems","category-lcd","category-peripheral-drivers","category-stm32"],"_links":{"self":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/1988"}],"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=1988"}],"version-history":[{"count":1,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/1988\/revisions"}],"predecessor-version":[{"id":1994,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/1988\/revisions\/1994"}],"wp:attachment":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1988"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1988"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1988"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}