那位老大能给一段生成Bcd码的完整代码(100分)

  • 主题发起人 主题发起人 honghs
  • 开始时间 开始时间
H

honghs

Unregistered / Unconfirmed
GUEST, unregistred user!
最近在搞一个pos机的系统,是pax公司的pos机,海南工行就是用这玩意。
其实我的程序只要向与pc机连接的串口发送一串指定格式的字符就行了。
按照它的"pos机与pc通讯接口说明书"上说的格式如下:
stx[1] 一字节,固定为0x02 ,其实就是delphi中的#2嘛
length[2]二字节,其后跟随数据的长度,以压缩bcd形式存放,高字节在前
data[...]数据
etx[1] 一字节,固定为0x03,就是#3了
lrc[1]一字节检验码,从length开始到etx为止的各字节依次异或值
现在我需要一个能生成lehgth[2]这个压缩bcd形式的代码,还有能把bcd转成我可以认的
长度的代码。
那位老大给个真正能用的吧,我在dfw上找了一下,发现都只是些简单的代码片断,运行
起来好象没什么结果。
这是以前的贴子内容,好象没什么用啊,再把bcd转成长度的话,会少数据的。
*************
话题256024的标题是: BCD码求解 (150分)
分类:Internet/TCPIP foxnt (2000-05-30 12:20:08)
小弟实在低手:对位运算糊里糊涂。
如: 数字:0,1
对应ACSII码为:0011 0000
0011 0001
经BCD码压缩后为: 0000 0001
即取右边的4位。把两个字节变成了1个来发送。用SOCKET发的。
解压则相反。
现问题是:算法知道了,但不知在DELPHI中如何实现。
1 : 如何截取字节的前N BIT?后N BIT?
2 : 截取后如何得到该BIT的值?
因为火烧屁股,恳请高手提供源码(压缩和解压的)。不要说:找HELP!
150大元立即送上

Kang (2000-05-30 12:24:30)
只发送 0,1吗?那就不难

Kang (2000-05-30 12:30:44)
b:array [1..2] of byte;
b->BCD:
BCD:=b[1] and $0f shl 4+b[2] and $0f;

BCD->b
b[1]:=BCD and $0f0 shr 4+$30;
b[2]:=BCD abd $0f0 + $30;

SuperMMX (2000-05-30 12:55:54)
不管 ascii 的事,
一个字符串为 s = '014748'( 前提是你的 s 都是数字, 长度被2 整除)
i, j, k: Integer;
bcd: Integer;
begin
for i := 0 to Length(s) div2 - 1 do
begin
j := ord(s[2 * i + 1]) - 48;
k := ord(s[2 * i + 2]) - 48;
bcd := j shl 4 + k;
//now you can send bcd;
end;

//bcd to two char
var
ch1, ch2: char;
begin
ch1 := chr((bcd and $f0) shr 4 + 48);
ch2 := chr((bcd and $0f) + 48);
end;

end;


foxnt (2000-06-03 15:23:49)
多人接受答案了。

Kang-50,SuperMMX-100,的回答最终被接受。
***********
 
kao,竟然没人回答?
 
unsigned char checkSum( unsigned char *s, int len )
{
int i;
unsigned char sum = 0;

for( i = 0;
i < len;
i ++ ) sum += s;
return( unsigned char )( 256 - sum );
}
 
dxd0222,你就给一段从整数生成bcd码和bcd码再生成整数的代码吧
 
结果不知道对不对?也许应该用PChar [:(]
Nstr_to_BCD只改了右对齐的部分,呵呵
const
RIGHT_ALIGN=0;
LEFT_ALIGN=1;
function BCD_to_Nstr(BCDstr:String;
BCDstr_len:Integer;
var Nstr:String;
Nstr_len:integer):integer;
var
i,n,k:integer;
c:Char;
begin
Result:=-1;
Nstr:='';
n:=BCDstr_len * 2;
if (n<2) or (Nstr_len<=0) or (Nstr_len>n) then
exit;
for i:=n-Nstr_len to n-1 do
begin
c:=BCDstr[i div 2];
if ((i and 1)=0) then
begin
k:=(ord(c) and $F0) shr 4;
end
else
begin
k:=ord(c) and $0F;
end;
if (k<0) or (k>9) then
exit;
Nstr:=Nstr+Chr(k+Ord('0'));
end;
Result:=Nstr_len;
end;

function Nstr_to_BCD(Nstr:String;
Nstr_len:Integer;
var BCDstr:String;
align:Integer):Integer;
var
i,j,n:integer;
c:Char;
begin
Result:=-1;
if (Length(Nstr) mod 2)<>0 then
begin
Nstr:='0'+Nstr;
end;
Nstr_len:=Length(Nstr);
n:=(Nstr_len ) div 2;
SetLength(BCDstr,n);
if align=RIGHT_ALIGN then
begin
i:=Nstr_len;
for j:=n do
wnto 1 do
begin
if i>=0 then
begin
c:=Nstr;
if (c<'0') or (c>'9') then
exit;
BCDstr[j]:=Chr(ord(c)-ord('0'));
dec(i);
end;
//if i>=0 then
if i>=0 then
begin
c:=Nstr;
if (c<'0') or (c>'9') then
exit;
BCDstr[j]:=Chr(((ord(c)-ord('0')) shl 4) or ord(BCDstr[j]));
Dec(i);
end;
//if i>=0 then
end;
end
else
begin
end;

Result:=n;
end;
 
再没人回答的话,我准备给分给教父了
 
BCD是数据传输中的一种校验方法,就是说将数据传道对方后,用BCD码校验,如果计算出来的
BCD码和文本后带的BCD码不同,说明传输有误,要求重传一次,你瞎搞什么,从整数生成bcd码
和bcd码再生成整数的代码的问题!!!!!!!!!!!!!!!!!!!!!
再说一下你的CRC码的问题,也是如此!!!!!!
 
dxd0222,你不懂的话,就闭嘴吧,如果你态度好点的话,我还可以和你讨论讨论,不过像你这
么狂妄的话,那我也不怎么客气了。
BCD编码
  在数字系统中,各种数据要转换为二进制代码才能进行处理,而人们习惯于使用十进制数,所以在数字系统的输入输出中仍采用十进制数,这样就产生了用四位二进制数表示一位十进制数的方法,这种用于表示十进制数的二进制代码称为二-十进制代码(Binary Coded Decimal),简称为BCD码。它具有二进制数的形式以满足数字系统的要求,又具有十进制的特点(只有十种有效状态)。在某些情况下,计算机也可以对这种形式的数直接进行运算。常见的BCD码表示有以下几种。
8421BCD编码
  这是一种使用最广的BCD码,是一种有权码,其各位的权分别是(从最有效高位开始到最低有效位)8,4,2,1。
  例 写出十进数563.97D对应的8421BCD码。
    563.97D=0101 0110 0011 . 1001 01118421BCD
  例 写出8421BCD码1101001.010118421BCD对应的十进制数。
    1101001.010118421BCD=0110 1001 . 0101 10008421BCD=69.58D
  在使用8421BCD码时一定要注意其有效的编码仅十个,即:0000~1001。四位二进制数的其余六个编码1010,1011,1100,1101,1110,1111不是有效编码。
2421BCD编码
  2421BCD码也是一种有权码,其从高位到低位的权分别为2,4,2,1,其也可以用四位二进制数来表示一位十进制数。其编码规则如下表。
余3码
  余3码也是一种BCD码,但它是无权码,但由于每一个码对应的8421BCD码之间相差3,故称为余3码,其一般使用较少,故正须作一般性了解,具体的编码如下表。
常见BCD编码表
十进制数 8421BCD码 2421BCD码 余3码
0 0000 0000 0011
1 0001 0001 0100
2 0010 0010 0101
3 0011 0011 0110
4 0100 0100 0111
5 0101 1011 1000
6 0110 1100 1001
7 0111 1101 1010
8 1000 1110 1011
9 1001 1111 1100
10 0001,0000 0001,0000 0100,0011
dxd0222,如果你连上面的文字都看不懂的话,干脆从幼儿园开始学识字吧
 
BCD码:用二进制表示的十进制数
计算机只认识二进制,人习惯用十进制。怎样让计算机理解人输入的十进制呢?
要表达十进制必须要4位二进制数
例:89->1000 1001
十进制
8
9

BCD码
1000
1001
下面是一段关于压缩bcd码的说明,
BCD有分为两种,非紧密式和紧密式两种。
前面这种81秒存成 “08,01” 是非紧密式,而紧密式会存成 “81h”
(直接以十六进制储存)。
 
对不起,我理解成传送格式问题啦,如果你玩过A-B PLC系列的话,你不会这么生气!
再见!!!!!!!!!!!!!!!
 
算了,等结束问题的时候给dxd0222些分压压惊吧
 
多人接受答案了。
 
后退
顶部