Bascom Windows Zeit via Uart an C übertragen

Kampfkartoffel

Neues Mitglied
10. März 2015
14
0
1
Sprachen
Hallo Allerseits

wie der Titel bereits andeutet, wollte ich mal fragen, ob es irgendwie möglich ist, die Zeit der Windows Uhr per UART (Rs232) an einen ATmega8 zu senden.

Damit will ich die Uhrzeit eines RTC's stellen lassen. Es muss also nur einmal kurz synchroniesiert werden und gut ist.
Gibt es irgendeine Möglichkeit, oder ein kleines Windows Programm, welches die Uhrzeit und evtl. auch das Datum via Uart sendet?

Der µC wird mit Bascom programmiert.
die Zeit synchro soll am Anfang des programmes passieren.
Ich hatte so daran gedacht, dass der µC auf eine Eingabe wartet und er dann nacheinander Stunde Minute Sekunde Tag Monat Jahr bekommt.

Vielen Dank für eure Hilfe :)

LG
 
Gibt es irgendeine Möglichkeit, oder ein kleines Windows Programm, welches die Uhrzeit und evtl. auch das Datum via Uart sendet?

Hallo,

ich weiß nicht, ob es da ein fertiges Programm gibt, welches du verwenden könntest. Eventuell könnte ich dir ein Programm erstellen, das die gewünschten Daten an eine COM-Schnittstelle sendet, ich bräuchte dafür ein bisschen Zeit (dieses Wochenende geht es nicht und eine kleine Spende für das Forum bzw. die Kaffeekasse wäre nett und motivierend :)). Falls hier keiner Ideen hat und du sonst keine Lösung findest, kannst du dich ja mal bei mir melden.

Dirk :ciao:
 
Hmm...

hat das irgendwas hiermit zu tun?

Je nachdem wie der AVR die Zeit in Variablen verwaltet, würde ich das in etwa so angehen:
Der AVR fordert(!) mit entsprechenden Kommandobytes die jeweiligen Variablen über den UART an (sinnigerweise unter Zuhilfenahme eines Software-Handshake-Commandos zu Deinem Windows Programm)
Das Windows-Programm würde ich in Visual Basic aufziehen - serielle Schnittstelle öffnen und auf das Handshake-Commando warten/antworten. Dann auf die Zeitanforderungskommandos warten und die entsprechenden Variablen senden. (Dafür hat die Schnittstelle bestimmt irgendso'n "onByteRecieved"-event oder so). Wie man in Visual Basic an die Zeit kommt, müßte ich auch erstmal gurgeln - da gibbet aber sicher irgendso'n "dateTime.now"-Objekt-Dingens, oder man braucht 'ne Instanz davon oder sowas...
(VorDemThomasInDeckungGeh...:vroam:)
 
Hi,

Je nachdem wie der AVR die Zeit in Variablen verwaltet, würde ich das in etwa so angehen:
Der AVR fordert(!) mit entsprechenden Kommandobytes die jeweiligen Variablen über den UART an (sinnigerweise unter Zuhilfenahme eines Software-Handshake-Commandos zu Deinem Windows Programm)
Das Windows-Programm würde ich in Visual Basic aufziehen - serielle Schnittstelle öffnen und auf das Handshake-Commando warten/antworten. Dann auf die Zeitanforderungskommandos warten und die entsprechenden Variablen senden. (Dafür hat die Schnittstelle bestimmt irgendso'n "onByteRecieved"-event oder so). Wie man in Visual Basic an die Zeit kommt, müßte ich auch erstmal gurgeln - da gibbet aber sicher irgendso'n "dateTime.now"-Objekt-Dingens, oder man braucht 'ne Instanz davon oder sowas...
(VorDemThomasInDeckungGeh...:vroam:)

sowas in der Art schwebte mir auch vor. Ich hätte allerdings nach dem Kommandobyte vom AVR zum PC den gesamten Zeitstring in eins vom PC zum AVR geschaufelt. Mit der PC-Programmierung steh ich allerdings auf recht niedrigem Level :rolleyes:

Gruß
Dino
 
...Ich hätte allerdings nach dem Kommandobyte vom AVR zum PC den gesamten Zeitstring in eins vom PC zum AVR geschaufelt...
Je nachdem, wie das im AVR letztendlich benötigt wird. Wenn der das alles eh in einzelnen Variablen (womöglich sogar einzelnen Digits) verwendet, kann der PC das doch auch gleich zerpflücken. Oder meinst Du, daß die einzelnen Werte dann zu inkohärent sind?
 
@LotaDac
Ja das Hat was mit dem Projekt der HDD Uhr zu tun.
Es ist eigentlich nur so gedacht, dass ich einmalig am Anfang des Programms auf die Uhrzeit warte, wenn nach sagen wir 10sek (via Timer) kein Signal angekommen ist, dann fährt das Programm ganz normal fort und startet die Hauptschleife.
Es geht nur darum, dass die Echtzeituhr, die richtige Uhrzeit und Datum bekommt damit man sich das umständliche Stellen via Taster ersparen kann.

Also hauptsächlich frag ich mich hier auch wie es von der Windows Seite aus geht. Also aka Vb script oder so :)

LG
 
Dann liegt die Entscheidung bei Dir. Entweder Du kaufst das bei Dirk gegen 'ne Premium-Mitgliedschaft (oder so), oder Du versuchst Dich selbst an dem Vorschlag, und lernst was dabei. Suchstichworte wären dann serialport, comport und datetime.now (bei dotnet-Sprachen)

Kannst natürlich auch bei Thomas anfragen, aber ich denke es dauert länger das Übertragungsprotokoll abzusprechen, als das selbst durchzuziehen...
 
Erstmal an Thomas: danke für das Angebot, aber ich das schon alles selber machen :)

Hab jezt mal ein wenig selbst recherchiert.
Bin dabei auf die Windows Powershell gestoßen.
Die kann rein theoretisch alles was ich brauche:
Zeit ausgeben mit Get-Datetime

Jedoch will das nicht so wie ich will :D
Hier mein Powershell script.
Code:
$port= new-Object System.IO.Ports.SerialPort COM4,9600,None,8,one
$port.open() #open serial connection
$port.WriteLine("Hello world") 
$port.Close()
Wenn ich dieses ausführe kommt davon leider nichts beim µC an.

Hier wird (als reines Testbeispiel) ein Input gemacht und dieser dann am LCD ausgegeben.
Mit Putty alles kein Problem.
Baudrate und so weiter stimme eigentlich alle :)

Doch hier trotzdem nochmal das Bascom TestProgramm:


CodeBox BascomAVR
$regfile "m8adef.dat"                                       'ATmega8a auswählen
$framesize = 32
$swstack = 32
$hwstack = 64
$crystal = 3686400                                          'Prozessor auf 3,6 MHz setzen
$baud = 9600

Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , Db7 = Portd.7 , E = Portd.3 , Rs = Portd.2
'LCD pins Konfigurieren
Config Lcd = 16 * 2                                         'LCD Größe
Initlcd
Cursor Off                                                  'Schreibmarke nicht anzeigen
Cls                                                         'LCD Löschen
Dim H As String * 16


Do
Input "Test: " , H
Cls
Locate 1 , 1
Lcd H
Loop
End
 
Du konfigurierst im AVR nirgends eine serielle Schnittstelle. Durch "Input" verwendet BASCOM irgendwelche Voreinstellungen die wir nicht kennen.

Hast Du schon einen Blick in die Hilfe zu "Input" geworfen? Meiner Meinung nach schreibt "Input" so lange eintrudelnde Bytes (meinetwegen auch Characters - als Assemblerer sieht man da keinen Unterschied)in den Puffer (String), bis ein festgelegtes "Ende"-Byte eintrifft. Bis dahin steht Dein Programm quasi. Komm kein "Ende", ...
Dieses Ende-Zeichen kannst Du AFAIK selbst festlegen, natürlich gibts auch da sicher irgend'n default...
PC-seitig muß das natürlich derselbe sein.

Du könntest ja wenn Du den Hardware-UART verwendest ja zusätzlich den UART-Recieved-IRQ einsetzen, und damit signalisieren, ob überhaupt irgendwelche Bytes am AVR ankommen. Der triggert dann aber bei jedem Byte.
 
Das mit dem Endbyte dürfte die lösung sein.

Doch wie stell ich das an?

Als uar5 brücke verwende ich das mysmartusb mk2
Mir is5 aufgefallen, dass jedes mal wenn ich daten übertrage eine led blinkt. Das ist auch der fall, wenn ich mein ps script ausführe.
Also muss ich quasi nur noch wissen, wie ich in powershell "enter" drücke.
Mit putty muss ich ja auch mit enter bestätigen. Die frage ist nur, was putty sendet, wenn man enter drückt

Lg
 
Das mit dem Endbyte dürfte die lösung sein.

Doch wie stell ich das an?
Indem Du einfach das entsprechende Zeichen als Bestandteil des Stringes mitsenden läßt. Die ganzen Steuerzeichen liegen in der ASCII-Tabelle unter 0x20 (also die ersten 32 dezimal), CR wäre zB 0x0D, LF 0x0A.

Das Visual Studio kennt diese als Konstanten (ControlChars.Cr, ControlChars.Lf, ControlChars.CrLf oder so).
Das sind dann konstante Strings, die Du mit deinem String konkatenieren kannst...
(wie das konkret in Deiner Umgebung ist, weiß ich nicht...)


OT: ischarwaiting liest doch auch nur das USART n recieve complete flag (RXCn), oder?
 
Dazu brauchts keine powershell ;)
Nur so zur Info.

Der Befehl Time gibt das Datum aus und lässt es ändern (letzteres wäre hier blöd).
Mit Argument /T wird es nur ausgegeben. Und diese Ausgabe lässt sich umleiten ;)

Code:
TIME /T >> COM4

Selbes funktioniert mit date statt time genau so.

Man könnte jetzt auch noch Strings mit übergeben um definiertes Start-Ende zu haben.
Das könnte man dann alles zusammen in eine .bat Datei packen.

Beispiel:
Code:
ECHO Start >> COM4
DATE /T >> COM4
TIME /T >> COM4
ECHO Ende >> COM4

Wenn das ganze fortlaufend sein soll würde nur noch ein Label und ein GoTo fehlen. Damit er nicht konstant sendet könnte man beispielsweise mit einem Ping Localhost etwas verzögern.
 
Hallo,

die Variante von TommyB ist gut, aber Verbesserungen sind möglich ...

TIME /T gibt nur Stunde und Minute aus, TIME ohne /T aber auch die Sekunden und noch was danach, sieht aus wie Hundertstel, stimmt aber nicht genau wg. DOS-Timern und es wird auf eine Eingabe gewartet.

Die Lösung:

Eine Datei erzeugen, die nur ein "ENTER" (0D0A hex) enthält und diese per Eingabeumleitung an das TIME-Kommando schicken.

Datei erzeugen mit "copy con enter"
copy - sollte klar sein ...
con - Console
enter - Dateiname

Nach dieser Eingabe steht der Cusor am Anfang der nächsten Zeile

"ENTER" drücken

Cursor steht noch eine Zeile weiter unten

"STRG" drücken, festhalten und "Z" drücken

dann erscheint "1 Datei(en) kopiert."

... Tasten jetzt wieder loslassen ;-)

Rest siehe unten ...


Code:
C:\tmp>time
Aktuelle Zeit: 19:12:55,23
Geben Sie die neue Zeit ein:

C:\tmp>time /T
19:13

C:\tmp>copy con enter

^Z
        1 Datei(en) kopiert.

C:\tmp>dir
 Datenträger in Laufwerk C: ist SystemSATA
 Volumeseriennummer: 2830-5C15

 Verzeichnis von C:\tmp

31.05.2015  19:13    <DIR>          .
31.05.2015  19:13    <DIR>          ..
31.05.2015  19:13                 2 enter
               1 Datei(en)              2 Bytes
               2 Verzeichnis(se), 148.277.325.824 Bytes frei

C:\tmp>time <enter
Aktuelle Zeit: 19:13:29,66
Geben Sie die neue Zeit ein:

C:\tmp>time <enter >com2

C:\tmp>
 
Gute Ergänzung, war ich jetzt so nicht drauf gekommen.
Höhere "Auflösung", dafür aber mehr "Overhead", also nutzlose Daten. Muss jeder selber wissen was wichtiger ist. Ich persönlich würd ja eher in Richtung DCF77 schielen ^^
 
So Leute ich habs jezt geschafft :)
Habs mit Powershell realisiert
für alle die Interresiert sind, hier der Code:

Code:
$ErrorActionPreference = "SilentlyContinue" #Fehlermeldungen auschalten

$port= new-Object System.IO.Ports.SerialPort COM17,9600,None,8,one #Comport definieren
 
$port.open() #Serielle verbindung starten
"Auf Mikrocontroller warten..."

Do{ #Mit µC synchronisieren, Solange lesen, bis Zeichen von µC bekommen
$test = $port.ReadLine()
}
Until ($test=1)
cls
$port.write("1")
"Signal erhalten!"
"beginne übertragung der Uhrzeit..."
""

Start-Sleep -Milliseconds 100 #100ms warten
#$port.Write() #Testzeile schreiben
$port.Write("12");
$port.Write("`r")
$port.close()
Start-Sleep -Milliseconds 100

"Zeit erfolgreich übertragen!" #Meldung ausgeben, dass die Zeit übertragen wurde
" " #Leerzeile
Write-Host "Beliebiege Taste zum Beenden drücken ..." 
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") #Wenn eine beliebige Taste gedrückt wird, wird das Programm beendet

Und hier nochmal der passende BASCOM code



CodeBox BascomAVR
$regfile "m8adef.dat"                                       'ATmega8a auswählen
$framesize = 32
$swstack = 32
$hwstack = 64
$crystal = 3686400                                          'Prozessor auf 3,6864 MHz setzen
$baud = 9600                                                'Datenrate Setzen

Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , Db7 = Portd.7 , E = Portd.3 , Rs = Portd.2
'LCD pins Konfigurieren
Config Lcd = 16 * 2                                         'LCD Größe
Initlcd                                                     'LCD Initalisieren
Cursor Off                                                  'Schreibmarke nicht anzeigen
Cls                                                         'LCD Löschen

'Ports Konfigurieren/Aliase/Pullups

Config Portd = Output                                       'LCD Pins sind output

Config Portc.0 = Input
Squarein Alias Pinc.0
Portc.0 = 0

Config Portc.1 = Output
Led0 Alias Portc.1

'Variablen Deklarieren

Dim X As Word

Dim Yy As Word
Dim Mm As Byte
Dim Dd As Byte
Dim H As Byte
Dim M As Word
Dim S As Word
Dim Weekday As Byte


'Konfiguration I²C

Config Sda = Portc.4                                        ' I2C Bus konfigurieren
Config Scl = Portc.5
Const Ds1307w = &HD0                                        ' Addresse der Ds1307 Uhr
Const Ds1307r = &HD1

Config Clock = User                                         ' Interne Time/Date Routinen für Bascom konfigurieren
Config Date = Dmy , Separator = .

' Stellen der Uhr, muss nur einmal ausgeführt werden
'Time$ = "11:55:00"
'Date$ = "24.04.15"
Gosub Squareout                                             'Rechtecksignal des DS1307 einschalten


Config Timer2 = Timer , Prescale = 1024
On Timer2 Isr_timer2
Enable Interrupts
Enable Timer2


Do
Print "1"
Locate 1 , 1
Lcd "Wait for PC..."
Loop Until Inkey() <> 0
Cls

Input "Jahr: " , _year
Disable Timer2                                              'Timeout Timer Abschalten
Input "Monat: " , _month
Input "Tag: " , _day

Input "Stunde: " , _hour
Input "Minute: " , _min
Input "Sekunde: " , _sec

Gosub Setdate
Gosub Settime
Led0 = 1
Waitms 2000
Led0 = 0
Uhrzeitabbruch:





' Main Loop
Do
Locate 2 , 1 : Lcd Date$                                    'Datum ausgeben
Locate 1 , 1 : Lcd Time$                                    'Zeit ausgeben


If Squarein = 1 Then Gosub Getdatetime
'End If


Loop

' Unterprogramme für die Bascom Date/Time-Funktionen
Getdatetime:
  I2cstart
  I2cwbyte Ds1307w
  I2cwbyte 0
  I2cstart
  I2cwbyte Ds1307r
  I2crbyte _sec , Ack
  I2crbyte _min , Ack
  I2crbyte _hour , Ack
  I2crbyte Weekday , Ack
  I2crbyte _day , Ack
  I2crbyte _month , Ack
  I2crbyte _year , Nack
  I2cstop
  _sec = Makedec(_sec) : _min = Makedec(_min) : _hour = Makedec(_hour)
  _day = Makedec(_day) : _month = Makedec(_month) : _year = Makedec(_year)
Return

Setdate:
  _day = Makebcd(_day) : _month = Makebcd(_month) : _year = Makebcd(_year)
  I2cstart
  I2cwbyte Ds1307w
  I2cwbyte 4
  I2cwbyte _day
  I2cwbyte _month
  I2cwbyte _year
  I2cstop
Return

Settime:
  _sec = Makebcd(_sec) : _min = Makebcd(_min) : _hour = Makebcd(_hour)
  I2cstart
  I2cwbyte Ds1307w
  I2cwbyte 0
  I2cwbyte _sec
  I2cwbyte _min
  I2cwbyte _hour
  I2cstop
Return

Squareout:
I2cstart
I2cwbyte Ds1307w
I2cwbyte 7
I2cwbyte &B00010000
I2cstop
Return

End

Isr_timer2:
Toggle Led0
X = X + 1
If X = 150 Then                                             'Ca 10 Sekunden
   Led0 = 0
   Disable Timer2
   Goto Uhrzeitabbruch
End If
Return
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)