CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

...Line-by-line software access to I2C

 
Post new topic   Reply to topic    CCS Forum Index -> Code Library
View previous topic :: View next topic  
Author Message
PICman



Joined: 02 Nov 2007
Posts: 26

View user's profile Send private message

...Line-by-line software access to I2C
PostPosted: Wed Mar 25, 2009 5:02 am     Reply with quote

This code is a "do-nothing" code that shows how I2C works. It continuously writes data into a 24LC256 I2C serial EEPROM and then checks it's contents for data integrity. Comments are sent on RB2 in 9600,n,8,1 (TTL)

The data is generated by a LFSR PRBG so it is random looking.

It's main goal is to show the user how I2C works and to implement I2C in microcontrollers that do not have I2C implemented.

Code:

//
//    My first experiences with I2C: EEPPROMS.
//   
//    I didn't want with the tiny 24LC00 and many
//    electronics stores hold the 24LC256. So i
//    chose it. The 24LC256 holds 262144 bits of
//    data organized in a 32kB fashion (32768 * 8)
//
//    This firmware includes random R/W procedures
//    for the 24LC256 I2C serial EEPROM.
//
//    This firmware is aimed at PIC's that do
//    not include the integrated I2C protocol. It's
//    goal is also to explain you how I2C works.
//
//              _________  _________
//           __|         \/         |__
//   Ground |__|A0               Vdd|__| +5V
//           __|                 __ |__
//   Ground |__|A1    EEPROM     WE |__| Ground to write, +5V to protect.
//           __|     24LC256        |__
//   Ground |__|A2               SCL|__|Serial CLock
//           __|                    |__
//   Ground |__|Vss              SDA|__|Serial DAta
//             |____________________|
//
// I2C lines:
// ==========
//
// What is interesting with I2C (developed by
// Philips), is that only two lines are required to access
// I2C devices. Those two lines are: SDA (Serial DAta) et SCL
// (Serial CLock).
//
// Another important feature of I2C is that ALL I2C devices
// can ONLY pull the lines LOW (to ground). Never, an I2C
// device may pull HIGH a line. Pulling-up the SDA and SCL
// lines is done by two pull-up RESISTORS (one per line).
// The suggested value for pullup resistors is 4700-20k ohms.
//
//    Waveforms:
//    ==========
//
// In the I2C protocol, normal address/read/write on the SDA
// line is done ONLY when the SCL line is LOW.
//
// The ONLY times when SDA is transited while SCL is high is
// on the (S)tart and sto(P) commands.
//
////////////////////////////////////////////////
//       ____S(tart)    //       (sto)P___    //
//    SDA    \_______   // ___________/   SDA //
//       _________      //       _________    //
//    SCL         \__   // _____/         SCL //
//                      //                    //
////////////////////////////////////////////////
//         ___     ___     ___     ___     ___     ___     ___     ___    ___
//  SCL  _/ 1 \___/ 0 \___/ 1 \___/ 0 \___/ A2\___/ A1\___/ A0\___/r/w\__/ack\
//       _______         _______
//  Mas_/       \_______/       \_______________________________________
//
//  Sla                                                                 \_____/
//
// For EEPROMS, 4 first bits MUST BE set at 1010.
// Every other value will be adressed to another
// component and will be ignored by EEPROMS.
//
//
// Bits A2, A1 and A0 on the stream must correlate with the hardwired
// logic states of corresponding pins (reapectively, pins 3, 2 and 1)
// of the I.C.
//
// Every other combination will be ignored by the EEPROM. This
// feature allows the user to use several (up to eight) 24LC256's
// on the same I2C pair by using different hardwired combinations on
// pins A2-0.
//
// For now, all A0-2 pins are tied to ground (Vss).sont à ground avec Vss.
//
//               PIC16F648A
//
// RB1 = RXD
// RB2 = TXD
//
//              _________  _________
//           __|         \/         |__
//          |__|Ra2              Ra1|__|SDA
//           __|                    |__
//          |__|Ra3              Ra0|__|SCL
//           __|                    |__
//          |__|Ra4            clkin|__|
//           __|____                |__
//       +5V|__|MCLR/Vpp      clkout|__|
//           __|                    |__
//        0V|__|Vss              Vdd|__| +5V
//           __|                    |__
//          |__|Rb0/int  Rb7/ICSPDAT|__|
//           __|                    |__
//          |__|Rb1          Rb6/PGC|__|
//           __|                    |__
// 9600baud |__|Rb2              Rb5|__|
//           __|                    |__
//          |__|Rb3              Rb4|__|
//             |____________________|
//

#include <16F648A.h>
//#FUSES XT,NOWDT,PUT,NOPROTECT,BROWNOUT,NOMCLR,NOLVP,NOCPD
//#use fast_io(b)  // We DO want to work around with TRIS (I2C port)
#use delay(clock=4000000)
#use rs232(baud=9600,parity=N,xmit=pin_b2,rcv=pin_b1,bits=8)
#FUSES intrc,NOWDT,PUT,NOPROTECT,BROWNOUT,NOMCLR,NOLVP,NOCPD
   //no master clear a5 (reset) ;cpd barrer eedata;nolvp lo-volt prog

////////////////////////////
void rad(void);           //
void init_pic(void);      //
int8 i2c_read(void);      //
void i2c_write(int8);     //
void S(void);             //
void P(void);             // P R O T O T Y P E S
void envoi_donnees(int1); //
void envoi_octet(int8);   //
int1 lire_donnees(void);  //
void aff_err(int8);       //
int8 adresse_haute;       //
int8 adresse_basse;       //
int8 donnee;              //
int8 hasard;              //
int8 x0,x1,x2,x3,x4,x5;   //
int8 x6,x7,y;             //
////////////////////////////


//#ZERO_RAM
//#int_RTCC

/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
void main()                                                             /////
{                                                                       /////
   int8 donnee,compteur,compteur2;                                      /////
   int1 valide;                                                         /////
   int16 nbre_erreurs,nbre_prog,octets_ecrits;                          /////
   /*=-=*//*=-=*//*=-=*//*=-=*//*=-=*//*=-=*//*=-=*//*=-=*//*=-=*/      /////
   init_pic();                                                          /////
   adresse_haute=0x00; // Adresse dans un 24LC256: 0x0000-0x07FF        /////
   adresse_basse=0x00; // Adresse basse = 0-255 haute=0-127             /////
//////////////                                                          /////
   x0=174;  // Initialisation                                           /////
   x1=152;  // RAD                                                      /////
   x2=67;   //                                                          /////
   x3=223;  // Here, i initialise an LFSR (Linear Feedback Shift        /////
   x4=98;   // Register) to be able to always generate the same         /////
   x5=42;   // pseudo-random stream. This way, i will be able, later,   /////
   x6=135;  // to re-initialise the LFSR the same way to start the      /////
   x7=201;  // verify routine with the same data.                       /////
//////////////                                                          /////
   for(compteur=0;compteur<3;compteur++)                                /////
      printf("\n\r----------Writing I2C EEPROM-------------------");    /////
                                                                        /////
                                                                        /////
   printf("\n\r");                                                      /////
                                                                        /////
   compteur2=0;                                                         /////
   nbre_prog=0;                                                         /////
   octets_ecrits=0;                                                     /////
   valide=1;                                                            /////
   while(valide)                                                        /////
   {                                                                    /////
      rad();                                                            /////
//////////////////////////////////////////////                          /////
      donnee=i2c_read();                    // Pre-read. If the correct /////
      if(donnee==hasard)                    // data is already present  /////
         compteur2++;                       // in the EEPROM, i don't   /////
      else                                  // touch it. This procedure /////
      {                                     // has two advantages:      /////
         printf("\n\rAdr: %2X%2X: ",        //                          /////
            adresse_haute,adresse_basse);   //                          /////
         printf(" ecrit: %2X",hasard);      //                          /////
         i2c_write(hasard);                 // 1) Much faster           /////
                                            //                          /////
         donnee=i2c_read();                 // 2) No useless            /////
         printf(" Lu: %2X",donnee);         //    writes on             /////
         if(donnee==hasard)                 //    write-limited EEPROM  /////
            octets_ecrits++;                //    cells.                /////
      }                                     //                          /////
      if(donnee==hasard)                    //                          /////
         nbre_prog++;                       //                          /////
      else                                  //                          /////
         aff_err(13);                       //                          /////
//////////////////////////////////////////////                          /////
                                                                        /////
////////////////////////////////////////////                            /////
         if(adresse_basse==255)           //                            /////
         {                                //                            /////
            if(adresse_haute==127)        // Address counter            /////
               valide=0;                  // Generates valid addresses  /////
         }                                // between 0x0000 and 0x7FFF  /////
         adresse_basse++;                 // (24LC256)                  /////
         if(adresse_basse==0)             //                            /////
            adresse_haute++;              //                            /////
////////////////////////////////////////////                            /////
                                                                        /////
////////////////////////////////////////////                            /////
      if(compteur2==0)                    // At each 256 correct        /////
         printf(".");                     // verifications              /////
////////////////////////////////////////////                            /////
   }                                                                    /////
   printf("\n\r%lu=bytes written during this session",octets_ecrits);   /////
   printf("\n\r%lu=Total of good bytes:",nbre_prog);                    /////
/////////////////////////////////////////////////////////////////////////////
   while(1)                                                             /////
   {                                                                    /////
      printf("\n\r--------Verification of I2C EEPROM-------------");    /////
      printf("\n\r");                                                   /////
      nbre_erreurs=0;                                                   /////
      adresse_haute=0x00;                                               /////
      adresse_basse=0x00;                                               /////
////////////// LFSR Initialisation                                      /////
   x0=174;  //                                                          /////
   x1=152;  // Here, i initialise the LFSR the same way as i did on     /////
   x2=67;   // beginning. This way, the LFSR will generate the EXACT    /////
   x3=223;  // same pseudorandom stream for verification as it did on   /////
   x4=98;   // writing. This way, i can fill the EEPROM with random     /////
   x5=42;   // looking data then, i can test it's data integrity.       /////
   x6=135;  //                                                          /////
   x7=201;  //                                                          /////
//////////////                                                          /////
                                                                        /////
/////////////////////////////////////////////                           /////
      valide=1;                            // Verification of EEPROM's  /////
      while(valide)                        // data contents.            /////
      {                                    //                           /////
         rad();                            //                           /////
         donnee=i2c_read();                //                           /////
         if(donnee!=hasard)                //                           /////
         {                                 //                           /////
            printf(" %X%X",adresse_haute,  //                           /////
               adresse_basse);             //                           /////
            nbre_erreurs++;                //                           /////
         }                                 //                           /////
/////////////////////////////////////////////                           /////
                                                                        /////
/////////////////////////////////////////////                           /////
                                           //                           /////
         if(adresse_basse==255)            //                           /////
         {                                 //                          /////
            printf("+");                   //                         /////
            if(adresse_haute==127)         // Address counter        /////
               valide=0;                   //                       /////
         }                                 //                      /////
         adresse_basse++;                  //                     /////
         if(adresse_basse==0)              //                    /////
            adresse_haute++;               //                   /////
                                           //                  /////
      }                                    //                 /////
      printf("\n\rTotal: %lu error(s)",    //                /////
              nbre_erreurs);               //               /////
/////////////////////////////////////////////              /////
   }                                                      /////
}                                                        /////
/////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////



///////////////////////////////////////////////////////////
void init_pic(void)                                      //
{                                                        //
   output_a(0); // IT IS IMPORTANT to set both bits 0    //
                // and 1 to LOW and MAINTAIN them LOW    //
                // throughout the whole program !        //
                // REMEMBER ! an I2C device CAN NOT      //
                // pull high an I2C line , master or     //
                // slave !                               //
   output_b(0);                                          //
   set_tris_a(0b11111111);  // gauche=bit7, droite=bit0  //
   set_tris_b(0b11111011);  // gauche=bit7, droite=bit0  //
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256);            //
   setup_timer_1(T1_DISABLED);                           // PIC
   setup_timer_2(T2_DISABLED,0,1);                       // initialisation
   setup_comparator(NC_NC_NC_NC);  //not connected       // Routine.
   setup_vref(FALSE);              // not used           //
   disable_interrupts(INT_RTCC);                         //
   disable_interrupts(GLOBAL);                           //
//   setup_oscillator(False);                            //
   port_b_pullups(true);                                 //
}                                                        //
///////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////


int8 i2c_read()
/////////////////////////////////////////////////////////////////////
{                                                                  //
   int1 ack,ein;                                                   //
   int8 rot;                                                       //
   int8 compteur;                                                  //
   /*=-=*//*=-=*/                                                  //
                                                                   //
                                                                   //
///////////                                                        //
   S();  // Start                                                  //
///////////                                                        //
                                                                   // I2C serial
////////////////////////                                           // EEPROM
   envoi_octet(0xA0); // ADRESSAGE/ÉCRITURE                        // reading
////////////////////////                                           //
                                                                   //
//////////////////////////////////                                 //
   envoi_octet(adresse_haute);  // Send                            //
////////////////////////////////// correct                         //
   envoi_octet(adresse_basse);  // address to                      //
////////////////////////////////// EEPROM.                         //
                                                                   //
/////////// Pour la lecture du EEPROM. on doit                     //
   S();  // exécuter un second "Start" après                       //
/////////// l'adressage...                                         //
                                                                   //
//////////////////////// ...et on envoie                           //
   envoi_octet(0xA1); // une commande de                           // I2C serial
//////////////////////// lecture                                   // EEPROM
                                                                   // reading
//////////////////////////////////                                 //
   donnee=0;                    // I2C EEPROM reading routine by   //
                                // itself.                         //
   compteur=7;                  //                                 //
   while(!bit_test(compteur,7)) // For tha, the "rot" variable is  //
   {                            // used. "rot"'s bit 0 is loaded   //
#asm                            // with the read bit on the I2C's  //
      rlf rot,f                 // SDA line.                       //
#endasm                         //                                 //
      ein=lire_donnees();       // Bertween each bit loading, the  //
                                // "rot" variable is rotated left. //
      bit_clear(rot,0);         //                                 //
      if(ein)                   // After eight, the "rot" variable //
         bit_set(rot,0);        // is loaded with the full         //
      compteur--;               // EEPROM's byte, the MSB loaded   //
   }                            // first.                          //
//////////////////////////////////                                 //
                                                                   //
////////////////////////// Final ACK                               //
   ack=lire_donnees();  //                                         //
   if(ack==0)           // Here, at the end of byte read, the     //
      aff_err(11);      // slave EEPROM MUST NOT send an ACK.    //
//////////////////////////                                      //
                                                               //
///////////                                                   //
   P();  // stoP                                             //
///////////                                                 //
                                                           //
   return(rot);                                           //
}                                                        //
//////////////////////////////////////////////////////////

void i2c_write(int8 octet)
/////////////////////////////////////////////////
{                                              //
   int1 ack,valide;                            //
   int8 limite_ecriture;                       //
 /*=-=*//*=-=*//*=-=*//*=-=*//*=-=*//*=-=*/    //
///////////                                    //
   S();  // Start                              //
///////////                                    //
                                               //
////////////////////////                       //
   envoi_octet(0xA0); // ADRESSING/WRITING     //
////////////////////////                       //
                                               //
//////////////////////////////////             //
   envoi_octet(adresse_haute);  // Send        //
////////////////////////////////// correct     //
   envoi_octet(adresse_basse);  // address to  //
////////////////////////////////// EEPROM.     //
                                               //
///////////////////////// Send byte to be      //
   envoi_octet(octet); // written into the     //
///////////////////////// EEPROM.              //
                                               //
/////////// At this stoP, EEPROM writes        //
   P();  // the byte in it's internal memory   //
/////////// cells.                             // Écriture du
                                               // EEPRM I2C
////////////////////////////                   //
   limite_ecriture=0;     //                   //
   valide=0;              // Here, we send a   //
   while(valide==0)       // check byte to the //
   {                      // EEPROM. It will   //
   ///////////            // reply with an ACK //
      S();  // Start      // only when the     //
   ///////////            // writing procedure //
      envoi_donnees(1);   // is completed.     //
      envoi_donnees(0);   //                   //
      envoi_donnees(1);   //                   //
      envoi_donnees(0);   //                   //
      envoi_donnees(0);   //                   //
      envoi_donnees(0);   //                  //
      envoi_donnees(0);   //                 //
      envoi_donnees(0);   //                //
                          //               //
      ack=lire_donnees(); //              //
      if(ack==0)          ///////        //
         valide=1;             //       //
      if(limite_ecriture>253)  //      //
      {                        //     //
         aff_err(12);     ///////    //
         valide=1;        //        //
      }                   //       //
   ///////////            //      //
      P();  // stoP       //     //
   ///////////            //    //
      limite_ecriture++;  //   //
   }                      //  //
//////////////////////////// //
}                           //
/////////////////////////////

/////////////////////////////////////////////////////////
void S(void)                                           //
{                                                      //
   int1 valide;                                        //
   int8 essais;                                        //
   /*=-=*//*=-=*//*=-=*//*=-=*/                        //
   set_tris_a(0b11111111); // Eneryone up !            //
                           //                          //
                           // Throughout this          //
                           // program, TRIS is used    //
                           // to either pull down a    //
                           // line or RELEASE it to    //
                           // high (via the pullup     //
                           // resistors).              //
                           //                          //
                           // Bits 0 (SCL) and 1 (SDA) //
                           // are either RESET LOW to  //
                           // pull down or SET HIGH to //
                           // release the              //
                           // corresponding line.      //
   delay_us(4);                                        //
//////////////////////////////////////////// We check  //
   if(!input_state(40)||!input_state(41)) // that BOTH //
      aff_err(7);                         // SDA and   //
//////////////////////////////////////////// SCL=High  //
                                                       //
//////////////////////////////////////                 //
   essais=0;                        //                 //
   valide=0;                        //                 //
   while(valide==0)                 //                 //
   {                                // SDA is pulled   // Start
      set_tris_a(0b11111101);       // down.           // routine.
      delay_us(4);                  //                 //
      if(!input_state(41))          //                 //
         valide=1;                  // SDA is tested   //
      else                          // to be sure it's //
      {                             // LO.             //
         aff_err(0);                //                 //
         essais++;                  //                 //
         if(essais>7)               //                 //
            valide=1;               //                 //
      }                             //                 //
   }                                //                 //
//////////////////////////////////////                 //
                                                       //
//////////////////////////////////////                 //
   essais=0;                        //                 //
   valide=0;                        //                 //
   while(valide==0)                 //                 // Start
   {                                // Then, SCL is    // routine.
      set_tris_a(0b11111100);       // pulled down.    //
      delay_us(4);                  //                 //
                                    //                 //
      if(!input_state(40))          // And we check    //
         valide=1;                  // that SCL is     //
      else                          // LOW.            //
      {                             //                 //
         aff_err(1);                //                 //
         essais++;                  //                 //
         if(essais>7)               //                 //
            valide=1;               //                 //
      }                             //                 //
   }                                //                 //
   delay_us(4);                     //                 //
//////////////////////////////////////                 //
}                                                      //
/////////////////////////////////////////////////////////

////////////////////////////////////////////////////
void P(void)                                      //
{                                                 //
   int1 valide=0;                                 //
   int8 essais;                                   //
   /*=-=*//*=-=*//*=-=*//*=-=*//*=-=*/            //
///////////////////////////// Before releasing    //
   set_tris_a(0b11111100); // SCL, we must get    //
   delay_us(4);            // sure that SDA is    //
///////////////////////////// LOW.                //
                                                  //
////////////////////////////////                  //
   essais=0;                  //                  //
   valide=0;                  //                  //
   while(valide==0)           //                  //
   {                          // We release SCL   //
      set_tris_a(0b11111101); // high...          // stoP
      delay_us(4);            //                  // routine
                              //                  //
      if(input_state(40))     // SCL is verified  //
         valide=1;            // for it's         //
      else                    // "highness" !     //
      {                       //                  //
         aff_err(1);          //                  //
         essais++;            //                  //
         if(essais>7)         //                  //
            valide=1;         //                  //
      }                       //                  //
   }                          //                  //
////////////////////////////////                  //
   delay_us(4);                                   //
                                                  //
////////////////////////////////                  //
   essais=0;                  //                  //
   valide=0;                  // THEN, SDA is     //
   while(valide==0)           // released high.   //
   {                          //                  //
      set_tris_a(0b11111111); //                 // stoP
      delay_us(4);            //                // routine
                              //               //
      if(input_state(41))     // SDA is       //
         valide=1;            // tested      //
      else                    // high.      //
      {                       //           //
         aff_err(10);         //          //
         essais++;            //         //
         if(essais>7)         //        //
            valide=1;         //       //
      }                       //      //
   }                          //     //
////////////////////////////////    //
}                                  //
////////////////////////////////////

///////////////////////////////////////////////////////////
void envoi_octet(int8 rot)                               //
//////////////////////////////////                       //
{                               // The "to-be-sent" byte // PIC-to-I2C EEPROM
   int1 ein,ack;                // is transferred to the // byte sending routine.
   int8 compteur;               // "rot" variable.       //
   /*=-=*//*=-=*//*=-=*//*=-=*/ //                       //
   compteur=7;                  //                       //
   while(!bit_test(compteur,7)) // From "rot", we send   //
   {                            // the MSB (bit 7) bit   //
      ein=0;                    // to I2C.               //
      if(rot&0x80)              //                       //
         ein=1;                 // Then, "rot" is        //
      envoi_donnees(ein);       // rotated left to pass  //
#asm                            // to the next bit.      //
      rlf rot,f                 //                       //
      bcf rot,0                 // This way, all eight   //
#endasm                         // bits are sent to I2C, //
      compteur--;               // one at a time,        //
   }                            // starting with         //
////////////////////////////////// the heaviest one.     //
                                                         //
///////////////////////// At the end of each byte, the   //
   ack=lire_donnees(); // PIC master waits for an        //
   if(ack==1)          // ACKnowledge from the slave     //
      aff_err(6);      // EEPROM. To send it's ACK, the  //
///////////////////////// slave PULLS DOWN SDA. The      //
// master releases it's SDA line and checks that the SDA //
// line is HELD DOWN by the slave.                       //
}                                                        //
///////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////
void envoi_donnees(int1 donnee)                               //
{                                                             //
   int1 valide=0;                                             //
   int8 essais;                                               //
   /*=-=*//*=-=*//*=-=*//*=-=*//*=-=*//*=-=*//*=-=*//*=-=*/   //
////////////////////////////////                              //
   essais=0;                  //                              //
   while(valide==0)           //                              //
   {                          // SCL is pulled down           //
      set_tris_a(0b11111110); // while SDA is left free to go //
      delay_us(4);            // high.                        //
////////////////////////////////                              //
                                                              //
///////////////////////////// Master checks that SDA goes HI. // Bit sending
      if(!input_state(41)) // If SDA id held LOW, then the    // procedure
         aff_err(11);      // slave EEPROM has sent an        // on I2C port.
                           // unattended ACK.                 //
                           //                                 //
/////////////////////////////                                 //
                                                              //
////////////////////////////////////                          //
      if(donnee==1)               // SDA is either held LOW   //
         set_tris_a(0b11111110);  // or released HIGH.        //
      else                        // obeying to the data bit. //
         set_tris_a(0b11111100);  //                          //
                                  //                          //
                                  //                          //
      delay_us(4);                //                          //
////////////////////////////////////                          //
                                                              //
////////////////////////////////                              //
      if(donnee)              //                              //
      {                       //                              //
         if(input_state(41))  // Verification. Has the SDA    //
            valide=1;         // line followed the DATA bit ? //
         else                 //                              //
         {                    //                              //
            aff_err(2);       //                              //
            essais++;         //                              //
            if(essais>7)      //                              //
               valide=1;      //                              // Bit sending
         }                    //                              // procedure
      }                       //                              // on I2C port.
      else                    //                              //
      {                       //                              //
         if(!input_state(41)) //                              //
            valide=1;         //                              //
         else                 //                              //
         {                    //                              //
            aff_err(3);       //                              //
            essais++;         //                              //
            if(essais>7)      //                              //
               valide=1;      //                              //
         }                    //                              //
      }                       //                              //
                              //                              //
   }                          //                              //
////////////////////////////////                              //
                                                              //
////////////////////////////////////                          //
   essais=0;                      //                          //
   valide=0;                      //                          //
   while(valide==0)               //                          //
   {                              //                          //
      if(donnee)                  //                          //
         set_tris_a(0b11111111);  //                          // Bit sending
      else                        // SCL is released HIGH...  // procedure
         set_tris_a(0b11111101);  //                          // on I2C port.
                                  //                          //
      delay_us(4);                //                          //
                                  //                          //
      if(input_state(40))         // Is SCL HIGH ?            //
         valide=1;                //                          //
      else                        //                          //
      {                           //                          //
         aff_err(4);              //                          //
         essais++;                //                          //
         if(essais>7)             //                          //
            valide=1;             //                          //
      }                           //                          //
   }                              //                          //
////////////////////////////////////                          //
                                                              //
///////////////////////////////////                           //
   essais=0;                     //                           //
   valide=0;                     //                           //
   while(valide==0)              //                           //
   {                             //                           //
      if(donnee)                 // ...and SCL is pulled      //
         set_tris_a(0b11111110); // down.                     // Bit sending
      else                       //                           // procedure
         set_tris_a(0b11111100); //                           // on I2C port.
                                 //                           //
      delay_us(4);               //                           //
                                 //                           //
      if(!input_state(40))       // ...and checked LOW.       //
         valide=1;               //                          //
      else                       //                         //
      {                          //                        //
         aff_err(3);            //                        //
         essais++;             //                        //
         if(essais>7)         //                        //
            valide=1;        //                        //
      }                     //                        //
   }                       //                        //
                          //                        //
///////////////////////////                        //
   delay_us(4);                                   //
}                                                //
//////////////////////////////////////////////////

////////////////////////////////////////////////////////////
int1 lire_donnees(void)                                   //
{                                                         //
   int1 lecture;                                          //
   int1 valide=0;                                         //
   int8 essais;                                           //
   /*=-=*//*=-=*//*=-=*//*=-=*//*=-=*/                    // Bit reading
////////////////////////////////                          // procedure
      set_tris_a(0b11111110); // SDA is left high...      // on I2C port.
      delay_us(4);            //                          //
////////////////////////////////                          //
                                                          //
////////////////////////////////                          //
   essais=0;                  //                          //
   valide=0;                  //                          //
   while(valide==0)           //                          //
   {                          // ...and SCL is left HIGH. //
      set_tris_a(0b11111111); //                          // Réception
                              //                          // d'un
      delay_us(4);            // delay                    // bit sur
                              //                          // le port
      if(input_state(40))     // We check that SCL is     // I2C
         valide=1;            // high.                    //
      else                    //                          //
      {                       //                          //
         aff_err(5);          //                          //
         essais++;            //                          //
         if(essais>7)         //                          //
            valide=1;         //                          //
      }                       //                          //
   }                          //                          //
////////////////////////////////                          //
                                                          //
/////////////////////////                                 //
   lecture=0;          //                                 //
   if(input_state(41)) // SDA line is read...             //
      lecture=1;       //                                 //
                       // ...and saved on "lecture"       //
   delay_us(4);        // boolean.                        //
/////////////////////////                                 //
                                                          //
////////////////////////////////                          //
   essais=0;                  //                          //
   valide=0;                  //                         //
   while(valide==0)           // ...and SCL is pulled   //
   {                          // DOWN.                 //
      set_tris_a(0b11111110); //                      //
                              //                     //
      delay_us(4);            //                    //
                              //                   //
      if(!input_state(40))    // and checked LOW. //
         valide=1;            //                 //
      else                    //                //
      {                       //               //
         aff_err(5);          //              //
         essais++;            //             //
         if(essais>7)         //            //
            valide=1;         //           //
      }                       //          //
   }                          //         //
////////////////////////////////        //
   delay_us(4);                        //
   return(lecture);                   //
}                                    //
//////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////
void aff_err(int8 erreur)                                                    //
{                                                                            //
   if(erreur!=13)                                                            //
      printf("\n\rError # %u: ",erreur);                                     //
   if(erreur==0)                                                             //
      printf("SDA not down in (S)tart");                                     //
   if(erreur==1)                                                             //
      printf("SCL not down in (S)tart or not UP is sto(P)");                 //
   if(erreur==2)                                                             //
      printf("SDA not following DATA HIGH in sending to EEPROM");            //
   if(erreur==3)                                                             //
      printf("SDA not following DATA  LOW in sending to EEPROM");            //
   if(erreur==4)                                                             //
      printf("SCL not rising high when data sent to EEPROM");                //
   if(erreur==5)                                                             //
      printf("SCL not following on data reading/ACK of EEPROM");             //
   if(erreur==6)                                                            //
      printf("NAK!");                                                      //
   if(erreur==7)                                                          //
      printf("SCL and SDA lines not HI before (S)tart");                 //
   if(erreur==8)                                                        //
      printf("SCL line not HI after sto(P)");                          //
   if(erreur==9)                                                      //
      printf("SDA line not HI after sto(P)");                        //
   if(erreur==10)                                                   //
      printf("SDA not going HI during sto(P)");                    //
   if(erreur==11)                                                 // Error messages
      printf("Unattended ACK !!");                               //
   if(erreur==12)                                               //
      printf("Writing time limit exceeded");                   //
   if(erreur==13)                                             //
      printf(" Data not written (WP ?)");                    //
   delay_ms(100);                                           //
}                                                          //
////////////////////////////////////////////////////////////

////////////////////////////////////
void rad(void)                    //
{                                 //
   int8 c2;                       //
                                  //
#asm                              //
                                  //
   movlw 8  // Eight times to     //
   movwf c2 // obtain a byte      //
                                  //
boucle2:                          //
                                  // LFSR used
   bsf   y,0  // ODD              // to generate
                                  // pseudo-random
   btfsc x0,5 // Multi-input XOR  // data.
   incf  y    // gate. (INCF acts //
   btfsc x1,6 // as a XOR on "y"  //
   incf  y    // bit 0)           //
   btfsc x2,4 //                  //
   incf  y    //                  //
   btfsc x3,7 //                  //
   incf  y    //                  //
   btfsc x4,2 //                  //
   incf  y    //                  //
   btfsc x5,3 //                  //
   incf  y    //                  //
   btfsc x6,4 //                  //
   incf  y    //                  //
   btfsc x7,7 //                  //
   incf  y    //                  //
              //                  //
              //                  //
                                  //
                                  //
   rlf   x0,f  // LEFT rotate     // LFSR
   rlf   x1,f  //                 //
   rlf   x2,f  //                 //
   rlf   x3,f  //                 //
   rlf   x4,f  //                 //
   rlf   x5,f  //                 //
   rlf   x6,f  //                 //
   rlf   x7,f  //                 //
                                  //
   bsf   x0,0  // Access to       //
   btfss y,0   // bit 0 of LFSR   //
   bcf   x0,0  // after bit       //
               // rotate          //
                                  //
   decfsz c2,f                    //
   goto boucle2                   //
                                  //
   movf  x0,w                     //
   movwf hasard                   //
#endasm                           //
   return;                        //
                                  //
}                                 //
////////////////////////////////////
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> Code Library All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group