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