.

QuickBuilder
for Microchip PICs

Home - About- Consulting* - Articles - FAQs - Contact
Tour - Application Example - Sub circuits - Projects - Download
Application Example

Application Example: Simple Remote Terminal (Comes with Trial Version 'File | Open' | 'demo1.qpr')


The remote terminal consists of:

  1. LCD: 32-character single line dot matrix display
  2. RS232 interface
  3. Two push switches

The target device is a Microchip PIC16F84. (visit www.microchip.com for further information on Micropchip PICs)

Operation: When SW_1 is pressed send an ASCII '1' out of the RS232 port, when SW_2 pressed send an ASCII '2' out of the RS232 port. If a character is received by the RS232 port, print it on the LCD unless it is a 0x0D (carriage return) in which case clear the LCD.

This remote terminal can be used as an operator interface connected to a PC or some other computer equipment. A simple menu system with Yes/No answers via the input switches could be affected. The applications are endless!


Stage 1
Fill sub-circuit palette. The following sub-circuits are selected using the Browse Library ('Edit | Browse Library')

  • 'LCD dot matrix display 44780'
  • 'RS232 Tranceiver'
  • 'Push switch SPNO,PU'

Stage 2
Add sub-circuits to design sheet: Selecting an item in the palette and then clicking the design sheet creates instances of the sub-circuits. Below is the design showing 'LCD', 'RS232', and two 'Push switch''s.

The design sheet looks like this:

Stage 3
Set sub-circuit properties, e.g. Port IO, for each sub-circuit. This is done by right-clicking a sub-circuit and selecting Properties. Once the Property form is open set individual properties for the sub-circuit


Stage 4
Generate source code: The project is saved then source code is generate using the Builder ('Project | Build'). Just one click and the source code file is generated!

This is how the generated code looks...

demo1.c:


///////////////////////////////////////////////////////////////////////
//
// The contents of this file have been generated by QuickBuilder
// To use this with your application code, carry out these steps:
//
// 1. Include this file using #include "filename" where file name
// is the filename including path. Place the #include before
// the start of you code.
//
// 2. Place a call to INIT_SUB_CIRCUITS() in the initialisation portion
// of your application code.
//
//
///////////////////////////////////////////////////////////////////////



//*********************************************************************
//*                            defines                                *
//*********************************************************************
//<SECTION DEFINE
#use delay(clock=4000000)
#DEFINE CLOCK 4000000
#DEFINE _Z 3,2
#DEFINE _C 3,0
#DEFINE _RP0 3,5
///SECTION>



//*********************************************************************
//*                           subroutines                             *
//*********************************************************************
//<SECTION SUBS
//<************************************************
// LCD_1
// 
// Driver for dot matrix LCDs based on the Hitachi HD44780
// controller and compatibles such as the Samsung (KS0070).
// 
//
// Functions:
// ----------
// LCD_1PUTC(c)    : write character c to display
// LCD_1CLEAR()    : clear display
// LCD_1INIT()     : initialise display
// LCD_1CURHOME()  : cursor home
// LCD_1CURLEFT()  : cursor left
// LCD_1CURRIGHT() : cursor right
// LCD_1CURMOVE(n) : cursor move to position n. Line 1 begins
// at 0x00, line 2 begins at 0x40.
//
// Low level functions:
// --------------------
// Consult Hitachi HD44780 data sheet for use
// LCD_1DWR(data)  : Write date to controller
// LCD_1IWR(inst)  : Write instruction to controller
//
// Rev2.0
//********************************************************
//            (C) Copyright 2002-2003 mTECH
// This source code may only be used by Licensees 
// of QuickBuilder as specified in the End User License
// Agreement ("EULA")located at www.quickbuilder.co.uk. 
// No other use, reproduction or distribution is permitted 
// without specific written permission from mTECH. 
// Derivative programmes created using this software in
// object code form are not restricted.
//************************************************>

#if 0 // 1=debug
#define PORTB  PORTC
#define TRISB  TRISC
#define 0 4
#define PORTB  PORTC
#define TRISB  TRISC
#define 0x00  0
#define 0x00  0
#endif


// ------------------ modified by script ------------------
#define FUNC_0      0x20 | 0x00 | 0x00

#define P_0         PORTB            // LCD data lines interface
#define TRISP_0     TRISB

#define PD4_0       PORTB, 0 + 0 // 4 bit portsh (db4-db7)
#define TRISPD4_0   TRISB, 0 + 0
#define PD5_0       PORTB, 1 + 0
#define TRISPD5_0   TRISB, 1 + 0
#define PD6_0       PORTB, 2 + 0
#define TRISPD6_0   TRISB, 2 + 0
#define PD7_0       PORTB, 3 + 0
#define TRISPD7_0   TRISB, 3 + 0

#define PE_0        PORTB, 6
#define TRISPE_0    TRISB, 6
#define PRW_0       PORTB, 5
#define TRISPRW_0   TRISB, 5
#define PRS_0       PORTB, 4
#define TRISPRS_0   TRISB, 4
// ------------------------------------------------------



// ------------------------ macros -----------------------------
#define LCD_1CURMOVE(x)  LCD_1IWR(0x80 | x)
#define LCD_1CURHOME()   LCD_1IWR(0x02)
#define LCD_1CLEAR()     LCD_1IWR(0x01)
#define LCD_1CURLEFT()   LCD_1IWR(0x10)

// ------------------------ code -------------------------------
//*********************
void DATA_OUT_0(BYTE data)
    {        
    bit_clear(*PD4_0);
    if (bit_test(data,0) )
        bit_set(*PD4_0);
        
    bit_clear(*PD5_0);
    if (bit_test(data,1) )
        bit_set(*PD5_0);
        
    bit_clear(*PD6_0);
    if (bit_test(data,2) )
        bit_set(*PD6_0);
        
    bit_clear(*PD7_0);
    if (bit_test(data,3) )
        bit_set(*PD7_0);

    delay_cycles(2);
    }

//*********************
BYTE DATA_IN_0( void )
    {
    int dat;
    delay_cycles(2);
    dat = *PORTB;
    dat = dat >> 0;    
    return (dat); 
    }


//*********************
void BUSY_0()
    {
    int R1;
    
    do {
        bit_set(*TRISPD4_0);    // input
        bit_set(*TRISPD5_0);
        bit_set(*TRISPD6_0);
        bit_set(*TRISPD7_0);

        bit_clear(*PRS_0);      // hi nibble in
        delay_cycles(2);
        bit_set(*PRW_0);
        delay_cycles(2);
        bit_set(*PE_0);
        R1 = DATA_IN_0();
        bit_clear(*PE_0);
        delay_cycles(2);

        bit_set(*PE_0);         // lo nibble
        delay_cycles(2);
        bit_clear(*PE_0);
        delay_cycles(2);
    } while ( bit_test(R1,3) );

    
    bit_clear(*TRISPD4_0);      // set data port to output
    bit_clear(*TRISPD5_0);
    bit_clear(*TRISPD6_0);
    bit_clear(*TRISPD7_0);

    return;
    }

//*********************
void LCD_1IWR(int command)
    {
    int cmd;
    
    BUSY_0();           // Wait while busy
    
    cmd = command;

    bit_clear(*PRS_0);  // hi nibble out
    bit_clear(*PE_0);
    delay_cycles(2);
    bit_clear(*PRW_0);
    delay_cycles(2);
    DATA_OUT_0( cmd >> 4 );
    delay_cycles(2);
    bit_set(*PE_0);
    delay_cycles(2);
    bit_clear(*PE_0);
    delay_cycles(2);
    
    DATA_OUT_0( cmd );  // lo nibble out
    delay_cycles(2);
    bit_set(*PE_0);
    delay_cycles(2);
    bit_clear(*PE_0);
    delay_cycles(2);
    }


void LCD_1DWR(int data)
{
    int R0,R1;
    int c;

    BUSY_0();           // Wait while busy

    c = data;

    bit_clear(*PRS_0);  // hi nibble out
    bit_clear(*PE_0);
    bit_clear(*PRW_0);
    DATA_OUT_0( c >> 4 );
    delay_cycles(2);
    bit_set(*PRS_0);
    delay_cycles(2);
    bit_set(*PE_0);
    delay_cycles(2);
    bit_clear(*PE_0);
    delay_cycles(2);
    
    DATA_OUT_0( c );    // lo nibble out
    bit_set(*PE_0);
    delay_cycles(2);
    bit_clear(*PE_0);
    delay_cycles(2);

}
//*********************
void LCD_1PUTC(int character)
{
    LCD_1DWR(character);
}
//*********************
void LCD_1PUTC_0(int character)
    {
    int R0,R1;
    int c;

    BUSY_0();           // Wait while busy

    c = character;

    bit_clear(*PRS_0);  // hi nibble out
    delay_cycles(2);
    bit_clear(*PE_0);
    delay_cycles(2);
    bit_clear(*PRW_0);
    delay_cycles(2);
    DATA_OUT_0( c >> 4 );
    delay_cycles(2);
    bit_set(*PRS_0);
    delay_cycles(2);
    bit_set(*PE_0);
    delay_cycles(2);
    bit_clear(*PE_0);
    delay_cycles(2);
    
    DATA_OUT_0( c );    // lo nibble out
    delay_cycles(2);
    bit_set(*PE_0);
    delay_cycles(2);
    bit_clear(*PE_0);
    delay_cycles(2);
    }


//*********************
void DMODE_0(int dmode)
    {
    dmode &= 0x007;
    dmode |= 0x008;
    LCD_1IWR(dmode);
    }

//*********************
void EMODE_0(int mode)
    {
    mode &= 0x003;
    mode |= 0x004;
    LCD_1IWR(mode);
    }


//*********************
void LCD_1INIT()
    {

    bit_clear(*TRISPD4_0);     // set data port to output
    bit_clear(*TRISPD5_0);
    bit_clear(*TRISPD6_0);
    bit_clear(*TRISPD7_0);
    
    bit_clear(*TRISPE_0 );      // set control lines to output
    bit_clear(*TRISPRW_0 );
    bit_clear(*TRISPRS_0 );

    delay_ms(15);               // power-up delay
    LCD_1IWR(FUNC_0);            // 4-bit-interface, 1-line, 5x8font
    DMODE_0(0);                 // disp.off, curs.off, no-blink
    LCD_1CLEAR();
    DMODE_0(0x04);              // disp.on, curs.off
    EMODE_0(0x02);              // auto-inc (shift-cursor)
    LCD_1CURHOME();
    }

//************************************************
// SW_1
// 
// Push switch with resistor pull up
//
// Functions:
// SW_1PRESSED()    ; returns switch pressed event
//
//************************************************
//#DEFINE P_1 PORTA,0 // debug
//#DEFINE TRISP_1 TRISA,0 //debug

#DEFINE P_1 PORTA,0
#DEFINE TRISP_1 TRISA,0

//******************
int SW_1PRESSED()
    {
    static int laststate=0;
    
    if (!bit_test(* P_1) )
        {
        if (bit_test(laststate,0))
            {
            laststate = 0;
            return(1);
            }
        }
    else
        bit_set(laststate,0);

    return (0);
    }

void SW_1INIT()
    {
#asm
    BSF _RP0
    BSF TRISP_1
#endasm
    }

//************************************************
// SW_2
// 
// Push switch with resistor pull up
//
// Functions:
// SW_2PRESSED()    ; returns switch pressed event
//
//************************************************
//#DEFINE P_2 PORTA,0 // debug
//#DEFINE TRISP_2 TRISA,0 //debug

#DEFINE P_2 PORTA,1
#DEFINE TRISP_2 TRISA,1

//******************
int SW_2PRESSED()
    {
    static int laststate=0;
    
    if (!bit_test(* P_2) )
        {
        if (bit_test(laststate,0))
            {
            laststate = 0;
            return(1);
            }
        }
    else
        bit_set(laststate,0);

    return (0);
    }

void SW_2INIT()
    {
#asm
    BSF _RP0
    BSF TRISP_2
#endasm
    }

//************************************************
// RS232_1 l
// 
// RS232_1IN()   ; recieve chracter
// RS232_1OUT(c) ; send character c
//
//************************************************
#use RS232(BAUD=1200,XMIT=PIN_A3,RCV=PIN_A4)


//*****************
int RS232_1IN()
    {
    return getch();
    }
//*****************
void RS232_1OUT(int c)
    {
    putc(c);
    }
//*****************
int RS232_1INCOMING()
    {
    return kbhit();
    }

///SECTION>


//*********************************************************************
//*                          initialisation                           *
//*********************************************************************
void INIT_SUB_CIRCUITS()
    {
//<SECTION INIT
// --- LCD initialise
    LCD_1INIT();
    SW_1INIT();
    SW_2INIT();
///SECTION>
    }				  
                      
 

Stage 5
Write your application code. The code below is the only code written for this project!

This is the only code you write...

 
 
///////////////////////////////////////////////////////////////////////
////                           APPDEMO1.C                          ////
////                                                               ////
////  Demo application of simple dumb terminal, consisting of      ////
////  2 x Push switchs                                             ////
////  1 x RS232 Tranceiver                                         ////
////  1 x LCD Dot matrix 32 character single line display          ////
////                                                               ////
////                                                               ////
////  This program is an example of how your application code is   ////
////  is organised. Note the #include "demo1.c", this include      ////
////  file was generated by QuickBuilder and contains all          ////
////  dirver code.                                                 ////
////                                                               ////
////  This demo is intended for  a PIC16F84                        ////
////  Compiled using CCS 'C'  visit www.quickbuilder.co.uk/qb/ccs  ////
////  for more information.                                        ////
///////////////////////////////////////////////////////////////////////

#include <16F84.H>

#fuses   XT,NOPROTECT,NOWDT

#include 


#define PORTA 5 
#define PORTB 6
#define TRISA 0x85 
#define TRISB 0x86


#INCLUDE "demo1.c"

void main()
    {
    int c;
    
    INIT_SUB_CIRCUITS();    
    
    while(1)
        {
        if (SW_1PRESSED())
            RS232_1OUT('1');
            
        if (SW_2PRESSED())
            RS232_1OUT('2');

        if ( RS232_1INCOMING() )
            {
            c = RS232_1IN();
            if (c==0x0d)   
                LCD_1CLEAR(); 
            else 
                LCD_1PUTC(C); 
            }
        }
    }				  

TOP OF PAGE

Copyright 2002-2009 Summit Electronics Ltd
www.quickbuilder.co.uk