/********************************************************************* * * 1-Wire Communication Protocol * ********************************************************************* * FileName: 1wire.c * Dependencies: * Processor: PIC18 * Complier: MCC18 v3.13 * Company: Microchip Technology, Inc. * * Software License Agreement * * Copyright © 2004-2007 Microchip Technology Inc. All rights reserved. * * Microchip licenses to you the right to use, copy and distribute Software * only when embedded on a Microchip microcontroller or digital signal * controller and used with a Microchip radio frequency transceiver, which * are integrated into your product or third party product (pursuant to the * sublicense terms in the accompanying license agreement). You may NOT * modify or create derivative works of the Software. * * * You should refer to the license agreement accompanying this Software for * additional information regarding your rights and obligations. * * SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” WITHOUT WARRANTY OF ANY * KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY WARRANTY * OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR * PURPOSE. IN NO EVENT SHALL MICROCHIP OR ITS LICENSORS BE LIABLE OR OBLIGATED * UNDER CONTRACT, NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF * WARRANTY, OR OTHER LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR * EXPENSES INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, * PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF * PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY * THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER * SIMILAR COSTS. * * Author Date Comment *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Sasha 12/20/07 Original ********************************************************************/ /****** I N C L U D E S **********************************************************/ #include "Config.h" #include "1wire.h" //****** V A R I A B L E S ********************************************************/ unsigned char macro_delay; /********************************************************************** * Function: void drive_OW_low (void) * PreCondition: None * Input: None * Output: None * Overview: Configure the OW_PIN as Output and drive the OW_PIN LOW. ***********************************************************************/ void drive_OW_low (void) { OW_PIN_DIRECTION = OUTPUT; OW_WRITE_PIN=LOW; } /********************************************************************** * Function: void drive_OW_high (void) * PreCondition: None * Input: None * Output: None * Overview: Configure the OW_PIN as Output and drive the OW_PIN HIGH. ***********************************************************************/ void drive_OW_high (void) { OW_PIN_DIRECTION = OUTPUT; OW_WRITE_PIN = HIGH; } /********************************************************************** * Function: unsigned char read_OW (void) * PreCondition: None * Input: None * Output: Return the status of OW pin. * Overview: Configure as Input pin and Read the status of OW_PIN ***********************************************************************/ unsigned char read_OW (void) { unsigned char read_data=0; OW_WRITE_PIN = INPUT; if (HIGH == OW_READ_PIN) read_data = SET; else read_data = CLEAR; return read_data; } /********************************************************************** * Function: unsigned char OW_reset_pulse(void) * PreCondition: None * Input: None * Output: Return the Presense Pulse from the slave. * Overview: Initialization sequence start with reset pulse. * This code generates reset sequence as per the protocol ***********************************************************************/ unsigned char OW_reset_pulse(void) { unsigned char presence_detect; drive_OW_low(); // Drive the bus low wait(DELAY_240Us); // delay 480 microsecond (us) wait(DELAY_240Us); drive_OW_high (); // Release the bus wait(DELAY_70Us); // delay 70 microsecond (us) presence_detect = read_OW(); //Sample for presence pulse from slave wait(DELAY_205Us); // delay 410 microsecond (us) wait(DELAY_205Us); drive_OW_high (); // Release the bus return presence_detect; } /********************************************************************** * Function: void OW_write_bit (unsigned char write_data) * PreCondition: None * Input: Write a bit to 1-wire slave device. * Output: None * Overview: This function used to transmit a single bit to slave device. * ***********************************************************************/ void OW_write_bit (unsigned char write_bit) { if (write_bit) { //writing a bit '1' drive_OW_low(); // Drive the bus low wait(DELAY_6Us); // delay 6 microsecond (us) drive_OW_high (); // Release the bus wait(DELAY_64Us); // delay 64 microsecond (us) } else { //writing a bit '0' drive_OW_low(); // Drive the bus low wait(DELAY_60Us); // delay 60 microsecond (us) drive_OW_high (); // Release the bus wait(DELAY_10Us); // delay 10 microsecond for recovery (us) } } /********************************************************************** * Function: unsigned char OW_read_bit (void) * PreCondition: None * Input: None * Output: Return the status of the OW PIN * Overview: This function used to read a single bit from the slave device. * ***********************************************************************/ unsigned char OW_read_bit (void) { unsigned char read_data; //reading a bit drive_OW_low(); // Drive the bus low wait(DELAY_6Us); // delay 6 microsecond (us) drive_OW_high (); // Release the bus wait(DELAY_9Us); // delay 9 microsecond (us) read_data = read_OW(); //Read the status of OW_PIN wait(DELAY_55Us); // delay 55 microsecond (us) return read_data; } /********************************************************************** * Function: void OW_write_byte (unsigned char write_data) * PreCondition: None * Input: Send byte to 1-wire slave device * Output: None * Overview: This function used to transmit a complete byte to slave device. * ***********************************************************************/ void OW_write_byte (unsigned char write_data) { unsigned char loop; for (loop = 0; loop < 8; loop++) { OW_write_bit(write_data & 0x01); //Sending LS-bit first write_data >>= 1; // shift the data byte for the next bit to send } } /********************************************************************** * Function: unsigned char OW_read_byte (void) * PreCondition: None * Input: None * Output: Return the read byte from slave device * Overview: This function used to read a complete byte from the slave device. * ***********************************************************************/ unsigned char OW_read_byte (void) { unsigned char loop, result=0; for (loop = 0; loop < 8; loop++) { result >>= 1; // shift the result to get it ready for the next bit to receive if (OW_read_bit()) result |= 0x80; // if result is one, then set MS-bit } return result; } /******************************************************************************************** E N D O F 1 W I R E . C *********************************************************************************************/ #ifndef _Config_H #define _Config_H //******* D E F I N I T I O N S ************************************************/ #define CLK_FREQ_25000000 0 //25MHz #define CLK_FREQ_24000000 0 //24MHz #define CLK_FREQ_20000000 1 //20MHz #define CLK_FREQ_16000000 0 //16MHz #define CLK_FREQ_12000000 0 //12MHz #if((CLK_FREQ_25000000+CLK_FREQ_24000000+CLK_FREQ_20000000+CLK_FREQ_16000000+CLK_FREQ_12000000) != 1) #error Select One Frequency for 1Us Delay Calculation. #endif //********************************************************************** //This wait MACRO gives 1Us delay depending upon clock Speed Select; //Wait_delay (200) generates a 200Us. // loop: nop\ // 1 INST cycle // nop\ // 1 INST cycle // nop\ // 1 INST cycle // decfsz macro_delay,1,1\ // 1 or 3INST cycle // bra loop\ // 2 INST cycle //********************************************************************** //********************************************************************** //#define CLOCK_FREQUENCY 25000000 //25MHz //Note: 1 INST Cycle = ((1/ CLOCK_SPEED) * 4) = (1/25000000)*4 = 0.16Us // Total INST Cycle in a loop = 0.16*6 = 0.96 ~ 1Us. //********************************************************************** #if(CLK_FREQ_25000000) #define wait(a) _asm movlw a\ movwf macro_delay,1\ loop: nop\ nop\ nop\ decfsz macro_delay,1,1\ bra loop\ _endasm #define BAUD_RATE 39 //********************************************************************** //#define CLOCK_FREQUENCY 24000000 //24MHz //Note: 1 INST Cycle = ((1/ CLOCK_SPEED) * 4) = (1/24000000)*4 = 0.1667Us // Total INST Cycle in a loop = 0.1667*6 = 1.0007 ~ 1Us. //********************************************************************** #elif (CLK_FREQ_24000000) #define wait(a) _asm movlw a\ movwf macro_delay,1\ loop: nop\ nop\ nop\ decfsz macro_delay,1,1\ bra loop\ _endasm #define BAUD_RATE 38 //********************************************************************** //#define CLOCK_FREQUENCY 20000000 //20MHz //Note: 1 INST Cycle = ((1/ CLOCK_SPEED) * 4) = (1/20000000)*4 = 0.2Us // Total INST Cycle in a loop = 0.2*5 = 1.00 ~ 1Us. //********************************************************************** #elif (CLK_FREQ_20000000) #define wait(a) _asm movlw a\ movwf macro_delay,1\ loop: nop\ nop\ decfsz macro_delay,1,1\ bra loop\ _endasm #define BAUD_RATE 31 //********************************************************************** //#define CLOCK_FREQUENCY 16000000 //16MHz //Note: 1 INST Cycle = ((1/ CLOCK_SPEED) * 4) = (1/16000000)*4 = 0.25Us // Total INST Cycle in a loop = 0.25*4 = 1.00 ~ 1Us. //********************************************************************** #elif (CLK_FREQ_16000000) #define wait(a) _asm movlw a\ movwf macro_delay,1\ loop: nop\ decfsz macro_delay,1,1\ bra loop\ _endasm #define BAUD_RATE 25 //********************************************************************** //#define CLOCK_FREQUENCY 12000000 //12MHz //Note: 1 INST Cycle = ((1/ CLOCK_SPEED) * 4) = (1/12000000)*4 = 0.3333Us // Total INST Cycle in a loop = 0.33333*3 = 0.9999 ~ 1Us. //********************************************************************** #elif (CLK_FREQ_12000000) #define wait(a) _asm movlw a\ movwf macro_delay,1\ loop: decfsz macro_delay,1,1\ bra loop\ _endasm #define BAUD_RATE 18 #endif //*************************************************************************/ /******* G E N E R I C D E F I N I T I O N S ************************************************/ #define HIGH 1 #define LOW 0 #define OUTPUT 0 #define INPUT 1 #define SET 1 #define CLEAR 0 /**PORT D E F I N I T I O N S ****************************************************/ //UART PORT DEFINITIONS #define UART_RX_DIRECTION TRISCbits.TRISC7 #define UART_TX_DIRECTION TRISCbits.TRISC6 #define UART_RX_STATUS RCSTA #define UART_TX_STATUS TXSTA //ONE WIRE PORT PIN DEFINITION ///**************************************************** // This Configuration is required to make any PIC MicroController // I/O pin as Open drain to drive 1-wire. ///**************************************************** #define OW_PIN_DIRECTION LATBbits.LATB2 #define OW_WRITE_PIN TRISBbits.TRISB2 #define OW_READ_PIN PORTBbits.RB2 /******* G E N E R I C D E F I N I T I O N S ************************************************/ #define DELAY_6Us 6 #define DELAY_9Us 9 #define DELAY_10Us 10 #define DELAY_55Us 55 #define DELAY_60Us 60 #define DELAY_64Us 64 #define DELAY_70Us 70 #define DELAY_205Us 205 // DELAY_410Us = DELAY_205Us + DELAY_205Us #define DELAY_240Us 240 // DELAY_480Us = DELAY_240Us + DELAY_240Us // since the variable is declared as unsigned char /************************************************************** function definition **************************************************************/ void initEUSART(void); void USART_RxTx(void); void high_isr(void); void low_isr(void); /*********************************************************** V A R I A B L E S ************************************************************/ #endif