Отговори на тема  [ 1 мнение ] 
PIC18F242 as I2C Slave 
Автор Съобщение
Ранг: Минаващ
Ранг: Минаващ

Регистриран на: Чет Окт 12, 2006 3:52 pm
Мнения: 21
Местоположение: Varna
Мнение 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 | Прегледано 585 пъти ]
Нед Апр 18, 2010 10:27 am
Профил ICQ
Покажи мненията от миналия:  Сортирай по  
Отговори на тема   [ 1 мнение ] 

Кой е на линия

Потребители разглеждащи този форум: 0 регистрирани и 3 госта


Вие не можете да пускате нови теми
Вие не можете да отговаряте на теми
Вие не можете да променяте собственото си мнение
Вие не можете да изтривате собствените си мнения
Вие не можете да прикачвате файл

Търсене:
Иди на:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.
Хостинг и Домейни