{"id":87,"date":"2011-01-07T12:41:05","date_gmt":"2011-01-07T11:41:05","guid":{"rendered":"http:\/\/gc.x3.net\/wordpress\/?page_id=87"},"modified":"2019-09-23T14:42:50","modified_gmt":"2019-09-23T13:42:50","slug":"avr-wecker-mit-rtc","status":"publish","type":"page","link":"https:\/\/www.byter.de\/wordpress\/?page_id=87","title":{"rendered":"Elektronik: AVR-Wecker mit RTC"},"content":{"rendered":"<p>Die Idee hinter diesem kleinen Projekt war recht simpel: eine zeitgesteuerte Station f\u00fcr einen Geocache.&nbsp; So sollte zu einer bzw. zwei vordefinierten Zeiten pro Tag eine Aktion ausgel\u00f6st werden (z.B. ein Relais geschaltet werden), das ganze dazu a) stromsparend f\u00fcr dauerhaften Batteriebetrieb und b) korrigierbar.<\/p>\n<p>Herausgekommen ist dieser kleine &#8222;Wecker&#8220; auf AVR-Basis (ATMEGA8) und einer Dallas 1337 Realtimeclock.<\/p>\n<p>Pro Tag lassen sich zwei Alarm-Zeiten einstellen, die ein Relais anziehen (im Schaltplan eine LED). Nat\u00fcrlich l\u00e4sst sich auch jede beliebige andere Aktion starten, freie Ports und freier Speicher sind noch genug vorhanden <img decoding=\"async\" title=\"zwinkern\" src=\"http:\/\/www.geoclub.de\/images\/smilies\/icon_wink.gif\" alt=\";)\"><\/p>\n<p>\u00dcber ein kleines LCD-Display und ein einfaches Men\u00fc mit 3 Taster-Eingaben lassen sich Zeit und Alarmzeiten jederzeit korrigieren, ohne daf\u00fcr an den Rechner zu m\u00fcssen.<br \/>\n(1 Taste Men\u00fc\/OK, 1 Taste Wert erh\u00f6hen, 1 Taste Cursorposition).<\/p>\n<p>Die Ruhestromaufnahme liegt bei etwa 7 uA und ist somit absolut &#8222;batterietauglich&#8220;.<\/p>\n<p>Hier der Schaltplan:<\/p>\n<p style=\"text-align: left;\"><a href=\"https:\/\/www.byter.de\/avr-wecker.JPG\"><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter\" title=\"Schaltplan\" src=\"https:\/\/www.byter.de\/avr-wecker.JPG\" alt=\"Schaltplan &quot;AVR-Wecker mit RTC&quot;\" width=\"922\" height=\"549\"><\/a>R1-R3: PullUp-Widerst\u00e4nde (~22k),&nbsp; Q1: Uhrenquarz mit 6pf Lastkapazit\u00e4t<\/p>\n<p style=\"text-align: left;\">&nbsp;<\/p>\n<p style=\"text-align: left;\">Und hier der Quellcode (BASCOM):<\/p>\n<pre class=\"brush:vb\">' ====================================\n' = \"AVR-Wecker\" mit Dallas 1337 RTC =\n' = -------------------------------- =\n' = Version 1.0 \/ qByter             =\n' ====================================\n\n$regfile = \"m8def.DAT\"\n$crystal = 1000000\n$baud = 9600\n$hwstack = 20\n\nDeclare Sub Set_menu\nDeclare Sub Settime_Menu\nDeclare Sub Incrcursor_setmenu\nDeclare Sub Selection_setmenu\nDeclare Sub Setalarm_menu\nDeclare Sub Alarm\nDeclare Sub Display_time\nDeclare Sub Display_setting\nDeclare Sub Raisevalue\nDeclare Sub Setcursor\nDeclare Sub Incrcursor\nDeclare Sub Turnoffavr\nDeclare Sub Getdatetime\nDeclare Sub Setdate\nDeclare Sub Settime\nDeclare Sub Setalarm\nDeclare Sub Resetalarm\nDeclare Sub Checkalarm\n\nConst Relaistime = 10\n\nConfig Portb = &amp;B00000011\nConfig Portc = &amp;B00111111\nConfig Portd = &amp;B00000011\n\nConfig Sda = Portb.7                                        ' I2C Bus konfigurieren\nConfig Scl = Portb.6\nConst Ds1307w = &amp;HD0                                        ' Addresse der Ds1307\/Ds1337 Uhr\nConst Ds1307r = &amp;HD1\n\nConfig Clock = User                                         ' Interne Time\/Date Routinen f\u00fcr Bascom konfigurieren\nConfig Date = Dmy , Separator = .\n\nConfig Lcd = 20 * 2                                         ' LCD konfigurieren\nConfig Lcdpin = Pin , Db4 = Portc.3 , Db5 = Portc.2 , Db6 = Portc.1 , Db7 = Portc.0 , E = Portc.4 , Rs = Portc.5\n\nConfig Debounce = 25                                        ' Wartezeit zum Entprellen der Taster\nPortd.7 = 1                                                 ' Pullups f\u00fcr Taster zuschalten\nPortd.6 = 1\nPortd.2 = 1\nPortd.3 = 1                                                 ' Pullup f\u00fcr D3\/INT1 zuschalten\n\n' Variablen\nDim Alarm_flag As Byte\nDim Int1_flag As Byte\nDim Zeichen As Byte\n'Dim Stri As String * 5\nDim Weekday As Byte\n\nDim Set_hour As Byte\nDim Set_min As Byte\nDim Set_sec As Byte\n\nDim Alarm1_hour As Byte\nDim Alarm1_min As Byte\nDim Alarm1_sec As Byte\nDim Alarm2_hour As Byte\nDim Alarm2_min As Byte\nDim Alarm2_sec As Byte\nDim Alarm_to_change As Byte\n\nDim Maincursorpos As Byte\nDim Cursorpos As Byte\n\nMaincursorpos = 1\nCursorpos = 1\nInt1_flag = 0\nAlarm_flag = 0\n\nEnable Interrupts\n\nStop Adc\nStop Ac\n\nPortb.1 = 1                                                 ' LCD anschalten\n\nWaitms 50                                                   ' Kleines INIT, zur Funktionspr\u00fcfung beim Start\nInitlcd\nCls\nLocate 1 , 1\nLcd \"Init...\"\n\n' Stellen der Uhr, muss nur einmal ausgef\u00fchrt werden\nTime$ = \"19:57:00\"                                          ' Initialwerte f\u00fcr Uhr\nDate$ = \"01.12.10\"                                          ' Datum setzen,  wird derzeit nicht wirklich gebraucht\n\nAlarm1_hour = 19                                            ' Alarmzeit 1\nAlarm1_min = 59\nAlarm1_sec = 20\nAlarm2_hour = 23                                            ' Alarmzeit 2\nAlarm2_min = 0\nAlarm2_sec = 1\n\nGosub Setalarm                                              ' Alarmzeiten in DS1337 programmieren\n\nEnable Int0                                                 ' INT0 = Alarm ausgel\u00f6st\nConfig Int0 = Low Level\nOn Int0 Int0_alarm\n\nEnable Int1                                                 ' INT 1 = Men\u00fc aufrufen\nConfig Int1 = Low Level\nOn Int1 Int1_alarm\n\nLcd \"OK!\"\nWait 1                                                      ' Ende der Initialisierung\n\n' =============\n' HAUPTSCHLEIFE\n' =============\n\nDo\n  If Int1_flag = 1 Then                                     ' INT1 ausgel\u00f6st, Men\u00fc aufrufen\n   Getdatetime\n   Set_menu\n   Int1_flag = 0\n   Gifr = 32\n  End If\n\n  If Alarm_flag = 1 Then                                    ' INT0 ausgel\u00f6st, Alarm ausl\u00f6sen\n   Disable Int0                                             ' Interrupt vorr\u00fcbergehend abschalten\n   Alarm\n   Alarm_flag = 0\n   Gifr = 32                                                ' Interrupt Status Flag zur\u00fccksetzen\n   Enable Int0\n  End If\n\n  Gosub Turnoffavr                                          ' LCD und AVR abschalten bis Interrupt\n\nLoop\nEnd\n\n' ===============\n' ISRs\n\nInt0_alarm:\nAlarm_flag = 1\nReturn\n\nInt1_alarm:\nInt1_flag = 1\nReturn\n\n' ==============\n' Sub-Routinen\n\nSub Alarm                                                   ' Alarm ausl\u00f6sen\n  Portb.1 = 1                                               ' LCD anschalten\n  Initlcd\n\n  Locate 2 , 1\n  Lcd Time$                                                 ' Zeit anzeigen\n\n  Locate 1 , 1\n  Lcd \"ALARM\"\n  Portb.0 = 1                                               ' Ausgang schalten (Relais)\n\n  Wait Relaistime                                           ' Definierte Zeit warten\n  Resetalarm                                                ' Alarm in der RTC resetten\/abschalten\n  Portb.0 = 0                                               ' Ausgang wieder abschalten\nEnd Sub\n\nSub Set_menu                                                'Hauptmen\u00fc - Auswahl ob Zeit, Alarm1 oder Alarm2 ge\u00e4ndert werden soll\n   Portb.1 = 1\n   Initlcd\n   Locate 1 , 1\n   Lcd \"SET: Zeit A1 A2\"\n   Locate 1 , 6\n   Cursorpos = 1\n   Cursor On Blink\n\n  Int1_flag = 0                                             ' Interrupt flag l\u00f6schen\n  Gifr = 32\n\n  While Int1_flag = 0                                       ' Warten auf Tasteneingabe\n    Debounce Pind.6 , 0 , Selection_setmenu , Sub\n    Debounce Pind.7 , 0 , Incrcursor_setmenu , Sub\n    Waitms 10\n  Wend\nEnd Sub\n\nSub Incrcursor_setmenu                                      ' Cursor im Men\u00fc auf Position bringen\nSelect Case Cursorpos\n  Case 1:\n    Incr Cursorpos\n    Locate 1 , 11\n  Case 2:\n    Incr Cursorpos\n    Locate 1 , 14\n  Case 3:\n    Cursorpos = 1\n    Locate 1 , 6\nEnd Select\nEnd Sub\n\nSub Selection_setmenu                                       ' Aktion je nach Auswahl im Men\u00fc\n  Select Case Cursorpos\n    Case 1:                                                 ' 1 = Zeit neu stellen\n      Call Settime_menu\n    Case 2:                                                 ' 2 = Alarm1 neu stellen\n      Alarm_to_change = 1\n      Call Setalarm_menu\n    Case 3:                                                 ' 3 = Alarm2 neu stellen\n      Alarm_to_change = 2\n      Call Setalarm_menu\n  End Select\nEnd Sub\n\nSub Setalarm_menu                                           ' Alarm neu stellen\n    Cls\n    Locate 1 , 1\n    Lcd \"Neue Alarm\" ; Str(alarm_to_change) ; \"-Zeit\"\n\n    If Alarm_to_change = 1 Then\n      Set_hour = Alarm1_hour\n      Set_min = Alarm1_min\n      Set_sec = Alarm1_sec\n    Else\n      Set_hour = Alarm2_hour\n      Set_min = Alarm2_min\n      Set_sec = Alarm2_sec\n    End If\n\n    Gosub Display_setting\n\n    While Int1_flag = 0                                     ' Warten auf Tasteneingabe\n      Debounce Pind.7 , 0 , Raisevalue , Sub\n      Debounce Pind.6 , 0 , Incrcursor , Sub\n      Waitms 10\n    Wend\n\n    If Alarm_to_change = 1 Then\n      Alarm1_hour = Set_hour\n      Alarm1_min = Set_min\n      Alarm1_sec = Set_sec\n    Else\n      Alarm2_hour = Set_hour\n      Alarm2_min = Set_min\n      Alarm2_sec = Set_sec\n    End If\n\n    Gosub Setalarm                                          ' Alarm in RTC neu stellen\n\n    Cls\n    Locate 1 , 1\n    Lcd \"Neuer Alarm\" ; Str(alarm_to_change) ; \": \"\n    Gosub Display_setting\n    Wait 3                                                  ' Pause f\u00fcr Anzeige + Entprellung\nEnd Sub\n\nSub Display_setting                                         ' Zu \u00e4ndernde Zeit anzeigen\n  Locate 2 , 1\n  If Set_hour &lt; 10 Then\n    Lcd \"0\" ; Str(set_hour) ; \":\"\n   Else\n    Lcd Str(set_hour) ; \":\"\n  End If\n\n  Locate 2 , 4\n  If Set_min &lt; 10 Then\n    Lcd \"0\" ; Str(set_min) ; \":\"\n   Else\n    Lcd Str(set_min) ; \":\"\n  End If\n\n  Locate 2 , 7\n  If Set_sec &lt; 10 Then\n    Lcd \"0\" ; Str(set_sec)\n   Else\n    Lcd Str(set_sec)\n  End If\n\n  Gosub Setcursor\nEnd Sub\n\nSub Settime_menu                                            ' Zeit neu stellen\n  Cls\n  Locate 1 , 1\n  Lcd \"Zeit einstellen:\"\n  Cursorpos = 1\n\n  Set_hour = _hour\n  Set_min = _min\n  Set_sec = _sec\n\n  Gosub Display_setting\n\n  While Int1_flag = 0                                       ' Auf Tasteneingabe warten\n    Debounce Pind.7 , 0 , Raisevalue , Sub\n    Debounce Pind.6 , 0 , Incrcursor , Sub\n    Waitms 10\n  Wend\n\n  ' An dieser Stelle ist Int1 erneut ausgel\u00f6st, also Zeit neu setzen\n\n  _hour = Set_hour\n  _min = Set_min\n  _sec = Set_sec\n\n  Gosub Settime                                             ' Zeit in RTC schreiben\n\n  Cls\n  Locate 1 , 1\n  Lcd \"Neue Zeit: \"\n  Gosub Display_setting\n  Wait 3                                                    ' Entprellpause, um sofortigen neuen INT zu verhindern\nEnd Sub\n\nSub Incrcursor                                              ' Cursor im Menu neu setzen \/ erh\u00f6hen\n  If Cursorpos &gt; 2 Then\n    Cursorpos = 1\n   Else\n    Incr Cursorpos\n  End If\n  Gosub Setcursor\nEnd Sub\n\nSub Raisevalue                                              ' Wert (h\/min\/sec) erh\u00f6hen\nSelect Case Cursorpos\n   Case 1:                                                  ' 1 = Stunden\n    If Set_hour = 23 Then\n      Set_hour = 0\n     Else\n      Incr Set_hour\n    End If\n    Locate 2 , 1\n    If Set_hour &lt; 10 Then\n      Lcd \"0\" ; Str(set_hour) ; \":\"\n     Else\n      Lcd Str(set_hour) ; \":\"\n    End If\n    Locate 2 , 1\n\n   Case 2:                                                  ' 2 = Minuten\n    If Set_min = 59 Then\n      Set_min = 0\n     Else\n      Incr Set_min\n    End If\n    Locate 2 , 4\n    If Set_min &lt; 10 Then\n      Lcd \"0\" ; Str(set_min) ; \":\"\n     Else\n      Lcd Str(set_min) ; \":\"\n    End If\n    Locate 2 , 4\n\n   Case 3:                                                  ' 3 = Sekunden\n    If Set_sec = 59 Then\n      Set_sec = 0\n     Else\n      Incr Set_sec\n    End If\n    Locate 2 , 7\n    If Set_sec &lt; 10 Then\n      Lcd \"0\" ; Str(set_sec)\n     Else\n      Lcd Str(set_sec)\n    End If\n    Locate 2 , 7\nEnd Select\nEnd Sub\n\nSub Setcursor                                               ' Cursor auf die Position der aktuellen Auswahl setzen\nSelect Case Cursorpos\n   Case 1:\n   Locate 2 , 1\n   Case 2:\n   Locate 2 , 4\n   Case 3:\n   Locate 2 , 7\nEnd Select\nEnd Sub\n\nSub Turnoffavr:\n  Portb.1 = 0                                               ' LCD aus\n  Portc = 0                                                 ' Alle Datenpins low\n  Powerdown\nEnd Sub\n\n' ==================================================\n' Unterprogramme f\u00fcr die RTC\n\nSub Getdatetime\n  I2cstart\n  I2cwbyte Ds1307w\n  I2cwbyte 0\n  I2cstart\n  I2cwbyte Ds1307r\n  I2crbyte _sec , Ack\n  I2crbyte _min , Ack\n  I2crbyte _hour , Ack\n  I2crbyte Weekday , Ack\n  I2crbyte _day , Ack\n  I2crbyte _month , Ack\n  I2crbyte _year , Nack\n  I2cstop\n  _sec = Makedec(_sec) : _min = Makedec(_min) : _hour = Makedec(_hour)\n  _day = Makedec(_day) : _month = Makedec(_month) : _year = Makedec(_year)\nEnd Sub\n\nSub Setdate\n  _day = Makebcd(_day) : _month = Makebcd(_month) : _year = Makebcd(_year)\n  I2cstart\n  I2cwbyte Ds1307w\n  I2cwbyte 4\n  I2cwbyte _day\n  I2cwbyte _month\n  I2cwbyte _year\n  I2cstop\nEnd Sub\n\nSub Settime\n  _sec = Makebcd(_sec) : _min = Makebcd(_min) : _hour = Makebcd(_hour)\n  I2cstart\n  I2cwbyte Ds1307w\n  I2cwbyte 0\n  I2cwbyte _sec\n  I2cwbyte _min\n  I2cwbyte _hour\n  I2cstop\nEnd Sub\n\nSub Setalarm\n  I2cstart\n  I2cwbyte Ds1307w\n  I2cwbyte 7\n  Zeichen = Makebcd(alarm1_sec)\n  I2cwbyte Zeichen\n  Zeichen = Makebcd(alarm1_min)\n  I2cwbyte Zeichen\n  Zeichen = Makebcd(alarm1_hour)\n  I2cwbyte Zeichen\n  I2cwbyte &amp;B10000000                                       '128 = Jeweils beim Erreichen von h\/m\/s ALARM ausl\u00f6sen\n\n    Zeichen = Makebcd(alarm2_sec)\n    I2cwbyte Zeichen\n    Zeichen = Makebcd(alarm2_min)\n    I2cwbyte Zeichen\n    Zeichen = Makebcd(alarm2_hour)\n    I2cwbyte Zeichen\n    I2cstop\n\n  I2cstart\n  I2cwbyte Ds1307w\n  I2cwbyte 14\n\n  I2cwbyte &amp;B00011011                                       'Alarme aktivieren\n  I2cwbyte 0                                                'Statusbits auf 0\n  I2cstop\nEnd Sub\n\nSub Resetalarm\n  I2cstart\n  I2cwbyte Ds1307w\n  I2cwbyte 15\n  I2cwbyte 0\n  I2cstop\nEnd Sub<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Die Idee hinter diesem kleinen Projekt war recht simpel: eine zeitgesteuerte Station f\u00fcr einen Geocache.&nbsp; So sollte zu einer bzw. zwei vordefinierten Zeiten pro Tag eine Aktion ausgel\u00f6st werden (z.B. ein Relais geschaltet werden), das ganze dazu a) stromsparend f\u00fcr &hellip; <a href=\"https:\/\/www.byter.de\/wordpress\/?page_id=87\">Weiterlesen <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":114,"parent":802,"menu_order":30,"comment_status":"open","ping_status":"open","template":"","meta":{"ngg_post_thumbnail":0},"_links":{"self":[{"href":"https:\/\/www.byter.de\/wordpress\/index.php?rest_route=\/wp\/v2\/pages\/87"}],"collection":[{"href":"https:\/\/www.byter.de\/wordpress\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.byter.de\/wordpress\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.byter.de\/wordpress\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.byter.de\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=87"}],"version-history":[{"count":24,"href":"https:\/\/www.byter.de\/wordpress\/index.php?rest_route=\/wp\/v2\/pages\/87\/revisions"}],"predecessor-version":[{"id":2505,"href":"https:\/\/www.byter.de\/wordpress\/index.php?rest_route=\/wp\/v2\/pages\/87\/revisions\/2505"}],"up":[{"embeddable":true,"href":"https:\/\/www.byter.de\/wordpress\/index.php?rest_route=\/wp\/v2\/pages\/802"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.byter.de\/wordpress\/index.php?rest_route=\/wp\/v2\/media\/114"}],"wp:attachment":[{"href":"https:\/\/www.byter.de\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=87"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}