Bonjour à tous,
Voilà j'ai récemment fait l'acquisition d'un capteur de taux CO2 avec sortie numérique. Cette sortie numérique utilise un protocole qui est très similaire au protocole I2C et se nomme : e2 interface. Ce protocole a été élaboré par la marque du capteur (E+E) est à la particularité d'être beaucoup plus lent que son grand frère I2C (fréquence d'horloge entre 500 et 5000 Hz).
Mais voilà, à l'heure actuelle, je n'arrive pas à interfacer mon capteur avec mon PIC18F45K22... Ce qui m'embête cruellement car c'est une mesure primordial pour mon projet de fin d'étude...
Voici la configuration dans laquelle je me trouve :
- PIC18F45K22 configurer avec oscillateur interne à 8MHz
- PICKIT3 + PICDEM2 PLUS pour programmer le PIC et faire des essais
- Résistance de tirage sur mon bus E2 Interface d'environ 5k (2 résistances de 10k en parallèle).
Je vais vous faire un copier/coller du code, des fois que l'un d'entre vous puisse détecter une erreur ou me suggérer de faire certain(s) test(s)...
e2_interface.h :
e2_interface.c :Code:#include <p18f45k22.h> /*---------------------------Définitions--------------------------------------*/ #define time 20 //config frequence d'horloge #define ACK 1 #define NACK 0 #define SDA TRISBbits.TRISB1 #define SCL TRISBbits.TRISB2 #define SDA_IN PORTBbits.RB1 /*-----------------------Prototypes Fonctions--------------------------------*/ // Fonctions e2_interface void start(void) ; void stop(void) ; void send(unsigned char d) ; unsigned char read(void) ; unsigned char check_ack(void) ; void send_ack(void) ; void send_nack(void) ; void delay(unsigned int duree) ; unsigned char read_SDA(void) ; // Fonctions Lecture Status et Acquisition Mesure unsigned char read_status(void) ; unsigned int mesure(void) ;
main.c :Code:#include "e2_interface.h" /*-----------------------Déclarations des variables---------------------------*/ unsigned char co2_low, co2_high = 0 ; unsigned int co2 ; unsigned char error = 0x00 ; /*-----------------------Fonctions E2_interface-------------------------------*/ void start(void) { SDA = 1 ; SCL = 1 ; delay(30 * time) ; SDA = 0 ; delay(30 * time) ; } void stop(void) { SCL = 0 ; delay(20 * time) ; SDA = 0 ; delay(20 * time) ; SCL = 1 ; delay(20 * time) ; SDA = 1 ; delay(20 * time) ; } void send(unsigned char d) { unsigned char i = 0 ; for(i=8; i>0; i--) { SCL = 0 ; delay(10 * time) ; if((d& 0x80)!= 0) SDA = 1 ; else SDA = 0 ; delay(20 * time) ; SCL = 1 ; d <<= 1 ; delay(30 * time) ; SCL = 0 ; } SDA = 1 ; } unsigned char read(void) { unsigned char d = 0 ; unsigned char x = 0X80 ; for(x = 0x80 ; x > 0; x >>= 1) { SCL = 0 ; delay(30 * time) ; SCL = 1 ; delay(15 * time) ; if (read_SDA()) d |= x ; delay(15 * time) ; SCL = 0 ; } return d ; } unsigned char check_ack(void) { unsigned char input = 0 ; delay(30 * time) ; SCL = 1 ; delay(15 * time) ; input = read_SDA() ; delay(15 * time) ; if (input == 1) return NACK ; else return ACK ; } void send_ack(void) { SCL = 0 ; delay(15 * time) ; SDA = 0 ; delay(15 * time) ; SCL = 1 ; delay(30 * time) ; SCL = 0 ; SDA = 1 ; } void send_nack(void) { SCL = 0 ; delay(15 * time) ; SDA = 1 ; delay(15 * time) ; SCL = 1 ; delay(30 * time) ; SCL = 0 ; } void delay(unsigned int duree) { while (duree != 0) { duree = duree - 1 ; } } unsigned char read_SDA(void) { if (SDA_IN == 1) return 1 ; else return 0 ; } /*-----------------Fonctions Permettant Lecture Status et Lecture Mesure Co2-----------------------*/ unsigned char read_status(void) { unsigned char status ; unsigned char checksum = 0 ; start() ; send(0x71) ; //demande du status if (check_ack() == 1) { status = read() ; send_ack() ; checksum = read() ; send_nack() ; stop() ; if(((status + 0x71) % 256) == checksum) return status ; else { error = 0x04 ; return 0xFF ; // erreur } } else error = 0x01 ; } unsigned int mesure(void) { unsigned char checksum = 0 ; start() ; send(0xE1) ; if (check_ack() == 1) { co2_low = read() ; send_ack() ; checksum = read() ; send_nack() ; stop() ; if (((co2_low + 0xE1) % 256) == checksum) { start() ; send(0xF1) ; if(check_ack() == 1) { co2_high = read() ; send_ack() ; checksum = read() ; send_nack() ; stop() ; if (((co2_high + 0xF1) % 256) == checksum) { return co2 = co2_low + 256 * co2_high ; } else error = 0x80 ; } else { stop() ; error = 0x20 ; } } else error = 0x40 ; } else { stop(); error = 0x10 ; } }
Actuellement, quand je fais mes essais en mode debug pour lire le status du capteur, e2_interface.c me retourne error = 0x01. Ce qui veut dire que le capteur ne renvoie pas ACK après la trame de commande émise par le PIC.Code:#include <p18f45k22.h> #include "e2_interface.h" #pragma config WDTEN = OFF // Watch Dog Timer disabled #pragma config FOSC = INTIO67 // Internal Oscillator Block, RA6 & RA7 enabled #pragma config DEBUG = ON // Background Debug enabled #pragma config LVP = OFF // Low Voltage Programming disabled #pragma config MCLRE = INTMCLR // RE3 enabled, MCLR disabled unsigned char test_status = 0 ; unsigned char status = 0 ; unsigned int acq_co2 = 0 ; unsigned char i = 0 ; void main() { OSCCON = 0x62 ; ANSELB = 0x00 ; PORTB = 0x00 ; TRISB = 0x06 ; PORTA = 0x00 ; TRISA = 0x00 ; test_status = read_status() ; while(1) { } }
Je ne sais plus quoi faire, et tout commentaire ou aide ne pourra m'être que très précieuse...
Par avance, merci à vous.
-----