Datum a cas z RTC DS1302

Dobry den,
chtel bych Vas pozadat o radu. Chtel bych cist realny cas z integrovaneho obvodu DS1302. zatim jsem vymyslel cast programu ale nevim jak definovat promene a zbytek. Jestli by nekdo vedel za kazdou malou radu budu hrozne rad.
Dekuji Stepan
RTC.bas (2.34 KB)
RTC.bas (2.34 KB)
RTC.bas (2.34 KB)

Ahoj.
Bascom sice neumim, ale hezky navod na nej je na strankach avrhelp.mcselec.com/index.html. Tam se dozvis vse o tom, jak definovat promennou, cykly, procedury apodobne.
Pokud jsi programoval v BASICu tak je to jeste jednodussi, dela se to podobne.
Pokud jsi neprogramoval v Basicu, zkus original AVR studio ovsem ve verzi max. 4.19 a budes programovat v cecku, kde ti bude moci pomoci mnohem vice lidi.
Hodne tady pomaha s Bascomem Kolbaba, ale ten se vrhnul na C a uz dlouho jsem o nem neslysel, doufam, ze z toho neonemocnel.
Jinak doporucim si potom otevrit datasheet, na prisluzne piny hodit LEDky, zpomalit si program a koukat, jestli vysilani odpovida datasheetu.
Hodne stesti

přidej si knihovnu: ds1302clock.lib
Vypis:
;the only changes needed are calling the main program to set/get the variables

[_make_dt]
; assigns the reserved variables TIME$ and DATE$
$external _byte2str
_make_dt:
Call Getdatetime ; This Is In The Main Prog
Loadadr Date$ , X ; Get Address Of Date$
Loadadr _month , Z ; Get Address Of _month Byte
Ld r24,Z ; get first byte is month
Rcall _byte2Str ; add to date string
Ldi r24,47 ; add /
St x+,r24 ; store
Ld r24, -z ; get day
rcall _byte2Str ; add to date string
ldi r24,47 ; add /
st x+,r24 ; store
adiw zl,2 ; point to year
ld r24,z ; get year
rcall _byte2Str ; add to date string
clr r24 ; string terminator
st x+,r24 ; store tring terminator
;now do the time time$ must be dimmed after date$
;this is handled by the compiler
sbiw zl,2 ; go back
ld r24,-z ; get hour
rcall _byte2Str ; add to date string
ldi r24,58 ; add :
st x+,r24 ; store
ld r24,-z ; get minutes
rcall _byte2Str ; add to date string
ldi r24,58 ; add :
st x+,r24 ; store
ld r24,-z ; get secs
rcall _byte2Str ; add to date string
clr r24
st x,r24 ; add null terminator
Ret
[end]

[_set_date]
$external _str2byte
; assigns the date$ variable to the date bytes
_set_date:
Loadadr _month , X ; Address Of Month Byte
Loadadr Date$ , Z ; Point To Date$ Variable
ld r24,z+ ; get month MSB
ld r25,z+ ; get month LSB
rcall _str2byte ; convert
st x,r16 ; save month
adiw zl,1 ; skip /
ld r24,z+ ; get day MSB
ld r25,z+ ; get day LSB
rcall _str2byte ; convert
st -x,r16 ; save day
adiw zl,1 ; skip /
ld r24,z+ ; get year MSB
ld r25,z ; get year LSB
rcall _str2byte ; convert
adiw xl,2 ; point to year
st x,r16 ; save year
Call Setdate ; Calls The Main Program
Ret
[end]

[_set_time]
$external _str2byte
;assigns the time$ variable to the time bytes of the clock
_set_time:
Loadadr _hour , X ; Load Address Of Hour
Loadadr Time$ , Z ; Point To Time$
ld r24,z+ ; get hour MSB
ld r25,z+ ; get hour LSB
rcall _str2byte ; convert
st x,r16 ; save hour
adiw zl,1 ; skip :
ld r24,z+ ; get minute MSB
ld r25,z+ ; get minute LSB
rcall _str2byte ; convert
st -x,r16 ; save minutes
adiw zl,1 ; skip :
ld r24,z+ ; get seconds MSB
ld r25,z ; get seconds LSB
rcall _str2byte ; convert
st -x,r16 ; save seconds
Call Settime
Ret

tady ukázka programu ovládání Ds1302:
'----------------------------------------------------------------------
’ ds1302include.bas
'----------------------------------------------------------------------

$lib “ds1302clock.lib”

Config Portc.4 = Output
Config Portc.6 = Output

Ds1302_clock Alias Portc.4 ’ DS1302 Pin 7 - Clock
Ds1302_io Alias Pinc.5 ’ DS1302 Pin 6 - I/O
Ds1302_io_port Alias Portc.5
Ds1302_enable Alias Portc.6 ’ DS1302 Pin 5 - Enable

Declare Sub Ds1302_write(byval Clockcommand As Byte , Clockbyte As Byte)
Declare Function Ds1302_read(byval Clockcomand As Byte) As Byte
Declare Sub Ds1302_set_time(byval Strtime As String)

'----------------------------------------------------------------------
’ Ds1302_read
'----------------------------------------------------------------------

Function Ds1302_read(byval Clockcomand As Byte) As Byte

Dim Readbyte As Byte

Config Ds1302_io_port = Output

Set Ds1302_clock

Set Ds1302_io

Set Ds1302_enable

Reset Ds1302_clock

Reset Ds1302_enable

Waitus 5

Set Ds1302_enable

Waitus 5 'tcc =4us, CE to clock setup time

Shiftout Ds1302_io_port , Ds1302_clock , Clockcomand , 3

Config Ds1302_io_port = Input

Set Ds1302_clock

Reset Ds1302_io

Set Ds1302_enable

Shiftin Ds1302_io , Ds1302_clock , Readbyte , 2

Reset Ds1302_enable

Rotate Readbyte , Left , 1

Waitus 5

Ds1302_read = Readbyte

End Function

'----------------------------------------------------------------------
’ Ds1302_write
'----------------------------------------------------------------------

Sub Ds1302_write(byval Clockcommand As Byte , Clockbyte As Byte)

Config Ds1302_io_port = Output

Set Ds1302_clock

Reset Ds1302_io

Set Ds1302_enable

Reset Ds1302_clock

Reset Ds1302_enable

Waitus 5

Set Ds1302_enable

Waitus 5 'tcc =4us, CE to clock setup time

Shiftout Ds1302_io_port , Ds1302_clock , Clockcommand , 3

Shiftout Ds1302_io_port , Ds1302_clock , Clockbyte , 3

Reset Ds1302_clock

Waitus 5

Reset Ds1302_enable

Waitus 5

End Sub

'----------------------------------------------------------------------
’ Getdatetime
'----------------------------------------------------------------------

’ Reads the date and time from the DS1302 real time clock and stores
’ them in the system variables _year, _month, _day, _hour, _min, and
’ _sec

'----------------------------------------------------------------------

Getdatetime:

_sec = Ds1302_read(&H81)

_min = Ds1302_read(&H83)

_hour = Ds1302_read(&H85)

_day = Ds1302_read(&H87)

_month = Ds1302_read(&H89)

_year = Ds1302_read(&H8d)

_sec = Makedec(_sec)
_min = Makedec(_min)
_hour = Makedec(_hour)
_day = Makedec(_day)
_month = Makedec(_month)
_year = Makedec(_year)

Return

'----------------------------------------------------------------------
’ Setdate
'----------------------------------------------------------------------

’ Writes the date stored in the system variables _year, _month, and
’ _day to the DS1302 real time clock. Called by ds1302clock.lib

’ To use:

’ Date$ = “yy-mm-dd”

'----------------------------------------------------------------------

Setdate:

_day = Makebcd(_day)
Ds1302_write &H86 , _year

_month = Makebcd(_month)
Ds1302_write &H88 , _month

_year = Makebcd(_year)
Ds1302_write &H8C , _year

Return

'----------------------------------------------------------------------
’ Settime
'----------------------------------------------------------------------

’ Writes the time stored in the system variables _hour, _min, and _sec
’ to the DS1302 real time clock. Called by ds1302clock.lib

’ To use:

’ Time$ = “hh:mm:dd”

'----------------------------------------------------------------------

Settime:

_hour = Makebcd(_hour)
Ds1302_write &H84 , _hour

_min = Makebcd(_min)
Ds1302_write &H82 , _min

_sec = Makebcd(_sec)
Ds1302_write &H80 , _sec

Return

myslim že takhle by to bylo jednoduší

Díval jsem se na ten tvůj program a kdyby si nenapsal, že je to v Bascomu, tak bych to nepoznal. Chybí ti definice mcu a jeho frekvence. Porty by se měly definovat na začátku. Definovat je v podprogramu, do něhož to vleze několikrát za sekundu je blbost. Vytvořit sériovou komunikaci s IO nebude zas taková legrace, zvláště, když nekomunikuje po rozhraní, co Bascom přímo podporuje jako je I2C nebo SPI.

[code]$regfile = “m48def.dat” ’ Zakladni nastaveni mcu
v tomto případě je to ATmega48
$crystal = 8000000 ’ Frekvence mcu

Config Portb.1 = Output ’ nastavení pinu 2 portu B jako výstup
Config Portb.2 = Output
Config Portc = input ’ nastavení celíého poru C jako vstup[/code]

Pokud na vstupním pinu bude tlačítko, musí se nastavil ještě pullup odpor tím, že se na něj pošle 1, ač je vstupní:
portc.1 = 1

Pin portu, jenž slouží jako reset se nesmí nastavit jako výstupní, jelikož poté již nejde mcu přeprogramovat. Jde to opravit, ale není to snadný.

Něco jsem našel, ale jen z hlavy nedokážu říct, zda to opravdu funguje:

[code]$regfile = “m128def.dat”
$crystal = 16000000
$baud = 115200

Dim I As Word
Dim A As Byte
Dim B As Byte
Dim C As Byte
Dim D As Byte
Dim S As Long
Dim Rok As Byte
Dim Dzien_tygodnia As Byte
Dim Dzien As Byte
Dim Miesiac As Byte
Dim Godzina As Byte
Dim Minuta As Byte
Dim Sekunda As Byte

'Dim Oc As Word
'Dim Oa As Byte
'Dim Ob As Byte

Dim Oc As Word At &H600 '0-1 zmienna word
Dim Oa As Byte At &H600 Overlay '0 zmienna
Dim Ob As Byte At &H601 Overlay '1 zmienna

Dim Writecommand As Byte
Dim Writebyte As Byte
Dim Readcommand As Byte
Dim Readbyte As Byte

Const Po = “Poniedzialek” ’ stałe do zegara
Const Wt = “wtorek” ’ stałe do zegara
Const Sr = “Sroda” ’ stałe do zegara
Const Cz = “Czwartek” ’ stałe do zegara
Const Pi = “Piatek” ’ stałe do zegara
Const So = “Sobota” ’ stałe do zegara
Const Ni = “Niedziela” ’ stałe do zegara

Const Sty = “Styczeń” ’ stałe do zegara
Const Lut = “Luty” ’ stałe do zegara
Const Mar = “Marzec” ’ stałe do zegara
Const Kwi = “Kwiecień” ’ stałe do zegara
Const Maj = “Maj” ’ stałe do zegara
Const Cze = “Czerwiec” ’ stałe do zegara
Const Lip = “Lipiec” ’ stałe do zegara
Const Sie = “Sierpień” ’ stałe do zegara
Const Wrz = “Wrzesienń” ’ stałe do zegara
Const Paz = “Pazdziernik” ’ stałe do zegara
Const Lis = “Listopad” ’ stałe do zegara
Const Gru = “Grudzien” ’ stałe do zegara

Config Portb.4 = Output
Config Portb.6 = Output

Serialclock Alias Portb.4
Serialin_out Alias Pinb.5 ’
Ds1302 Alias Portb.6

Declare Sub 1302_czytam
Declare Sub 1302_zapisuj
Declare Sub Zegar_1302
Declare Sub Czytam_zegar

Zegar_1302 'tu jest zapis
Czytam_zegar
Waitms 1000
Czytam_zegar
Waitms 1000
Czytam_zegar
Waitms 1000
Czytam_zegar
Waitms 1000
Czytam_zegar
Waitms 1000
Czytam_zegar
Waitms 1000
Czytam_zegar
Waitms 1000
Czytam_zegar
Waitms 1000
Czytam_zegar
Waitms 1000
Czytam_zegar
Waitms 1000
Czytam_zegar
Waitms 1000
Czytam_zegar
Waitms 1000
Czytam_zegar
Waitms 1000
Czytam_zegar
Waitms 1000
Czytam_zegar
Waitms 1000
Czytam_zegar
Waitms 1000
Czytam_zegar

End 'end program

'*****************************************************************************
'+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
'*****************************************************************************
Sub Zegar_1302

Print “Wpisuje bit odbezpieczający zapis Protect”
Writecommand = &H8E
Writebyte = &B00000000
1302_zapisuj

Waitus 5

Print “Wpisuje rok”
Writecommand = &H8C
Writebyte = &B00010000
1302_zapisuj

Print “Wpisuje dzień nazwa”
Writecommand = &H8A
Writebyte = &B00000100
1302_zapisuj

Print “Wpisuje miesiąc”
Writecommand = &H88
Writebyte = &B00000010
1302_zapisuj

Print “Wpisuje dzień”
Writecommand = &H86
Writebyte = &B00010000
1302_zapisuj

Print “Wpisuje godzina”
Writecommand = &H84
Writebyte = &B00100000
1302_zapisuj

Print “Wpisuje minuty”
Writecommand = &H82
Writebyte = &B00110101
1302_zapisuj

Print “Wpisuje sekundy”
Writecommand = &H80
Writebyte = &B00000000
1302_zapisuj

End Sub

'*****************************************************************************
'+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
'*****************************************************************************
Sub Czytam_zegar

Readcommand = &H81
1302_czytam
Sekunda = Readbyte

'Print “sekunda=” ; Bcd(readbyte)

Readcommand = &H83
1302_czytam
Minuta = Readbyte
'Print “minuta=” ; Bcd(readbyte)

Readcommand = &H85
1302_czytam
Godzina = Readbyte
'Print “godzina=” ; Bcd(readbyte)

Readcommand = &H87
1302_czytam
Dzien = Readbyte
'Print “data=” ; Bcd(readbyte)

Readcommand = &H89
1302_czytam
Miesiac = Readbyte
'Print “miesiąc=” ; Bcd(readbyte)

Readcommand = &H8B
1302_czytam
Dzien_tygodnia = Readbyte
'Print “dzień tygodnia=” ; Bcd(readbyte)

Readcommand = &H8D
1302_czytam
Rok = Readbyte
'Print “rok=” ; Bcd(readbyte)

Print “20” ; Bcd(rok) ; “r.-” ;

If Miesiac = 1 Then 
Print Sty; 
Elseif Miesiac = 2 Then                                 'Bcd(miesiac) 
Print Lut; 
Elseif Miesiac = 3 Then 
Print Mar; 
Elseif Miesiac = 4 Then 
Print Kwi; 
Elseif Miesiac = 5 Then 
Print Maj; 
Elseif Miesiac = 6 Then 
Print Cze 
Elseif Miesiac = 7 Then 
Print Lip; 
Elseif Miesiac = 8 Then 
Print Sie; 
Elseif Miesiac = 9 Then 
Print Wrz; 
Elseif Miesiac = 10 Then 
Print Paz; 
Elseif Miesiac = 11 Then 
Print Lis; 
Elseif Miesiac = 12 Then 
Print Gru; 
End If 

Print ; "-" ; Bcd(dzien) ; "   " ;                      ' 


If Dzien_tygodnia = 1 Then 
Print Po ;                                              ' 
Elseif Dzien_tygodnia = 2 Then                          ' 
Print Wt ;                                              ' 
Elseif Dzien_tygodnia = 3 Then                          ' 
Print Sr ; 
Elseif Dzien_tygodnia = 4 Then                          ' 
Print Cz ; 
Elseif Dzien_tygodnia = 5 Then                          ' 
Print Pi ; 
Elseif Dzien_tygodnia = 6 Then                          '            Bcd(dzien_tygodnia) 
Print So ; 
Elseif Dzien_tygodnia = 7 Then                          ' 
Print Ni ;                                              ' 
End If 
Print ; "  "; 

Print Bcd(godzina) ; “:”; Bcd(minuta) ; “:” ; Bcd(sekunda)

                                       ' 

End Sub
'*****************************************************************************
'+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
'*****************************************************************************

'*****************************************************************************
'+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
'*****************************************************************************
Sub 1302_czytam
’ Przeznaczenie:
'Wsuwa ciąg bitów do zmiennej.
'Składnia:
'SHIFTIN pin_danych , pin_zegarowy , zmienna , opcje , il_bitów , opóźnienie ]

'0 najpierw bit MSB jest wpisywany przy wystawieniu niskiego poziomu logicznego na końcówce zegarowej
'1 najpierw bit MSB jest wpisywany przy wystawieniu wysokiego poziomu logicznego na końcówce zegarowej
'2 najpierw bit LSB jest wpisywany przy wystawieniu niskiego poziomu logicznego na końcówce zegarowej
'3 najpierw bit LSB jest wpisywany przy wystawieniu wysokiego poziomu logicznego na końcówce zegarowej
'Gdy liczba określająca opcję zostanie powiększona o 4, wtedy sygnał zegarowy nie będzie generowany i lina zegarowa będzie pełnić rolę wejścia zewnętrznego sygnału zegarowego (tryb SLAVE).:

'4 najpierw bit MSB jest wpisywany przy niskim poziomie logicznym na końcówce zegarowej
'5 najpierw bit MSB jest wpisywany przy wysokim poziomie logicznym na końcówce zegarowej
'6 najpierw bit LSB jest wpisywany przy niskim poziomie logicznym na końcówce zegarowej
'7 najpierw bit LSB jest wpisywany przy wysokim poziomie logicznym na końcówce zegarowej

'Oa = &H81 '&H81
'Ob = &H00
'Oc = Oa + Ob
'Portb.6 = 1
'Print Hex(oc)

'Shiftin Pinb.5 , Portb.4 , Oc , 0 , 16 , 1000 'odczytuje 16 bitów

'Portb.6 = 0

'Print Hex(oc)
Config Portb.5 = Output
Serialin_ou Alias Portb.5
Serialclock = 1
Serialin_ou = 1
Ds1302 = 1
Reset Serialclock
Reset Ds1302
Waitus 5
Set Ds1302
Waitus 5 'tcc =4us, CE to clock setup time
Shiftout Serialin_ou , Serialclock , Readcommand , 3

Config Portb.5 = Input
Serialin Alias Pinb.5

Serialclock = 1
Serialin_out = 0
Ds1302 = 1
Shiftin Serialin , Serialclock , Readbyte , 2
Reset Ds1302
Rotate Readbyte , Left , 1

Waitus 5

End Sub

'*****************************************************************************
'+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
'*****************************************************************************
Sub 1302_zapisuj
'Przeznaczenie:
'Wysuwa ciąg bitów pochodzący z określonej zmiennej.
'Składnia:
'SHIFTOUT pin_danych , pin_zegarowy , zmienna , opcje , il_bitów , opóźnienie ]
'0 najpierw bit MSB jest podawany przy niskim poziomie logicznym na końcówce zegarowej
'1 najpierw bit MSB jest podawany przy wysokim poziomie logicznym na końcówce zegarowej
'2 najpierw bit LSB jest podawany przy niskim poziomie logicznym na końcówce zegarowej
'3 najpierw bit LSB jest podawany przy wysokim poziomie logicznym na końcówce zegarowej

'Oa = &H80 '&H80
'Ob = &H26

'Oc = Oa + Ob
'Portb.6 = 1
'Print Hex(oc)
'Shiftout Pinb.5 , Portb.4 , Oc , 2 , 16 , 1000 'nadanie 16 bitów

'Portb.6 = 0

'Print Hex(oc)
Config Portb.5 = Output
'Serialin_out Alias Portb.5
Serialclock = 1
Serialin_ou = 0
Ds1302 = 1
Reset Serialclock
Reset Ds1302
Waitus 5
Set Ds1302
Waitus 5 'tcc =4us, CE to clock setup time
Shiftout Serialin_ou , Serialclock , Writecommand , 3
Shiftout Serialin_ou , Serialclock , Writebyte , 3
Reset Serialclock
Waitus 5
Reset Ds1302
Waitus 5

End Sub
'*****************************************************************************
'+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
'***************************************************************************** [/code]

Našel jsem ho tady

P.S.Nějak jsem nezjistil, řím se liší od sebe ty 3 vložený přílohy.


DragonSoul: Já sem chodím, ale není k čemu se vyjadřovat. :stuck_out_tongue: V práci finišujeme s výrobou a uvedením do provozu AM vysílačů na jedno rádio, po ukončení fixace hypotěky nam banka nabídla úrok skoro 7% (tak jsem sehnal 3%) a taky jsem se hrabal ve svým webu (jeden update za rok mě přišel málo) a tak jsem se k tomu C skoro nedostal.

Zdravim,
zkousel jsem oba priklady ktere jste mi poslali ale nejak jsem nerozchodil ani jeden z nich :frowning: pokousim se ale stale mi to ukazuje veci o kterych se mi ani nezda :smiley: ale opravdu dekuji za snahu :slight_smile:

Tak jsem zkusil napsat program v Bascomu pro DS1302, ale není to nic extra(jen zápis dat do RTC a poté čtení). Moc v programu Bascom nedělám.
Otestoval jsem to jen v simulaci(DS1302 doma nemám, abych to zkusil):
RTC_DS1302.bas (6.09 KB)