Forum: Mikrocontroller und Digitale Elektronik PIC12F1840 als I2C Master


von As B. (b-a)


Lesenswert?

Schaffe es nicht I2C Master auf dem PIC12F1840 zum laufen zu bringen.
Laut den Beispielen müsste es mit dieser Initialisierung funktionieren.
Nach dem senden der Startbedingung wartet er auf das Interruptflag, was 
aber nicht kommt.

Sieht hier jemand zufällig den Fehler?
1
; CONFIG1
2
; __config 0xF9E4
3
 __CONFIG _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_OFF & _MCLRE_ON & _CP_OFF & _CPD_OFF & _BOREN_OFF & _CLKOUTEN_OFF & _IESO_ON & _FCMEN_ON
4
; CONFIG2
5
; __config 0xFFFF
6
 __CONFIG _CONFIG2, _WRT_OFF & _PLLEN_OFF & _STVREN_ON & _BORV_LO & _LVP_OFF
7
8
init
9
  bank1
10
  movlw  b'01111010'
11
  movwf  OSCCON
12
  bank3
13
  clrf  ANSELA
14
  bank0
15
  return
16
17
init_i2c
18
  bank1
19
  movlw  0x06
20
  movwf  TRISA
21
  bank4
22
  clrf  SSP1STAT
23
  bsf  SSP1STAT,SMP
24
  movlw  0x39
25
  movwf  SSP1ADD
26
  movlw  0x08
27
  movwf  SSP1CON1
28
  clrf  SSP1CON2
29
  bsf  SSP1CON1,SPEN
30
  bank0
31
    bcf PORTA,5
32
  bcf  PIR1,SSP1IF
33
  bcf  PIR2,BCL1IF
34
  return
35
36
i2c_start
37
  bcf  PIR1,SSP1IF
38
  bank4
39
  bsf  SSP1CON2,SEN
40
  bank0
41
i2c_wait
42
  btfss  PIR1,SSP1IF
43
  goto  i2c_wait
44
    bsf PORTA,5
45
  return

von Max H. (hartl192)


Lesenswert?

Ist die Hardware in Ordnung, hast du die Pullups am I2C?

P.S: Fürs Auswählen der RAM-Banken, würde ich BANKSEL verwenden. Ist 
übersichtlicher und man muss nicht nachschauen in welcher Bak jedes 
Register ist.

: Bearbeitet durch User
von As B. (b-a)


Lesenswert?

Pullups sind dran (10k). Hardware ist in Ordnung. Ich habe immer eine 
LED angeschlossen, mit der ich feststellen kann, wie weit die Software 
läuft. Programmer ist nicht angeschlossen, da einer der I2C-Pins auch 
für die Programmierung/Debugging verwendet wird.
Ich verwende den Internen Quarz mit 16MHz und eine Spannung von 3V3.

: Bearbeitet durch User
von As B. (b-a)


Lesenswert?

Hier der Sourcecode mit Kommentaren
Das SSP1IF wird nicht gesetzt.
1
; CONFIG1
2
; __config 0xF9E4
3
 __CONFIG _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_OFF & _MCLRE_ON & _CP_OFF & _CPD_OFF & _BOREN_OFF & _CLKOUTEN_OFF & _IESO_ON & _FCMEN_ON
4
; CONFIG2
5
; __config 0xFFFF
6
 __CONFIG _CONFIG2, _WRT_OFF & _PLLEN_OFF & _STVREN_ON & _BORV_LO & _LVP_OFF
7
8
init
9
  ; Internen Oszillator auf 16 MHz einstellen
10
  banksel OSCCON
11
  movlw  b'01111010'
12
  movwf  OSCCON
13
14
  return
15
16
init_i2c
17
  ; RA1 und RA2 als Eingänge für I2C
18
  banksel  TRISA
19
  movlw  b'00000110'
20
  movwf  TRISA
21
22
  ; Alle Portpins als I/O
23
  banksel  ANSELA
24
  clrf  ANSELA
25
26
  banksel  SSP1ADD
27
  ; Geschwindigkeit auf 100 kHz bei FOSC von 16 MHz
28
  movlw  0x27
29
  movwf  SSP1ADD
30
  ; Slew rate control ausschalten
31
  movlw  0x80
32
  movwf  SSP1STAT
33
  ; I2C-Master einstellen und Portpins als SDA und SCL konfigurieren
34
  movlw  0x28
35
  movwf  SSP1CON1
36
  clrf  SSP1CON2
37
38
  banksel PIR1
39
  bcf  PIR1,SSP1IF
40
  bcf  PIR2,BCL1IF
41
42
        ; LED ausschalten
43
  banksel PORTA
44
  bcf PORTA,5
45
  return
46
47
i2c_wait
48
        banksel PIR1
49
i2c_wait_wdh
50
  btfss  PIR1,SSP1IF
51
  goto  i2c_wait_wdh
52
53
         ;LED einschalten
54
  banksel PORTA
55
  bsf PORTA,5
56
57
  return
58
59
i2c_start
60
  banksel PIR1
61
  bcf  PIR1,SSP1IF
62
  banksel SSP1CON2
63
  bsf  SSP1CON2,SEN
64
65
  goto  i2c_wait
66
67
i2c_send_byte
68
  movwf  daten
69
  banksel PIR1
70
  bcf  PIR1,SSP1IF
71
72
  banksel SSP1BUF
73
  movf  daten,w
74
  movwf  SSP1BUF
75
76
  goto  i2c_wait
77
78
i2c_stop
79
  banksel PIR1
80
  bcf  PIR1,SSP1IF
81
  banksel SSP1CON2
82
  bsf  SSP1CON2,PEN
83
84
  goto  i2c_wait

von michael "meikel" D. (meikel)


Lesenswert?

Max H. schrieb:

> P.S: Fürs Auswählen der RAM-Banken, würde ich BANKSEL verwenden. Ist
> übersichtlicher und man muss nicht nachschauen in welcher Bak jedes
> Register ist.

banksel finde ich im instruction set nicht, aber das:

MOVLB Move literal to BSR
Syntax: [ label ] MOVLB k
Operands: 0 <= k <= 15
Operation: k -> BSR
Status Affected: None
Description: The five-bit literal ‘k’ is loaded into the
Bank Select Register (BSR).

von Max H. (hartl192)


Lesenswert?

michael "meikel" D. schrieb:
> banksel finde ich im instruction set nicht, aber das:
Banksel ist auch kein Befehl, sondern ein Macro.
Wenn du banksel TRISA schreibst, mach der Assembler das daraus:
MOVLB 0x1
Er schaut also nach, in welcher Bank sich das Register befindet und 
erstellt automatisch den MOWLB Befehl.
http://www.sprut.de/electronic/pic/assemble/pseudo.html#banksel

von Sascha (Gast)


Lesenswert?

Banksel ist kein "richtiger" Maschinenbefehl, sondern ein Makro. Es wird 
vom Assembler in passende Befehle umgesetzt, die auf die passende Bank 
umschalten.

von Max H. (hartl192)


Lesenswert?

Max H. schrieb:
> http://www.sprut.de/electronic/pic/assemble/pseudo.html#banksel
Edit: Die Beschreibung im Link ist nicht so gut, da sie von PIC16 
spricht und da das Banking ein bisschen anders funktioniert.

von michael "meikel" D. (meikel)


Lesenswert?

Max H. schrieb:
> michael "meikel" D. schrieb:
>> banksel finde ich im instruction set nicht, aber das:
> Banksel ist auch kein Befehl, sondern ein Macro.

OK und danke für die Info.

von Max H. (hartl192)


Lesenswert?

As B- schrieb:
> ; CONFIG1
> ; __config 0xF9E4
>  __CONFIG _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_OFF & _MCLRE_ON &
> _CP_OFF & _CPD_OFF & _BOREN_OFF & _CLKOUTEN_OFF & _IESO_ON & _FCMEN_ON
> ; CONFIG2
> ; __config 0xFFFF
>  __CONFIG _CONFIG2, _WRT_OFF & _PLLEN_OFF & _STVREN_ON & _BORV_LO &
> _LVP_OFF
>
> init
>   ; Internen Oszillator auf 16 MHz einstellen
>   banksel OSCCON
>   movlw  b'01111010'
>   movwf  OSCCON
>
>   return
Ist das eigentlich der komplette Sourcecode, und wie hast du erkannt, 
dass das SSP1IF gesetzt wird.

Laut diesem Code, sollte der PIC das OSCCON beschreiben und dann ins 
nichts return'en: Stack Underflow +  _STVREN_ON ==> Reset.
Und das END am Ende fehlt. Da es der Assembler ohne end gar nicht 
assemblieren würde, vermute ich, dass es nicht der gesamte Code ist...

Für meinen Geschmack fehlen die ORG Anweisungen:
Ich beginne meine ASM Programme immer so
1
ORG 0x00
2
  goto init
3
ORG 0x04    ;Interrupt Vector
4
  retfie      ;Wenn mit Interrupts: Die ISR oder GOTO isr
5
6
init:
7
  ; Internen Oszillator auf 16 MHz einstellen
8
  banksel OSCCON
9
  movlw  b'01111010'
10
  .
11
  .
12
  .
13
END

: Bearbeitet durch User
von NochEinGast (Gast)


Lesenswert?

Ich weiss nicht, ob es daran liegt, aber schau 'mal in die Beschreibung 
von SSP1CON3:

bit 5 SCIE: Start Condition Interrupt Enable bit (I2C mode only)
1 = Enable interrupt on detection of Start or Restart conditions
0 = Start detection interrupts are disabled(2)

von Max H. (hartl192)


Lesenswert?

Die Interrupt Flags werden beim PIC immer gesetzt, auch wenn das 
Interrupt deaktiviert ist.

von NochEinGast (Gast)


Lesenswert?

Die Frage war, warum das Interrupt-Bit nicht gesetzt wird.

von As B. (b-a)


Lesenswert?

1. Es war nicht das gesamte Programm, sondern nur die Teile die mit der 
MSSP Schnittstelle arbeiten.
2. Ich lasse eine LED leuchten, wenn das Interruptbit gesetzt ist. 
Diesen Befehl schiebe ich immer weiter nach hinten. Daher weiß ich, ob 
das Programm dort vorbeikommt.
3. Ich warte jetzt, bis der Oszillator stabil läuft. Jetzt geht es auch.

Jetzt nur noch das Display in Gang bringen.

von Michael (Gast)


Lesenswert?

Hallo, kann mir jemand von euch sagen, warum das Flag einfach nicht 
gesetzt wird beim Masterbetrieb und senden?? Ich verzweifele, denn ich 
kann überhaupt nicht erkennen, wann er fertig mit dem einem Byte ist 
bzw. bereit für das erste Byte. Mit einer festen Zeitschleife krieg ich 
es hin, aber das ist doch Pillepalle. Danke

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.