View previous topic :: View next topic |
Author |
Message |
Paulvk
Joined: 28 Jul 2006 Posts: 1257 Location: SYDNEY
|
Posted: Fri Mar 06, 2020 9:50 am Post subject: usung goto in bytematch sub |
|
|
I tried a number of ways and this is working but is there a problem in doing this
jumping to other code?
It was the only way I could get the M644p to react immediately to a page change on the Nextion
putting code in the sub causes problems even lockups.
Note its triggered by a carage return
Regards Paul
Code: |
Serial0charmatch:
Goto Screenchng
Return
|
(BASCOM-AVR version : 2.0.8.2 ) |
|
Back to top |
|
|
hgrueneis
Joined: 04 Apr 2009 Posts: 902 Location: A-4786 Brunnenthal
|
Posted: Fri Mar 06, 2020 2:39 pm Post subject: |
|
|
Paul,
yes there is the problem of leaving the return address on the stack.
Depending on how many subs are stacked and led to this one, it gives the processor the wrong return, which may turn out fatal.
It also in my opinion will not continue the match. It will never return to the correct memory address.
Instead of 'goto', can't you use 'call' or 'gosub'?
Best regards
Hubert |
|
Back to top |
|
|
Paulvk
Joined: 28 Jul 2006 Posts: 1257 Location: SYDNEY
|
Posted: Sat Mar 07, 2020 3:04 am Post subject: |
|
|
Using call/gosub does not work reliably and even locks up.
I can not just set a variable and wait for the main loop as I want it to respond immediately.
But I put Serial0charmatch: in the main loop and it works.
Now I am even more confused as there is no return and it compiles and works!
Regards Paul
Code: |
'Interface between MPP solar products and PC terminal
$regfile = "m644pdef.dat" ' specify the used micro
$crystal = 8000000 ' used crystal frequency
'$baud = 9600 ' use baud rate
$hwstack = 100
$swstack = 100
$framesize = 100
Dim Crc_16 As String * 2
Dim Work2 As Word At Crc_16 Overlay
Dim Work (35) As String * 40
Dim Thecrc As Word
Dim Rs232 As Byte
Dim Uart_command_in As String * 50
Dim Uart_command As String * 254
Dim Aruart_command (253) As Byte At Uart_command Overlay
Dim Send_command As String * 50
Dim Send_bytes (49) As Byte At Send_command Overlay
Dim Crcstr As String * 2
Dim Crcwrd As Word At Crcstr Overlay
Dim Z As Byte
Dim Task As Byte
Dim Temp1 As String * 20
Dim Temp2 As Word
Dim V As Byte
Dim Crc As Byte
Declare Sub Chopup
Declare Sub Find_command
Declare Sub Cal_crc16
Declare Sub Nextion
$lib "glcdKS108.lbx"
'Config Graphlcd = 240x64 , Dataport = Portc , Controlport = Porta , Ce = 5 , Cd = 6 , Wr = 3 , Rd = 4 , Reset = 7 , Fs = 0 , Mode = 6
Config Graphlcd = 128 * 64sed , Dataport = Porta , Controlport = Portc , Ce = 2 , Ce2 = 3 , Cd = 7 , Rd = 6 , Reset = 4 , Enable = 5
Setfont Font8x8
Config Com1 = 9600 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
Config Com2 = 2400 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
Config Serialin0 = Buffered , Size = 20 , Bytematch = 13
Config Serialin1 = Buffered , Size = 150
Enable Interrupts
Open "com2:" For Binary As # 2
Open "com1:" For Binary As # 1
V = 0
Temp1 = "Booting"
'Print #2 , "get page"
'Call Nextion
' Wait 1
'Call Get_chr
Print # 1 , "status.gridvolts.txt=" ; Chr(34) ; Temp1 ; Chr(34);
Call Nextion
'Wait 2
'Print #2 , "status.gridvolts.txt=" + Chr(34) + Work(1) + Chr(34);
'Call Nextion
Cls
Setfont Font8x8
Lcdat 1 , 1 , "BOOTING"
Do
'Task = 0
' Select Case Uart_command_in
Select Case V
Case 0 'get the state of inverter
Uart_command_in = "QPIGS"
Task = 1
V = 1
Case 1
Uart_command_in = "QMOD" 'get mode inverter is in
Task = 3
V = 2
Case 2
Uart_command_in = "QPGS0" 'get inverter one state
Task = 4
V = 3
Case 3
Uart_command_in = "QPGS1" 'get inverter two state
Task = 4
V = 0
End Select
'Temp1 = "dog"
'Print "data" ; Temp1
'Wait 4
' End Select
'Uart_command_in = "QPIGS"
Send_command = Uart_command_in
Uart_command_in = ""
Z = Len(send_command )
Thecrc = Crc16(send_bytes () , Z ) 'workout the CRC
Swap Thecrc
'Print Hex(thecrc)
Crcwrd = Thecrc
Wait 2
Print # 2 , Send_command ; Crcstr ; Chr(13) ;
'Print #2 , Send_command ; Crcstr ; Chr(13) ;
'Print #1 , "QPIGS" + Chr(183) + Chr(169) + Chr(13);
Wait 2
While Ischarwaiting(# 2) = 1
Rs232 = Inkey(# 2) 'get a character from the buffer
If Rs232 = 13 Or Len(uart_command ) > 253 Then 'uart_command full or enter key sent
Temp2 = Instr(uart_command , "NAKss" )
If Temp2 > 0 Then 'inverter did not accept command
Uart_command = ""
Clear Serialin1
Print # 1 , "gridvolts.txt=" ; Chr(34) ; "NAKss" ; Chr(34);
Call Nextion
'Print #2 , ""
'Print #2 , "not accepted"
'Print #2 , ""
Else
Call Find_command
End If
Uart_command = ""
Clear Serialin1
Else
Uart_command = Uart_command + Chr(rs232 ) 'add the character to the uart_command buffer
End If
Wend
Serial0charmatch :
While Ischarwaiting(# 1) = 1
Rs232 = Inkey(# 1) 'get a character from the buffer
If Rs232 = 13 Or Len(uart_command_in ) > 49 Then 'uart_command full or enter key sent
'make uper case
Z = Len(uart_command_in )
' Z = Z - 2
Temp1 = Left(uart_command_in , Z )
Temp1 = Ucase(temp1 )
Cls
Lcdat 6 , 1 , Temp1
Select Case Temp1
Case "STATUS"
Cls
Lcdat 1 , 1 , "STATUS"
Lcdat 7 , 1 , Temp1
Case "STATUS2"
Cls
Lcdat 1 , 1 , "STATUS2"
Lcdat 7 , 1 , Temp1
Case "SETTINS"
Cls
Lcdat 1 , 1 , "SETTINGS"
Lcdat 7 , 1 , Temp1
End Select
Uart_command_in = ""
Clear Serialin0
Else
Uart_command_in = Uart_command_in + Chr(rs232 ) 'add the character to the uart_command buffer
' Print Chr(rs232) ;
'Exit Do
End If
'End If
Wend
Loop
End 'end program
Sub Find_command
Local A As String * 3
Local B As String * 1
Local C As Byte
Local D As Byte
Local E As Long
C = &B00000111
Call Cal_crc16
If Crc = 1 Then
Select Case Task
'Print "Status bits>" ; Work(17)
Case 1
Call Chopup
'get the state of inverter
Delchar Work (1) , 1 'remove the (
'work(17) staus bits
'Print ">>Inverter Stats<<"
' Print "Grid Volts=" ; Work(1)
Print # 1 , "gridvolts.txt=" ; Chr(34) ; Work (1) ; Chr(34);
Call Nextion
'Print "Grid Frequency=" ; Work(2)
Print # 1 , "gridfreq.txt=" ; Chr(34) ; Work (2) ; Chr(34);
Call Nextion
'Print "AC Output Volts=" ; Work(3)
Print # 1 , "outvolts.txt=" ; Chr(34) ; Work (3) ; Chr(34);
Call Nextion
'Print "AC Output Frequency" ; Work(4)
Print # 1 , "outfreq.txt=" ; Chr(34) ; Work (4) ; Chr(34);
Call Nextion
'Print "Apparent Power=" ; Work(5)
Temp2 = Val(work (5))
Temp1 = Str(temp2 )
Print # 1 , "outwatts.txt=" ; Chr(34) ; Temp1 ; Chr(34);
Call Nextion
'Print "Active Power=" ; Work(6)
'Print "Load=" ; Work(7) ; "%"
Temp2 = Val(work (7))
Temp1 = Str(temp2 )
Temp1 = Temp1 + "%"
Print # 1 , "load.txt=" ; Chr(34) ; Temp1 ; Chr(34);
Call Nextion
'Print "Buss Volts=" ; Work(
Print # 1 , "bussvolt.txt=" ; Chr(34) ; Work (8) ; Chr(34);
Call Nextion
'Print "Battery Volts=" ; Work(9)
Print # 1 , "battvolts.txt=" ; Chr(34) ; Work (9) ; Chr(34);
Call Nextion
'Print "Battery Discharge Current=" ; Work(16) ; "Amps"
'Print "Battery Current=" ; Work(10) ; "Amps"
'are we discharging
Temp2 = Val(work (10))
Print
Print "work10" ; Work (10)
Print
Temp2 = Val(work (10))
Select Case Temp2
Case Is > 0
'Temp2 = Val(work(10))
Work (10) = Str(temp2 )
'Work(10) = "+" + Work(10)
Print # 1 , "battamps.txt=" ; Chr(34) ; Work (10) ; Chr(34);
Call Nextion
Case 0
Temp2 = Val(work (16))
If Temp2 = 0 Then
Temp2 = 1
End If
Work (16) = Str(temp2 )
Work (16) = "-" + Work (16)
Print # 1 , "battamps.txt=" ; Chr(34) ; Work (16) ; Chr(34);
Call Nextion
End Select
'Print "Battery Capacity=" ; Work(11) ; "%"
Temp2 = Val(work (11))
Temp1 = Str(temp2 )
Temp1 = Temp1 + "%"
Print # 1 , "soc.txt=" ; Chr(34) ; Temp1 ; Chr(34);
Call Nextion
'Print "Inverter Heat Sink Temp=" ; Work(12) ; "C"
Temp2 = Val(work (12))
Temp1 = Str(temp2 )
Print # 1 , "inverttmp.txt=" ; Chr(34) ; Temp1 ; Chr(34);
Call Nextion
'Print "PV Current into Battery=" ; Work(13) ; "Amps"
'Print "PV Voltage=" ; Work(14) ; "Volts"
Temp2 = Val(work (14))
Temp1 = Str(temp2 )
Print # 1 , "panlvolts.txt=" ; Chr(34) ; Temp1 ; Chr(34);
Call Nextion
'Print "Solar Charger Battery Voltage=" ; Work(15) ; "Volts"
Temp2 = Val(work (13))
Temp1 = Str(temp2 )
Print # 1 , "panlamps.txt=" ; Chr(34) ; Temp1 ; Chr(34);
Call Nextion
A = Mid(work (17) , 1)
If A = "1" Then
'Print "SBU Priority=Yes"
Else
'Print "SBU Priority=No"
End If
A = Mid(work (17) , 2)
If A = "1" Then
'Print "Configuration Change"
Else
'Print "Configuration No Change"
End If
A = Mid(work (17) , 3)
If A = "1" Then
'Print "Solar Charger Firmware Updated"
Else
'Print "Solar Charger Firmware Not Updated"
End If
A = Mid(work (17) , 4)
If A = "1" Then
'Print "Load is On"
Else
'Print "Load is Off"
End If
A = Mid(work (17) , 6 , 3)
D = Binval(a )
'Select Case D
' Case 0
'Print "No charging On"
'Case 6
'Print "Solar charging On"
'Case 5
'Print "AC charging On"
'Case 7
'Print "Solar & AC Charging On"
'End Select
'QMOD device mode
Case 3
Work (1) = Mid(uart_command , 2 , 1 )
Select Case Work (1)
Case "P" 'POWER ON MODE
Work (4) = "POWER ON MODE"
Case "S" 'STANDBY MODE
Work (4) = "STANDBY MODE"
Case "L" 'LINE MODE
Work (4) = "LINE MODE"
Print # 1 , "va12.val=1" ;
Call Nextion
Case "B" 'BATTERY MODE
Work (4) = "BATTERY MODE"
Print # 1 , "va12.val=0" ;
Call Nextion
Case "F" 'FAULT MODE
Work (4) = "FAULT MODE"
Case "H" 'POWER SAVING MODE
Work (4) = "POWER SAVING MODE"
End Select
'Work(4) = "status.invmode.txt=" + Work(4)
Print # 1 , "invmode.txt=" ; Chr(34) ; Work (4) ; Chr(34);
Call Nextion
Uart_command = ""
'inverter two state
Case 4
' V=0 QPGS1 V=1 QPGS0
If V = 0 Then
B = "2"
Else
B = ""
End If
Call Chopup
'the state of parallel inverter
'work() variable contents
'1 = parallel number 1 to 9 zero = not exist
'2 inverter serial number
'3 working mode
'4 fault code
Delchar Work (1) , 1 'remove the (
'work(17) staus bits
'Print ">>Inverter Stats<<"
' Print "Grid Volts=" ; Work(1)
If Work (1) = "1" Then 'yes have parra
'Print #2 , "yes have parra"
Print # 1 , "serial" ; B ; ".txt=" ; Chr(34) ; Work (2) ; Chr(34);
Call Nextion
Print # 1 , "gridvolts.txt=" ; Chr(34) ; Work (5) ; Chr(34);
Call Nextion
'Print "Grid Frequency=" ; Work(2)
Print # 1 , "gridfreq.txt=" ; Chr(34) ; Work (6) ; Chr(34);
Call Nextion
'Print "AC Output Volts=" ; Work(3)
Print # 1 , "outvolts.txt=" ; Chr(34) ; Work (7) ; Chr(34);
Call Nextion
'Print "AC Output Frequency" ; Work(4)
Print # 1 , "outfreq" ; B ; ".txt=" ; Chr(34) ; Work (8) ; Chr(34);
Call Nextion
'Print "Apparent Power=" ; Work(5)
Temp2 = Val(work (9))
Temp1 = Str(temp2 )
Print # 1 , "outwatts" ; B ; ".txt=" ; Chr(34) ; Temp1 ; Chr(34);
Call Nextion
'Print "Active Power=" ; Work(10)
'Print "Load=" ; Work(7) ; "%"
Temp2 = Val(work (11))
Temp1 = Str(temp2 )
Temp1 = Temp1 + "%"
Print # 1 , "load" ; B ; ".txt=" ; Chr(34) ; Temp1 ; Chr(34);
Call Nextion
'Print "Buss Volts=" ; Work(
' Print #2 , "status.bussvolts.txt=" + Chr(34) + Work() + Chr(34);
'Call Nextion
'Print "Battery Volts=" ; Work(9)
Print # 1 , "battvolts.txt=" ; Chr(34) ; Work (12) ; Chr(34);
Call Nextion
'Print "Battery Discharge Current=" ; Work(16) ; "Amps"
'Print "Battery Current=" ; Work(10) ; "Amps"
'are we discharging
Temp2 = Val(work (13)) Print
'Print "work13" ; Work(13)
' Print
Select Case Temp2
Case Is > 0
Work (13) = Str(temp2 )
'Work(13) = "+" + Work(13)
Print # 1 , "battamps" ; B ; ".txt=" ; Chr(34) ; Work (13) ; Chr(34);
Call Nextion
Case 0
Temp2 = Val(work (27))
If Temp2 = 0 Then
Temp2 = 1
End If
Work (27) = Str(temp2 )
Work (27) = "-" + Work (27)
Print # 1 , "battamps" ; B ; ".txt=" ; Chr(34) ; Work (27) ; Chr(34);
Call Nextion
End Select
'Print "Battery Capacity=" ; Work(11) ; "%"
Temp2 = Val(work (14))
Temp1 = Str(temp2 )
Temp1 = Temp1 + "%"
Print # 1 , "soc.txt=" ; Chr(34) ; Temp1 ; Chr(34);
Call Nextion
'Print "Inverter Heat Sink Temp=" ; Work(12) ; "C"
' Print #2 , "status.inverttmp.txt=" + Chr(34) + Work(12) + Chr(34);
'Call Nextion
'Print "PV Current into Battery=" ; Work(13) ; "Amps"
'Print "PV Voltage=" ; Work(14) ; "Volts"
Temp2 = Val(work (15))
Temp1 = Str(temp2 )
Print # 1 , "panvolts" ; B ; ".txt=" ; Chr(34) ; Temp1 ; Chr(34);
Call Nextion
'Print "Solar Charger Battery Voltage=" ; Work(15) ; "Volts"
Temp2 = Val(work (26))
Temp1 = Str(temp2 )
Print # 1 , "panlamps" ; B ; ".txt=" ; Chr(34) ; Temp1 ; Chr(34);
Call Nextion
'this section needs changes!!!!
' A = Mid(work(20) , 1)
' If A = "1" Then
'Print "SBU Priority=Yes"
' Else
'Print "SBU Priority=No"
' End If
'A = Mid(work(20) , 2)
' If A = "1" Then
'Print "Configuration Change"
' Else
'Print "Configuration No Change"
'End If
'A = Mid(work(20) , 3)
' If A = "1" Then
'Print "Solar Charger Firmware Updated"
'Else
'Print "Solar Charger Firmware Not Updated"
'End If
'A = Mid(work(20) , 4)
'If A = "1" Then
'Print "Load is On"
'Else
'Print "Load is Off"
'End If
'A = Mid(work(17) , 6 , 3)
'D = Val(work(21))
'Select Case D
'Case 0 'single machine
'Print "No charging On"
'Case 1
'Print "Solar charging On"
'Case 5
'Print "AC charging On"
'Case 7
'Print "Solar & AC Charging On"
'End Select
'Print ">>>>>>>>>>>" + Chr(34) + Work(3) + Chr(34)
Select Case Work (3)
Case "P" 'POWER ON MODE
Temp1 = "POWER ON MODE"
Case "S" 'STANDBY MODE
Temp1 = "STANDBY MODE"
Case "L" 'LINE MODE
Temp1 = "LINE MODE"
Case "B" 'BATTERY MODE
Temp1 = "BATTERY MODE"
Case "F" 'FAULT MODE
Temp1 = "FAULT MODE"
Case "H" 'POWER SAVING MODE
Temp1 = "POWER SAVING MODE"
End Select
'Work(4) = "status.invmode.txt=" + Work(4)
Print # 1 , "invmode.txt=" ; Chr(34) ; Temp1 ; Chr(34);
Call Nextion
End If
End Select
Else
Work (1) = "BAD CRC"
Print # 1 , "gridvolts.txt=" ; Chr(34) ; Work (1) ; Chr(34);
Call Nextion
Wait 2
End If
End Sub
'get the individual parameters returned
Sub Chopup
Local Lx As Byte
Lx = Split(uart_command , Work (1) , " ")
'Print "we had " ; Lx ; " lots of data returned"
End Sub
Sub Cal_crc16
Local Z As Word
Local Rcrc As Word
Local Rcrc2 As Word
Z = Len(uart_command )
Z = Z - 2 'last two bytes are crc
'Print "Z is>" ; Z
Rcrc = Crc16(aruart_command () , Z ) 'calculate the CRC
Swap Rcrc 'bytes are in reverse order to what is sent to us
'Print "Cal CRC is>" ; Hex(rcrc)
Crc_16 = Right(uart_command , 2) 'get the last two bytes the crc
Rcrc2 = Work2 'this is a word variable overlayed on Crc_16
' Print "The sent crc>" ; Hex(rcrc2)
If Rcrc = Rcrc2 Then 'they match data good
' Print "CRC OK
Crc = 1
Else
' Print "CRC BAD"
Crc = 2
End If
End Sub
Sub Nextion
Printbin # 1 , &HFF ; &HFF ; &HFF
Waitms 200
End Sub
'Serial0charmatch:
'Goto Screenchng
'Return
$include "font8x8.font"
|
|
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Sat Mar 07, 2020 5:04 pm Post subject: |
|
|
Paulvk wrote: | But I put Serial0charmatch: in the main loop and it works. |
Welcome in the world of ultimate botchery.
Hope you do not work on devices that may affect anybody's life.
Serial0charmatch is defined in mcs.lib and can be looked up.
Furthermore Serial0charmatch is a stub of the URXC0-interrupt and is called this way from the lib:
Code: | * call Serial0CharMatch |
After return, these registers will be restored:
Code: | Pop r24 ; restore used register
* Out Sreg , R24 ; SREG first
pop r25 ; and the rest
pop r24
pop r27
pop r26
Pop r16
Pop r23 |
and finally the routine returns to it's calling vector:
Code: | Reti ; watch out this needs reti |
while the RETI re-enables global interrupts.
In your code if a match happens, the Serial0charmatch's exit code is not executed.
The saved registers stay on stack, if called several time this would result finally in stack overflow.
But in this special case it won't matter much, as messing up the stack happens only one time, after this suicide all interrupts stay disabled.
If you manage it by the rest of this code somehow to reset the controller, it gives you at least a second run.
You really call this 'working'? |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You cannot download files in this forum
|
|