Gast
#118524
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