2017-08-01 1 views
1

Ich bin Neuling zu Pic-Programmierung, ich verwende MPLAb & Hitech-Compiler, um obigen Code auszuführen. Ich versuche, PIC16F886 mit ISL12022M Realzeit I2C Gerät zu verbinden. Ich kopierte Codebeispiel für DS1307-Schnittstelle mit 16F887A PIC geschrieben. Ich bin in der Lage, grundlegende Funktionalität mit oben zu verbinden. Im unteren Code Während des Schreibens in ISL12022M konnte ich sehen, was ich im Speicherregister gesendet habe. Aber wie beim Versuch, rtc-Zeit zu lesen, konnte ich den letzten Speicher-Schreibwert von SSPBUF lesen. lassen Sie mich einen Fehler im unteren Code wissen. Sobald I2c lesen Wert sollte auf 4-stellige Sieben-Segment-Display angezeigt werden.Problem beim Lesen von Daten von I2c Slave-Gerät mit PIC16F886

Ich denke, ich mache Misatake in diesem Teil. Beim Lesen von Daten bin ich gerade dabei, die Adresse so zu senden, wie sie zuletzt in der Adresse geschrieben wurde.

#include <htc.h> 
    #include <stdio.h> 
    #include<pic.h> 
    #include<stdint.h> 

#define _XTAL_FREQ 40000000 
unsigned int i=0; 
unsigned int k=0; 
unsigned int count; 
#define Pulse RA5 

#define LED RC0 
#define LED1 RC2 
#define CONTROLREG 0xFF 
#define SDA   RC4    // Data pin for i2c 
#define SCK   RC3    // Clock pin for i2c 
#define SDA_DIR  TRISC4   // Data pin direction 
#define SCK_DIR  TRISC3   // Clock pin direction 
#define DP RA4 
#define I2C_SPEED 100    // kbps 

unsigned short int cnt, num,Dgt=0;; 
unsigned short int temp1,temp2,temp3; 

unsigned short sec; 
unsigned short min; 
unsigned short hour; 
unsigned short date; 
unsigned short month; 
unsigned short year; 
unsigned short day; 
unsigned short int temp=0; 
unsigned short r_data; 
#define Seg1 0x01 
#define Seg2 0x02 
#define Seg3 0x04 
#define Seg4 0x08 



    void SetSeg(unsigned short data, unsigned short segno) 

    { 
        switch(data) 
        { 
         case 0: PORTB = 0x3F; break; 
         case 1: PORTB = 0x06; break; 
         case 2: PORTB = 0x5B; break; 
         case 3: PORTB = 0x4F; break; 
         case 4: PORTB = 0x66; break; 
         case 5: PORTB = 0x6D; break; 
         case 6: PORTB = 0x7D; break; 
         case 7: PORTB = 0x07; break; 
         case 8: PORTB = 0x7F; break; 
         case 9: PORTB = 0x6F; break; 
         default : PORTB = 0X00; break; 
        } 

       if(segno==1) 
        { 
        PORTA = Seg4; 
        } 
      if(segno==2) 
        { 
        PORTA = Seg3; 
        } 
      if(segno==3) 
        { 
        PORTA = Seg2; 
        } 
      if(segno==4) 
        { 
        PORTA = Seg1; 
        } 
    } 


void Delay(int k) 
{ 
int j; 
for(j=0;j<k;j++); 
} 


void InitI2C(void) 
{ 
    SDA_DIR = 1;  // Make SDA and 
    SCK_DIR =0;  // SCK pins input 
    SSPCON = 0b00111000;   //enables port for i2c 
    SSPCON2 = 0b00000000; 
    SSPADD = 10;     // 100KHz = 8MHz/4(SSPADD+1) 
    // SSPSTAT = 0b11000000;  // Slew rate disabled 

} 

void i2c_waitForIdle(void) 
{ 
    unsigned int i2ctimeout; 

    while(1) 
    { 

     i2ctimeout++; 
     if(i2ctimeout > 10) 
      { 
      i2ctimeout = 0; 
      return; 
      } 
    } 
} 

void I2C_Start(void) 
{ 
    SEN = 1;   // Send start bit 
    i2c_waitForIdle(); 
/* while(!SSPIF);  // Wait for it to complete 
    SSPIF = 0;   // Clear the flag bit*/ 

} 

void I2C_ReStart(void) 
{ 
    RSEN = 1;   // Send Restart bit 
    i2c_waitForIdle(); 
/* while(!SSPIF);  // Wait for it to complete 
    SSPIF = 0;   // Clear the flag bit 
    while(RSEN==1);*/ 
} 


void I2C_Stop(void) 
{ 
    PEN = 1;   // Send stop bit 
    i2c_waitForIdle(); 
} 


void I2C_Send_ACK(void) 
{ 
    ACKDT = 0;   // 0 means ACK 
    ACKEN = 1;   // Send ACKDT value 
    i2c_waitForIdle(); 
} 


void I2C_Send_NACK(void) 
{ 
    ACKDT = 1;   // 1 means NACK 
    ACKEN = 1;   // Send ACKDT value 
    i2c_waitForIdle(); 
} 


unsigned char I2C_Write(unsigned char i2cWriteData) 
    { 
    i2c_waitForIdle(); 
    SSPBUF = i2cWriteData; 
    return (!ACKSTAT);      // function returns '1' 
    } 

int I2C_Read(unsigned char ack) 
    { 
    unsigned char i2cReadData; 
    //unsigned int i2cReadData; 
    i2c_waitForIdle(); 
    RCEN = 1; 
    SDA=1; 
    SCK=1; 
    i2c_waitForIdle(); 

    i2cReadData = SSPBUF; 
    SCK=0; 
    i2c_waitForIdle(); 
    SCK=1; 
    if(ack) 
     { 
     ACKDT = 0; 
     } 
    else 
     { 
     ACKDT = 1; 
     } 
    ACKEN = 1;    // send acknowledge sequence 

    return(i2cReadData); 
    } 

    unsigned int bcdtodecimal(unsigned int bcd) 
{ 
    unsigned int decimal; 
    decimal = (((bcd & 0xF0) >> 4) * 10) + (bcd & 0x0F); 
    return decimal; 
} 

void Init_ISL12022M(void) 
{ 
    I2C_Start(); // Start I2C communication 
    I2C_Write(0XD0); //Write Device Address 
    I2C_Write(0X08); // 
    I2C_Write(0X41); // Write 0x00 to Control register to disable SQW-Out 
    I2C_Stop(); // Stop I2C communication after initilizing 
} 


unsigned int Write_ISL12022M(unsigned short address, unsigned short w_data) 
{ 
    I2C_Start(); // Start I2C communication 
    I2C_Write(0XD0); 
    I2C_Write(address); //write address to write data 
    I2C_Write(w_data); //write data into hexadecimal 
    I2C_Stop();//stop I2C communication 
    return(w_data); 
} 

unsigned short Read_ISL12022M(unsigned short address) 
{ 

    I2C_Start(); 
    I2C_Write(address); //address 0x68 followed by direction bit (0 for write, 1 for read) 0x68 followed by 0 --> 0xD0 
    I2C_Write(address); 
    I2C_ReStart(); 
    I2C_Write(0xD1); //0x68 followed by 1 --> 0xD1 
    r_data=I2C_Read(0); 
    I2C_Stop(); 
    return(r_data); 
} 

void SetDateTime() 
{ 

     I2C_Start(); 
     I2C_Write(0xD0); 
     I2C_Write(0x00); 
     sec= Write_ISL12022M(0X00, 12); //01 sec 
     min = Write_ISL12022M(0X01,52); //01 sec 
     hour = Write_ISL12022M(0X02,9); //01 sec 
     day= Write_ISL12022M(0X03,7); //01 sec 
     date = Write_ISL12022M(0X04, 29); //01 sec 
     month =Write_ISL12022M(0X05,07); //01 sec 
     year = Write_ISL12022M(0X06,17); //01 sec 
     I2C_Stop(); 

} 




void RTC_GetDateTime() 
{ 
    I2C_Start();       // Start I2C communication 
    I2C_Send_ACK(); 
    sec = I2C_Read(1);    // read second and return Positive ACK 
    I2C_Send_ACK(); 
    min = I2C_Read(1);     // read minute and return Positive ACK 
    I2C_Send_ACK(); 
    hour= I2C_Read(0);    // read hour and return Negative/No ACK 
    I2C_Send_ACK(); 
    day = I2C_Read(1);   // read weekDay and return Positive ACK 
    I2C_Send_ACK(); 
    date= I2C_Read(1);    // read Date and return Positive ACK 
    I2C_Send_ACK(); 
    month=I2C_Read(1);   // read Month and return Positive ACK 
    I2C_Send_ACK(); 
    year =I2C_Read(0);    // read Year and return Negative/No ACK 
    I2C_Send_ACK(); 
    I2C_Stop();        // Stop I2C communication after reading the Date 
} 


    void interrupt isr(void) 
    { 
      if(TMR1IF==1) 
      { 
       TMR1H=0xF6; // Load the time value(0xBDC) for 100ms delay 
       TMR1L=0x18; //Timer1 Interrupt for 65000 
       TMR1IF=0; // Clear timer interrupt flag 
       Dgt++; 

       if(Dgt>=5) 
       { 
        Dgt=0; 
        LED=!LED; 

       } 

      }   

    } 


    void Timer1_Interrupt() 
    { 

    INTCON = 0b00000000; 
    PIE1=0b00000001; 
    PIR1=0x01; 
    TMR1H=0x0B; 
    TMR1L=0xDC; 
    T1CON=0x31; 

    } 

    void Init_Controller() 
    { 
    cnt=100;   
    TRISC=0b01000000;       // Intialize INput & output pheripherals 
    TRISB=0b10000000; 
    PORTB = 0b00000000; 
    TRISA=0b0000000;        
    ADCON0 = 0b00000000; 
    ANSEL = 0b00000000; 
    Timer1_Interrupt(); 

    } 

     void main(void) 
    { 

       Init_Controller(); 
      /* GIE=1; 
       PEIE=1; 
       TMR1IE=1; */ 
      InitI2C(); 
      Init_ISL12022M(); 
       SetDateTime(); 

       while(1) 

       { 
        RTC_GetDateTime(); 
        SetSeg(year/ 10,2); 
        SetSeg(year%10,1); 
       } 

     } 

Antwort

0

Die Linien mögen:

I2C_Write(0XD0); //Write Device Address 

Adressen kein gültiges Gerät sind. Verwenden Sie 0xDE (oder 0xAE für Benutzer SRAM)

Aus dem Datenblatt:

Nach einer Startbedingung, muss der Master-Ausgang eine Slave-Adresse Byte. Die 7 MSBs sind die Gerätekennungen. Diese Bits sind "1101111" für die RTC-Register und "1010111" für den Benutzer-SRAM.

Verwandte Themen