pointhi
27.03.2013, 17:07
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:
SSPBUF = 0x77;
funktioniert schon mehr oder weniger gut,
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:
SSPBUF = 0x77;
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:
SSPBUF = 0xFF;
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)
/*
* 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
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:
SSPBUF = 0x77;
funktioniert schon mehr oder weniger gut,
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:
SSPBUF = 0x77;
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:
SSPBUF = 0xFF;
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)
/*
* 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