picspalsandgals

University of Washington Electrical Engineering Blog

Code

This is where we will post code:

The code below is for the PIC18F LCD Hello World.  Only shown are the header file and the main.c file, the remainder of the files needed (delay.c, delay.h and lcd.c are included in Hi-Tech PIC C18).

main.c:

/*   piclcd.c
*   (C) 2011 Joshua Jones
*   This program is free software: you can redistribute it and/or modify
*   it under the terms of the GNU General Public License as published by
*   the Free Software Foundation, either version 3 of the License, or
*   (at your option) any later version.
*
*   This program is distributed in the hope that it will be useful,
*   but WITHOUT ANY WARRANTY; without even the implied warranty of
*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*   GNU General Public License for more details.
*
*   You should have received a copy of the GNU General Public License
*   along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <pic18.h>
#include <htc.h>
#include "delay.h"
#include "lcd.h"

/*
* a trivial program display "Hello World" on an LCD.  This uses all
* of PORT D for LCD data and RC0-RC2 for LCD control signals.
* This was also built using HI-TECH PIC C and the LCD library included
* with it - which is really just a generic driver for many alphanumeric
* LCDs of this type.
*/

/* Configure our PIC's Configuration words, this is for a PIC18F4455
* with a 20 MHz crystal oscillator
*/
__CONFIG(1,USBPLL&PLLDIV5&CPUDIV4&HSPLL&FCMEN&IESOEN);
__CONFIG(2,VREGDIS&PWRTEN&BORDIS&BORV42&WDTDIS&WDTPS32K);
__CONFIG(3,PBDIGITAL&LPT1DIS&MCLREN);
__CONFIG(4,XINSTDIS&STVRDIS&LVPDIS&ICPORTDIS&DEBUGDIS);
__CONFIG(5,UNPROTECT);
__CONFIG(6,UNPROTECT);
__CONFIG(7,UNPROTECT);

/* our main program loop */
void main(void)
{
   /* initialize our ports to zero and as outputs */
   PORTD = 0x00;
   TRISD = 0x00;
   PORTC = 0x00;
   TRISC = 0x00;

   /* init the lcd in full byte mode, home the cursor
    * and write "Hello World"
    */
   lcd_init(EIGHTBIT_MODE);
   lcd_home();
   lcd_puts("HELLO WORLD");

   while(1) {
     //nothing!
   }
}

lcd.h:

#ifndef _LCD_H_
#define _LCD_H_

/*
*    LCD interface header file
*/

/*     Defining CHECKBUSY will check if the LCD is busy. The RW bit of the
*     LCD must connected to a port of the processor for the check busy
*     process to work.
*
*     If CHECKBUSY is not defined it will instead use a delay loop.
*     The RW bit of the LCD does not need to connected in this case.
*/

#ifdef CHECKBUSY
#define    LCD_WAIT lcd_check_busy()
#else
#define LCD_WAIT DelayMs(5)

#endif

#define MESSAGE_LINE        0x0

#define LCD_RS    LATC2 //RC2
#define LCD_EN    LATC0 //RC0
#define LCD_RW    LATC1 //RC1
#define LCD_DATA    LATD
#define LCD_DATA_PORT    PORTD
#define LCD_RS_TRIS    TRISC2
#define LCD_EN_TRIS    TRISC0
#define LCD_RW_TRIS    TRISC1
#define LCD_DATA_TRIS    TRISD

#define FOURBIT_MODE    0x0
#define EIGHTBIT_MODE    0x1
#define OUTPUT_PIN      0x0
#define INPUT_PIN       0x1
#define OUTPUT_DATA     0x0
#define INPUT_DATA      0x0F

#define LCD_STROBE()    LCD_EN = 1; asm("nop"); asm("nop"); LCD_EN = 0

#define LCD_STROBE_READ(value)    LCD_EN = 1; \
asm("nop"); asm("nop"); \
value=LCD_DATA_PORT; \
LCD_EN = 0;

#define    lcd_cursor(x)            lcd_cmd(((x)&0x7F)|0x80)
#define lcd_clear()            lcd_cmd(0x1)
#define lcd_putch(x)            lcd_data(x)
#define lcd_goto(x)            lcd_cmd(0x80+(x));
#define lcd_cursor_right()        lcd_cmd(0x14)
#define lcd_cursor_left()        lcd_cmd(0x10)
#define lcd_display_shift()        lcd_cmd(0x1C)
#define lcd_home()            lcd_cmd(0x2)

extern void lcd_cmd(unsigned char);
extern void lcd_data(unsigned char);
extern void lcd_puts(const char * s);
extern void lcd_init(unsigned char);

#endif

The below code is the LED blinking code for the 18F4550. With some basic modifications, this was taken from the second tutorial on the http://www.pic18f.com website.

;    Tutorial2.asm - LED Blink
;    Copyright (C) 2007 www.pic18f.com
;
;    This program is free software: you can redistribute it and/or modify
;    it under the terms of the GNU General Public License as published by
;    the Free Software Foundation, either version 3 of the License, or
;    (at your option) any later version.
;
;    This program is distributed in the hope that it will be useful,
;    but WITHOUT ANY WARRANTY; without even the implied warranty of
;    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;    GNU General Public License for more details.
;
;    You should have received a copy of the GNU General Public License
;    along with this program.  If not, see <http://www.gnu.org/licenses/>.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

#include <p18F4550.inc>

	CONFIG WDT=OFF; disable watchdog timer
	CONFIG MCLRE = ON; MCLEAR Pin on
	CONFIG DEBUG = ON; Enable Debug Mode
	CONFIG LVP = OFF; Low-Voltage programming disabled (necessary for debugging)
	CONFIG FOSC = INTOSCIO_EC;Internal oscillator, port function on RA6 

        ;This control block reserves the memory needed for the two variables
        CBLOCK 0
        Delay1:1
        Delay2:1
        ENDC

        org 0; start code at 0

Start:
	CLRF PORTD
	CLRF TRISD

	CLRF Delay1
	CLRF Delay2
MainLoop:
	BTG PORTD,RD1 ;Toggle PORT D PIN 1 (20)

Delay:
	DECFSZ    Delay1,1 ;Decrement Delay1 by1, skip next instruction if Delay1 is0
	GOTO Delay
	DECFSZ	  Delay2,1
	GOTO Delay

	GOTO MainLoop

	end

Hello World in C (Hi-Tech C compiler):

/* Blinking LED Demo Thingy */
#include "pic18f4550.h"
#include "htc.h"

/* Config words for PIC18F4455 & PIC18F4550 */
__CONFIG(1,INTCLKO&FCMDIS&IESODIS);
__CONFIG(2,VREGDIS&PWRTDIS&BORDIS&BORV42&WDTDIS&WDTPS32K);
__CONFIG(3,PBDIGITAL&LPT1DIS&MCLREN);
__CONFIG(4,XINSTDIS&STVRDIS&LVPDIS&ICPORTDIS&DEBUGDIS);
__CONFIG(5,UNPROTECT);
__CONFIG(6,UNPROTECT);
__CONFIG(7,UNPROTECT);

/* function prototypes */
void init(void);

/* descriptive pin names */
#define LED_PIN RD1

void main(void)
{
 init();
 volatile int i=0;
 LED_PIN=1;
 while(1)
 {
 LED_PIN=0;
 for(i=0;i<16000;i++);
 LED_PIN=1;
 for(i=0;i<16000;i++);
 }   
}

void init(void)
{
 /* These settings disable interrupts */
 GIE        =    0;        /* no interrupts are used */
 PEIE    =    0;        /* disable periph ints */
 PIE1    =    0x00;
 PIR1    =    0x00;

 /* setup the ports */
 TRISA    =    0;    /* Configure Port A I/O */
 TRISB    =    0;    /* Configure Port B I/O */
 TRISC    =    0;    /* Configure Port C I/O 0=output, 1=input */
 TRISD    =    0;    /* Configure Port B I/O */
 TRISE    =    0;    /* Configure Port C I/O 0=output, 1=input */

 /* start initial values */
 PORTA    =    0x00;
 PORTB    =    0x00;
 PORTC    =    0x00;
 PORTD    =    0x00;
 PORTE    =    0x00;

}

Hello World in C (Microchip C18 compiler):

#include <p18f4550.h>
#include <delays.h>

#pragma config FOSC = INTOSCIO_EC //Inter osc, port function on RA6, EC used by USB
#pragma config WDT = OFF //Disable watchdog timer

#define LEDPin LATDbits.LATD1 //Define LEDPin as PORT D Pin 1
#define LEDTris TRISDbits.TRISD1 //Define LEDTris as TRISD Pin 1

void main()
{
 LEDTris = 0;//Set LED Pin data direction to OUTPUT
 LEDPin = 1;//Set LED Pin

 while(1)
 {
 LEDPin = ~LEDPin;//Toggle LED Pin
 Delay10KTCYx(25);//Delay 250K cycles
 }

}

Leave a comment