Ich bin schon am Verzweifeln, schreibe bereits das komplette Projekt neu und hab keine ahnung mehr was da alles falsch läuft.
Meine Technik
Windows 7, MPLAB X mit XC8-Compiler
18F2420 als I2C Slave
Was ich brauche
Einen einfachen I2C-Slave von dem ich die ADC-Werte auslesen kann. I2C-Master ist ein Raspberry Pi, dessen I2C-Treiber meiner Meinung vollständig funktionsfähig sind.
Der I2C-Teil sollte leicht an SMbus orentiert sein, folglich: Der Erste wert der vom Master -> Slave geschrieben wird ist ein Position im Register, bei jedem folgenden Schreibe oder Lese-Befehl wird dieser Wert dann erhöht.
Meine Probleme
Undurchsichtige Softwareprobleme, undurchsichtige Dokumentation
Beispiel:
funktioniert schon mehr oder weniger gut,
	Code:
	unsigned char I2cRegisterSelect;
// ....
I2cRegisterSelect = 0x77;
SSPBUF = I2cRegisterSelect;
 Funktioniert nicht mehr? Dabei ist es egal ob man einen eigentlich richtigen Datentyp nimmt oder gleich int oder sonst was.
SSPBUF schreibt auserdem nicht das höchste Bit auf den Bus:
	Code:
	sudo i2cdump -y 1 0x44
No size specified (using byte-data access)
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef
00: 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77    wwwwwwwwwwwwwwww
10: 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77    wwwwwwwwwwwwwwww
20: 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77    wwwwwwwwwwwwwwww
30: 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77    wwwwwwwwwwwwwwww
40: 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77    wwwwwwwwwwwwwwww
50: 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77    wwwwwwwwwwwwwwww
60: 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77    wwwwwwwwwwwwwwww
70: 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77    wwwwwwwwwwwwwwww
80: 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77    wwwwwwwwwwwwwwww
90: 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77    wwwwwwwwwwwwwwww
a0: 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77    wwwwwwwwwwwwwwww
b0: 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77    wwwwwwwwwwwwwwww
c0: 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77    wwwwwwwwwwwwwwww
d0: 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77    wwwwwwwwwwwwwwww
e0: 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77    wwwwwwwwwwwwwwww
f0: 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77    wwwwwwwwwwwwwwww
 Das passt, aber:
	Code:
	sudo i2cdump -y 1 0x44
No size specified (using byte-data access)
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef
00: 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f    ????????????????
10: 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f    ????????????????
20: 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f    ????????????????
30: 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f    ????????????????
40: 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f    ????????????????
50: 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f    ????????????????
60: 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f    ????????????????
70: 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f    ????????????????
80: 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f    ????????????????
90: 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f    ????????????????
a0: 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f    ????????????????
b0: 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f    ????????????????
c0: 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f    ????????????????
d0: 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f    ????????????????
e0: 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f    ????????????????
f0: 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f    ????????????????
 Mein Quellcode :
(umfasst derzeit nur I2C, da dieser Teil noch immer hakt)
	Code:
	/* 
 * File:   main.c
 * Author: pointhi
 *
 * Created on 24. März 2013, 18:36
 */
//############### DEFINE CONSTANT
#define __OSC_INTOSC 1          // nutze Internen Oszillator
#define __I2C_ADRESS 0x88
//############### END OF DEFINE CONSTANT
#include <pic18.h>
#include <xc.h>
#ifdef __OSC_INTOSC
    #pragma config IESO = OFF, OSC = INTIO67, FCMEN = OFF               // CONFIG 1H        // Internal Oscilator
#else
    #pragma config IESO = OFF, OSC = HS, FCMEN = OFF                    // CONFIG 1H        // External Oscillator
#endif
#pragma config BOREN = OFF, PWRT = OFF                                  // CONFIG 2L
#pragma config WDT = OFF                                                // CONFIG 2H
#pragma config CCP2MX = PORTC, PBADEN = OFF, LPT1OSC = OFF, MCLRE = OFF // CONFIG 3H
#pragma config STVREN = OFF, XINST = OFF, DEBUG = OFF                   // CONFIG 4L
#pragma config CP0 = OFF, CP1 = OFF                                     // CONFIG 5L
#pragma config CPD = OFF, CPB = OFF                                     // CONFIG 5H
#pragma config WRT0 = OFF, WRT1 = OFF                                   // CONFIG 6L
#pragma config WRTB = OFF, WRTC = OFF, WRTD = OFF                       // CONFIG 6H
#pragma config EBTR0 = OFF, EBTR1 = OFF                                 // CONFIG 7L
#pragma config EBTRB = OFF                                              // CONFIG 7H
unsigned char I2cRegisterSelect;
unsigned char I2cHelp;
void interrupt tc_int(void)
    {
    if(PIR1bits.ADIF == 1 && PIE1bits.ADIE == 1)    // ADC-Interrupt
        {
        PIR1bits.ADIF = 0;
        }
    if(PIR1bits.SSPIF == 1 && PIE1bits.SSPIE == 1)  // I2C-Interrupt
        {
        if(SSPSTATbits.BF)  // New Byte recive
            {
            if(!SSPSTATbits.R_NOT_W) // Master Write Data
                {
                if(SSPSTATbits.D_NOT_A) // Last recived Byte was Data
                    {
                    I2cRegisterSelect = SSPBUF;
                    }
                else    // Last recived Byte was Adress
                    {
                    I2cRegisterSelect = SSPBUF; // Update Register Select
                    }
                
                SSPCON1bits.CKP = 1;
                }
            else    // Master Request Data
                {
//                if(I2cRegisterSelect > 0x7F || I2cRegisterSelect == 0x00) // Test System
//                    {
//                    I2cRegisterSelect = 0x01;
//                    }
//                I2cRegisterSelect = 0x77;
                SSPBUF = 0x77;
//                SSPBUF = 0xFF;
                I2cRegisterSelect ++;
                SSPCON1bits.CKP = 1;
                }
            }
        
        PIR1bits.SSPIF = 0; // Reset Interrupt-Byte
        }
    }
int main() {
    #ifdef __OSC_INTOSC          // PLL Enable, 8MHz => 32MHz
        OSCCONbits.IRCF2    = 1;
        OSCCONbits.IRCF1    = 1;
        OSCCONbits.IRCF0    = 1;
        OSCTUNEbits.PLLEN   = 1;
    #endif
    TRISA   = 0b11111000;       // 1... Input
    TRISB   = 0b11110011;       // 0... Output
    //TRISC   = 0b11111110;
    TRISC   = 0b11111000;       // openpoint todo
    // Clear Ports to Default Value
    PORTA   = 0x00;
    PORTB   = 0x00;
    PORTC   = 0x00;
    LATA    = 0x00;
    LATB    = 0x00;
    LATC    = 0x00;
    // Init Interrupt
    INTCON  = 0x00;
    INTCON2 = 0x00;
    INTCON3 = 0x00;
    PIE1    = 0x00;
    PIE2    = 0x00;
    INTCONbits.PEIE = 1;        // Aktiviere Pheripherale Interrupts
    RCONbits.IPEN   = 0;        // Keine Interrupt Level (High/Low)
    INTCONbits.GIE = 1;         // Aktiviere Interrupt global
    // Init I2C
    I2cRegisterSelect = 0;
    SSPADD = __I2C_ADRESS;      // Set Adress
    SSPSTAT = 0x00;
//    SSPSTAT &= 0x3F;            // Delete Bit 6. and 7.
    
//    SSPSTATbits.SMP = 1;        // Slew Rate Control disabled for Standard Speed mode
//    SSPSTATbits.CKE = 1;        // Enable SMBus specific inputs
    SSPCON1 = 0x00;
//    SSPCON1 &= 0x2F;
//    SSPCON1 |= 0x0E;            // Slave mode, 7-bit adress with STart and Stop bit interrupts enabled
    SSPCON1 |= 0x06;            // Slave mode, 7-bit adress
    
    SSPCON1bits.SSPEN = 1;      // Enables the serial Port
    SSPCON2 = 0x00;
//    SSPCON2bits.GCEN = 1;       // Enable interrupt on general adress
//    SSPCON2bits.SEN = 1;        // Clock Streching is enabled for transmit and receive
    PIE1bits.SSPIE = 1;         // Aktiviere Interrupt für MSSP-Modul
    // Init ADC
//    PIE1bits.ADIE = 1;        // Aktiviere Interrupt für ADC
    
    while(1)
        {
        }
}
 Ich hab keine ahnung was falsch läuft, brauche aber einen funktionierenden Slave aber in wenigen Wochen. Ich hab schon eine laufende I2C-Slave-Routine geschrieben, die sich dafür aber hin und wieder aufgehängt hat. Die Dokumentation hab ich auch schon mehrmals durchgelesen, ohne auf die Probleme zu stoßen.
mfg, pointhi
						
					
Lesezeichen