Forum: Mikrocontroller und Digitale Elektronik SAA1064 mit i2c ansteuern


von Manuel G. (manuel90)


Lesenswert?

Hallo zusammen,

Ich bin ein Neuling in Sachen PIC-Programmierung. Ich habe mir ein Board 
gekauft, um mich "fortzubilden". Mein Problem ist, das die meisten 
Komponenten mit einem I2C-Bus funktionieren. Nach tagelangen lesen und 
verstehen, was ein i2c ist, hänge ich an der Programmierung mit dem 
SAA1064 und der Kommunikation mit Ihm. Programmieroberfläche nehme ich 
den MPLAB X mit dem Compiler XC8 für den PIC18F4685.

Ich habe mich schon mal daran versucht, ein Code zu schreiben. Ich weiß 
nur nicht, habe ich was vergessen, falsch gemacht oder übersehen.

//////////////////////////////////////////////////////////////////////// 
///
//                             [2][1]_test.X
//////////////////////////////////////////////////////////////////////// 
///


#include    <xc.h>
#include    <p18cxxx.h>
#include    <plib/i2c.h>

//////////////////////////////////////////////////////////////////////// 
///

#pragma     config OSC  = HS            // CPU=20 MHz
#pragma     config PWRT = ON            // Power-up-Timer
#pragma     config WDT  = OFF           // Watchdog Timer
#pragma     config LVP  = OFF           // Low Voltage ICSP
#pragma     config MCLRE = ON           // Master Clear Reset

//////////////////////////////////////////////////////////////////////// 
///

#define     _XTAL_FREQ  4000000         // Oscillator ist 4MHz
#define     I2C_V1
#define     I2C_IO_V1

//////////////////////////////////////////////////////////////////////// 
///

void delay_100ms(unsigned char n)       // Warteschleife von 100ms
{
    while (n-- != 0)
    {
        __delay_ms(100)                ;
    }
}

//unsigned char const SEGMENT_ZAHL[10] = 
//{0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};

void main()                   // main()
{
    TRISC = 0x18             ;// RC3(SCL),RC4(SDA) als Eingang
    SSPADD = 0x11            ;// I²C Baud = 100kHz (_XTAL_FREQ = 4MHz)

    SSPCON1bits.SSPEN = 1    ;// RC3,RC4 wird gelöst und dienen als I2C

    OpenI2C(MASTER, SLEW_OFF);
    IdleI2C()                ;// Warten, bis der Bus frei ist
    StartI2C()               ;// Start I2C (Sendefreigabe)
    IdleI2C()                ;// Warten, bis Ende der START-Bedingung

    WriteI2C(0b01110000 & 0xFE) ;// Adr. Slave SAA1064, R/W=0 (senden)

    IdleI2C()                ;// Warten auf ACK
    WriteI2C(0x3F)           ;// Schreibe Byte für 0

    IdleI2C ();              ;// Warten auf ACK
    StopI2C()                ;// Stop I2C

    while(1)
    {}
}

sry, für etwas seltsame Formatierung
Ich wäre sehr erfreut zu wissen, wieso und warum das nicht funktioniert.

von holger (Gast)


Lesenswert?

>Ich wäre sehr erfreut zu wissen, wieso und warum das nicht funktioniert.

Du sendest kein Instruction Byte. Woher soll der jetzt wissen
in welches Register du schreibst. Dann wäre wohl auch noch eine
Initialisierung des Controlregisters sinnvoll damit überhaupt
was angezeigt wird.

von Manuel G. (manuel90)


Lesenswert?

Danke holger für die Antwort.

Da bemerkt man, dass man nach 2 Wochen noch viel zu lernen hat. Scheint 
nicht so einfach zu sein, als den Ausgang mit einem high oder low zu 
setzen.

In Sachen Controlregister habe ich gefunden:

Bit     0  Dynamic mode
        1  Blank digits 1+3
        2  Blank digits 2+4
        3  Testmodus
        4  Ausgangsstrom 3mA
        5  Ausgangsstrom 6mA
        6  Ausgangsstrom 12mA
        7  auf 0 setzen

Bis auf Bit 1 und 2 habe ich das schon mal verstanden. Was bewirken 
diese beiden Bit's und wo in meinem Quellcode sollte das auftauchen. 
Wird das den auf dem I2C-Bus geschrieben und der SAA1064 weiß damit was 
anzufangen ?

In sachen Instruction Byte, ist das damit gemeint?

  Register:
  0 Control Register
  1 Digit 1
  2 Digit 2
  3 Digit 3
  4 Digit 4

Falls ja, wo würde dies in dem Quellcode gehören.

Für Anfänger wie mich ist das zum Teil alles neu. Wenn ich teilweise 
andere Beispiele sehe, steht da viel viel mehr Code als bei mir, als 
würde bei mir 200 Zeilen Code fehlen.

Über eine anfängerfreundliche Antwort wäre ich sehr dankbar

von Dominic A. (neo123)


Lesenswert?

Schau dir mal im Datenblatt Seite 5 an. Da ist beschrieben was du alles 
senden musst. Da siehst du auch das du zwischen Adresse und Daten noch 
ein instuctions Byte senden musst. Auf dieser Seite siehst du auch aus 
was es zusammengesetzt ist. Nämlich aus 5 Nullen und der Adresse des 
Registers welches du beschreiben willst.

von Manuel G. (manuel90)


Lesenswert?

Danke an euch Beiden für die Hilfe,

Das Datenblatt hat mir richtig gut geholfen.
Vielleicht sollte man es vorher lesen, bevor man nachfragt.

WriteI2C(0b01110000 & 0xFE)  ;// Adr. Slave SAA1064, R/W=0 (senden)
WriteI2C(0b00000000)         ;// Instruction byte
WriteI2C(0b00011111)         ;// Control bits

C3 im Controllregister ersteinmal auf 1 gesetzt, um zu testen, ob alle 4 
7-Segment-LED's funktionieren und es leuchten alle !!!

Joa, mit dem Resultat kann man beruhigt schlafen.
Nochmals danke an Alle

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.