Example to drive 8 LEDS

/************************************************
*
*
*
COPYRIGHT (c) Blitzlogic Sdn. Bhd.
*
*
Author : Abraham Wong 21/1/2000
*
*
*
*
example of using WHILE loop construct
*
*
to drive 8 LEDS connected to port B
*
*
*
************************************************/
#include <16c84.h>
#USE DELAY( CLOCK=4000000 ) /* Using a 4 Mhz clock */
#FUSES XT,NOWDT,NOPROTECT,NOPUT
/* Use XT mode, No Watch Dog, No Code Protect, No
Power-up Timer */
#byte port_b=6 /* define the location of register
port_b */
main(){
byte cnt; value;
set_tris_b(0); /* set port_b to be outputs */
port_b = 0; /* initialize All port_b outp/uts to
be zero */
value = 0x01;
while( TRUE )
{ /* forever loop using WHILE construct */
cnt = 0;
while ( cnt<8 )
{
port_b = value;
DELAY_MS(1000);

value = value << 1; /* shift left will put
0x01, 0x02, 0x04, 0x08, 0x10 */
cnt++; /* 0x20, 0x40, 0x80 to port_b */
}
}
}

Dieu khien led 7 doan

Example to drive two 7-Segment
LEDs
/****************************************
*
* COPYRIGHT (c) Blitzlogic Sdn. Bhd.
* Author : Abraham Wong 21/1/2000
*
* example of using FOR loop to drive
* two 7-Segment LEDs
****************************************/
#include <16c84.h>
#USE DELAY( CLOCK=4000000 ) /* Using a 4 Mhz clock */

#FUSES XT,NOWDT,NOPROTECT,NOPUT
/* Use XT mode, No Watch Dog, No Code Protect, No
Power-up Timer */
#byte port_b=6 /* define the location of register
port_b */
#byte port_a=5 /* define the location of register
port_b */
byte CONST LED_MAP[10] =
{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
main(){
byte cnt, right,num ;
set_tris_b(0); /* set port_b as outputs */
set_tris_a(0); /* set port_a as output */
port_b = 0; /* ZERO port_a & port_b */
port_a = 0;
for( ;; ){
for (right=1;right<3;right++){
port_a = right;
for (cnt=0;cnt<10;cnt++){
port_b = LED_MAP[cnt];
DELAY_MS(1000); /* one second delay */
}
}
}
}

Ket noi voi matran 5x7

Example to drive 5 x 7 Matrix LED
/************************************************
*
*
*
COPYRIGHT (c) Blitzlogic Sdn. Bhd.
*
*
Author : Abraham Wong 21/1/2000
*
*
*
*
example of driving 5 x 7 Matrix LEDs
*
*
*
************************************************/
#include <16c84.h>
#USE DELAY( CLOCK=4000000 ) /* Using a 4 Mhz clock
*/
#FUSES XT,NOWDT,NOPROTECT,NOPUT

/* Use XT mode, No Watch Dog, No Code Protect, No
Power-up Timer */
#byte port_b=6 /* define the location of register
port_b */
#byte port_a=5 /* define the location of register
port_b */
char const pat[5]={0x3f,0x02,0x04,0x02,0x3f};
main(){
char cnt, col;
set_tris_b(0); /* set port_b as outputs */
set_tris_a(0); /* set port_a as output */
port_b = 0; /* ZERO port_a & port_b */
port_a = 0;
for( ;; )
{
col = 1;
for(cnt = 0;cnt < 5;cnt++)
{
port_b = pat[cnt];
port_a = col;
delay_ms(1);
col<<=1;
}
}
}

Ket noi voi ma tran 16x1

EXAMPLE to use KBD.C and LCD.C
drivers
/////////////////////////////////////////////////////
////////////////////
////
EX_LCDKB.C
////
////
////
//// This program uses both the KBD.C and LCD.C
drivers to allow
////
//// keypad entry and LCD display. All keys are
echoed except *
////
//// that will clear the display. Either the
kbd_getc or lcd_putc ////
//// may be replaced with getc or putc to use just
one device with ////
//// the RS-232.
////

////
////
////
(C) Copyright 1996,1997 Custom Computer
Services
////
////
////
/////////////////////////////////////////////////////
////////////////////
#include <16F84.H>
#fuses XT,NOPROTECT,NOWDT
#use delay(clock=4000000)
#include
#include
main() {
char k;
lcd_init();
kbd_init();
lcd_putc("\fReady...\n");
while (TRUE) {
k=kbd_getc();
if(k!=0)
if(k=='*')
lcd_putc('\f');
else
lcd_putc(k);
}
}

Driver for common LCD modules
/////////////////////////////////////////////////////
///////////////////////

////
LCD.C
////
////
Driver for common LCD modules
////
////
////
//// lcd_init()
Must be called before any other
function.
////
////
////
//// lcd_putc(c) Will display c on the next
position of the LCD.
////
////
The following have special
meaning:
////
////
\f Clear display
////
////
\n Go to start of second
line
////
////
\b Move back one position
////
////
////
//// lcd_gotoxy(x,y) Set write position on LCD
(upper left is 1,1)
////
////
////
//// lcd_getc(x,y)
Returns character at position
x,y on LCD
////
////
////
////
(C) Copyright 1996,1997 Custom Computer
Services
////
////
////
/////////////////////////////////////////////////////
///////////////////////
// As defined in the following structure the pin
connection is as follows:
//
B0 enable
//
B1 rs
//
B2 rw

//
B4 D4
//
B5 D5
//
B6 D6
//
B7 D7
//
//
LCD pins D0-D3 are not used and PIC B3 is not
used.
struct lcd_pin_map {
structure is overlayed
boolean enable;
port to gain
boolean rs;
LCD pins.
boolean rw;
allocated from
boolean unused;
ENABLE will
int
data : 4;
} lcd;

// This

#byte lcd = 6
entire structure

// This puts the

// on to an I/O
// access to the
// The bits are
// low order up.
// be pin B0.

// on to port B
(at address 6)
#define lcd_type 2
lines
#define lcd_line_two 0x40
the second line

// 0=5x7, 1=5x10, 2=2
// LCD RAM address for

byte CONST LCD_INIT_STRING[4] = {0x20 | (lcd_type <<
2), 0xc, 1, 6};
// These bytes need to
be sent to the LCD
// to start it up.
// The following are
used for setting

// the I/O port
direction register.
STRUCT lcd_pin_map
For write mode all
STRUCT lcd_pin_map
For read mode data

const LCD_WRITE = {0,0,0,0,0}; //
pins are out
const LCD_READ = {0,0,0,0,15}; //
pins are in

byte lcd_read_byte() {
byte low,high;
set_tris_b(LCD_READ);
lcd.rw = 1;
delay_cycles(1);
lcd.enable = 1;
delay_cycles(1);
high = lcd.data;
lcd.enable = 0;
delay_cycles(1);
lcd.enable = 1;
delay_us(1);
low = lcd.data;
lcd.enable = 0;
set_tris_b(LCD_WRITE);
return( (high<<4) | low);
}
void lcd_send_nibble( byte n ) {
lcd.data = n;
delay_cycles(1);
lcd.enable = 1;
delay_us(2);
lcd.enable = 0;
}
void lcd_send_byte( byte address, byte n ) {

lcd.rs = 0;
while ( bit_test(lcd_read_byte(),7) ) ;
lcd.rs = address;
delay_cycles(1);
lcd.rw = 0;
delay_cycles(1);
lcd.enable = 0;
lcd_send_nibble(n >> 4);
lcd_send_nibble(n & 0xf);
}
void lcd_init() {
byte i;
set_tris_b(LCD_WRITE);
lcd.rs = 0;
lcd.rw = 0;
lcd.enable = 0;
delay_ms(15);
for(i=1;i<=3;++i) {
lcd_send_nibble(3);
delay_ms(5);
}
lcd_send_nibble(2);
for(i=0;i<=3;++i)
lcd_send_byte(0,LCD_INIT_STRING[i]);
}
void lcd_gotoxy( byte x, byte y) {
byte address;
if(y!=1)
address=lcd_line_two;
else
address=0;
address+=x-1;
lcd_send_byte(0,0x80|address);
}
void lcd_putc( char c) {

switch (c) {
case '\f'
case '\n'
case '\b'
default

: lcd_send_byte(0,1);
delay_ms(2);
: lcd_gotoxy(1,2);
: lcd_send_byte(0,0x10);
: lcd_send_byte(1,c);

break;
break;
break;
break;

}
}
char lcd_getc( byte x, byte y) {
char value;
lcd_gotoxy(x,y);
lcd.rs=1;
value = lcd_read_byte();
lcd.rs=0;
return(value);
}

Generic keypad scan driver
/////////////////////////////////////////////////////
//////////////////////
////
KBD.C
////
////
Generic keypad scan driver
////
////
////
//// kbd_init()
Must be called before any other
function.
////
////
////
//// c = kbd_getc(c) Will return a key value if
pressed or /0 if not ////
////
This function should be called
frequently so as ////
////
not to miss a key press.
////

////
////
////
(C) Copyright 1996,1997 Custom Computer
Services
////
////
////
/////////////////////////////////////////////////////
//////////////////////
////////////////// The following defines the keypad
layout on port B
#byte kbd = 6
// Keypad is connected to port B
(address 6)
//Keypad connection:
//
Bx:

(for example column 0 is B2)

#ifdef
blue_keypad
For the blue
#define COL0
#define COL1
#define COL2

/////////////////////////////////////
keypad
(1 << 2)
(1 << 3)
(1 << 6)

#define
#define
#define
#define

(1
(1
(1
(1

ROW0
ROW1
ROW2
ROW3

<<
<<
<<
<<

4)
7)
1)
5)

#else ///////////////////////////////////////////////
/// For my keypad
#define COL0 (1 << 6)
#define COL1 (1 << 2)
#define COL2 (1 << 3)
#define
#define
#define
#define
#endif

ROW0
ROW1
ROW2
ROW3

(1
(1
(1
(1

<<
<<
<<
<<

4)
5)
1)
7)

#define ALL_ROWS (ROW0|ROW1|ROW2|ROW3)
#define ALL_PINS (ALL_ROWS|COL0|COL1|COL2)
// Keypad layout:
char const KEYS[4][3] = {{'1','2','3'},
{'4','5','6'},
{'7','8','9'},
{'*','0','#'}};
#define KBD_DEBOUNCE_FACTOR 33
to apx n/333 where

// Set this number
// n is the number

of times you expect
// to call kbd_getc
each second

void kbd_init() {
#ifdef __PCM__
port_b_pullups(true);
use external pullups
#endif
}

// If not PCM be sure to

char kbd_getc( ) {
static byte kbd_call_count;
static short int kbd_down;
static char last_key;
static byte col;
byte kchar;
byte row;
kchar='\0';
if(++kbd_call_count>KBD_DEBOUNCE_FACTOR) {
switch (col) {
case 0
: set_tris_b(ALL_PINS&~COL0);
kbd=~COL0&ALL_PINS;
break;

case 1
case 2

: set_tris_b(ALL_PINS&~COL1);
kbd=~COL1&ALL_PINS;
break;
: set_tris_b(ALL_PINS&~COL2);
kbd=~COL2&ALL_PINS;
break;

}
if(kbd_down) {
if((kbd & (ALL_ROWS))==(ALL_ROWS)) {
kbd_down=false;
kchar=last_key;
last_key='\0';
}
} else {
if((kbd & (ALL_ROWS))!=(ALL_ROWS)) {
if((kbd & ROW0)==0)
row=0;
else if((kbd & ROW1)==0)
row=1;
else if((kbd & ROW2)==0)
row=2;
else if((kbd & ROW3)==0)
row=3;
last_key =KEYS[row][col];
kbd_down = true;
} else {
++col;
if(col==3)
col=0;
}
}
kbd_call_count=0;
}
set_tris_b(ALL_PINS);
return(kchar);
}

Giao tiep voi ltc1298

Driver for LTC1298 A/D Converter
/
*****************************************************
************************
*
*
*
Driver for LTC1298 A/D
Converter
*
*
*
*
adc_init()
Call after power up
*
*
*
*
value = read_analog( channel )
Read a analog channel
*
*
channel is 0 or 1
*

*
*
*
convert_to_volts( value, string )
Fills in string with
*
*
the true voltage in
*
*
the form 0.000
*
*
*
*
(C) Copyright 1996,1997 Custom Computer
Services
*
*
*
****************************************************
*************************/
#ifndef ADC_CS
#define
#define
#define
#define

ADC_CLK
ADC_DOUT
ADC_DIN
ADC_CS

PIN_B0
PIN_B1
PIN_B2
PIN_B3

#endif
void adc_init() {
output_high(ADC_CS);
}
void write_adc_byte(byte data_byte, byte
number_of_bits) {
byte i;
delay_us(2);
for(i=0; i>1;
output_high(ADC_CLK);
delay_us(50);
output_low(ADC_CLK);
delay_us(50);
}
}

byte read_adc_byte(byte number_of_bits) {
byte i,data;
data=0;
for(i=0;i<<8)|l);
}
void convert_to_volts( long int data, char volts[6])
{
byte i, d, div_h, div_l;
long int temp,div;
div=0x3330;
for(i=0;i<=4;i++) {
temp=data/div;
volts[i]=(byte)temp+'0';
if(i==0) {
volts[1]='.';
i++;
}
temp=div*(byte)temp;
data=data-temp;
div=div/10;
}
volts[i]='\0';
}

Example to read two A/D Channels of
LTC1298
/////////////////////////////////////////////////////
////////////////////
////
EX_AD12.C
////
////
////
//// This program will read both A/D channels and
display the
////

//// results as both a voltage and raw hex number
over the RS-232. ////
//// A reading is taken every second.
////
////
////
////
(C) Copyright 1996,1997 Custom Computer
Services
////
////
////
/////////////////////////////////////////////////////
////////////////////
#include <16F84.H>
#fuses

HS,NOPROTECT,NOWDT

#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_A3, rcv=PIN_A2)
#include
void display_data( long int data ) {
char volt_string[6];
convert_to_volts( data, volt_string );
printf(volt_string);
printf(" (%4lX)",data);
}
main() {
long int value;
adc_init();
printf("Sampling:\r\n");
do {
delay_ms(1000);

value = read_analog(0);
printf("\n\rCh0: ");
display_data( value );
value = read_analog(1);
printf("
Ch1: ");
display_data( value );
} while (TRUE);
}

I2C Library Sub-Routines for 24LC02
/////////////////////////////////////////////////////
//////////////////////
////
/
///
////
Library for a MicroChip 24LC02B configured for
a x8 org
////
////
////
////
init_ext_eeprom();
Call before the other
functions are used ////
////
////
////
write_ext_eeprom(a, d); Write the byte d to
the address a
////
////
////
////
d = read_ext_eeprom(a);
Read the byte d from
the address a
////
////
////
////
The main program may define eeprom_sda
////
////
and eeprom_scl to override the defaults below.
////
////
////

////
/
///
////
(C) Copyright 1996,1997 Custom Computer
Services
////
////
////
/////////////////////////////////////////////////////
//////////////////////
#ifndef EEPROM_SDA
#define EEPROM_SDA
#define EEPROM_SCL

PIN_B7
PIN_B6

#endif
#use i2c(master,sda=EEPROM_SDA, scl=EEPROM_SCL)
#define EEPROM_ADDRESS byte
#define EEPROM_SIZE
256
void init_ext_eeprom() {
output_low(eeprom_scl);
output_high(eeprom_sda);
}
void write_ext_eeprom(byte address, byte data) {
i2c_start();
i2c_write(0xa0);
i2c_write(address);
i2c_write(data);
i2c_stop();
delay_ms(11);
}
byte read_ext_eeprom(byte address) {
byte data;
i2c_start();

i2c_write(0xa0);
i2c_write(address);
i2c_start();
i2c_write(0xa1);
data=i2c_read(0);
i2c_stop();
return(data);
}

I2C EEPROM 24LC02 EXAMPLE

I2C EEPROM 24LC02 EXAMPLE
/////////////////////////////////////////////////////
////////////////////
////
EX_EXTEE.C
////

////
////
//// This program uses the 24xx or 93xx external
EEPROM drivers to ////
//// read and write to an external serial EEPROM.
z ////
////
////
//// Change the #include <9356.C> to any of the
other drivers to
////
//// test other parts. Note each driver defines
EEPROM_ADDRESS
////
//// indicate 8 or 16 bit addresses.
////
////
////
////
(C) Copyright 1996,1997 Custom Computer
Services
////
////
////
/////////////////////////////////////////////////////
////////////////////
#include <16F84.H>
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_A3, rcv=PIN_A2)
#include
#include <2402.C>
main() {
byte value,cmd;
EEPROM_ADDRESS address;
init_ext_eeprom();
do {
do {
printf("\r\nRead or Write: ");
cmd=getc();

cmd=toupper(cmd);
putc(cmd);
} while ( (cmd!='R') && (cmd!='W') );
printf("\n\rLocation: ");
#if sizeof(EEPROM_ADDRESS)==1
address = gethex();
#else
#if EEPROM_SIZE>0xfff
address = gethex();
#else
address = gethex1();
#endif
address = (address<<8)+gethex();
#endif
if(cmd=='R')
printf("\r\nValue:
%X\r\n",READ_EXT_EEPROM( address ) );
if(cmd=='W') {
printf("\r\nNew value: ");
value = gethex();
printf("\n\r");
WRITE_EXT_EEPROM( address, value );
}
} while (TRUE);
}

Stop Watch function via RTCC &
interrupts
/////////////////////////////////////////////////////
////////////////////
////
EX_STWT.C
////

////
////
//// This program uses the RTCC (timer0) and
interrupts to keep a
////
//// real time seconds counter. A simple stop watch
function is
////
//// then implemented.
////
////
////
////
(C) Copyright 1996,1997 Custom Computer
Services
////
////
///
/
/////////////////////////////////////////////////////
////////////////////
#include <16F84.H>
#fuses XT,NOWDT,NOPROTECT
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_A3, rcv=PIN_A2)
#define INTS_PER_SECOND 76
(4*256*256))

// (20000000/

byte seconds;
// A running seconds counter
byte int_count;
// Number of interrupts left
before a second has elapsed
#int_rtcc
is called every time
clock_isr() {
(timer0) overflows (255->0).

// This function
// the RTCC
// For this

program this is apx 76 times
if(--int_count==0) {
++seconds;
int_count=INTS_PER_SECOND;
}

// per second.

}
main() {
byte start;
int_count=INTS_PER_SECOND;
set_rtcc(0);
setup_counters( RTCC_INTERNAL, RTCC_DIV_256);
enable_interrupts(RTCC_ZERO);
enable_interrupts(GLOBAL);
do {
printf("Press any key to begin.\n\r");
getc();
start=seconds;
printf("Press any key to stop.\n\r");
getc();
printf("%u seconds.\n\r",seconds-start);
} while (TRUE);
}

Example to create a pulse via
RTCC( timer0 )
/////////////////////////////////////////////////////
////////////////////
////
EX_PULSE.C
////
////
////
//// This program uses the RTCC (timer0) to time a
single pulse
////
//// input to the PIC.
////
////
////
////
////
////
(C) Copyright 1996,1997 Custom Computer
Services
////

////
////
/////////////////////////////////////////////////////
////////////////////
#include <16F84.H>
#fuses

XT,NOPROTECT,NOWDT

#include
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_A3, rcv=PIN_A2)
char get_scale() {
char scale;
do {
printf("\n\rPress S for short or L for long: ");
scale = getc();
scale = toupper(scale);
} while ( (scale!='S') && (scale!='L') );
return(scale);
}
void wait_for_low_to_high() {
while(input(PIN_B1)) ;
for a low */

/* if it's high, wait

delay_us(3);
time */

/* account for fall

while(!input(PIN_B1));
go high */
}

/* wait for signal to

void wait_for_low() {

delay_us(3);
time */

/* account for rise

while(input(PIN_B1));
go high */
}

/* wait for signal to

main() {
char scale;
byte time;
do {
scale = get_scale();
if(scale=='S')
setup_counters( RTCC_INTERNAL,
RTCC_DIV_64 );
else
setup_counters( RTCC_INTERNAL,
RTCC_DIV_256 );
printf("\n\rWaiting...\n\r");
wait_for_low_to_high();
set_rtcc(0);
wait_for_low();
time = get_rtcc();
printf("Counter value: %2X\n\n\r", time);
} while (TRUE);
}

Library for Dallas 1621 Temperature
chip
/////////////////////////////////////////////////////
//////////////////////
////
////
////
Library for a Dallas 1621 Temperature chip
////
////
////
////
init_temp();
Call before the other
functions are used ////
////
////
////
d = read_temp();
Read the temerature in
degrees (0-255)
////
////
////

////
////
////
(C) Copyright 1996,1997 Custom Computer
Services
////
////
////
/////////////////////////////////////////////////////
//////////////////////
#use i2c(master,sda=PIN_B7, scl=PIN_B6)
void temp_config(byte data) {
i2c_start();
i2c_write(0x90);
i2c_write(0xac);
i2c_write(data);
i2c_stop();
delay_ms(11);
}
void init_temp() {
output_high(PIN_B7);
output_high(PIN_B6);
i2c_start();
i2c_write(0x90);
i2c_write(0xee);
i2c_stop();
temp_config(8);
}
byte read_temp() {
(0-255)
byte datah,datal;
long data;
i2c_start();
i2c_write(0x90);
i2c_write(0xaa);

////// Returns degrees F

i2c_start();
i2c_write(0x91);
datah=i2c_read();
datal=i2c_read(0);
i2c_stop();
data=datah;
data=data*9;
if((datal&0x80)!=0)
data=data+4;
data=(data/5)+32;
datal=data;
return(datal);
}

Example to Read temperature using
the DS1621

/////////////////////////////////////////////////////
//////////////////////
////
////
////
EX_TEMP.C
////
////
////
////
Reads temperature using the DS1621 and sends
it over the RS232 ////
////
////
////
(C) Copyright 1996,1997 Custom Computer
Services
////
////
////
/////////////////////////////////////////////////////
//////////////////////
#include <16F84.H>
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_A3, rcv=PIN_A2)
#include
main() {
byte value;
init_temp();
do {
value = read_temp();
printf("%u\r\n",value);
delay_ms(1000);
}while (TRUE);
}

74595 Library Routine to expand no.
of output lines
/////////////////////////////////////////////////////
//////////////////////
////
Library for a 74595 Expanded Output Chip
////
////
////
////
Any number of these chips may be connected in
serise to get
////
////
8 additional outputs per chip. The cost is 3
I/O pins for
////
////
any number of chips.
////
////
////
////
write_expanded_outputs(eo); Writes the array
eo to the chips
////
////
////
////
(C) Copyright 1996,1997 Custom Computer
Services
////
////
////
/////////////////////////////////////////////////////
//////////////////////
#IFNDEF EXP_OUT_ENABLE
#define
#define
#define
#define

EXP_OUT_ENABLE
EXP_OUT_CLOCK
EXP_OUT_DO
NUMBER_OF_74595

PIN_B0
PIN_B1
PIN_B2
1

#ENDIF
void write_expanded_outputs(byte* eo) {
byte i;

output_low(EXP_OUT_CLOCK);
output_low(EXP_OUT_ENABLE);
for(i=1;i<=NUMBER_OF_74595*8;++i) { // Clock out
bits from the eo array
if((*(eo+(NUMBER_OF_74595-1))&0x80)==0)
output_low(EXP_OUT_DO);
else
output_high(EXP_OUT_DO);
shift_left(eo,NUMBER_OF_74595,0);
output_high(EXP_OUT_CLOCK);
output_low(EXP_OUT_CLOCK);
}
output_high(EXP_OUT_ENABLE);
}

74165 Library Routine to expand no.
of input lines
/////////////////////////////////////////////////////
//////////////////////
////
Library for a 74165 Expanded Input Chip
////
////
////
////
Any number of these chips may be connected in
series to get
////
////
8 additional inputs per chip. The cost is 3
I/O pins for
////
////
any number of chips.
////
////
////
////
read_expanded_inputs(ei); Reads the array ei
from the chips
////
////
////

/////////////////////////////////////////////////////
//////////////////////
////
(C) Copyright 1996,1997 Custom Computer
Services
////
//// This source code may only be used by licensed
users of the CCS C
////
//// compiler. This source code may only be
distributed to other
////
//// licensed users of the CCS C compiler. No other
use, reproduction ////
//// or distribution is permitted without written
permission.
////
//// Derivative programs created using this software
in object code
////
//// form are not restricted in any way.
////
/////////////////////////////////////////////////////
///////////////////////
#IFNDEF EXP_IN_ENABLE
#define
#define
#define
#define

EXP_IN_ENABLE
EXP_IN_CLOCK
EXP_IN_DI
NUMBER_OF_74165

PIN_B3
PIN_B4
PIN_B5
1

#ENDIF
void read_expanded_inputs(byte *ei) {
byte i;
output_high(EXP_IN_CLOCK);
output_low(EXP_IN_ENABLE);
output_high(EXP_IN_ENABLE);

// Latch all inputs

for(i=1;i<=NUMBER_OF_74165*8;++i) {
// Clock
in bits to the ei structure
shift_left(ei,NUMBER_OF_74165,input(EXP_IN_DI));
output_low(EXP_IN_CLOCK);
output_high(EXP_IN_CLOCK);
}

output_low(EXP_IN_ENABLE);
}

Example to expand number of I/O
using 74165 & 74595
/////////////////////////////////////////////////////
////////////////////
////
EX_EXPIO.C
////
////
////
////
This program shows how to use the 74165.C
and 74595.C
////
//// libraries for extended input and output.
////
////
////
////
When button S1 is pushed, LED 1 will toggle
green. Button
////
//// S2 will toggle LED 2. However, when both
buttons are pushed,
////
//// LED 3 will toggle green.
////
////
////
////
(C) Copyright 1996,1997 Custom Computer
Services
////
////
////
/////////////////////////////////////////////////////
/////////////////////
#ifdef __PCB__
#include <16C56.H>
#else
#include <16C74.H>
#endif

#include <74595.C>
#include <74165.C>
main() {
byte data;
do {
read_expanded_inputs (&data);
data |= 0xF8;
//Force
the unused input bits on
data -= (!(data&0x01)&!(data&0x02))<<2; //Turn
on bit 2 it both inputs are
//toggl
ed
write_expanded_outputs (&data);
} while (TRUE);
}

TW523 X10 Driver
/////////////////////////////////////////////////////
/////////////////////
//// TW523 X10 Driver
////
////
////
//// x10_write(house_code,key_code)
Send a data
burst, house_code ////
////
must be 'A'
to 'P' and
////
////
key_code is
0-1F
////
////
////
//// x10_read( house_code, key_code)
Waits for and
reads the next ////
////
data burst.
////
////
////
//// x10_data_ready()
Returns true
if a data burst ////
////
is starting.
Be sure to call ////
////
faster than
1khz in order not ////
////
to miss any
data.
////
////
Connect B0 to TW523 pin 1
////
////
B1
3
////
////
B2
4
////
////
GND
2
////
////
////

////
(C) Copyright 1996,1997 Custom Computer
Services
////
////
////
/////////////////////////////////////////////////////
/////////////////////
#ifndef X10_ZERO_CROSS
#define X10_ZERO_CROSS
#define X10_TO_PIC
#define X10_FROM_PIC

PIN_B0
PIN_B1
PIN_B2

#endif
char const X10_HOUSE_CODES[16] =
{'M','N','O','P','C','D','A','B','E',
'F','G','H','K','L'
,'I','J'};
byte const X10_KEY_CODES[16] =
{13,14,15,16,3,4,1,2,5,6,7,8,11,12,9,10};
void wait_for_zero_cross() {
if(input(X10_ZERO_CROSS))
while(input(X10_ZERO_CROSS)) ;
else
while(!input(X10_ZERO_CROSS)) ;
}
void x10_write_bits(byte data, byte n, byte start) {
byte i;
boolean the_bit;
for(i=1;i<=n;++i) {
wait_for_zero_cross();
the_bit=shift_right(&data,1,0);
output_bit(X10_FROM_PIC, the_bit);
delay_ms(1);
output_low(X10_FROM_PIC);
if(start==0) {

wait_for_zero_cross();
output_bit(X10_FROM_PIC, !the_bit);
delay_ms(1);
output_low(X10_FROM_PIC);
}
}
}
void x10_write(byte house_code, byte key_code) {
byte i;
i=0;
while (X10_HOUSE_CODES[i]!=house_code)
i++;
house_code=i;
if(key_code<16) {
i=0;
while (X10_KEY_CODES[i]!=key_code)
i++;
key_code=i;
}
x10_write_bits(7,4,1);
x10_write_bits(house_code,4,0);
x10_write_bits(key_code,5,0);
x10_write_bits(0,6,1);
}
byte x10_data_ready() {
port_b_pullups(TRUE);
return(!input(X10_TO_PIC));
}
byte x10_read_bits(byte n) {
byte data,i;
for(i=1;i<=n;++i) {
wait_for_zero_cross();
delay_us(300);
shift_right(&data,1,input(X10_TO_PIC));
wait_for_zero_cross();
delay_us(300);
}

data>>=8-n;
return(data);
}
void x10_read(byte *house_code,byte *key_code) {
port_b_pullups(TRUE);
x10_read_bits(2);
*house_code=x10_read_bits(4);
*house_code=X10_HOUSE_CODES[*house_code];
*key_code=x10_read_bits(5);
if(*key_code<16)
*key_code=X10_KEY_CODES[*key_code];
}

X10 TO RS232 INTERFACE EXAMPLE
/////////////////////////////////////////////////////
////////////////////
////
EX_X10.C
////
////
////
//// This program interfaces a X10 TW523 unit to RS232. This
////
//// program will accept and send three character
codes of the
////
//// form xyy where x is A-P and yy is 00-1F.
////
//// Key codes 00-0F are translated to the key
number.
////
////
////
//// A * is sent to indicate transmition was aborted
due to
////
//// a collision. A > is sent when reception begins
to reduce
////
//// the chance of attempting to transmit during
reception.
////

////
////
////
Connect B0 to TW523 pin 1
////
////
B1
3
////
////
B2
4
////
////
GND
2
////
////
////
//// For a 40 pin part such as the 16C74 add jumpers
from
////
//// 8 to 11, 7 to 12, and change the #USE RS232 to:
////
////
#use rs232(baud=9600, xmit=PIN_C6,
rcv=PIN_C7)
////
////
////
////
(C) Copyright 1996,1997 Custom Computer
Services
////
////
////
/////////////////////////////////////////////////////
////////////////////
#include <16F84.H>
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_A3, rcv=PIN_A2)
#fuses

XT,NOPROTECT,NOWDT

#include < x10.c >
#include < input.c >
main() {
char house_code;
byte key_code;

printf("Online\n\r");
while (TRUE) {
if(kbhit()) {
house_code = getc();
if((house_code>='A') && (house_code<='P')) {
putc(house_code);
key_code=gethex();
x10_write(house_code,key_code);
x10_write(house_code,key_code);
}
}
if(x10_data_ready()) {
putc('>');
x10_read(&house_code,&key_code);
printf("%c%2X",house_code,key_code);
}
}
}

Sub-Routines for standard inputs
/////////////////////////////////////////////////////
///////////////////////
////
////
////
Routines for standard inputs
////
////
////
////
(C) Copyright 1996,1997 Custom Computer
Services
////
////
////
/////////////////////////////////////////////////////
///////////////////////
#include < CTYPE.H >

byte gethex1() {
char digit;
digit = getch();
putchar(digit);
if(digit<='9')
return(digit-'0');
else
return((toupper(digit)-'A')+10);
}
byte gethex() {
int lo,hi;
hi = gethex1();
lo = gethex1();
if(lo==0xdd)
return(hi);
else
return( hi*16+lo );
}
void get_string(char * s,int max) {
int len;
char c;
max--;
len=0;
do {
c=getc();
if(c==8) { // Backspace
if(len>0) {
len--;
putc(c);
putc(' ');
putc(c);
}
} else if ((c>=' ')&&(c<='~'))

if( len < max ) {
s[len++]=c;
putc(c);
}
} while(c!=13);
s[len]=0;
}
#ifdef _stdlib_
signed int get_int() {
char s[5];
signed int i;
get_string(s, 5);
i=atoi(s);
return(i);
}
signed long get_long() {
char s[7];
signed long l;
get_string(s, 7);
l=atol(s);
return(l);
}
#endif