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