PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : ATTiny als I²C Slave?



nyquest
12.01.2007, 13:51
Hallo Roboternetz!

Ich versuche einen ATTiny11 als I²C Slave anzusteuern. Als SDA will ich PB0 und als SCL PB1 nehmen. Das ganze soll in Assembler programmiert werden. PB2 wird für eine andere Anwendung als Ausgang verwendet.

Zunächst mal wollte ich testen, ob der ATTiny11 die Startbedingung versteht. Im Ruhezustand sind SCL = SDA = 5 V. Wenn ich die Funktion aufrufe, soll er zunächst testen, ob sich der Bus im Ruhemodus befindet. Dann wartet er auf die Startbedingung.


__iic_start:
; SDA = SCL = Hi?
sbis pinb, 0x00
rjmp __iic_wait_start

sbis pinb, 0x01
rjmp __iic_wait_start

; SDA = Lo, SCL = Hi?

____iic_start1:
sbic pinb, 0x00
rjmp ____iic_start1

sbis pinb, 0x01
rjmp ____iic_start1 ; Eventuell hier Rücksprung zu iic_start?

; SDA = Lo, SCL = Lo?

____iic_start2:
sbic pinb, 0x00 ; Eventuell hier Rücksprung zu iic_start?
rjmp ____iic_start2

sbic pinb, 0x01
rjmp ____iic_start2 ; Eventuell hier Rücksprung zu iic_start?

reti


Das Problem ist, dass der Controller die Startbedigung nicht erkennt (wenn er sie erkennt, soll zum Test an PB2 ein Signal ausgegeben werden). Da ich leider noch Anfänger bin, habe ich das Programm zunächst mal zum Debug so umgeschrieben, dass an PB2 ein Signal ausgeben werden soll, wenn PB0 Hi ist:


; ...
rcall pb0hi ; warte bis PB0 = Hi
; ...

; PB0 = Hi?
pb0hi:
sbis pinb, 0x00 ; Wenn PINB[0] = Lo ...
rjmp pb0hi ; ... dann springe zurück
reti

Dieser Code funktioniert auch. Allerdings habe ich das Problem, dass wenn ich einmal den PB0 auf Hi gesetzt habe, dass der Controller bei einem erneuten Start wieder PB0 = Hi erkennt. Eigentlich müsste PBO bei einem Neustart doch Lo sein, oder?

Danke für die Hilfe!

linux_80
12.01.2007, 18:13
Hallo,
was mir zum T11 einfällt, da der kein SRAM hat, kann man nur max. 3 rcalls (incl. ISR) auf einmal aufrufen (da der Stack nur 3 Plätze hat), hast du das beachtet ?
Dann steht hier immer RETI, ein normales Unterprogramm beendet man nur mit RET !

nyquest
12.01.2007, 19:47
Hallo,

Danke schon mal für den Hinweis. Es muss natürlich RET heissen. Die Stacktiefe wird nicht überschritten. Die Daten über PB2 werden später von einem Timer Interrupt gestellt. Insgesamt beträgt die Stacktiefe damit 2.

Ich habe die Start Bedigung jetzt so verändert:


iic_start:
; SDA = SCL = Hi?
sbis pinb, 0x00
rjmp iic_start

sbis pinb, 0x01
rjmp iic_start

; SDA = Lo, SCL = Hi?
__iic_start1:
sbic pinb, 0x00
rjmp __iic_start1

__iic_start2:
sbis pinb, 0x01
rjmp __iic_start2 ; Eventuell hier Rücksprung zu iic_start?

; SDA = Lo, SCL = Lo?
__iic_start3:
sbic pinb, 0x00 ; Eventuell hier Rücksprung zu iic_start?
rjmp __iic_start3

__iic_start4:
sbic pinb, 0x01
rjmp __iic_start4 ; Eventuell hier Rücksprung zu iic_start?

ret

Das komische ist, manchmal scheint der Controller durch welche Zufälle auch immer die Start Bedigung zu erkennen. Da mir komischerweise schon zwei ATTiny11 kaputt gegangen sind (sie lassen sich nicht mehr beschreiben) habe ich das Programm mit dem Simulator getestet. Nach meiner Meinung funktioniert der Code!

Nur in der Praxis sieht es dann wieder anders aus.

Gruß,

Stefan