{"id":940,"date":"2015-03-28T23:26:50","date_gmt":"2015-03-29T03:26:50","guid":{"rendered":"https:\/\/ve2cuy.wordpress.com\/?page_id=940"},"modified":"2015-03-28T23:26:50","modified_gmt":"2015-03-29T03:26:50","slug":"proteus-pic-18f4550-usart-and-lcd","status":"publish","type":"page","link":"https:\/\/ve2cuy.com\/blog\/index.php\/proteus-pic-18f4550-usart-and-lcd\/","title":{"rendered":"Proteus &#8211; PIC 18F4550 USART and LCD"},"content":{"rendered":"<p>Using Proteus, this project demonstrates how to use the 18F4550 USART to receive, using <span style=\"text-decoration:underline;\">hardware interrupts<\/span>, and transmit characters. The\u00a0characters will be displayed on the LCD.<\/p>\n<h1>The schematic diagram<\/h1>\n<p><a href=\"http:\/\/ve2cuy.com\/blog\/wp-content\/uploads\/2015\/03\/mplab_xc8-v2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-971 size-large\" src=\"http:\/\/ve2cuy.com\/blog\/wp-content\/uploads\/2015\/03\/mplab_xc8-v2.png?w=630\" alt=\"mplab_xc8.v2\" width=\"630\" height=\"465\" srcset=\"https:\/\/ve2cuy.com\/blog\/wp-content\/uploads\/2015\/03\/mplab_xc8-v2.png 1250w, https:\/\/ve2cuy.com\/blog\/wp-content\/uploads\/2015\/03\/mplab_xc8-v2-300x222.png 300w, https:\/\/ve2cuy.com\/blog\/wp-content\/uploads\/2015\/03\/mplab_xc8-v2-1024x756.png 1024w, https:\/\/ve2cuy.com\/blog\/wp-content\/uploads\/2015\/03\/mplab_xc8-v2-768x567.png 768w\" sizes=\"auto, (max-width: 630px) 100vw, 630px\" \/><\/a><\/p>\n<h1>A video of the simulation<\/h1>\n<p><iframe loading=\"lazy\" title=\"Proteus simulation - PIC 18F + UART + LCD\" width=\"700\" height=\"394\" src=\"https:\/\/www.youtube.com\/embed\/ia1Z8MHVgWc?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen><\/iframe><\/p>\n<p><span style=\"color:#ff0000;\"><strong>Note<\/strong><\/span>: On the video version of the simulation, I&rsquo;m using a COM Port Physical Interface Model, <a href=\"http:\/\/www.eterlogic.com\/Downloads.html\">Eterlogic virtual serial port emulator<\/a>\u00a0and putty. The &lsquo;<strong>spbrg<\/strong> divider&rsquo; is set to <strong>16<\/strong>:\u00a0&lsquo;<em>int divisor = 16;<\/em>&lsquo;<\/p>\n<h1>The working prototype on a physical PIC 18F4553<\/h1>\n<p><a href=\"http:\/\/ve2cuy.com\/blog\/wp-content\/uploads\/2015\/03\/pic_uart_small.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-980\" src=\"http:\/\/ve2cuy.com\/blog\/wp-content\/uploads\/2015\/03\/pic_uart_small.png\" alt=\"PIC_UART_small\" width=\"630\" height=\"502\" srcset=\"https:\/\/ve2cuy.com\/blog\/wp-content\/uploads\/2015\/03\/pic_uart_small.png 806w, https:\/\/ve2cuy.com\/blog\/wp-content\/uploads\/2015\/03\/pic_uart_small-300x239.png 300w, https:\/\/ve2cuy.com\/blog\/wp-content\/uploads\/2015\/03\/pic_uart_small-768x612.png 768w\" sizes=\"auto, (max-width: 630px) 100vw, 630px\" \/><\/a><\/p>\n<p>To test the project in Proteus, you will need to install <a href=\"http:\/\/www.microchip.com\/pagehandler\/en_us\/devtools\/mplabxc\/\">MPLAB XC8<\/a> on your workstation:<\/p>\n<p><a href=\"http:\/\/ve2cuy.com\/blog\/wp-content\/uploads\/2015\/03\/xc8-conf.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-large wp-image-977\" src=\"http:\/\/ve2cuy.com\/blog\/wp-content\/uploads\/2015\/03\/xc8-conf.png?w=630\" alt=\"xc8-conf\" width=\"630\" height=\"345\" srcset=\"https:\/\/ve2cuy.com\/blog\/wp-content\/uploads\/2015\/03\/xc8-conf.png 683w, https:\/\/ve2cuy.com\/blog\/wp-content\/uploads\/2015\/03\/xc8-conf-300x164.png 300w\" sizes=\"auto, (max-width: 630px) 100vw, 630px\" \/><\/a><\/p>\n<p><a href=\"http:\/\/ve2cuy.com\/blog\/wp-content\/uploads\/2015\/03\/mplab_xc8.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-958\" src=\"http:\/\/ve2cuy.com\/blog\/wp-content\/uploads\/2015\/03\/mplab_xc8.png\" alt=\"mplab_xc8\" width=\"593\" height=\"514\" srcset=\"https:\/\/ve2cuy.com\/blog\/wp-content\/uploads\/2015\/03\/mplab_xc8.png 593w, https:\/\/ve2cuy.com\/blog\/wp-content\/uploads\/2015\/03\/mplab_xc8-300x260.png 300w\" sizes=\"auto, (max-width: 593px) 100vw, 593px\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<hr \/>\n<h1><\/h1>\n<h1>Source code listing<\/h1>\n<p>&nbsp;<\/p>\n<pre><\/pre>\n<p>[sourcecode language=\u00a0\u00bbcpp\u00a0\u00bb]<br \/>\n\/*<br \/>\n * Auteur &#8211; Author: Alain Boudreault (VE2CUY)<br \/>\n * Date: 2015.03.28<br \/>\n * &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br \/>\n * Description: Get characters from COM port and display them on LCD.<br \/>\n * &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br \/>\n * Note: Compiled with xc8 &#8211; make shure that you have installed MPLAB XC8<br \/>\n * &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br \/>\n * Directives de connexions du PIC avec le LCD:<br \/>\n *<br \/>\n * Ce projet utilise les valeurs par d\u00e9faut de plib\/xlcd.h sur BUS 4 bits<br \/>\n *<br \/>\n * &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br \/>\n * Connections between the PIC and the LCD<br \/>\n *<br \/>\n * LCD PIN PIC PIN<br \/>\n * RW 5 RB6 39<br \/>\n * RS 4 RB5 38<br \/>\n * E 6 RB4 37<br \/>\n *<br \/>\n * DATA: 4 bits<br \/>\n * LCD PIN PIC PIN<br \/>\n * D4 11 RB0 33<br \/>\n * D5 12 RB1 34<br \/>\n * D6 13 RB2 35<br \/>\n * D7 14 RB3 36<br \/>\n *<br \/>\n * UART<br \/>\n * RX -&gt; RC6 (TX)<br \/>\n * TX -&gt; RC7 (RX)<br \/>\n *<br \/>\n * &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br \/>\n * Data Sheet: http:\/\/ww1.microchip.com\/downloads\/en\/devicedoc\/39632c.pdf<br \/>\n * See page 237 for USART<br \/>\n *\/<\/p>\n<p>#include &lt;xc.h&gt;<br \/>\n#include &lt;plib\/xlcd.h&gt;<br \/>\n#include &lt;plib\/usart.h&gt;<\/p>\n<p>#pragma config FOSC = INTOSC_EC \/\/ Internal clock<br \/>\n#pragma config LVP = 0; \/\/ The real LCD will not work with out it. Someone knows why?<br \/>\n#define VITESSE_8MHZ 0b01110000<br \/>\n#define _XTAL_FREQ 8000000L \/\/ needed for __delay_ms()<br \/>\n#define BAUD_RATE 38400<br \/>\n#define SYS_FREQ 8000000L<br \/>\n#define FCY (SYS_FREQ\/4)<br \/>\n#define END_OF_TIME 1<br \/>\n#define LINE_2 0x40<br \/>\n#define LINE_3 0x14<br \/>\n#define LINE_4 0x54<br \/>\n#define COLONNE_DROITE 19 \/\/ Last column<br \/>\n#define LCD_SIZE 80<br \/>\n#define USE_AND_MASKS<\/p>\n<p>unsigned char MsgFromPIC[] = &quot;\\r\\nYou have typed: \\r\\n\\r\\n&quot;;<br \/>\nunsigned char enter[] = &quot;\\r\\n\\r\\n&quot;;<br \/>\nunsigned char info[] = &quot;=====================================================\\r\\nUART example on 18F4550\\r\\nBy Alain Boudreault &#8211; AKA VE2CUY, AKA Puyansude\\r\\n(c) 2015.28.03\\r\\n=====================================================\\r\\n\\r\\n&quot;;<br \/>\nunsigned char msg_depart[] = &quot;Type some characters followed by &lsquo;Enter&rsquo;\\r\\n&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;\\r\\n\\r\\n&quot;;<\/p>\n<p>unsigned char MessageBuffer[200];<br \/>\nint i=0;<\/p>\n<p>\/\/ ***************************************************<br \/>\n\/\/ Prototypes des fonctions locales au projet<br \/>\n\/\/ &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br \/>\n\/\/ Functions Prototype<br \/>\n\/\/ ***************************************************<br \/>\nvoid init_XLCD(void);<br \/>\nvoid initXLCDWithShift(void);<br \/>\nvoid cls(void);<br \/>\nvoid DelayFor18TCY(void);<br \/>\nvoid DelayPORXLCD(void);<br \/>\nvoid DelayXLCD(void);<br \/>\nvoid uneDemieSeconde(void);<br \/>\nvoid afficherMessage(void);<br \/>\nvoid afficherMsgAvecDelai(char * msg[], int sec, int position);<br \/>\nvoid testerUART(void);<\/p>\n<p>\/\/ ***************************************************<br \/>\nvoid testerUART(void)<br \/>\n\/\/ ***************************************************<br \/>\n{<br \/>\n int UART1Config = USART_TX_INT_OFF &amp; USART_RX_INT_ON &amp; USART_ASYNCH_MODE &amp; USART_EIGHT_BIT &amp; USART_BRGH_HIGH ;<\/p>\n<p> \/\/ These are default values &#8211; but just in case:<br \/>\n SYNC = 0; \/\/ Asynchronous<br \/>\n BRG16 = 0; \/\/ 8-bit<br \/>\n BRGH = 1; \/\/ High Baud Rate<br \/>\n int divisor = 4;<\/p>\n<p> int spbrg = _XTAL_FREQ \/ BAUD_RATE \/ divisor &#8211; 1; \/\/ Set baud rate<br \/>\n OpenUSART(UART1Config,spbrg);<\/p>\n<p> __delay_ms(50); \/\/ or else garbage the first time&#8230;<br \/>\n putsUSART(info);<br \/>\n putsUSART(msg_depart);<br \/>\n} \/\/ testerUART()<\/p>\n<p>\/\/ ***************************************************<br \/>\nvoid interrupt traitementDesInterruptions()<br \/>\n\/\/ ***************************************************<br \/>\n{<br \/>\n \/\/UART RX ?<br \/>\n if(PIR1bits.RCIF == 1)<br \/>\n {<br \/>\n if(i&lt;200) \/\/our buffer size<br \/>\n {<br \/>\n MessageBuffer[i] = ReadUSART(); \/\/read the byte from rx register<\/p>\n<p> if(MessageBuffer[i] != 0x0D) {<br \/>\n putcXLCD(MessageBuffer[i]); \/\/ Afficher le car sur le LCD<br \/>\n PORTD = MessageBuffer[i]; \/\/ R\u00e9troaction sur PORTD<br \/>\n }<br \/>\n else \/\/ Nous avons re\u00e7u un Enter -&gt; renvoyer vers UART<br \/>\n {<br \/>\n for (int compteur = 1; compteur&lt;=LCD_SIZE; compteur++)<br \/>\n putrsXLCD(&quot; &quot;);<\/p>\n<p> putsUSART(MsgFromPIC);<br \/>\n putsUSART(MessageBuffer);<br \/>\n putsUSART(enter); putsUSART(msg_depart);<\/p>\n<p> for(;i&gt;0;i&#8211;)<br \/>\n MessageBuffer[i] = 0x00; \/\/clear the array<br \/>\n i=0; \/\/for sanity<br \/>\n return;<br \/>\n }<\/p>\n<p> i++;<br \/>\n PIR1bits.RCIF = 0; \/\/ clear rx flag<br \/>\n }<br \/>\n else<br \/>\n {<br \/>\n putsUSART(MessageBuffer);<br \/>\n for(;i&gt;0;i&#8211;)<br \/>\n MessageBuffer[i] = 0x00; \/\/clear the array<br \/>\n i=0; \/\/for sanity<br \/>\n return;<br \/>\n }<br \/>\n } \/\/ if(PIR1bits.RCIF == 1)<br \/>\n} \/\/ traitementDesInterruptions()<\/p>\n<p>\/\/ ***************************************************<br \/>\nvoid main(void) {<br \/>\n\/\/ ***************************************************<\/p>\n<p> OSCCON = VITESSE_8MHZ; \/\/ set Fosc to 8mhz<br \/>\n init_XLCD();<\/p>\n<p> \/\/Set interrupt (for USART)<br \/>\n RCIF = 0; \/\/reset RX pin flag<br \/>\n RCIP = 0; \/\/Not high priority<br \/>\n RCIE = 1; \/\/Enable RX interrupt<br \/>\n PEIE = 1; \/\/Enable pheripheral interrupt (serial port is a pheripheral)<br \/>\n ei(); \/\/remember the master switch for interrupt?<\/p>\n<p> \/\/ Display start messages on startup<br \/>\n afficherMsgAvecDelai(&quot;USART test &quot;, 1, 0);<br \/>\n afficherMsgAvecDelai(&quot;At 38400 baud&quot;, 1, LINE_2);<br \/>\n afficherMsgAvecDelai(&quot;By VE2CUY (c) 2015&quot;, 3, LINE_3);<br \/>\n afficherMsgAvecDelai(&quot;This is line 4&quot;, 1, LINE_4);<br \/>\n cls();<br \/>\n afficherMsgAvecDelai(&quot; Start putty &quot;, 1, 0);<br \/>\n afficherMsgAvecDelai(&quot;and type&quot;, 1, LINE_2);<br \/>\n afficherMsgAvecDelai(&quot;some characters&#8230;&quot;, 3, LINE_3);<br \/>\n cls();<\/p>\n<p> initXLCDWithShift();<br \/>\n testerUART();<br \/>\n while (END_OF_TIME); \/\/ This is possible because we are using interrupts for the USART<\/p>\n<p>} \/\/ main()<\/p>\n<p>\/\/ ***************************************************<br \/>\n\/\/ local functions<\/p>\n<p>\/\/ ***************************************************<br \/>\nvoid init_XLCD(void)<br \/>\n\/\/ ***************************************************<br \/>\n{<br \/>\n OpenXLCD(FOUR_BIT&amp;LINES_5X7); \/\/ configure LCD: 4-bit, 5x7char, multi-lines<br \/>\n while(BusyXLCD()); \/\/ Wait until LCD !busy<br \/>\n WriteCmdXLCD(0x06); \/\/ 06 = pas de swift, 07 = shift vers la gauche<br \/>\n WriteCmdXLCD(0x0C); \/\/ display on without cursor<br \/>\n } \/\/ init_XLCD<\/p>\n<p>\/\/ ***************************************************<br \/>\nvoid initXLCDWithShift(void)<br \/>\n\/\/ ***************************************************<br \/>\n{<br \/>\n OpenXLCD(FOUR_BIT&amp;LINES_5X7); \/\/ configure LCD: 4-bit, 5x7char, multi-lines<br \/>\n while(BusyXLCD()); \/\/ Wait until LCD !busy<br \/>\n WriteCmdXLCD(0x07); \/\/ 06 = pas de swift, 07 = shift vers la gauche<br \/>\n WriteCmdXLCD(0x0F); \/\/ display on with blink cursor<br \/>\n while(BusyXLCD());<br \/>\n SetDDRamAddr(COLONNE_DROITE); \/\/ Placer le curseur \u00e0 la derni\u00e8re colonne de la ligne 1<\/p>\n<p> } \/\/ init_XLCD<\/p>\n<p>\/\/ ***************************************************<br \/>\n\/\/ Clear LCD screen<br \/>\nvoid cls(void){<br \/>\n\/\/ ***************************************************<br \/>\n while(BusyXLCD()); \/\/Check if the LCD controller is not busy<br \/>\n WriteCmdXLCD(0x01); \/\/ Clear LCD<br \/>\n} \/\/ cls<\/p>\n<p>\/\/ ***************************************************<br \/>\n\/\/ Wait 500ms<br \/>\nvoid uneDemieSeconde(void){<br \/>\n\/\/ ***************************************************<br \/>\n for (int i=0;i&lt;10;i++)<br \/>\n __delay_ms(50);<br \/>\n} \/\/ uneDemieSeconde<\/p>\n<p>\/\/ ***************************************************<br \/>\n\/\/ Display message on LCD and wait delay<br \/>\nvoid afficherMsgAvecDelai(char * msg[], int sec, int position) {<br \/>\n\/\/ ***************************************************<br \/>\n while(BusyXLCD());<br \/>\n SetDDRamAddr(position);<br \/>\n while(BusyXLCD());<br \/>\n putrsXLCD( msg );<br \/>\n while(BusyXLCD());<br \/>\n for (int i = 0 ; i&lt;sec; i++) {<br \/>\n uneDemieSeconde();<br \/>\n }<br \/>\n} \/\/ afficherMsgAvecDelai<\/p>\n<p>\/\/ Impl\u00e9mentation des routines de d\u00e9lais pour plib\/xlcd.h<br \/>\n\/\/ Note: Il faut d\u00e9finir la constante suivante:<br \/>\n\/\/ #define _XTAL_FREQ 8000000 \/\/ Note: 8mg est un exemple<br \/>\n\/\/<br \/>\n\/\/ &#8212;&#8212;&#8212;&#8211; Delay functions for the LCD &#8212;&#8212;&#8212;&#8211;<\/p>\n<p>\/\/ ***************************************************<br \/>\nvoid DelayFor18TCY(void)<br \/>\n\/\/ ***************************************************<br \/>\n{ __delay_us(72); \/\/ Value of 18 did not work for me!<br \/>\n}<\/p>\n<p>\/\/ ***************************************************<br \/>\nvoid DelayPORXLCD(void)<br \/>\n\/\/ ***************************************************<br \/>\n{ __delay_ms(15); }<\/p>\n<p>\/\/ ***************************************************<br \/>\nvoid DelayXLCD(void)<br \/>\n\/\/ ***************************************************<br \/>\n{ __delay_ms(5); }<br \/>\n[\/sourcecode]<\/p>\n<p>The Proteus project with source code is available\u00a0<a href=\"https:\/\/drive.google.com\/uc?export=download&amp;id=0BwVyrqVfxGkRYWFfa2FQR3NWczg\">here<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Using Proteus, this project demonstrates how to use the 18F4550 USART to receive, using hardware interrupts, and transmit characters. The\u00a0characters will be displayed on the LCD. The schematic diagram A video of the simulation Note: On the video version of the simulation, I&rsquo;m using a COM Port Physical Interface Model, Eterlogic virtual serial port emulator\u00a0and [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"open","ping_status":"open","template":"","meta":{"footnotes":""},"class_list":["post-940","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/ve2cuy.com\/blog\/index.php\/wp-json\/wp\/v2\/pages\/940","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ve2cuy.com\/blog\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/ve2cuy.com\/blog\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/ve2cuy.com\/blog\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/ve2cuy.com\/blog\/index.php\/wp-json\/wp\/v2\/comments?post=940"}],"version-history":[{"count":0,"href":"https:\/\/ve2cuy.com\/blog\/index.php\/wp-json\/wp\/v2\/pages\/940\/revisions"}],"wp:attachment":[{"href":"https:\/\/ve2cuy.com\/blog\/index.php\/wp-json\/wp\/v2\/media?parent=940"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}