Forum: Mikrocontroller und Digitale Elektronik Inkey bei Software-UART in Bascom/ATmega8


von jens (Gast)


Lesenswert?

Hallo!

Ich habe ein Navilock-GPS Modul (NL-504ETT), bei dem ich lediglich die 
Höhe benötige (ATmega8/Bascom).

Der unten genannte Code läuft nicht. Werden die GPS-Signale/NMEA-Daten 
auf den Hardware-UART-Eingang gesendet und mit Inkey() ausgwertet, so 
läuft alles...

Nehme ich für die eingehenden Signale den Software-UART, überliefert das 
"Inkey(#2)" nichts...

Ich weiß nicht mehr weiter, ich würde mich über Hilfestellungen freuen!


hier der Code:

1
$regfile = "m8def.dat"
2
$crystal = 7372800                                          ' 7,3728 Mhz Quarzoszillator an PB6 / XTAL 1
3
$hwstack = 32
4
$swstack = 32
5
$framesize = 32
6
7
Pwr_all Alias Portd.2
8
Pwr_gps Alias Portd.5
9
10
Dim Gpshoehe As String * 5
11
12
Dim Gps_zeichen As Byte
13
Dim Gpsdaten As String * 98
14
Dim Gps_header As String * 6
15
Dim Gps_anzahl As Byte
16
Dim Gps_teilstring(14) As String * 12
17
Dim Gps_hoehenteilstring(2) As String * 8
18
19
Pwr_all = 1                                                 ' bei Systemstart Peripherie auf ON
20
Pwr_gps = 1
21
22
Config Pwr_all = Output
23
Config Pwr_gps = Output
24
25
Config Com1 = 9600 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
26
Config Serialin = Buffered , Size = 128
27
Open "com1:" For Binary As #1
28
Open "comb.7:9600,8,n,1" For Input As #2
29
30
Enable Interrupts
31
32
Print #1 , "KaprigPRINT"
33
Waitms 1500
34
35
Do
36
37
38
   Wait 1
39
   Gps_zeichen = Inkey(#2)                                  ' Zeichen einlesen
40
41
42
   If Gps_zeichen = 36 Then Input #2 , Gpsdaten Noecho      ' ist "$"  vorhanden, dann Daten/SoftUART #2 einlesen >> Gpsdaten
43
44
45
46
      Gps_header = Mid(gpsdaten , 1 , 5)                    'ersten 5 Zeichen nach Gps_header einlesen
47
      If Gps_header = "GPGGA" Then                          'wenn GPGGA Befehlssatz, dann
48
49
50
         Gps_anzahl = Split(gpsdaten , Gps_teilstring(1) , ",")       'aus Gpsdaten in 14 Teilstrings/Arrays, getrennt durch ",", aufteilen
51
52
         Gpsdaten = ""
53
54
         Gps_anzahl = Split(gps_teilstring(10) , Gps_hoehenteilstring(1) , ".")       'Teilstring 10, Höhe xxx.xx, aufteilen in Wert vor dem "."
55
56
         Gpshoehe = Gps_hoehenteilstring(1)                 'gpshoehe = Höhe in Metern vor dem Komma über Meeresspiegel
57
58
         Print #1 , Gpshoehe
59
60
      End If
61
62
63
Loop
64
End

von Peter R. (peterfido)


Lesenswert?

Das Wait 1 ist für Software UART absolut fehl am Platz. Soft UART kennt 
meines Erachtens kein Echo. Die "Schnittstelle" wird ja auch nur für 
Input geöffnet.


Hier wie ich es anfangen würde (ungetestet):
1
$regfile = "m8def.dat"
2
$crystal = 7372800                                          ' 7,3728 Mhz Quarzoszillator an PB6 / XTAL 1
3
$hwstack = 32
4
$swstack = 32
5
$framesize = 32
6
7
Pwr_all Alias Portd.2
8
Pwr_gps Alias Portd.5
9
10
Dim Gpshoehe As String * 5
11
12
Dim Gps_zeichen As Byte
13
Dim Gpsdaten As String * 98
14
Dim Bgpsdaten(98) As Byte At Gpsdaten Overlay
15
Dim Gps_header As String * 6
16
Dim Gps_anzahl As Byte
17
Dim Gps_teilstring(14) As String * 12
18
Dim Gps_hoehenteilstring(2) As String * 8
19
Dim Anzahl As Byte
20
Dim Modus As Byte
21
22
Pwr_all = 1                                                 ' bei Systemstart Peripherie auf ON
23
Pwr_gps = 1
24
25
Config Pwr_all = Output
26
Config Pwr_gps = Output
27
28
Config Com1 = 9600 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
29
Config Serialin = Buffered , Size = 128
30
Open "com1:" For Binary As #1
31
Open "comb.7:9600,8,n,1" For Input As #2
32
33
Enable Interrupts
34
35
Print #1 , "KaprigPRINT"
36
Waitms 1500
37
38
Do
39
  Gosub Softempfang
40
41
42
Loop
43
End
44
45
Softempfang:
46
     Gps_zeichen = Inkey(#2)
47
     If Gps_zeichen > 0 Then
48
         If Modus = 0 Then
49
            If Gps_zeichen = 36 Then
50
               Anzahl = 0
51
               Modus = 1
52
            End If
53
         Else
54
            If Gps_zeichen = 13 Then                        'Falls am Ende der Daten ein chr13 gesendet wird, falls nicht löschen
55
               Gosub Auswerten                              'Falls am Ende der Daten ein chr13 gesendet wird, falls nicht löschen
56
            Else                                            'Falls am Ende der Daten ein chr13 gesendet wird, falls nicht löschen
57
               Incr Anzahl
58
               Bgpsdaten(anzahl) = Gps_zeichen
59
               If Anzahl = 98 Then
60
                  Gosub Auswerten
61
               End If
62
            End If                                          'Falls am Ende der Daten ein chr13 gesendet wird, falls nicht löschen
63
         End If
64
     End If
65
Return
66
67
68
69
Auswerten:
70
   Modus = 0
71
   Gps_header = Mid(gpsdaten , 1 , 5)                    'ersten 5 Zeichen nach Gps_header einlesen
72
   If Gps_header = "GPGGA" Then                          'wenn GPGGA Befehlssatz, dann
73
74
75
      Gps_anzahl = Split(gpsdaten , Gps_teilstring(1) , ",")       'aus Gpsdaten in 14 Teilstrings/Arrays, getrennt durch ",", aufteilen
76
77
      Gpsdaten = ""
78
79
      Gps_anzahl = Split(gps_teilstring(10) , Gps_hoehenteilstring(1) , ".")       'Teilstring 10, Höhe xxx.xx, aufteilen in Wert vor dem "."
80
81
      Gpshoehe = Gps_hoehenteilstring(1)                 'gpshoehe = Höhe in Metern vor dem Komma über Meeresspiegel
82
83
      Print #1 , Gpshoehe
84
   End If
85
Return


Du kannst aber auch Hardware nutzen. Falls von Com1 nicht gelesen wird, 
dort einfach den GPS anschließen.

von bezen b. (bezenbu)


Lesenswert?

@peterfido

ich suche schon ne ganze weile nach einem grundgerüst um mein projekt 
voranzutreiben....allerdings finde ich nicht viel....und bin auch recht 
unerfahren was die programmierung betrifft.

nach diesem thread zu urteilen, kennst du dich aus mit gps daten über 
uart einzulesen...

deswegen würde ich dich bitten mal nen blick auf meinen thread zu 
werfen:

Beitrag "Re: GPS Daten über RS232 in Atmega8 einlesen, Code gesucht!"


danke im vorraus


lg

von Peter R. (peterfido)


Lesenswert?

Ich habe keinerlei Erfahrungen mit GPS Auswertung. Wenn der uC ständig 
mit Daten beliefert wird, rate ich zu Hardware UART. Da geht auch bei 
umfangreichem Code nichts verloren. Es gibt auch Atmels mit mehreren 
Hardware UARTs, falls Du mehr als eine Schnittstelle benötigst.

Kommen immer gleich lange Strings rein, würde ich mit Overlay arbeiten, 
variieren diese z.B. durch mal 1 und dann wieder 2 stellige Zahlen, dann 
jeweils am Trennzeichen in ein Array schieben. Dieses würde ich dann 
schon beim Empfang erledigen.

von Weingut P. (weinbauer)


Lesenswert?

Auch einen schönen Trick gibt es mit den externen Interrupts.
Wenn ich die Softuart verwende lege ich den Pin auf einen
Interrupt-Pin und konfiguriere den auf falling.
Dann in der Interruptroutine frage ich per Inkey ab, so geht
mir kein Zeichen durch die Lappen.

Noch was ... du springst aus einer Subroutine in eine Subroutine.
Kann man machen wird aber bei größeren Programmen zum Einen irgendwann 
sehr unübersichtlich, zum Andern läuft irgendwann der Stack über -> 
Quelle für sehr dubiose Fehlfunktionen ...
Besser, du setzt ein Flag und springst dann bei gesetztem Flag aus der 
Mainloop in die Auswerte-Sub.

von Weingut P. (weinbauer)


Lesenswert?

Ach so, einen Tip hab ich noch ...
Die Abfrage ob ein Zeichen eingegangen ist kann man besser in der 
Mainloop vornehmen und erst bei Zeichenempfang in die Subroutine 
springen.
Der Vorteil ist, es spart Rechenzeit, weil das Stackschreiben etc. 
wegfällt wenn nix zu machen ist.
Bei dem kurzen Programm noch kein Problem, kann aber bei längeren 
timingkritischen Geschichten ordentlich was aus machen.

von Peter R. (peterfido)


Lesenswert?

Ja, das kann man machen. Die Register werden ja eh gesichert, da macht 
es dann nichts, wenn man weiter springt. Allerdings schalte ich am 
Anfang den INT aus und aktiviere ihn erst am Ende wieder.

Ich springe allerdings schon seit Jahren aus der Empfangsroutine in die 
Auswertung. Das klappt auch bei bei Soft-UART per INT, wenn man diesen 
dann auch solange deaktiviert. Das hat bei mir den Vorteil, dass sich 
während der Abarbeitung das Byte nicht ändert.

Bei kleineren Atmegas kann dann aber das RAM bei verschachtelten 
Sprüngen schonmal knapp werden, wie Du bereits erwähnt hast. Bei meinen 
Projekten hat dieser bisher immer gereicht. Wichtig ist, dass man immer 
sauber zurückspringt.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.