Forum: Mikrocontroller und Digitale Elektronik PIC12F1840 im I2C Slave Betrieb


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Chris B. (chrisb20)


Lesenswert?

Hallo zusammen,

ich versuche gerade einen PIC12F1840 im I2C Slave Modus in Gang zu 
bekommen.
Der Master der den Slave steuert ist ebenfalls ein PIC (PIC16F887)

Erste Aufgabe ist mal nur das der Master den Slave anspricht und dieser 
im
einen Wert zurück senden. Der Master soll dann den empfangenen Wert an 
den LEDs an PortD ausgeben.

Im Moment ist es so das ich entweder die Adresse des Slaves an den LEDs 
sehe oder nichts.

Hat schon einmal jemand vllt etwas mit dem PIC12F1840 in diesem Modus 
gemacht?

Danke für die Hilfe.

Gruß Chris Br

von icke (Gast)


Lesenswert?

Wie wäre es denn mit ein paar mehr Infromationen?
Wie sieht der Aufbau aus?
Hängen noch andere Teilnehmer am Bus?
Wie sieht der Code vom Slave aus? Wie der vom Master?
Hat der master schon mit anderen Slaves funktioniert?

von Chris B. (chrisb20)


Lesenswert?

Hab den Fehler gefunden, lag an einer Varaiblen die den falschen 
Datentyp hatte und an einem Feld das nicht geladen war.

Werde später noch die Syntax als Beispiel für andere User rein stellen, 
wenn das Schreiben zum Slave auch funktioniert.

Gruß Chris Br

von Chris B. (chrisb20)


Lesenswert?

So wie oben versprochen hier ist der Code um zwei PICs über I2C zu 
Betreiben.

Kurz etwas zum Aufbau:

PIC16F887:
Dieser PIC agiert als Master des I2C Bus, am PORTD sind 8 LEDs 
angeschlossen.

PIC12F1840:
Dieser PIC agiert als Slave am I2C Bus, an den nicht verwendeten PINs 
habe ich 3 LEDs angeschlossen.

Das Programm macht folgendes:
Zuerst intialisiert sich jeder Controller als Master oder Slave. Im 
Slave habe ich feste Werte als Rückgabewert eingespeichert.

Der Master schreibt den Slave an das er ihn auslesen möchte und dieser 
gibt ihm die fest vorgegebenen Werte zurück. Wenn der Master dem Slave 
Daten sendet dann habe ich jetzt gerade eine Routine drin die einfach 
wenn der Wert 1 kommt die erste LED einschaltet bei einer 2 die 2te und 
bei einer 3 die dritte.

Source Master:
1
/*-------------------------------------------------------------------------------------------------------------------------------------------------
2
  Filename:                         
3
  Date:                                         
4
  File Version:     1.0                                    
5
  Author:                                     
6
  Company:          ---            
7
  -------------------------------------------------------------------------------------------------------------------------------------------------
8
  Features:    
9
  -------------------------------------------------------------------------------------------------------------------------------------------------
10
  Ports:     
11
-------------------------------------------------------------------------------------------------------------------------------------------------*/
12
#define _LEGACY_HEADERS               // notwendig ab Compiler-Version 9.81
13
#include <htc.h>                  // einbinden des htc.h headers
14
#include <pic16f887.h>                // einbinden des pic16f887.h headers
15
16
#include "delay.h"                  // einbinden des Pausen Headers
17
#include "I2C_Treiber.h"              // einbinden des I2C_Treibers der die Ports richtig einrichtet
18
19
char Ausg = 0x00;                  // erstellen der Variable Ausg mit dem Datentyp char
20
int Addr = 0x70;                  // erstellen der Variable Addr für die Adresse des Slaves
21
22
void main(void)
23
{
24
TRISD = 0x00;                    // setze des TRISD Registers auf 0 => Ausgang
25
PORTD = 0x00;                    // lösche PORTD
26
27
28
I2C_init();                      // initialisere den Controller als Master
29
30
  while(1)
31
  {
32
  I2C_start();                  // I2C Startbedingung
33
  I2C_WriteToAddress(Addr);            // spreche den Slave an und sag ihm das du an ihn schreiben willst
34
  I2C_SendByte(0x03);                // Sende an den Slave ein Datenpacket
35
  I2C_stop();                    // I2C Stoppbedingung
36
37
  DelayMs(500);                  // warte 500ms
38
39
  I2C_start();                  // I2C Startbedingung
40
  I2C_ReadFromAddress(Addr);            // spreche den Slave an und sag ihm das du von ihm lesen willst
41
  Ausg = I2C_GetByte();              // schreibe die ausgelesenen Werte in die Variable Ausg
42
  I2C_SendAck();                  // schicke dem Slave ein Acknowledge damit er das zweite Datenpacket sendet
43
  Ausg = I2C_GetByte();              // zweites Datenpacket in die Variable Ausg schreiben
44
  I2C_stop();                    // I2C Stoppbedingung
45
46
  PORTD = Ausg;                  // schreibe auf PORTD den Wert aus Ausg
47
  DelayMs(50);                  // warte 50ms
48
  PORTD = 0x00;                  // lösche PORTD
49
  DelayMs(50);                  // warte 50ms
50
  Ausg = 0x00;                  // lösche die Variable Ausg
51
52
  }
53
54
}




Source Slave:
1
#include <htc.h>
2
#include <pic12f1840.h>
3
#include "delay.h"
4
#include "I2C_Treiber_PIC12F1840.h"
5
6
/* Variablen fuer die I2C Kommunikation */
7
/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
8
unsigned char I2C_Adresse = 0x70;                  // I2C_Adresse
9
unsigned char Befehl = 0;                      // Ankommende Kommandos
10
unsigned char I2C_Daten[2] = {0x53, 0xAA};              // Feld für die I2C Übertrageung und wird mit Werten gefühlt 
11
unsigned char Write;                        // Variable Write für 2x Senden der Tachowerte(2 x Byte).          
12
bit I2C_Status = 0, Read = 0;                    // Statusvariable für den Eingang an Daten. Read für Schreibender parameter (I2C_Level)
13
bit I2C_level_Bit = 0;                        // Statusbit zum löschen von I2C_level
14
unsigned char i, loop = 10;                      // Schleifenvariablen
15
16
unsigned char Wert_MA = 0;
17
18
19
/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
20
21
22
23
/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
24
void interrupt my_isr(void)
25
{
26
  if(SSP1IE && SSP1IF)                      // Interrupt wird ausgelöst wenn der Interrupt Enable gesetzt ist und das Interrupt Flag gesetzt ist
27
  {
28
/*------Schreiben----------------------------------------------------------------*/
29
    if(R_nW)                          // Antwort von Slave
30
    {
31
I2C_Daten[0] = 0x53;                        // Beschreibe die Stelle 1 des Felds I2C_Daten
32
I2C_Daten[1] = 0xAA;                        // Beschreibe die Stelle 2 des Felds I2C_Daten
33
34
      SSP1BUF = I2C_Daten[Write];                // Schreibe die Daten in den SSP1BUF der die Daten über I2C überträgt
35
      CKP = 1;                        // Setze das Bit CKP
36
      SSP1IF = 0;                        // Lösche das Interrupt Flag
37
      I2C_Daten[Write] = 0;                  // Lösche die Daten die gerade übertragen wurden
38
      for(i = 0; i < loop; i++)                // Warten bis die übertragung vollständig ist
39
      {
40
        if(!BF)  break;                    // Warten bis die übertragung vollständig ist
41
      }    
42
      if (I2C_ReadAck())                    // Zweiter Byte wird angefragt
43
      {
44
        Write++;                      // Index wird erhöht
45
        if(Write > 1) Write = 0;              // Maximal 2 Byte sind möglch
46
      }
47
      else Write = 0;                      // wenn nicht lösche die Variable Write
48
//      Read = 0;                        
49
    }
50
51
52
/*------Lesen----------------------------------------------------------------*/
53
        if(!R_nW)                                               // Befehle vom Master
54
        {
55
                if (SSP1BUF == I2C_Adresse)    SSP1BUF = 0;         // Adresse im Register? Dann SSPBUF löschen
56
                else
57
                {
58
                    Befehl = SSP1BUF;                          // Befehl wird gespeichert
59
                    I2C_Status = 1;                              // Nach dem Eingang der Daten wird Status Bit gesetezt
60
                }
61
            SSP1IF = 0;                        // Lösche das Interrupt Flag
62
        }
63
  
64
    if (SSPOV) SSPOV = 0;                    // Überlauf Bit wird gelöscht
65
    
66
  }
67
}
68
69
//------------------------------------------------------------------------------
70
void main()
71
{
72
  ANSELA = 0xFF;                          // Konfiguriere den PORTA als Digital
73
  TRISA = 0x00;                            // Setze das TRISA Register auf 0 => Ausgang
74
  PORTA = 0x00;                            // Lösche den PORTA
75
  I2C_Init_Slave();                          // Initialisieren den Controller als Slave
76
  ei();                                // Enable Interrupt
77
78
    while(1)
79
    {
80
  if(Befehl == 1)                          // Wenn die Variable Befehl den Wert 1 hat
81
      {
82
      RA0 = 1;                        // dann setze RA0 auf 1 => LED    
83
      }
84
      
85
  if(Befehl == 2)                          // Wenn die Variable Befehl den Wert 2 hat
86
      {
87
      RA2 = 1;                        // dann setze RA2 auf 1 => LED    
88
      }
89
      
90
  if(Befehl == 3)                          // Wenn die Variable Befehl den Wert 3 hat
91
      {
92
      RA4 = 1;                        // dann setze RA4 auf 1 => LED  
93
      }
94
  }
95
  
96
}


Hoffe es hilft dem ein oder anderen weiter.

Gruß Chris Br

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.