Hallo Leuz!
Ich habe folgendes problem, ich möchte nen analogwert vom kanal1 von
meinem pcf8591 per uart auf meinen rechner schicken, hab auch schon den
code und ewig rumprobiert, aber ich krig imer nur leerzeichen!?!
also hier mal der code incl. i2c routine.
ich hoffer ihr könnt mir helfen, würd mich sehr freuen
THX im vorraus
===============================================================
.include "8515def.inc"
.equ scl = 7
.equ sda = 6
.equ i2c_port = PORTC
.equ i2c_pin = PINC
.equ i2c_ddr = DDRC
.def temp = r16
; Stackpointer initialisieren
ldi temp, LOW(RAMEND)
out SPL, temp
ldi temp, HIGH(RAMEND)
out SPH, temp
; Baudrate einstellen
ldi temp, 25
out UBRR, temp
sbi UCR,TXEN
;;;;;;;;;;;;;;;;;;;;;;;
;START
;;;;;;;;;;;;;;;;;;;;;;;Start, 145, Wert lesen + NAK, Stop
loop:
rcall i2c_start
ldi r16, 144
rcall putbyte
ldi r16, 64
rcall putbyte
ldi r16, 64
rcall putbyte
rcall i2c_stop
rcall i2c_start
ldi r16, 144
rcall putbyte
ldi r16, 64
rcall putbyte
rcall i2c_stop
rcall i2c_start
ldi r16, 145
rcall putbyte
rcall getbyte
mov r17, r16
rcall i2c_stop
rcall serout
rjmp loop
serout:
out UDR, r16
; =============================
; Warteschleifen-Generator
; 400000 Zyklen:
; -----------------------------
; warte 399999 Zyklen:
ldi R17, $97
WGLOOP0: ldi R18, $06
WGLOOP1: ldi R19, $92
WGLOOP2: dec R19
brne WGLOOP2
dec R18
brne WGLOOP1
dec R17
brne WGLOOP0
; -----------------------------
; warte 1 Zyklus:
nop
; =============================
ret
.include "i2c_routinen.txt"
=================================================
ROUTINE
=================================================
;*********************[ Erläuterungen ]*********************
;*
;* I2C - Routinen für Atmel AVRs
;*
;* die Routine benutzt r16. Alle anderen Register bleiben unverändert
;*
;* in der Hauptroutine müssen die Pins und Register für
;* die I2C - Schnittstelle festgelegt werden
;*
;* .equ scl = 7
;* .equ sda = 6
;*
;* .equ i2c_port = PORTC
;* .equ i2c_pin = PINC
;* .equ i2c_ddr = DDRC
;*
;* Dann kann man die I2C - Schnittstelle über die Befehle
;*
;* i2c_start -> Stellt Startbedingung für I2C - Bus her.
;* i2c_stop -> Stellt Stopbedingung für I2C - Bus her.
;* getbyte -> Lies ein Byte vom I2C - Bus. Ergebnis
;* liegt in Register r16.
;* putbyte -> Überträgt ein Byte über den I2C - Bus. Erwartet
;* das zu sendende Byte in Register r16.
;*
;* Das Programm könnte dann für den I2C - Portexpander PCF8754 so
aussehen:
;*
;* rcall i2c_start
;* ldi r16, 0x41 ; Adresse des Chips senden ( 0x41 = lesen , 0x40
=
schreiben)
;* rcall putbyte
;* rcall getbyte ; Wert vom Chip lesen
;* rcall i2c_stop
;*
;* Das Programm liest die Eingänge des PCF8754 in r16 ein.
;*
;***********************************************************
i2c_start:
sbi I2C_PORT, sda
sbi I2C_PORT, scl
;Überprüfung ob Bus verfügbar
cbi I2C_PORT, sda
cbi I2C_PORT, scl
ret
i2c_stop: ; Stoppbedinung für den I2C-Bus generieren
cbi I2C_PORT, sda
sbi I2C_PORT, scl
nop
sbi I2C_PORT, sda
ret
putbyte: ; ein Byte ausgeben
push r17
ldi r17, 0x08
putbyte_:
clc ; CarryBit löschen
adc r16, r16 ; Register über das Carrybit um eins nach rechts
verschieben
brcc carry_set ; Wenn Carrybit gestezt springe zu carry_set
sbi I2C_PORT, sda ; Setzte Datenleitung
rjmp put_out
carry_set:
cbi I2C_PORT, sda ; Lösche Datenleitung
put_out:
rcall pause
sbi I2C_PORT, scl ; Signalpuls erzeugen
rcall pause
cbi I2C_PORT, scl
rcall pause
dec r17
brne putbyte_
cbi I2C_DDR, sda
sbi I2C_PORT, sda ; Acknowledge Puls Abwarten
rcall pause
sbi I2C_PORT, scl
rcall pause
;getack_:
; sbic I2C_PIN, sda
; rjmp getack_
sbi I2C_DDR, sda
cbi I2C_PORT, scl
rcall pause
pop r17
ret
getbyte: ; ein Byte einlesen
push r17
clr r16
sbi I2C_PORT, sda ; Datenpin hochohmig schalten (=Eingang)
cbi I2C_DDR, sda
ldi r17, 0x08
clc
getbyte_:
sbi I2C_PORT, scl ; Signalpuls erzeugen
rcall pause
sbic I2C_PIN, sda ; Datenleitung auslesen
rjmp data_set
clc ; lösche Carry Flag
rjmp get_data
data_set:
sec ; setzte Carry Flag
get_data:
adc r16,r16 ; Register über das Carrybit um eins nach rechts
verschieben
cbi I2C_PORT, scl ; ( c -> r7 , r(n + 1) -> r(n) , r0 -> c )
rcall pause
dec r17
brne getbyte_
sbi I2C_DDR, sda ; Datenleitung wieder zu Ausgang machen
rcall pause
cbi I2C_PORT, sda ; Acknowledge Puls erzeugen
rcall pause
sbi I2C_PORT, scl
rcall pause
cbi I2C_PORT, scl
rcall pause
pop r17
ret
pause: ; eine sehr kurze Pause
push r16 ; Schleife wird 0x14 (=20) mal durchlaufen
ldi r16, 0x14
pause_:
nop
dec r16
brne pause_
pop r16
ret
GRUß Felix
Hallo, Versuch mal serout: sbis USR, UDRE ; wait until UDR is ready rjmp serout out UDR, tmp ret Mit welchem Programm empfängst Du denn Daten auf dem PC? Gruss Andreas
Ich empfange im moment mit Hypertrm unn des tut eigendlich so weit ganz gut. Die Uart-Sende-Routine funktioniert eigendlich auch, die hab ich soweit mal getestet in dem ich über des uart einfach en mehrzeiligen text rausgelassen hab, den hat des hypertrm auch empfangen und richtig dargestellt. natürlich ist des mit dem delay-loop nich des gelbe vom ei aber es finktioniert, der fehler muss also irgendwo anders liegen. THX Gruß Felix
Mal ne Frage : Schreibst Du den Wert vom 8591 direkt als Byte auf die serielle Schnittstelle ?? Den mußt du in ASCII umwandeln sonst siehst du mit hyperterm nix ! z.B. 8 Bit Wert Value >> AscByte1=(Value / 0x64)+0x30; AscByte2=((Value-((AscByte1-0x30)*0x64))/0x0A)+0x30; AscByte3=(Value-((AscByte1-0x30)*0x64)-((AscByte2-0x30)*0x0A))+0x30; dann die drei AscByte serielle raus und gut ist. MfG Uwe
aber ich müsste doch eigendlich zumindest en paar hyroglyphen aus dem ding raus krigen oder ?? gruß Felix
Hallo, versuch doch mal mit einem Terminalprogramm, dass Hexadezimale Darstellung verwendet. Ich verwende AVRTERM (Downloadbar unter http://rowalt.de/mc/index.htmm, dann Tools im Menue anwählen). Bist Du sicher, dass der Abfrageablauf am 8591 korrekt ist? Ich hab es mit einem AVR noch nicht probiert, jedoch mal in Delphi. Da sieht der Ablauf anders aus. Ansonsten mal die Original TWI-Routinen von ATMEL verwenden. Damit habe ich bisher alle Bausteine relativ schnell zum laufen gebracht. Gruss Andreas
ich hab des mal getestet aber da hat sich nix geändert ich krig nur 255 also lauter einsen. ich hab die bus-leitungen vom pcf ohne irgendwas an 2 1\0-Ports vom 90s8515 gehängt, des müsste doch gehen oder ? die restliche beschaltung vom pcf müsste auch richtig sein. kann es an der bus-beschaltung liegen? Danke Felix
Hallo, also keine Pull-Up-Widerstände? Pullup (4k7-10k) solltest Du einbauen. Ich habe immer 10k genommen und zusätzlich noch 330Ohm in der SDA und SCL-Leitung (die letzteren sind aber nicht nötig). Gruss Andreas
Ich hab jetzt die pull-ups reingesetzt und die sache mal mit nem pcf8574
ausprobiert, aber der macht genauso wenig irgend en mux, ich kann
nichtmal einen wert hinschicken, denm er dann ausgibt, ich binn kurz
vorm verzweifeln mit nem *** i2c-Bus !!
weiss einer von euch an was des sonst noch liegen könnte?
hier mal mein 2. test-code für den 8574, a0 bis a2 sind an masse.
==================================================================
.include "8515def.inc"
.include "i2c_routinen.inc"
.equ scl = 7
.equ sda = 6
.equ i2c_port = PORTC
.equ i2c_pin = PINC
.equ i2c_ddr = DDRC
.def temp = r16
; Stackpointer initialisieren
ldi temp, LOW(RAMEND)
out SPL, temp
ldi temp, HIGH(RAMEND)
out SPH, temp
ldi r16, 0xff
out DDRC, r16
;;;;;;;;;;;;;;;;;;;;;;;
;START
;;;;;;;;;;;;;;;;;;;;;;;
;Initialisierung (1x nach dem Einschalten):
;Start, 144, 64, 64, Stop
;ADC auslesen:
;Start, 144, 64+Kanal, Stop
;Start, 145, Wert lesen + NAK, Stop
rcall i2c_start
ldi r16, 0x40 ; Adresse des Chips senden
; ( 0x41 = lesen , 0x40 = schreiben)
rcall putbyte
ldi r16, 0xaa
rcall putbyte ; Bytewert AA (=10101010) an den
; Chip senden
rcall i2c_stop
Hi, hast Du mal die Original Atmel routinen versucht? Um zu testen, verwende ich manchmal BASCOM, weil man sich da nicht um das Timing kümmern muss. Die freie Version reicht für einen kleinen Test aus. Dann kannst Du wenigstens sicher sein, das es die Hardware tut. Gruss Andreas
Könntest du mal nen link posten, wo ich die originalen atmel routinen runterlanden kann? THX felix
Hallo, ich habe den Code auf meiner Internetseite www.andi-hesse.de/download.html ( DSM-0822a-Display) geladen. Die Beschreibung (Atmel Application Note AVR300) hat Atmel leider vom Netz genommen. Ich hab sie leider nicht mehr bei mir gefunden. Aber vielleicht kommst Du mit dem Code zurecht. Du musst das Timing anpassen. (Im Zweifelsfall mal die Wartezeiten etwas grösser machen, das ist zum testen wohl Ok) Gruss A.Hesse
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.