AVR och DS1302, tappar en bit?
Postat: 29 oktober 2004, 00:22:29
Programmering har aldrig varit min starka sida, så jag är helt euforisk över att jag överhuvudtaget lyckas kommunicera med RTCn. Även med färdig kod för just det. Koden är snodd från boken Programming and customizing the AVR microcontroller av Dhananjay V. Gadre. En synnerligen bra bok för övrigt som alla AVR-medpysslare borde ha.
Problemet yttrar sig som så att jag bara får udda siffror i minuter och sekunder. Tiosekunder går bra. Tiominuter går inte så bra. Timmar hag jag inte kollat än (vafan, det tar ju en timme!
). I mina öron låter det som att en bit på ett eller annat vis faller bort.
Här är hela koden till min Nixie-klocka. Har inga direkta förbehållningar men om nu använder den eller delar av den vill jag gärna veta det. Om inte annat så för skojs skull
.
Edit: Nej jag använder inte interrupts just nu. Skulle se hur det fungerar att fråga RTCn hela tiden om uppdateringar.
Problemet yttrar sig som så att jag bara får udda siffror i minuter och sekunder. Tiosekunder går bra. Tiominuter går inte så bra. Timmar hag jag inte kollat än (vafan, det tar ju en timme!

Här är hela koden till min Nixie-klocka. Har inga direkta förbehållningar men om nu använder den eller delar av den vill jag gärna veta det. Om inte annat så för skojs skull

Kod: Markera allt
.include "8515def.inc"
.org $0000
rjmp reset
.org ovf0ADDR
rjmp sweep
.def temp=r16
.def rtcdat=r17
.def cnt=r18
.def tim1=r19
.def tim2=r20
;initiera stackpekaren
ldi temp, HIGH(RAMEND)
out SPH, temp
ldi temp, LOW(RAMEND)
out SPL, temp
reset:
;initiera stackpekaren
ldi temp, HIGH(RAMEND)
out SPH, temp
ldi temp, LOW(RAMEND)
out SPL, temp
;Sätt upp portar
ser temp
out ddra, temp
out ddrb, temp
out ddrc, temp
ldi temp, 0b11111000
out ddrd, temp
;initiera interrupts
ldi temp, 0b00000010
out timsk, temp
; sei
;initiera timer0
ldi temp, 0b00000010
out tccr0, temp
;Sätt igång RTC
;ldi rtcdat, 0b10000000
;sbi PORTD, PIND7
;rcall txrtc
;ldi rtcdat, 0b00000000
;rcall txrtc
;cbi PORTD, PIND7
;sei
main:
;sbis PIND, 0
;rjmp settime
rcall sweep
rjmp main
Sweep:
clr tim1
clr tim2
sbi ddrd, 6
ldi rtcdat, 0b10000001
sbi PORTD, PIND7
rcall txrtc
cbi ddrd, 6
;rcall delay
clr rtcdat
rcall rxrtc
cbi PORTD, PIND7
out porta, rtcdat
sbi PORTD, PIND7
sbi ddrd, 6
ldi rtcdat, 0b10000011
;rcall delay
rcall txrtc
cbi ddrd, 6
;rcall delay
clr rtcdat
rcall rxrtc
cbi PORTD, PIND7
out portb, rtcdat
sbi PORTD, PIND7
sbi ddrd, 6
ldi rtcdat, 0b10000101
;rcall delay
rcall txrtc
cbi ddrd, 6
;rcall delay
clr rtcdat
rcall rxrtc
;rcall delay
cbi PORTD, PIND7
out portc, rtcdat
ret
inccnt:
push temp
in temp, sreg
push temp
inc tim1
cpi tim1, 90
brne return
clr tim1
inc tim2
cpi tim2, 10
brne return
rcall sweep
rjmp return
return:
pop temp
out sreg, temp
pop temp
reti
settime:
rjmp settime
Delay:
dec temp
brne delay
ret
;****************************************************************************
;'txrtc'
;Aim
; Function to write a byte to rtc. Value to be written is passed from
; calling function in register rtcdat.
;Registers used
; cnt to store no of bits
; rtcdat to store the data
;Functions called
; none
;*****************************************************************************
txrtc: ldi cnt, $08 ; load counter
txbck: ror rtcdat ; rotate data right through carry
cbi PORTD,PIND5 ; clear SCLK
brcc txnxt ; if carry set
sbi PORTD,PIND6 ; set I/O
rjmp txnxt1 ; else
txnxt: cbi PORTD,PIND6 ; clear I/O
txnxt1: sbi PORTD,PIND5 ; set SCLK
dec cnt ; decrement counter
brne txbck ; if counter not zero, go back
nop
cbi PORTD,PIND5 ; clear SCLK
ret
;******************************************************************************
;'rxrtc'
;Aim
; Function to read a byte from rtc. Value read is returned in register
; rtcdat
;Registers used
; cnt to store no of bits
; rtcdat to store the data read
;Functions called
; none
;*****************************************************************************
rxrtc: ldi cnt,$08 ; load counter
ldi rtcdat,0
rxbck: sbi PORTD,PIND5 ; set SCLK
sbic PIND,PIND6 ; if I/O set then
sec ; set carry
sbis PIND,PINB6 ; else
clc ; clear carry
ror rtcdat
cbi PORTD,PIND5 ; clear SCLK
dec cnt ; decrement counter
brne rxbck ; if counter equals zero, goto calling function
ret ; else jump back
Edit: Nej jag använder inte interrupts just nu. Skulle se hur det fungerar att fråga RTCn hela tiden om uppdateringar.