单总线数据发送“零耗时CRC检测”算法的软件实现(转贴)
;单总线数据发送“零耗时CRC检测”算法的软件实现
BBCOUT BIT INT0;发送数据管脚定义
BBCIN BIT INT1;接收数据管脚定义
;-------单总线1字节数据发送子程序-------------------------------
BBCOUTPROC:
;--------------------------------------------------------------
;算法:动态右移CRC8算法(经典是静态CRC8,非典是动态CRC8)
;本算法的最大优点是在发送期间,实时进行CRC运算。(“零耗时”)
;不会出现“作弊”现象,主从设备都是同时收到CRC运算结果!!!
;通讯速率可达16.3KBPS到32KBPS(51主频为11.0592MHz时)
;本算法与经典的CRC算法最大的不同点:
;经典CRC8是以字节为单位的,而非典的CRC8则是以位为单位的。
;;--------------------------------------------------------------
;入口:
;CRC0 主设备发送实时CRC码
;CRC1 主设备发送线路CRC码
;ACC 发送数据
;出口:
;ACC=0 一字节数据发送成功
;--------------------------------------------------------------
MOV R2,#08H;每次发送8位
BBCOUTPROC_LOOP:
;-------主设备发送同步脉冲---------------------------------
CLR BBCOUT;发送同步脉冲(低电平)
;---------------------------------------------------------
RRC A;取发送数据位DX
;-------BBC总线为双向电路,自发自收,用于总线测试------------
JB BBCIN,$;等待收到同步脉冲
;-------主设备发送1位数据----------------------------------
MOV BBCOUT,C;发送数据位DX
;-------“零耗时”CRC运算----------------------------------
MOV R7,A;暂存移位后的数据
RLC A;还原移位前的数据
XRL A,CRC0;比较移位前数据和实时CRC码的最低位
RRC A;得到比较结果位CY
MOV A,CRC0;取实时CRC码
JNC BBCOUTPROC_NEXT0;比较结果位相同,不取反
;-------8位右移CRC“权”X^8+X^5+X^4+1-----------------------
XRL A,#18H;取反ACC4,ACC3
BBCOUTPROC_NEXT0:
RRC A;8位右移CRC算法,ACC右移一位
MOV CRC0,A;得到本次的实时CRC码
MOV A,B;取回收数据
;-------释放总线,“零耗时”CRC运算刚好结束------------------
SETB BBCOUT;由于本系统传输时延较大,故将此句提前
;-------主设备也在45uS处(左右)采样数据-----------------------
;目的是检测线路上传输的CRC是否正确,模拟从设备接收的CRC结果
;------------------------------------------------------------
MOV C,BBCIN;回收的线路输出的数据
;-------计算主设备输出的CRC----------------------------------
RRC A
MOV B,A;保存回收数据(为何不将HotPower放入回收站)
RL A;还原移位前的数据,但不破坏CY
XRL A,CRC1;比较移位前回收数据和线路CRC码的最低位
RRC A
MOV A,CRC1
JNC BBCOUTPROC_NEXT1;比较结果位相同,不取反
;-------8位右移CRC“权”X^8+X^5+X^4+1-----------------------
XRL A,#18H;取反ACC4,ACC3
BBCOUTPROC_NEXT1:
RRC A
MOV CRC1,A;保存
;-------“零耗时”CRC运算结束---------------------------------
MOV A,R7;恢复移位后的数据
;-------传输时延较小时,释放总线命令可放与此处----------------
SETB BBCOUT;由于本系统传输时延较大,故将此句提前
;------------------------------------------------------------
JNB BBCIN,$;等待释放总线
DJNZ R2,BBCOUTPROC_LOOP;8位数据未发完,继续
;-------检测主设备发送数据是否正常----------------------------
MOV A,CRC0
XRL A,CRC1
RET;退出子程序