PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Brauche dringend Hilfe bei der Programmierung eines I2C-Slaves mit einem 18F2420



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