Beste software Guru's,

Ik ben al een tijdje bezig om bovenstaande te verwezelijken.

Aan de Nano heb ik een 2 x 16 Display en ik probeer de bovenste regel te veranderen, ik zie alles naar blank

gaan maar mijn tekst komt niet binnen

Ik kan niet Niet Niet in C programmeren, wel ervaring met PIC's

en Basic. Ik wil perse over de USB aansluiting werken.

Ik werk met de Free Bascom version en kan niet met mijn vragen bij het

Forum terecht.

Hier is de Code gevonden op het forum van Wilfred, ook een Nederlander

of Luxemburger aan de vlag te zien.

Wie kan me helpen om dit aan de gang te krijgen.

very simple serial communication routine and automatic uploa

Post new topic Reply to topic www.mcselec.com Forum Index -> Share your working BASCOM-AVR code here
View previous topic :: View next topic
Author Message
Wilfred

Bascom Member

Joined: 15 Jul 2010
Posts: 40

netherlands.gif
PostPosted: Sun Oct 29, 2017 11:51 pm Post subject: very simple serial communication routine and automatic uploa Reply with quote
Hi guys,
here my go to serial communication routine.
and automatic upload of your code when BASCOM bootloader is installed.

When I began BASCOM, this was a difficult thing for me. So to help out, copy this and try it out Smile

Code:

'********************************************************
' reading the serial port and auto upload of your code
'********************************************************
'
' An Arduino NANO with BASCOM bootloader is used in this case.
'
' select MCS bootloader in Options, programmer.
'
' in MCS bootloader tab serial, select 57600 baud as the speed and the correct comport.
' in MCS bootloader tab MCS loader tab, select "soft" and enter {27} in the inputbox, indeed with the curly brackets.
' Tick program after compile, auto flash, and upload code and data.
'
' if you need a good terminal program you could look here http://www.der-hammer.info/terminal/
' I have nothing to do with the program(mer), I just like the program a lot and it's free Smile
' if you want to know what the connected com ports are, click on the R button next to the ports
'
$regfile = "m328pdef.dat" ' specify the used micro
$crystal = 16000000 ' used crystal frequency
$baud = 57600 ' use baud rate
$hwstack = 40 ' default use 32 for the hardware stack
$swstack = 40 ' default use 10 for the SW stack
$framesize = 40
Config Submode = New

On Urxc Rxcom1_isr
Enable Urxc

Dim Comchar1 As Byte ' data on com1
Dim Rxdata1$ As String * 25 ' this string gets filled with data
Dim Rxcom1 As Bit ' there is some data in rxdata1$ shal we do something with it?

Enable Interrupts
Do

If Rxcom1 = 1 Then 'there was data on the serial port now lets do something with it
Reset Rxcom1 ' first we reset the "there was data" bit for a new go
If Instr(rxdata1$ , "Hello") > 0 Then ' look in the string for a "code" word
Print Left(rxdata1$ , 5) ; " BASCOM" ' do something (we don't want the carriage return)
'Print Rxdata1$ ; " BASCOM" ' you see what happens if you uncomment this line
End If
If Instr(rxdata1$ , "Bascom") > 0 Then ' another "code" word
Print "HELLO " ; Rxdata1$
' or do something else ofcourse
End If
Rxdata1$ = "" ' clear the data string
End If

'the rest of your program goes here

Loop

Rxcom1_isr: 'usb comport to PC
Comchar1 = Inkey()
Rxdata1$ = Rxdata1$ + Chr(comchar1)
If Comchar1 = 27 Then Goto &H3C00 ' jump to boot vector ofcourse you loaded the BASCOM bootloader first.
If Comchar1 = 13 Then ' detect end of line
Set Rxcom1 ' there is some new data received
End If
Return

Aan de Nano heb ik een 2 x 16 Display en ik probeer de bovenste regel te veranderen, ik zie alles naar blank

gaan maar mijn tekst komt niet binnen

Op 23 februari 2019 12:02:39 schreef Waters:

Aan de Nano heb ik een 2 x 16 Display en ik probeer de bovenste regel te veranderen, ik zie alles naar blank

gaan maar mijn tekst komt niet binnen

De eerste van belang zijnde bovenste regel is:

$regfile = "m328pdef.dat" ' specify the used micro 

Maar die zul je vast niet bedoelen. Dus welke regel heb je het dan wel over, en wat stond daar origineel, en waarin heb je het veranderd?

Wat ik mis is dat je je 2x16 LCD initialiseert.

Ik heb even een stuk broncode voor je geschreven, wat je een beetje op weg kan helpen. Ik heb zoveel mogelijk commentaar erbij gevoegd, zodat je kunt zien wat een stukje broncode doet.


$regfile "m328def.dat"
$crystal = 16000000
$hwstack = 40
$swstack = 16
$framesize = 32
$baud = 9600                                                'LET OP : Baud-rate aanpassen naar gewense snelheid
'Stel je USB COM-poort in, op 9600-8-N-1

'VARS
'Hier je variabelen
 Dim Uart_in As Byte , Uart_char As String * 1 , Uart_str As String * 25 , Uart_flag As Boolean
 Dim Sec As Byte , Seconden As Byte , Minuten As Byte , Uren As Byte , Tijd_str As String * 8

'CONSTANTS
'Hier je constanten
 Const Timer1_preload = 3036                                '1 seconde timer

'ALIASES
'Hier je aliasses


'FUNCS
'Hier je functies
 Declare Sub Initialize()                                   'Basis instellingen


'** PROGRAMMA START **
Call Initialize()

Do
    If Sec > 0 Then                                         '1 seconde voorbij ?
      'Ja
      'LET OP : Je komt maar 1x per seconde in dit gedeelte
       Seconden = Seconden + Sec                            'Tijd bijhouden : seconden
       Sec = 0
       If Seconden > 59 Then                                'Meer dan 59 seconden voorbij ?
          Incr Minuten                                      'Verhoog aantal minuten met 1
          Seconden = Seconden - 60                          'Veilige reset voor seconden
       End If
       If Minuten > 59 Then                                 'Meer dan 59 minuten voorbij ?
          Incr Uren                                         'Verhoog aantal uren met 1
          Minuten = 0                                       'Reset aantal minuten
       End If
       If Uren > 23 Then                                    'Meer dan 24 uur voorbij
          Uren = 0                                          'Reset aantal uren
       End If

      'Tijd naar 2x16 LCD, op eerste regel
       Tijd_str = ""                                        'Legen Tijdstring
      'Text : Uren in 2 cijfers
       If Uren < 10 Then Tijd_str = "0"
       Tijd_str = Tijd_str + Str(uren) + ":"                'xx:
      'Text : Minuten in 2 cijfers erbij
       If Minuten < 10 Then Tijd_str = Tijd_str + "0"
       Tijd_str = Tijd_str + Str(minuten) + ":"             'xx:xx:
      'Text : Seconden in 2 cijfers erbij
       If Seconden < 10 Then Tijd_str = Tijd_str + "0"
       Tijd_str = Tijd_str + Str(seconden)                  'xx:xx:xx
       Locate 1 , 1                                         'Ga naar 1e regel, 1e positie (links)
       Lcd Tijd_str                                         'Update LCD met nieuwe tijd

    Else
      'Nee, doe allerlei andere dingen
      'LET OP : Je komt meerdere keren per seconde in dit gedeelte

      'Controleer of UART-data is ontvangen
       If Uart_flag = 1 Then                                'Is er UART-data ?
         'Ja
         'Ga aan de slag met jouw programmeercode, bijvoorbeeld :

          Cls                                               'Leeg scherm 2x16 LCD
          Locate 2 , 1                                      'Ga naar 2e regel, 1e positie
          Lcd "Jouw text"                                   'Text naar display

         'Legen buffers
          Uart_char = ""                                    'Legen character
          Uart_str = ""                                     'Legen text-string
          Uart_flag = 0                                     'Commando uitgevoerd
       Else
         'Nee, geen UART-data, dus doe iets anders
       End If
    End If
Loop

'** PROGRAMMA EINDE **

'FUNCTIES
Sub Initialize()                                            'Instellingen voor de microcontroller
   'LET OP : Aanpassen naar eigen instellingen
    Ddrd.7 = 1                                              'OUTPUT : LCD Rs
    Ddrb.0 = 1                                              'OUTPUT : LCD E
    Ddrb.1 = 1                                              'OUTPUT : LCD DB.4
    Ddrb.2 = 1                                              'OUTPUT : LCD DB.5
    Ddrb.3 = 1                                              'OUTPUT : LCD DB.6
    Ddrb.4 = 1                                              'OUTPUT : LCD DB.7 

    Sec = 0
    Seconden = 0
    Minuten = 0
    Uren = 0
    Tijd_str = ""

    Uart_in = 0
    Uart_char = ""
    Uart_str = ""
    Uart_flag = 0

   'LCD
   'Zet hier de correcte pinpoorten voor je 2x16 LCD !!
    Config Lcdpin = Pin , Db4 = Portb.1 , Db5 = Portb.2 , Db6 = Portb.3 , Db7 = Portb.4 , E = Portb.0 , Rs = Portd.7
    Config Lcd = 16 * 2
    Cursor Off

   'UART
    On Urxc Onrxd
    Enable Urxc
    Uart_in = 0
    Uart_str = ""

   'Indien je nog iets met ADC wil doen, dan :
   'ADC
    Config Adc = Single , Prescaler = Auto , Reference = Internal       '2.56V
    Start Adc

   'Timer1 instellingen
    Config Timer1 = Timer , Prescale = 256                  'Zorgt voor 1 seconde, samen met Timer1_Preload
    Enable Timer1
    Timer1 = Timer1_preload
    On Timer1 Isr_timer1

    Enable Interrupts                                       'Alle ingestelde interrupts activeren

End Sub

'INTERUPTS
Isr_timer1:                                                 'Tijd bijhouden
   Timer1 = Timer1_preload                                  'Zet Timer1 terug : aftellen duurt 1 seconde
   Incr Sec                                                 'Ophogen Sec (Er is een seconde voorbij gegaan)
Return

Onrxd:
   Uart_in = Udr                                            'Er is iets ontvangen in de RX-buffer
   Uart_char = Chr(uart_in)                                 'Conversie van byte naar leesbaar character

   If Uart_in = 13 Then                                     'End of Line karakter ontvangen (Enter)
     'Programmeercode voor wat er moet gebeuren
      Uart_flag = 1                                         'Flag : Text-einde ontvangen
      Print "Received"                                      'Bevestiging over USB : data ontvangen
   Else
      Uart_str = Uart_str + Uart_char                       'Vul de text-string
   End If

Return

Extra info
Dit is eigenlijk hoe ik programmeer met Bascom.
Het vormt de kale basis van een project, inclusief een "Initialize"-functie. Deze wordt eenmalig aangeroepen tijdens het opstarten. Het zorgt voor de basis-instellingen van de micro-controller.

Het gedeelte onderaan met "INTERUPTS" verloopt op de achtergrond van de micro-controller. Je hoeft bijvoorbeeld alleen maar een "flag" te zetten, om aan te geven dat er iets is gebeurd.
In de Do .. loop, hoef je dan alleen maar te kijken of deze "flag" is gezet, zodat je weet dat je iets moet doen. In dit geval gaat het bijvoorbeeld om :

1) "sec"-flag
Dit laat zien dat er een seconde voorbij is. Je kunt dan het scherm updaten, zodat je LCD keurig de tijd weer geeft.

2) "Uart_flag"
Geeft aan dat er data is ontvangen via UART / USB en afgesloten met een ENTER.

Tijdens het programmeren vul ik telkens bij met extra functies. Het handige daarvan is dat ze dan makkelijker te volgen zijn, dan wanneer je het allemaal in het hoofdprogramma (Do .. Loop) zet. Indien het niet werkt zoals je zou verwachten, kun je sneller je fouten isoleren / opsporen.

Ik hoop dat je met bovenstaande een eindje op weg komt.

P.S. Code is niet geverifieerd op fouten. Maar als ze er in zitten, zijn het minimale foutjes (typefoutjes o.i.d.).

-=[ EDIT 27 feb ]=-
Inmiddels zijn we een aantal dagen verder, maar mis een reactie van je. Ik ben namelijk best benieuwd of je verder bent gekomen met de code.

Dank voor de opzet zodat ik verder kan borduren.

Ik kan nu een ascii text sturen en weer terug zenden.

Nu moet ik weer verder studeren, omdat er nog door mij

onbegrepen dingen zijn.

Ook mijn display werkt nu.

Volgende probleem waar ik niet uitkom,

Ik wil de serieele interrupt uitspringen naar de top
van mijn programma.
Ik heb dit met Goto Main gedaan maar het lijkt erop dat ik weer in de oude loop
terecht kom.
Ik heb met NOSAVE geprobeerd maar helaas.

Heeft iemand een voorbeeld hiervan ?

Je hebt toch hopelijk niet "GoTo Main" in de interrupt-routine staan? Als je dat doet gaat er van alles fout (je stack loopt vol)en crasht je programma. Het kan dan gebeuren dat je programma weer 'bovenaan' begint...
Wil je echt uit de interrupt routine springen, dan moet je dat doen met 'Return'. Nu kom je terug op de plek waar je programma was toen de interrupt kwam.

Beste Soldeersmurf en anderen die met Bascom werken,

Ik wil echt niet naar de routine waar ik in was terugspringen

vanuit de interrupt.

Ik wil naar Main "Fixed Label" terug vanuit het interrupt met de nieuwe

waarde die in de RS232 serieel is binnengekomen.

In principe wil ik alleen de seriele interrupt, de rest staat uit

Main valideert deze nieuwe waarde, vandaar.

Misschien kun je nog eens helpen, bij voorbaat dank

Je kunt niet zomaar naar een label buiten de interrupt springen (ook niet main), als je dat doet crasht de stack vroeger of later.
Je moet gewoon netjes een return from interrupt doen... (dan wordt de stack bijgewerkt)

Op 5 mei 2019 14:49:39 schreef Waters:
Ik wil echt niet naar de routine waar ik in was terugspringen vanuit de interrupt.

Tuurlijk wil je dat wel. Je bent met iets bezig en op een willekeurig moment komt er een interrupt tussendoor. Als die klaar is wil je toch verdergaan met wat je bezig was? Of is dat ineens niet meer belangrijk? Het is al gezegd, maar programmeer zoals het bedoeld is, bedenk niet spontaan iets nieuws want zo speciaal is het echt niet wat je doet. Dat is al duizenden keer eerder gedaan.

Nog een verzoekje: typ aub niet overal een [enter] tussendoor. Typ gewoon verder, de website breekt de regels wel voor je af. Al die lege regels zijn super onleesbaar. Een gebruiker die dat doet is al erg genoeg :-) (r...7)

Bij Proton Basic "Picbasic" kon ik wel terugspringen uit de interrupt naar het begin van mijn programma. De RS232 interrupt gebruik ik om een nieuwe waarde op te halen die ik in Main gebruik.
Kan ik op een of andere manier werken met NOSAVE ?
Maar hoe dan !
Heeft iemand een voorbeeld ?

NoSave heeft geen invloed op de program counter, die wordt altijd gesaved.
Je kunt de stackpointer manipuleren met push en pop, maar met moderne processoren is dat niet nodig en 'bad practice'...
(er zijn genoeg andere manieren om je doel te bereiken)

Je kunt bijvoorbeeld een flag zetten in de interrupt als er iets gewijzigd is, en dan gewoon de interrupt doorlopen.
Na terugkeer naar main() kun je door de flag zien dat er iets gewijzigd is. Als dat is afgehandeld, reset je de flag weer.