techElder
Well-known member
Here's a snippet that I've used to generate a longitudinal redundancy check (LRC). I have used it on an RS-485 setup with success. It is fast and provides some minimum checking. I've forced 1-bit errors to show up, but haven't done any documented testing. The algorithm is straight from MODBUS when ASCII only is transmitted.
Originally, I posted this on an HC-12 thread and got some interesting additions from forum members.
lbenson - Why, at the end of the loop, is "LRC = $FF - LRC + 1" preferable to just LRC?
Buzby - Because in the receiver you just need to sum the data including the LRC, and check that the result is zero. It's a bit quicker and saves a variable.
AllyCat - BTW the last three lines of Tex's LRC macro can be replaced by simply: @bptr = - LRC to save 8 bytes.
PS. This post is just to document what I (and others) had posted within the forum about a year ago (2017-JAN-25).
Code:
[color=Navy]#macro [/color][color=Black]LRC_RAM[/color][color=Blue]([/color][color=Purple]LRC[/color][color=Black],[/color][color=Blue]LRCRAM_BEG[/color][color=Black],[/color][color=Blue]LRCRAM_END) [/color][color=Green]; "2018-01-06 06:12:19"
' Procedure to generate longitudinal redundancy check (LRC) 8-bit field
' Uses bptr, LRC (byte variables)
' Uses LRCRAM_BEG, LRCRAM_END as constants pointing to start RAM and end RAM
' bptr is set to the beginning RAM location of bytes to be added
' All bytes important including LRCRAM_BEG to LRCRAM_END
' LRC is poked into the last byte; LRCRAM_END
[/color][color=Purple]LRC [/color][color=DarkCyan]= [/color][color=Navy]0 [/color][color=Green]; clear sum
[/color][color=Purple]bptr [/color][color=DarkCyan]= [/color][color=Blue]LRCRAM_BEG [/color][color=Green]; start here in RAM
[/color][color=Blue]do
[/color][color=Purple]LRC [/color][color=DarkCyan]= [/color][color=Purple]LRC [/color][color=DarkCyan]+ [/color][color=Purple]@bptrinc [/color][color=Green]; Add in 8-bit variable (carries discarded)
[/color][color=Blue]loop until [/color][color=Purple]bptr [/color][color=DarkCyan]= [/color][color=Blue]LRCRAM_END [/color][color=Green]; Changed from ">" ; "2018-01-06 06:12:36"
'LRC = $FF - LRC ; Subtract from 0xFF to produce a ones-complement
'LRC = LRC + 1 ; Add 1 to produce the twos-complement
'poke bptr, LRC ; Poke LRC into 1 byte after LRCRAM_END
[/color][color=Purple]@bptr [/color][color=DarkCyan]= - [/color][color=Purple]LRC
LRC [/color][color=DarkCyan]= [/color][color=Purple]@bptr [/color][color=Green]; Update and return the variable from RAM[/color]
[color=Navy]#endm[/color]
lbenson - Why, at the end of the loop, is "LRC = $FF - LRC + 1" preferable to just LRC?
Buzby - Because in the receiver you just need to sum the data including the LRC, and check that the result is zero. It's a bit quicker and saves a variable.
AllyCat - BTW the last three lines of Tex's LRC macro can be replaced by simply: @bptr = - LRC to save 8 bytes.
PS. This post is just to document what I (and others) had posted within the forum about a year ago (2017-JAN-25).
Last edited: