here is my code, working, except that it doesnt seem to display numbers correctly when the values roll over from 999 to 1000 and 9999 to 10000, here is what it shows when it rolls over:-
ok until now…
996
997
998
999
100
101
102
103
104
105
106
107
108
109
1010
1011
ok after this…
Sub Ser_Init
#define baud 12
#define halfbaud 6 ;place Read of SerRx in middle of bit
#define SerTxHigh Set PortC.4 On
#define SerTxLow Set PortC.4 Off
#define SerRx PortC.5
dir PortC.5 in ;Rx
dir PortC.4 out ;Tx
SerTxHigh ;Initial RS232 idle state
end sub
sub XMIT_PRINT (PrintData$)
PrintLen = PrintData(0)
if PrintLen = 0 then exit sub
'Write Data
for SysPrintTemp = 1 to PrintLen
XMIT_RS232(PrintData(SysPrintTemp))
next
end sub
Sub XMIT_RS232(Xmit_Byte)#NR
SerTxLow
wait baud us
For cntr = 1 to 8
Rotate Xmit_Byte Right
If Status.C ON Then SerTxHigh
If Status.C Off Then SerTxLow
wait baud us
Next
SerTxHigh
wait baud us
end sub
sub Bin2ascii(LCDValue as word )#NR
dim LCDValueTemp as word
SERDECMIL = 0
SERMIL = 0
SERCEN = 0
SERDEC = 0
SERUN = 0
LCDValueTemp = 0
IF LCDValue >= 10000 then
LCDValueTemp = LCDValue / 10000
SERDECMIL = LCDValueTemp + 48
Xmit_RS232(SERDECMIL) 'SerSend (1,SERDECMIL)
LCDValue = LCDValue - LCDValueTemp * 10000
End if
If LCDValueTemp > 0 Or LCDValue >= 1000 Then
LCDValueTemp = LCDValue / 1000
SERMIL = LCDValueTemp + 48
Xmit_RS232(SERMIL) 'SerSend (1,SERMIL)
LCDValue = LCDValue - LCDValueTemp * 1000
End if
IF LCDValueTemp > 0 OR LCDValue >= 100 then
LCDValueTemp = LCDValue / 100
SERCEN = LCDValueTemp + 48
Xmit_RS232(SerCen) 'SerSend (1,SERCEN)
LCDValue = LCDValue - LCDValueTemp * 100
end if
IF LCDValueTemp > 0 OR LCDValue >= 10 then
LCDValueTemp = LCDValue / 10
SERDEC = LCDValueTemp + 48
Xmit_RS232(Serdec) 'SerSend (1,SERDEC)
LCDValue = LCDValue - LCDValueTemp * 10
end if
SERUN = LCDValue + 48
Xmit_RS232(Serun) 'SerSend (1,SERUN)
end sub
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Bit errors due to slow clock and overhead of routines, is my guess. To get a fast baudrate with the internal oscillator is pretty much a guessing game. Some buadrates work while others will not. I think I claimed that a 115200 baud rate was possible. The conditions were a 16f648a with a 20Mhz crystal, buad = 7,halfbuad = 4, and the data was just a loop back test from a terminal key press. So a fast clock and no word size maths, in addition to juggling baud wait states for overhead. Even then, other high baud rate(s) trys did not work out.
You could try other buad rates, also see if using a string of nop instructions would work, in place of the wait buad/half buad us? The 16f688 has a hardware usart, it should be used with the hardware usart routines, along with a faster crystal osc for reliable usart buad rates.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The quick and kind of ugly work around is to change the conditionals in bin2ascii sub. Works on rollovers of 999 to 1000 and 9999 to 10000. Only problem is you've got leading zero's now.
Looks like some sort of word size conditional problem, but not sure at the moment.
If LCDValueTemp >= 0 Or LCDValue >= 1000 Then
….
…
IF LCDValueTemp >= 0 OR LCDValue >= 100 Then
…
…
IF LCDValueTemp >= 0 OR LCDValue >= 10 Then
…
…
Kent
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The answer was from Hugh in plain sight. The maths have changed a bit as explained in this thread here. So using that info, a new bin2asciiNew sub has been created. No leading zero's and promises to be much more efficient. The shadow registers, SERDECMIL, SERMIL, etc. seemed to work better at high bit rates.
Tested with the latest update of 11/29/09 at 115,200kbs, baud is 7 us, halfbaud is 4 us, on a 18f1330 PIC with a 20Mhz crystal,. It will easily overrun the terminal display output without some number of ms's of delay in the code.
sub bin2asciiNew (LCDValue as word ) #NR
Dim SysCalcTempX As Word
LCDValueTemp = 0
LCDShowChar = 0
SERDECMIL = 0
SERMIL = 0
SERCEN = 0
SERDEC = 0
SERUN = 0
If LCDValue >= 10000 then
LCDValueTemp = LCDValue / 10000 [word]
LCDValue = SysCalcTempX
SERDECMIL = LCDValueTemp + 48
Xmit_RS232 (SERDECMIL)
LCDShowChar = TRUE
End If
If LCDShowChar > 0 or LCDValue >= 1000 then
LCDValueTemp = LCDValue / 1000 [word]
LCDValue = SysCalcTempX
SERMIL = LCDValueTemp + 48
Xmit_RS232 (SERMIL)
LCDShowChar = TRUE
End If
If LCDShowChar > 0 or LCDValue >= 100 then
LCDValueTemp = LCDValue / 100 [word]
LCDValue = SysCalcTempX
SERCEN = LCDValueTemp + 48
Xmit_RS232 (SERCEN)
LCDShowChar = TRUE
End If
If LCDShowChar > 0 or LCDValue >= 10 then
LCDValueTemp = LCDValue / 10 [word]
LCDValue = SysCalcTempX
SERDEC = LCDValueTemp + 48
Xmit_RS232 (SERDEC)
End If
SERUN = LCDValue + 48
Xmit_RS232 (SERUN)
End Sub
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
here is my code, working, except that it doesnt seem to display numbers correctly when the values roll over from 999 to 1000 and 9999 to 10000, here is what it shows when it rolls over:-
ok until now…
996
997
998
999
100
101
102
103
104
105
106
107
108
109
1010
1011
ok after this…
and then
ok before this….
9997
9998
9999
100
101
102
103
104
105
106
107
108
109
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
10100
10101
10102
then ok again…
'Chip model
#chip 16f688,8
#config Osc = Int
Ser_Init
Dim stamp as word
stamp = 0
Do
Bin2ascii(stamp)
XMIT_RS232 (13)
XMIT_RS232 (10)
stamp = stamp +1
wait 4 ms
Loop
Sub Ser_Init
#define baud 12
#define halfbaud 6 ;place Read of SerRx in middle of bit
#define SerTxHigh Set PortC.4 On
#define SerTxLow Set PortC.4 Off
#define SerRx PortC.5
dir PortC.5 in ;Rx
dir PortC.4 out ;Tx
SerTxHigh ;Initial RS232 idle state
end sub
sub XMIT_PRINT (PrintData$)
PrintLen = PrintData(0)
if PrintLen = 0 then exit sub
'Write Data
for SysPrintTemp = 1 to PrintLen
XMIT_RS232(PrintData(SysPrintTemp))
next
end sub
Sub XMIT_RS232(Xmit_Byte)#NR
SerTxLow
wait baud us
For cntr = 1 to 8
Rotate Xmit_Byte Right
If Status.C ON Then SerTxHigh
If Status.C Off Then SerTxLow
wait baud us
Next
SerTxHigh
wait baud us
end sub
sub Bin2ascii(LCDValue as word )#NR
dim LCDValueTemp as word
SERDECMIL = 0
SERMIL = 0
SERCEN = 0
SERDEC = 0
SERUN = 0
LCDValueTemp = 0
IF LCDValue >= 10000 then
LCDValueTemp = LCDValue / 10000
SERDECMIL = LCDValueTemp + 48
Xmit_RS232(SERDECMIL) 'SerSend (1,SERDECMIL)
LCDValue = LCDValue - LCDValueTemp * 10000
End if
If LCDValueTemp > 0 Or LCDValue >= 1000 Then
LCDValueTemp = LCDValue / 1000
SERMIL = LCDValueTemp + 48
Xmit_RS232(SERMIL) 'SerSend (1,SERMIL)
LCDValue = LCDValue - LCDValueTemp * 1000
End if
IF LCDValueTemp > 0 OR LCDValue >= 100 then
LCDValueTemp = LCDValue / 100
SERCEN = LCDValueTemp + 48
Xmit_RS232(SerCen) 'SerSend (1,SERCEN)
LCDValue = LCDValue - LCDValueTemp * 100
end if
IF LCDValueTemp > 0 OR LCDValue >= 10 then
LCDValueTemp = LCDValue / 10
SERDEC = LCDValueTemp + 48
Xmit_RS232(Serdec) 'SerSend (1,SERDEC)
LCDValue = LCDValue - LCDValueTemp * 10
end if
SERUN = LCDValue + 48
Xmit_RS232(Serun) 'SerSend (1,SERUN)
end sub
Bit errors due to slow clock and overhead of routines, is my guess. To get a fast baudrate with the internal oscillator is pretty much a guessing game. Some buadrates work while others will not. I think I claimed that a 115200 baud rate was possible. The conditions were a 16f648a with a 20Mhz crystal, buad = 7,halfbuad = 4, and the data was just a loop back test from a terminal key press. So a fast clock and no word size maths, in addition to juggling baud wait states for overhead. Even then, other high baud rate(s) trys did not work out.
You could try other buad rates, also see if using a string of nop instructions would work, in place of the wait buad/half buad us? The 16f688 has a hardware usart, it should be used with the hardware usart routines, along with a faster crystal osc for reliable usart buad rates.
OOPs………Scratch the previous post…………!!!!
I see what you mean. Will have to dig deeper to see what is happening.
The quick and kind of ugly work around is to change the conditionals in bin2ascii sub. Works on rollovers of 999 to 1000 and 9999 to 10000. Only problem is you've got leading zero's now.
Looks like some sort of word size conditional problem, but not sure at the moment.
If LCDValueTemp >= 0 Or LCDValue >= 1000 Then
….
…
IF LCDValueTemp >= 0 OR LCDValue >= 100 Then
…
…
IF LCDValueTemp >= 0 OR LCDValue >= 10 Then
…
…
Kent
OK then,
The answer was from Hugh in plain sight. The maths have changed a bit as explained in this thread here. So using that info, a new bin2asciiNew sub has been created. No leading zero's and promises to be much more efficient. The shadow registers, SERDECMIL, SERMIL, etc. seemed to work better at high bit rates.
Tested with the latest update of 11/29/09 at 115,200kbs, baud is 7 us, halfbaud is 4 us, on a 18f1330 PIC with a 20Mhz crystal,. It will easily overrun the terminal display output without some number of ms's of delay in the code.
perfect, thanks, i wont even post my nasty code work around i have been using!