vi du pic dung c
-
Upload
phillipcarter800 -
Category
Documents
-
view
586 -
download
1
description
Transcript of vi du pic dung c
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 { // This structure is overlayed boolean enable; // on to an I/O port to gain boolean rs; // access to the LCD pins. boolean rw; // The bits are allocated from boolean unused; // low order up. ENABLE will int data : 4; // be pin B0. } lcd;
#byte lcd = 6 // This puts the entire structure // on to port B (at address 6)
#define lcd_type 2 // 0=5x7, 1=5x10, 2=2 lines#define lcd_line_two 0x40 // LCD RAM address for the second line
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 const LCD_WRITE = {0,0,0,0,0}; // For write mode all pins are outSTRUCT lcd_pin_map const LCD_READ = {0,0,0,0,15}; // For read mode data 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' : lcd_send_byte(0,1); delay_ms(2); break; case '\n' : lcd_gotoxy(1,2); break; case '\b' : lcd_send_byte(0,0x10); break; default : lcd_send_byte(1,c); 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: (for example column 0 is B2)// Bx:
#ifdef blue_keypad ///////////////////////////////////// For the blue keypad#define COL0 (1 << 2)#define COL1 (1 << 3)#define COL2 (1 << 6)
#define ROW0 (1 << 4)#define ROW1 (1 << 7)#define ROW2 (1 << 1)#define ROW3 (1 << 5)
#else ////////////////////////////////////////////////// For my keypad#define COL0 (1 << 6)#define COL1 (1 << 2)#define COL2 (1 << 3)
#define ROW0 (1 << 4)#define ROW1 (1 << 5)#define ROW2 (1 << 1)#define ROW3 (1 << 7)
#endif
#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 // Set this number to apx n/333 where // n is the number of times you expect // to call kbd_getc each second
void kbd_init() {#ifdef __PCM__ port_b_pullups(true); // If not PCM be sure to use external pullups#endif}
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 : set_tris_b(ALL_PINS&~COL1); kbd=~COL1&ALL_PINS; break; case 2 : 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 ADC_CLK PIN_B0#define ADC_DOUT PIN_B1#define ADC_DIN PIN_B2#define ADC_CS 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 PIN_B7#define EEPROM_SCL 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 // (20000000/(4*256*256))
byte seconds; // A running seconds counterbyte int_count; // Number of interrupts left before a second has elapsed
#int_rtcc // This function is called every timeclock_isr() { // the RTCC (timer0) overflows (255->0).
// For this program this is apx 76 times if(--int_count==0) { // per second. ++seconds; int_count=INTS_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)) ; /* if it's high, wait for a low */
delay_us(3); /* account for fall time */
while(!input(PIN_B1)); /* wait for signal to go high */}
void wait_for_low() {
delay_us(3); /* account for rise time */
while(input(PIN_B1)); /* wait for signal to go high */}
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() { ////// Returns degrees F (0-255) byte datah,datal; long data;
i2c_start();
i2c_write(0x90); i2c_write(0xaa); 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 EXP_OUT_ENABLE PIN_B0#define EXP_OUT_CLOCK PIN_B1#define EXP_OUT_DO PIN_B2#define NUMBER_OF_74595 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 EXP_IN_ENABLE PIN_B3#define EXP_IN_CLOCK PIN_B4#define EXP_IN_DI PIN_B5#define NUMBER_OF_74165 1
#ENDIF
void read_expanded_inputs(byte *ei) { byte i;
output_high(EXP_IN_CLOCK); output_low(EXP_IN_ENABLE); // Latch all inputs output_high(EXP_IN_ENABLE);
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 //toggled 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 PIN_B0#define X10_TO_PIC PIN_B1#define X10_FROM_PIC 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 RS-232. 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