Микроконтролери и електроника
http://mcu-bg.com/mcu_site/

PIC18F242 as I2C Slave
http://mcu-bg.com/mcu_site/viewtopic.php?f=3&t=7752
Страница 1 от 1

Автор:  edi [ Нед Апр 18, 2010 10:27 am ]
Заглавие:  PIC18F242 as I2C Slave

Здравейте, преди няколко дни писах подобна тема но е изтрих т.к. всичко тръгна, но сега отново имам проблем.
Имам един master(18F452), двe slave устройства - MCP9803, 18F242.
Четенето и писането на данни от температурния сензор е наред, но проблема е следния.
Преди каквато и да е комуникация с МСР9803 си пиша и чета от 18F242 по I2C, но винаги при опит за изпращане на данни към подчинения контролер, след като един път съм прочел температурния сензор пропадат.
Код:
//Inicializaciqta
   RCONbits.IPEN=1;   //Razreshawane na prioriteta na prekyswaniqta
   INTCON=0b00100000;   //TMR0 iterupt enabled.
   INTCON2=0b10000000;   //TMR0 - LOW priority
   INTCON3=0b00000000;
   PIR1=0b00000000;
   PIR2=0b00000000;
   PIE1=0b00001000;   //I2C prekyswaneto e razresheno
   PIE2=0b00000000;
   IPR1=0b00001000;   //I2C e s wisok prioritet
   IPR2=0b00000000;
   
   status0=0;status1=0;

   PIR1bits.SSPIF=0;
   PIE1bits.SSPIE=1;   //I2C iterrupt enabled
   IPR1bits.SSPIP=1;   //Visok priopritet za I2C
   SSPCON2bits.SEN = 1; //S code straching

   SSPADD = 0b11011000;
   OpenI2C(SLAVE_7, SLEW_OFF);

   SSPCON1bits.CKP = 1;
   SSPSTATbits.BF=0;
   SSPCON1bits.SSPOV=0;

   INTCONbits.GIEL=1;INTCONbits.GIEH=1;
   T0CONbits.TMR0ON=1;
//ISR-------------------------------------------------
   unsigned char flags;
   PIR1bits.SSPIF=0;   

   flags=(SSPSTATbits.BF)|(SSPSTATbits.D_A<<1)|(SSPSTATbits.R_W<<2);

   switch(flags)
   {   case 0b011:
         addr = SSPBUF;   
         addr = 1;
         break;
      case 0b001:
         if(addr==1)  //Priet e adresa
         {
            switch(status0)
            {
               case 0:
                  ch_sel = SSPBUF;
                  status0++;break;
               case 1 :
                  ch_val= SSPBUF;
                  status0++;break;
            }
         }
         temp= SSPBUF;
         break;
      case 0b100:
      case 0b101:
         temp = SSPBUF;
           SSPBUF = 0x05;
         break;
      case 0b110:
      case 0b111:
         temp = SSPBUF;
           SSPBUF = 0x04;   
         break;
      case 0b010:   //NACK
         temp = SSPBUF;
         break;
   }
   
   if(status0==2)
   {
      if(ch_sel<=7)
      {   
         chd[ch_sel]=ch_val;
         status0=0;
      }
      else if(ch_sel==8)
      {
         switch(ch_val)
         {
            case 0:
               SetChanADC(ADC_CH0);break;
            case 1:
               SetChanADC(ADC_CH1);break;
            case 2:
               SetChanADC(ADC_CH1);break;
         }
      }
   }

   SSPCON1bits.CKP = 1;
   temp=SSPBUF;   //Za da izchisti BF flaga.

След като един път съм прочел стойността на температурата от МСР9803, при опит да изпратя данни към подчинения контролер винаги става показаното на атачвания фаил.
Код:
// MASTER SOURCE
       //SEND DATA
   INTCONbits.GIEH=0;INTCONbits.GIEL=0;
   IdleI2C();
   StartI2C();
   WriteI2C(0b11011000);
   waitack();
   IdleI2C();
   WriteI2C(chan);
   waitack();
   IdleI2C();
   WriteI2C(chd[chan]);
   waitack();
   IdleI2C();
   StopI2C();
   INTCONbits.GIEH=1;INTCONbits.GIEL=1;
//Receive Data
   IdleI2C();
   StartI2C();
   WriteI2C(0b11011001);
   waitack();
   IdleI2C();
   i2cadc1=ReadI2C();
   AckI2C();
   IdleI2C();
   i2cadc0=ReadI2C();
   NotAckI2C();
   StopI2C();

A ето и кода на главния контролер.
Къде греша според вас ?

EDIT:
Проблема се реши, по следния начин :) :
Код:
void high_isr_h(void)
{
   unsigned char flags;
   PIR1bits.SSPIF=0;   
   //temp=SSPBUF;
   SSPCON1bits.SSPOV=0; //Без този ред винаги се генерира NACK.
   
   flags=(SSPSTATbits.BF)|(SSPSTATbits.D_A<<1)|(SSPSTATbits.R_W<<2);

   switch(flags)
   {
      case 0b001:
         status0=1;
         addr=SSPBUF;
         break;
         
      case 0b011:
            
         if(status0==1 && addr==0b11011000)
         {
            ch_sel=SSPBUF;
            status0++;
         }
         else if(status0==2 && addr==0b11011000)
         {
            ch_val=SSPBUF;
            status0++;
         }
         break;
      case 0b100:
      case 0b101:
         temp = SSPBUF;
           //SSPBUF = 0x05;
         SSPBUF=ADRESH;
         break;
      case 0b110:
      case 0b111:
         temp = SSPBUF;
           //SSPBUF = 0x04;
         SSPBUF=ADRESL;
         break;
      case 0b010:   //NACK
         temp = SSPBUF;
         break;
   }
   
   if(status0==3)
   {
      if(ch_sel<=7)
      {   
         chd[ch_sel]=ch_val;
         status0=0;
      }
      else if(ch_sel==8)
      {
         switch(ch_val)
         {
            case 0:
               SetChanADC(ADC_CH0);break;
            case 1:
               SetChanADC(ADC_CH1);break;
            case 2:
               SetChanADC(ADC_CH2);break;
            case 128:
               ConvertADC();break;
         }
      }
   }
   
   temp=SSPBUF;
   SSPCON1bits.CKP = 1;
}


Прикачени файлове:
i2c_error.JPG
i2c_error.JPG [ 28.15 KiB | Прегледано 593 пъти ]

Страница 1 от 1 Часовете са според зоната UTC + 2 часа [ DST ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/