Enzo Gomez [enzo.gomez at ieee.org] says:
I have this code to connect with DS1990A, an electronic key (its just a ROM device). It was originally written for PIC 16F84
The code is C code, compiled great with C2C compiler, from Pavel Baranov.
http//www.geocities.com/SiliconValley/Network/3656/c2c/c.html
a shareware compiler.
// Interfaz con dispositivos DALLAS #ifndef true #define true 1 #endif #ifndef false #define false 0 #endif #define Dallas_Port PORTB // Define el puerto de datos de DS1990A #define Dallas_Tris TRISB // Define el puerto de configuración #define Dallas_Pin 7 // para acceder a la memoria DS1990A. asm { DALLAS_PORT EQU PORTB DALLAS_PIN EQU 7 } char SN_Dallas[8]; // Para guardar el Serial Number de Dalas // 0x01 + SN[6] + CRC[1] char CRC_Dallas; // Para el chequeo del CRC. //Configura el puerto como salida void SetOut_Dallas(void) { set_bit( STATUS, RP0 ); //Selecciona el banco de registros 1 clear_bit(Dallas_Tris, Dallas_Pin); clear_bit( STATUS, RP0 ); //Selecciona el banco de registros 0 } //Configura el puerto como entrada void SetIn_Dallas(void) { set_bit( STATUS, RP0 ); //Selecciona el banco de registros 1 set_bit(Dallas_Tris, Dallas_Pin); clear_bit( STATUS, RP0 ); //Selecciona el banco de registros 0 } //Pone un cero a la salida del pin DS1990A void Set0_Dallas(void) { clear_bit( Dallas_Port, Dallas_Pin); } // Transmite un bit a DS1990A. void Write_Dallas(char bit) { // Pone un CERO a la salida // (pulso de comienzo). clear_bit( Dallas_Port, Dallas_Pin); SetOut_Dallas(); // Pone el puerto como salida. delay_us(17); // Espera 15us min if (bit) { // si llega aqui debe transmitir un UNO SetIn_Dallas(); // Configura puerto como entrada para que // suba en tensión automáticamente. delay_us(50); // Espera 50us (este tiempo debe completar // los 60us como mínimo). } else { delay_us(100); // Espera el tiempo que es como máximo 120us SetIn_Dallas(); // Pone el puerto como entrada. } // Espera 1us (tREC) en el return } //Transmite un Byte al dispositivo void WriteByte_Dallas(char Data) { char n; for(n=0; n<8; n++) { if (Data & 0x01) { // Pone un CERO a la salida // (pulso de comienzo). clear_bit( Dallas_Port, Dallas_Pin); set_bit( STATUS, RP0 ); //Selecciona el banco de registros 1 clear_bit(Dallas_Tris, Dallas_Pin); // Pone un cero a la salida set_bit(Dallas_Tris, Dallas_Pin); // Pone el puerto en entrada clear_bit( STATUS, RP0 ); //Selecciona el banco de registros 0 delay_us(103); // Espera 103us (este tiempo debe completar // los 120us como mínimo). } else { SetOut_Dallas(); // Pone el puerto como salida. clear_bit( Dallas_Port, Dallas_Pin);// Pone un CERO a la salida delay_us(100); // Espera 100us SetIn_Dallas(); // Configura puerto como entrada para que // suba en tensión automáticamente. } Data >>= 1; } } //Lee el puerto de Dallas. char ReadIn_Dallas(void) { asm { clrw btfsc DALLAS_PORT, DALLAS_PIN movlw D'1' return } } //Lee un bit de la memoria Dallas. char ReadBit_Dallas(void) { char Lectura; // Pone un CERO a la salida // (pulso de comienzo). clear_bit( Dallas_Port, Dallas_Pin); set_bit( STATUS, RP0 ); //Selecciona el banco de registros 1 clear_bit(Dallas_Tris, Dallas_Pin); // Configura como salida \ nop(); // espera... > Pulso de inicio set_bit(Dallas_Tris, Dallas_Pin); // Configura como entrada / clear_bit( STATUS, RP0 ); //Selecciona el banco de registros 0 nop(); // Espera para leer nop(); nop(); nop(); nop(); Lectura = ReadIn_Dallas(); delay_us(60-18); // Espera para completar los 120us max return Lectura; // Lee el pin } // Envia el pulso de Reset al bus 1-Wire, y devuelve // true si recibe el pulso de presencia char Reset_Dallas(void) { // Pone un CERO a la salida // (pulso de RESET). clear_bit( Dallas_Port, Dallas_Pin); SetOut_Dallas(); // Pone el puerto en salida. delay_us(255); // Espero 480us mínimo. delay_us(225); SetIn_Dallas(); // Pone el puerto como entrada y // espera a que la DS1990A ponga un cero. delay_us(75); // Espera un mínimo de 15us+60us. if ( ReadIn_Dallas() ) // Si lee un UNO es que no hay memoria colgada del return false; // bus. delay_us(165); // Espera para completar los 480us (peor caso) delay_us(240); return true; } // Calcula el CRC8 acumulado char CRC8_Dallas(char Data) { char i, f; for (i = 0; i < 8; i++) { f = 1 & (Data ^ CRC_Dallas); CRC_Dallas >>= 1; Data >>= 1; if (f) CRC_Dallas ^= 0x8c; // b10001100 es la palabra del CRC (x8 + x5 + x4 + 1) // 7..43..0 junto con el 1 aplicado a f. } return CRC_Dallas; } //Chequea el CRC de los datos recibidos char CheckCRC() { char k; CRC_Dallas = 0; for (k = 0; k < 8; k++) CRC8_Dallas(SN_Dallas[k]); return !CRC_Dallas; } // Lee un byte desde el dispositivo char ReadByte_Dallas() { char n, Byte_Dallas; for (n=0; n<8; n++) { Byte_Dallas >>= 1; if ( ReadBit_Dallas() ) Byte_Dallas |= 0x80; // LSB first! nop(); } return Byte_Dallas; } //Lee el código de la memoria y lo guarda en la variable //global SN_Dallas char ReadSN_Dallas(void) { //Escribe el comando de lectura de ROM (Read ROM = 0x33) WriteByte_Dallas(0x33); // 0x33 - Read ROM for(CRC_Dallas = 0; CRC_Dallas < 8; CRC_Dallas++) SN_Dallas[CRC_Dallas] = ReadByte_Dallas(); return CheckCRC(); } // Inicializa todo lo necesario // para manejar las llaves Dallas // (pines, interrupciones) void Init_Dallas( void ) { //Inicializacion del HW del uC. set_bit( STATUS, RP0 ); //Seleccciona el banco de registros 1. set_bit( Dallas_Tris, Dallas_Pin ); // Configura el pin para entrada. set_bit( OPTION_REG, 7 ); //Deshabilita las pull-up del puerto B. clear_bit( STATUS, RP0 ); //Seleccciona el banco de registros 0. set_bit( INTCON, 3 ); // Habilita las interrupciones por cambios en puerto B. } //////////////////////////////////////////////////////////////////////// /* main() { Init_Dallas(); Reset_Dallas(); ReadSN_Dallas(); } /* */
Questions: