|
Application Example: Simple Remote Terminal (Comes
with Trial Version 'File | Open' | 'demo1.qpr')
The remote terminal consists of:
- LCD: 32-character single line dot matrix display
- RS232 interface
- 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
|