⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hm16.c

📁 在定时器中断中做LED的PWM输出 AT89C2051实现A/D转换的C51程序 单片机开发系统 指令系统 程序设计 定时与中断 系统扩展 接口技术 串行口
💻 C
字号:
//16比特汉明码测试程序(原始数据11字节,编码结果为16字节)
//  [16,11,4] 增广汉明码校验矩阵:    |
//    D15 D14 D13 D12 D11 D10  D9 D7  D6  D5  D3  D16  D8  D4  D2  D1      校验码
//  |  1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1  |    C4=0FFFFH
//  |  1   1   1   1   1   1   1   0   0   0   0   0   1   0   0   0  |    C3=0FE08H
//  |  1   1   1   1   0   0   0   1   1   1   0   0   0   1   0   0  |    C2=0F1C4H 
//  |  1   1   0   0   1   1   0   1   1   0   1   0   0   0   1   0  |    C1=0CDA2H  
//  |  1   0   1   0   1   0   1   1   0   1   1   0   0   0   0   1  |    C0=0AB61H 

unsigned int err[16]={0x0000,0x0001,0x0002,0x0020,0x0004,0x0040,0x0080,0x0100,
		0x0008,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x8000};//错误图样

unsigned char S[11]={0x05,0x16,0x27,0x38,0x49,0x5A,0x6B,0x7C,0x8D,0x9E,0xAF};//原始数据
unsigned char D[16];	//原始数据的汉明码(发送的内容)
unsigned char R[11];	//解码结果(接收的内容)

unsigned char parity (unsigned int k ) //16比特偶校验
{
	int i;
	unsigned char t=0;
	for (i=0;i<16;i++) {
		if ( k & 0x0001 ) t ^= 0x01;
		k >>= 1;
		}
	return t;
}

void TRANS (  ) //编码程序(模拟发送)
{
	unsigned char c0,c1,c2,c3,c4;
	int i,j;
	unsigned int m;
	c0=S[8];c1=S[9];c2=S[10];//后三字节用来拆分
	for (i=0,j=0;i<8;i++) {	//分8组进行编码
		c3=S[i];c4=0;	//从前8个字节中取一个字节,作为高字节
		if ( c0 & 0x80 ) c4 += 0x80;//从后三字节中各取一比特,作为低字节的高3位
		if ( c1 & 0x80 ) c4 += 0x40;
		if ( c2 & 0x80 ) c4 += 0x20;
		c0 <<= 1 ;c1 <<= 1 ;c2 <<= 1 ;//后三字节进行移位,丢弃已经使用的信息
		m = 256*c3 + c4 ;//将两个字节拼装为16比特无符号整数
		if ( parity ( m & 0xAB61 ) ) m += 1;	//生成校验位D1
		if ( parity ( m & 0xCDA2 ) ) m += 2;	//生成校验位D2
		if ( parity ( m & 0xF1C4 ) ) m += 4;	//生成校验位D4
		if ( parity ( m & 0xFE08 ) ) m += 8;	//生成校验位D8
		if ( parity ( m ) ) m += 16;		//生成校验位D16
		D[j++]=c3; D[j++]=m%256;		//输出两字节编码结果
		}
}

int RECEV ( ) //解码程序(模拟接收)	
{
	int i,j,l; 
	int k=1; 	//初始化解码成功标志
	unsigned char c1,c2,p,q,r;
	unsigned int m,n;
	p=q=r=0;
	for (i=0,j=0;i<8;i++,j++) {	//分为8组处理
		c1=D[2*i];c2=D[2*i+1];	//每组两个字节
		m=256*c1+c2;		//将两个字节拼装为16比特无符号整数
		n=0;			//校验结果初始化
		if ( parity ( m & 0xAB61 ) ) n += 1;	//计算校验结果D1
		if ( parity ( m & 0xCDA2 ) ) n += 2;	//计算校验结果D2
		if ( parity ( m & 0xF1C4 ) ) n += 4;	//计算校验结果D4
		if ( parity ( m & 0xFE08 ) ) n += 8;	//计算校验结果D8
		l = parity ( m ) ;		//计算校验结果D16
		if ( n && !l) k=0;		//两个差错,解码失败
		m ^= err[n];			//纠错处理
		R[j]=m/256;			//输出高字节的8比特信息
		p<<=1;q<<=1;r<<=1;		//将3比特信息拼装保存
		if ( m & 0x0080) p++;
		if ( m & 0x0040) q++;
		if ( m & 0x0020) r++;
		}
	R[8]=p;R[9]=q;R[10]=r;			//输出拼装出来的3字节信息。
	return k;	//返回解码是否成功的信息
}

 main ( )
{
	int f;		//解码成功标志
	TRANS ( ) ;	//对原始数据进行汉明编码(模拟发送)
	f = RECEV ( );	//对没有干扰的数据进行解码(模拟接收),f=1,成功.
	D[5] ^= 0x20 ;	//在接收数据中制造一比特差错
	f = RECEV ( );	//对有干扰的数据进行解码(模拟接收),f=1,成功.
	D[8] ^= 0x24 ;	//在接收数据中制造两比特差错
	f = RECEV ( );	//对有干扰的数据进行解码(模拟接收),f=0,失败.
	while (1) ; //在这一行设置断点,中止程序运行,以便观察程序运行的结果 
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -