曼彻斯特解码程序
曼彻斯特解码方法

曼彻斯特解码方法曼彻斯特解码方法是一种用于将二进制数据转换为可读文本的方法,它起源于1950年代的曼彻斯特大学。
这种解码方法被广泛应用于计算机科学和通信领域,特别是在网络通信中。
曼彻斯特解码方法的基本原理是将每个二进制位转换为一个时间间隔,通过这种方式来表示数据。
具体而言,如果一个二进制位为0,则对应的时间间隔为高电平持续一段时间,而如果一个二进制位为1,则对应的时间间隔为低电平持续一段时间。
通过解码这些时间间隔,我们可以恢复出原始的二进制数据。
曼彻斯特解码方法的优点之一是它具有很好的抗干扰性能。
由于每个二进制位都被表示为一个时间间隔,即使在信号传输过程中产生了一些噪声,我们仍然可以通过判断时间间隔的长短来正确解码数据。
这在无线通信和有线通信中都非常有用,因为信号的传输过程中常常会受到各种干扰。
另一个优点是曼彻斯特解码方法可以很容易地实现同步。
由于每个二进制位都被表示为一个时间间隔,接收方可以通过检测时间间隔的变化来确定数据的起始点,并与发送方进行同步。
这对于数据的正确接收非常重要,尤其是在高速数据传输中。
曼彻斯特解码方法虽然具有很多优点,但也存在一些限制。
首先,由于每个二进制位都需要表示为一个时间间隔,这导致了数据传输速率的下降。
相比于其他编码方法,曼彻斯特解码方法的传输速率较低。
其次,由于每个二进制位都需要表示为一个时间间隔,这意味着数据的传输距离受到限制。
在远距离传输中,由于信号衰减和传输延迟等问题,曼彻斯特解码方法可能会导致数据错误。
尽管存在一些限制,曼彻斯特解码方法仍然被广泛应用于许多领域。
在计算机网络中,以太网中的物理层就使用了曼彻斯特解码方法。
在无线通信中,蓝牙和红外线通信等也采用了曼彻斯特解码方法。
此外,在一些特殊的应用中,如音频和视频传输,曼彻斯特解码方法也得到了广泛应用。
曼彻斯特解码方法是一种将二进制数据转换为可读文本的方法,它具有抗干扰性能强、易于实现同步等优点。
尽管存在一些限制,但曼彻斯特解码方法仍然是计算机科学和通信领域中重要的编码方法之一。
AVR单片机 曼彻斯特编码 中断方式解码C程序文件

96
{
97
if ((capbuf[j] + capbuf[j+1] + capbuf[j+2] + capbuf[j+3])%2 != capbuf[j+4])
98
{
99
return ; //行偶校验失败
100
}
101
}
102
PrintString("找到啦!\r\n");
103
for (i = 0, j = 0; i < 5; i++, j += 10)
104
{
105
num = capbuf[j] << 7;
106
num |= capbuf[j+1] << 6;
107
num |= capbuf[j+2] << 5;
108
num |= capbuf[j+3] << 4;
109
num |= capbuf[j+5] << 3;
110
num |= capbuf[j+6] << 2;
57 void UARTInit(void)
58 {
59
UCSR0B |= (1<<TXEN0)|(1<<RXEN0);
60
UBRR0H = 0;
61
UBRR0L = 12;
62
UCSR0C = 0x6;
63 }
64
65 void UARTSend(char c)
66 {
67
while(!(UCSR0A & (1 << UDRE0)));
曼彻斯特编解码电路设计毕业设计

毕业设计(论文)题目名称:曼彻斯特编解码电路设计学生姓名:院(系):电子信息学院专业班级:电气10602指导教师:辅导教师:时间:2010年3月15日至2010年6月10日目录毕业设计(论文)开题报告 (V)曼彻斯特编解码电路设计 (12)Manchester encoding and decoding circuit (13)前言 0曼彻斯特编解码电路设计 (1)1 选题背景 (1)普通NRZ码存在的问题 (1)应用背景 (1)2 方案论证 0曼彻斯特码简介 0曼彻斯特编解码解析 0曼彻斯特编解码具体实现方式 (1)方案选择 (2)3 硬件电路设计 (5)系统实物照片展示 (5)系统的硬件框图 (6)AT89S52单片机简介 (7)单片机外围电路 (9)信号调理电路 (13)4 软件设计 (16)资源利用 (16)曼彻斯特码编解码方式分析 (18)程序流程图 (19)编码实现 (21)改良方向 (24)参考文献 (26)致谢 (27)附录1:地下液位测量系统实物照片 (28)长江大学毕业设计(论文)任务书学院(系)电子信息学院专业电气工程及自动化班级电气10602学生姓名熊香春指导教师/职称吴爱平/讲师1.毕业设计(论文)题目曼彻斯特编解码电路设计2.毕业设计(论文)起止时刻:2010年3月15日-2010年6月10日3.毕业设计(论文)所需资料及原始数据(指导教师选定部份)所需资料:(1)《MCS-51单片机原理与应用》(2)《单片机的C语言编程》(3) 通信原理原始数据传输速度为20Kb/S,一帧数据有16个字节,一帧的命令有2个字节。
4.毕业设计(论文)应完成的主要内容(1)利用C语言编程实现曼彻斯特编码、解码模块,并在PROTUES软件中仿真;(2)设计曼彻斯特信号调理电路;(3)毕业论文中必需包括如下内容:大体原理介绍、整体框图、软件流程图、软件原理介绍、源程序清单。
5.毕业设计(论文)的目标及具体要求利用单片机和C语言编程实现曼彻斯特编码、解码模块,并在PROTUES软件中仿真通过;通过单片机最小系统,辅之外围电路,能够实现编解码。
曼彻斯特码

曼彻斯特码1、将10111001换成曼彻斯特编码.解:根据基本曼彻斯特编码原理和差分曼彻斯特编码原理将10111001换成曼彻斯特编码如下表:原码基本曼彻斯特编码差分曼彻斯特编码10111001 1001101010010110 10100110010101102、曼彻斯特码的编码原理是:由每位的中间为采样时间,如果电平由高电平跳变为低电平,则为“1”;反之则为“0”;3、差分曼彻斯特码的编码原理是:由每位的开始是否存在电压跳变,如果有,则为“0”,反之为“1”。
今天看了一下从fpga上下的曼彻斯特编解码的程序,感觉不是很清楚,仿真了一下,更迷茫了,大家看看为啥这程序要这么编呢?程序比较长,不过写的应该还是不错的,看了后应该有收获。
总的思路是这样:1 通过一个高频的时钟检测wrn信号,如果检测到上升沿,则表明开始编码,将输入的8位数据转为串行,并编码,然后输出。
2 定时信号是从高频时钟16分频后得到的,在wrn上升沿后16分频使能,在编码结束后禁止分频输出。
3 no_bits_sent记录串行输出的位数,应该是从0010到1001输出串行信号,到1010时编码结束,输出tbre表明编码完成。
问题是no_bits_sent在到了1010后还是会继续增加,直到1111,然后clk1x_enable 就为0,无法分频,clk1x就为一直流信号。
这样当clk1x_enable再次为1的时候,no_bits_sent也不会增加,在1111上不变,clk1x_enable又会回到0了。
//***************************************************************************** *** File Name: me.v* Version: 1.0* Date: January 22, 2000* Model: Manchester Encoder Chip** Company: Xilinx*** Disclaimer: THESE DESIGNS ARE PROVIDED "AS IS" WITH NO WARRANTY* WHATSOEVER AND XILINX SPECIFICALL Y DISCLAIMS ANY* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR* A PARTICULAR PURPOSE, OR AGAINST INFRINGEMENT.** Copyright (c) 2000 Xilinx, Inc.* All rights reserved*******************************************************************************/module me (rst,clk16x,wrn,din,tbre,mdo) ;input rst ;input clk16x ;input wrn ;input [7:0] din ;output tbre ;output mdo ;wire clk1x ;reg clk1x_enable ;wire clk1x_disable ;reg [3:0] clkdiv ;reg [3:0] no_bits_sent ;wire mdo ;reg tbre ;reg [7:0] tsr ;reg [7:0] tbr ;reg parity ;reg wrn1 ;reg wrn2 ;// form 2 FF register for write pulse detectionalways @(posedge rst or posedge clk16x)if (rst)beginwrn2 <= 1'b1 ;wrn1 <= 1'b1 ;endelsebeginwrn2 <= wrn1 ;wrn1 <= wrn ;end// Enable clock when detect edge on write pulsealways @(posedge rst or posedge clk16x)beginif (rst)clk1x_enable <= 1'b0 ;else if (wrn1 == 1'b1 && wrn2 == 1'b0)clk1x_enable <= 1'b1 ;else if (no_bits_sent == 4'b1111)clk1x_enable <= 1'b0 ;end// Generate Transmit Buffer Register Empty signalalways @(posedge rst or posedge clk16x)beginif (rst)tbre <= 1'b1 ;else if (wrn1 == 1'b1 && wrn2 == 1'b0)tbre <= 1'b0 ;else if (no_bits_sent == 4'b1010)tbre <= 1'b1 ;elsetbre <= 1'b0 ;end// Detect edge on write pulse to load transmit bufferalways @(posedge rst or posedge clk16x)beginif (rst)tbr <= 8'h0 ;else if (wrn1 == 1'b1 && wrn2 == 1'b0)tbr <= din ;end// Increment clockalways @(posedge rst or posedge clk16x)beginif (rst)clkdiv <= 4'b0000 ;else if (clk1x_enable == 1'b1)clkdiv <= clkdiv + 1 ;endassign clk1x = clkdiv[3] ;// Load TSR from TBR, shift TSRalways @(posedge rst or posedge clk1x)beginif (rst)tsr <= 8'h0 ;else if (no_bits_sent == 4'b0001)tsr <= tbr ;else if (no_bits_sent >= 4'b0010 && no_bits_sent < 4'b1010) begintsr[7:1] <= tsr[6:0] ;tsr[0] <= 1'b0 ;endend// Generate Manchester data from NRZassign mdo = tsr[7] ^ clk1x ;// Generate parityalways @(posedge rst or posedge clk1x) beginif (rst)parity <= 1'b0 ;elseparity <= parity ^ tsr[7] ;end// Calculate number of bits sentalways @(posedge rst or posedge clk1x) beginif (rst)no_bits_sent <= 4'b0000 ;else if (clk1x_enable)no_bits_sent <= no_bits_sent + 1 ;// else if (no_bits_sent == 4'b1111) else if (clk1x_disable)no_bits_sent <= 4'b0000 ;endassign clk1x_disable = !clk1x_enable ; endmodule测试程序:(其中的系统函数编译有问题,可以删去)`timescale 1 ns / 1 nsmodule me_tf ;reg [7:0] din ;reg rst ;reg clk ;reg wr ;wire mdo ;wire ready ;me u1 (rst,clk,wr,din,ready,mdo) ; initial beginrst = 1'b0 ;clk = 1'b0 ;din = 8'h0 ;wr = 1'b0 ;me.clk1 = 1'b0 ;me.count = 3'b0 ;endinteger me_chann ;initial beginme_chann = $fopen("me.rpt") ;$timeformat(-9,,,5) ;endparameter clock_period = 10 ;setup_time = clock_period/4 ;always #(clock_period/2) clk = ~clk ;initial begin$fdisplay(me_chann, "Verilog simulation of Manchester encoder\n\n:); $shm_open("me.shm") ;$shm_probe("AS") ;$fmonitor(me_chann,"%ime=%t,rst=%b,wr=%b,me.clk=%b,din=%h,me.count=%b ,mdo=%b,ready=%b",$time,rst,wr,clk,me.clk1,din,me.count,mdo,ready) ; #5 rst = 1'b1;#15 rst = 1'b0 ;#(3 * clock_period - setup_time) din = 8'hff ;#(1 * clock_period) wr = 1'b1 ;#(1 * clock_period) wr = 1'b0 ;#(20 * clock_period) din = 8'haa ;#(1 * clock_period) wr = 1'b1 ;#(1 * clock_period) wr = 1'b0 ;#(20 * clock_period) din = 8'h00 ;#(1 * clock_period) wr = 1'b1 ;#(1 * clock_period) wr = 1'b0 ;#(20 * clock_period) din = 8'hf0 ;#(1 * clock_period) wr = 1'b1 ;#(1 * clock_period) wr = 1'b0 ;#(20 * clock_period) din = 8'h0f ;#(1 * clock_period) wr = 1'b1 ;#(1 * clock_period) wr = 1'b0 ;#(100 * clock_period) ;$fdisplay (me_chann,"\nSimulation of Manchester encoder complete."); $finish ;endendmodule。
曼彻斯特解码原则 125K EM4100系列RFID卡解码源程序分析资料

曼彻斯特解码原则+125K EM4100系列RFID卡解码源程序分析曼彻斯特解码原则1.曼彻斯特编码曼彻斯特编码(Manchester Encoding),也叫做相位编码(PE),是一个同步时钟编码技术,被物理层使用来编码一个同步位流的时钟和数据。
曼彻斯特编码被用在以太网媒介系统中。
曼彻斯特编码提供一个简单的方式给编码简单的二进制序列而没有长的周期没有转换级别,因而防止时钟同步的丢失,或来自低频率位移在贫乏补偿的模拟链接位错误。
在这个技术下,实际上的二进制数据被传输通过这个电缆,不是作为一个序列的逻辑1或0来发送的(技术上叫做反向不归零制(NRZ))。
相反地,这些位被转换为一个稍微不同的格式,它通过使用直接的二进制编码有很多的优点。
曼彻斯特编码,常用于局域网传输。
在曼彻斯特编码中,每一位的中间有一跳变,位中间的跳变既作时钟信号,又作数据信号;从高到低跳变表示"1",从低到高跳变表示"0"。
还有一种是差分曼彻斯特编码,每位中间的跳变仅提供时钟定时,而用每位开始时有无跳变表示"0"或"1",有跳变为"0",无跳变为"1"。
对于以上电平跳变观点有歧义:关于曼彻斯特编码电平跳变,在雷振甲编写的<<网络工程师教程>>中对曼彻斯特编码的解释为:从低电平到高电平的转换表示1,从高电平到低电平的转换表示0,模拟卷中的答案也是如此,张友生写的考点分析中也是这样讲的,而《计算机网络(第4版)》中(P232页)则解释为高电平到低电平的转换为1,低电平到高电平的转换为0。
清华大学的《计算机通信与网络教程》《计算机网络(第4版)》采用如下方式:曼彻斯特编码从高到低的跳变是0 从低到高的跳变是1。
两种曼彻斯特编码是将时钟和数据包含在数据流中,在传输代码信息的同时,也将时钟同步信号一起传输到对方,每位编码中有一跳变,不存在直流分量,因此具有自同步能力和良好的抗干扰性能。
RFID—曼彻斯特解码器

谢谢观赏
RFID标签芯片
—曼彻斯特简码器
电路与系统
冯海洋
2012.3.4
曼彻斯特简码器
功能描述
曼彻斯特解码器的功能是对模拟前端解调出来的 曼彻斯特码进行解码,并提取同步时钟。 具体分为四步:
1.对曼彻斯特码进行同步,消除可能产生的毛刺。 2.对数据的帧头进行识别。 3.对分隔符进行识别。 4.对数据进行解码
一个曼彻斯特码是由两个NRZ码构成。
曼彻斯特简码器
上升沿检测方法
根据数据延迟输出可以很好的判读上升沿,其具体实现 电路如下:
曼彻斯特简码器
下降沿检测方法
根据数据延迟输出可以很好的判读下降沿,其具体实现 电路如下:
曼彻斯特简码器
电路设计
根据其功能描述进行设计,本设计中主要部分为一 个状态机,其状态转移图如下:
曼彻斯特简码器
曼彻斯特码
曼彻斯特码是由NRZ码构成的,其共有四种状态,分 别如下:
曼彻斯特简码器 曼彻斯特解码算法
当NRZ为“01”的时候,曼彻斯特码为“0”;当 NRZ为“10”的时候,曼彻斯特码为“1”;当 NRZ为“11”和“00”的时候,曼彻斯特码不存 在。因为时钟频率为1.28MHz,而曼彻斯特码 的传输速率为40KHz,所以只需要设计一个32 位计数器,在计数器计数到一半的时候进行判 断。若其为上升沿,则输出为“0”;若其为下 降沿,则输出为“1”。
曼彻斯特简码器
状态机描述
S_quiet :当复位时候进入此状态,此状态下检测到的输入数据为低电平,若检 测到上升沿则转换至S_preamble_detect状态,否则状态保持不变。 S_preamble_detect:帧头检测域,由一个持续时间至少为400s的稳定的无调制 的载波组成。此状态下,输入数据一直为高电平,若检测到数据的下降沿,状态 转换至S_preamble状态,否则状态保持不变。 S_preamble:检测帧头9个“01”。利用计数器对“01”的个数进行计数。若结果 为9 时,则说明帧头正确,状态转换至S_delimiter 状态;若结果为10,则说明该信 号为阅读器发送的再同步信号,此时,解码器输出再同步信号resynce,状态转换 至S_quiet状态;否则状态转换至S_quiet状态。
matlab 曼彻斯特码编解码

matlab 曼彻斯特码编解码Matlab是一种用于科学计算和工程领域的编程语言和开发环境。
在通信领域中,编码和解码技术起着重要的作用。
曼彻斯特编码是一种常用的线路编码方式,可以将数字信号转换为对应的数据序列,以便在传输过程中进行可靠的数据传输。
本文将介绍如何使用Matlab进行曼彻斯特码的编码和解码。
一、曼彻斯特编码曼彻斯特编码是一种基于时钟信号的线路编码方式,它将每个比特分为两个时钟周期,每个时钟周期内信号的电压变化表示不同的数据。
具体来说,当输入数据为1时,信号在一个时钟周期内由高电平变为低电平,而当输入数据为0时,信号在一个时钟周期内由低电平变为高电平。
这种编码方式能够提高传输的可靠性和抗干扰能力。
在Matlab中,可以使用以下代码实现曼彻斯特编码:```matlabfunction manchesterCode = encodeManchester(data)N = length(data);manchesterCode = zeros(1, 2*N);for i = 1:Nif data(i) == 1manchesterCode(2*i-1) = 1;elsemanchesterCode(2*i) = 1;endendend```上述代码中,encodeManchester函数接受一个输入数据序列,并返回对应的曼彻斯特编码序列。
首先,我们获取输入数据的长度N,并初始化一个长度为2N的输出序列manchesterCode。
然后,对于输入数据中的每个比特,若为1,则在输出序列的奇数索引位置处设置为1,若为0,则在输出序列的偶数索引位置处设置为1。
最后,返回曼彻斯特编码序列。
二、曼彻斯特解码对于接收到的曼彻斯特编码序列,我们需要进行解码操作,将其还原为原始的数据序列。
在曼彻斯特编码中,每个时钟周期内信号的电压变化表示一个比特的数据。
因此,我们可以根据电压变化的情况来判断数据的取值,例如,当信号由高电平变为低电平时,表示该比特为1,而当信号由低电平变为高电平时,表示该比特为0。
简单的曼彻斯特编码的C语言实现

简单的曼彻斯特编码的C语言实现曼彻斯特编码是减小信号交流分量,实现固定信号占空比的基本方法。
用C语言实现如下:#include <stdio.h>#define uint8_t unsigned char#define uint16_t int#define BOOL int#define TRUE 1#define FALSE 0BOOL app_ManchesterEncode(uint8_t *indata,uint8_t *outdata,uint16_t inlength);BOOL app_ManchesterDecode(uint8_t *indata,uint8_t *outdata,uint16_t inlength);uint8_t indata[10]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0x43,0xb8};uint8_t middata[20];uint8_t outdata[10];uint16_t inlength;int main(){int length=10;int i=0;app_ManchesterEncode(indata,middata,length);if(app_ManchesterDecode(middata,outdata,length*2)==FALSE)printf("decode failed!\n");printf("in:");for(i=0;i<length;i++)printf(" %2.2x",indata[i]);printf("\n");printf("mid:");for(i=0;i<length*2;i++)printf(" %2.2x",middata[i]);printf("\n");printf("out:");for(i=0;i<length;i++)printf(" %2.2x",outdata[i]);printf("\n");}BOOL app_ManchesterEncode(uint8_t *indata,uint8_t *outdata,uint16_t inlength) {uint16_t i=0;uint8_t j=0;for(i=0;i<inlength;i++){outdata[2*i]=0;outdata[2*i+1]=0;for(j=0;j<8;j++)if(j<4)outdata[2*i+1]|=(((indata[i]>>j)&0x01)?2:1)<<j*2;elseoutdata[2*i]|=(((indata[i]>>j)&0x01)?2:1)<<(j*2-8);}return TRUE;}BOOL app_ManchesterDecode(uint8_t *indata,uint8_t *outdata,uint16_t inlength) {uint16_t i=0;uint8_t j=0;for(i=0;i<inlength/2;i++){outdata[i]=0;for(j=0;j<8;j++){if(j<4){if((indata[2*i+1]>>(j*2)&0x03)==0x01);else if((indata[2*i+1]>>(j*2)&0x03)==0x02)outdata[i]|=0x01<<j;else{printf("at i=%d j=%d data:%2.2x ",i,j,indata[2*i+1]&0x03);return FALSE;}}else{if((indata[2*i]>>(j*2-8)&0x03)==0x01);else if((indata[2*i]>>(j*2-8)&0x03)==0x02)outdata[i]|=0x01<<j;else{printf("at i=%d j=%d\n",i,j);return FALSE;}}}}return TRUE;}。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
曼彻斯特解码1、变量定义 (2)2、Manchest初始化 (2)3、Manchest解码信号翻转 (3)4、过滤错误的卡号 (4)5、获取正确的卡号 (5)6、Manchest获取卡号数据 (6)7、通过中断采样获取刷卡数据 (9)1、变量定义#define TH1_370US_H 0XFE //晶振11.0592MHZ,12T模式#define TL1_370US_L 0XAB#define SIGNAL_FLIP_TIME 10 //每隔100ms翻转一次读卡信号#define REPEAT_TIME 5 //500ms后重复读卡#define CLEAR_CARD_TIME 20 //2S后清除卡号数据#define MANCHEST_TIME 5sbit PULSE = P3^2;sbit RFEN = P3^5; //曼彻斯特解码脉冲信号sbit MANCHEST0= P3^2; //wiegand0sbit MANCHEST1= P3^3; //wiegand1uchar code CheckingTab[32]={ //接收到10组卡号的偶校验0X00,0X01,0X01,0X00,0X01,0X00,0X00,0X01, //这里数值是低五位的偶校验值0X01,0X00,0X00,0X01,0X00,0X01,0X01,0X00,0X01,0X00,0X00,0X01,0X00,0X01,0X01,0X00,0X00,0X01,0X01,0X00,0X01,0X00,0X00,0X01};uchar WGCardBuf[5]; //卡号uchar CopyCardBuf[5]; //备份卡号uchar ManchestBuf[11]; //暂存接收到的11组数据uchar idata g_ucManchestTime = MANCHEST_TIME; //uchar idata g_ucDWithCardTime= 0; //隔500ms处理该卡号uchar idata g_ucPreambleFlag = 0;uchar idata g_ucERAgainTimer = 0; //每隔100ms翻转一次RFENuchar idata g_ucStoreGroupCnt= 0; //接收到几组数据,这里为11组才可能正确uchar idata g_ucEGroupBitCnt = 0; //每组数据有5个为,5=4位卡号+1位偶校验uchar idata g_ucPreambleCount= 0; //9位为1的引导码uchar idata g_ucRemvoeCardTime=0; //隔多久清除以前的卡号数据,这里为3s2、Manchest初始化/******************************************************************** 函数原型:ManchestInit功能:曼彻斯特解码变量初始化输入:无输出:无说明:无*-------------------------------------------------------------------- *修改时间| 修改者| 备注*-------------------------------------------------------------------- *2012-02-14 Oscar First********************************************************************/ void ManchestInit(void) //初始化读卡参数{RFEN = 1;g_ucPreambleFlag = 0;g_ucStoreGroupCnt = 0;g_ucEGroupBitCnt = 5;g_ucPreambleCount = 9;g_ucERAgainTimer = SIGNAL_FLIP_TIME;}3、Manchest解码信号翻转/******************************************************************** 函数原型:ProcessManchestSignal功能:manchest解码的翻转信号输入:无输出:无说明:无*-------------------------------------------------------------------- *修改时间| 修改者| 备注*-------------------------------------------------------------------- *2012-02-14 Oscar First********************************************************************/ void ProcessManchestSignal(void){if((g_ucDWithCardTime!=0)&&(--g_ucDWithCardTime==0)){}if((g_ucRemvoeCardTime!=0)&&(--g_ucRemvoeCardTime==0)){CopyCardBuf[0] = 0; //清除卡号缓冲区CopyCardBuf[1] = 0;CopyCardBuf[2] = 0;CopyCardBuf[3] = 0;CopyCardBuf[4] = 0;}RFEN = ~RFEN;g_ucPreambleFlag = 0;g_ucPreambleCount= 9;if(RFEN){EX0 = 1;EX1 = 1;}else{EX0 = 0;EX1 = 0;}}4、过滤错误的卡号/******************************************************************** 函数原型:CalibrationCardData功能:一张卡号,如果出现全部相同的数字或者该卡号只有两种数据,则认为是错误的卡号。
输入:uchar *pCard,uchar ucCount输出:0或1说明:无*-------------------------------------------------------------------- *修改时间| 修改者| 备注*-------------------------------------------------------------------- *2012-02-14 Oscar First********************************************************************/ uchar CalibrationCardData(uchar *pCard,uchar ucCount){uchar ucCnt = 0;uchar ucVal = 0;uchar ucVerify = 0;uchar ucVerifyCnt= 0;ucVerify = 0;ucVal = pCard[0];for(ucCnt=1;ucCnt<ucCount;ucCnt++) //和第一个数相同的共有多少个{if(ucVal==pCard[ucCnt]){ucVerify++;}}if(ucVerify!=ucCount-1) //所有数据都相同?{ //不是ucVal = pCard[0];for(ucCnt=1;ucCnt<ucCount;ucCnt++){if(ucVal != pCard[ucCnt]) //找出和第一个数不同的数{break;}}ucVal=pCard[ucCnt];ucCnt++;ucVerifyCnt=0;while(ucCnt<ucCount){if(ucVal==pCard[ucCnt]){ucVerifyCnt++;} //和这个数相同的数有几个ucCnt++;}ucVerify = ucVerify + ucVerifyCnt; //两种数共有多少个if(ucVerify==(ucCount-2)) //这张卡只有两种数据{return 1; //则认为错误卡号}else{return 0; //不止两种数据}}else{return 1; //错误卡号}}5、获取正确的卡号/******************************************************************** 函数原型:DealWithCardData功能:处理卡号数据输入:无输出:0或1说明:无*-------------------------------------------------------------------- *修改时间| 修改者| 备注*-------------------------------------------------------------------- *2012-02-14 Oscar First********************************************************************/ uchar DealWithCardData(void){uchar ucCnt = 0;uchar ucValH = 0;uchar ucValL = 0;ucValH=CalibrationCardData(ManchestBuf,10);if(ucValH==0) //卡号正确{for(ucCnt=0;ucCnt<5;ucCnt++) //获取卡号{ucValH = ManchestBuf[2*ucCnt];ucValL = ManchestBuf[2*ucCnt+1];ucValH = (ucValH<<4) | ucValL;ManchestBuf[ucCnt] = ucValH;}return 0;}else //卡号错误{return 1;}}6、Manchest获取卡号数据/******************************************************************** 函数原型:ProcessManchest功能:停止位为0、行校验、列校验、输入:无输出:0或1说明:无*-------------------------------------------------------------------- *修改时间| 修改者| 备注*--------------------------------------------------------------------*2012-02-14 Oscar First********************************************************************/ void ProcessManchest(void){uchar ucCnt = 0;uchar ucVal = 0;uchar ucValue = 0;uchar ucVerify= 0;RFEN = 0;g_ucERAgainTimer = SIGNAL_FLIP_TIME;ucVal=ManchestBuf[10]&0X01; //获取停止位if(ucVal==0) //判断停止位是否为0{ //曼彻斯特编码的停止位为0 ucVerify=ManchestBuf[10]>>1; //获取列偶校验值for(ucCnt=0;ucCnt<10;ucCnt++) //获取行、列偶校验值{ucValue=ManchestBuf[ucCnt]&0X1F;if(CheckingTab[ucValue]!=0) //行校验是否正确{ucVerify = 1; //不正确break; //结束}ucVal = ManchestBuf[ucCnt]; //行校验通过ucVal = ucVal>>1; //移除行校验位ucVal = ucVal & 0X0F; //计算卡号ManchestBuf[ucCnt]=ucVal; //暂存卡号ucVerify=ucVal ^ ucVerify; //列校验}ucVerify = ucVerify&0X0F; //获取列校验值if(ucVerify==0) //列校验正确?{ucVal=DealWithCardData(); //正确,获取卡号if(ucVal==0){for(ucCnt=0;ucCnt<5;ucCnt++) //和上次卡号数据对比是否相等{if(CopyCardBuf[ucCnt]!=ManchestBuf[ucCnt]){break;}}if(ucCnt==5) //连续两次接收到是同一张卡号{if(g_ucDWithCardTime==0) //{for(ucCnt=0;ucCnt<5;ucCnt++)//暂存卡号{CopyCardBuf[ucCnt] = ManchestBuf[ucCnt];WGCardBuf[ucCnt] = ManchestBuf[ucCnt];}g_ucTask |= 0X04;EX0 = 1; //开外部中断EX1 = 1;g_ucDWithCardTime = REPEAT_TIME;}else{EX0 = 1; //开外部中断EX1 = 1;g_ucDWithCardTime = REPEAT_TIME;g_ucRemvoeCardTime= CLEAR_CARD_TIME;} //2S后清除卡号缓冲区}else{for(ucCnt=0;ucCnt<5;ucCnt++) //赋卡号,与下一次接收卡号匹配{CopyCardBuf[ucCnt] = ManchestBuf[ucCnt];}RFEN= 1;EX0 = 1;EX1 = 1;g_ucDWithCardTime = 0;g_ucRemvoeCardTime= CLEAR_CARD_TIME;} //2S后清除卡号缓冲区}else{RFEN= 1; //读取线圈数据EX0 = 1; //开中断EX1 = 1;}}else{EX0 = 1;EX1 = 1;}}else{EX0 = 1;EX1 = 1;}}7、通过中断采样获取刷卡数据/******************************************************************** ********************************************************************* *************************以下为曼彻斯特解码程序********************** *************通过外部中断0、1和定时器TI匹配解码卡号****************** ********************************************************************* ********************************************************************/ /******************************************************************** 函数原型:Int0Routine功能:触发Timer1采样输入:无输出:无说明:无*-------------------------------------------------------------------- *修改时间| 修改者| 备注*-------------------------------------------------------------------- *2012-02-14 Oscar First********************************************************************/ void Int0Routine(void) interrupt 0{if(MANCHEST0!=1){TH1 = TH1_370US_H;TL1 = TL1_370US_L;TR1 = 1;ET1 = 1;TF1 = 0;EX0 = 0;EX1 = 0;}}/******************************************************************** 函数原型:Int1Routine功能:触发Timer1采样输入:无输出:无说明:无*-------------------------------------------------------------------- *修改时间| 修改者| 备注*-------------------------------------------------------------------- *2012-02-14 Oscar First********************************************************************/ void Int1Routine(void) interrupt 2{if(MANCHEST1!=1){TH1 = TH1_370US_H;TL1 = TL1_370US_L;TR1 = 1;ET1 = 1;TF1 = 0;EX0 = 0;EX1 = 0;}}/******************************************************************** 函数原型:Timer1Routine功能:触发Timer1采样输入:无输出:无说明:无*-------------------------------------------------------------------- *修改时间| 修改者| 备注*-------------------------------------------------------------------- *2012-02-14 Oscar First********************************************************************/ void Timer1Routine(void) interrupt 3{uchar ucVal =0; //暂存获取数据TR1=0;if(g_ucPreambleFlag) //9个1到了?{if(PULSE){g_ucPreambleCount--;if(g_ucPreambleCount==0) //在PULSE==1的情况下如果g_ucPreamble_Count{ //还能减到0说明有连续的1出现IE0 = 0;IE1 = 0;EX1 = 1;EX0 = 1;g_ucPreambleFlag = 1;g_ucStoreGroupCnt= 0;g_ucEGroupBitCnt = 5;g_ucPreambleCount= 9;return;}}else{ //只要有低电平出现就重新付值,g_ucPreambleCount = 0X09; //看有否连续的高电平出现}ucVal = ManchestBuf[g_ucStoreGroupCnt];ucVal = ucVal<<1;if(PULSE) //为高{ucVal |= 1; //置位}else{ucVal &=0XFE;}ManchestBuf[g_ucStoreGroupCnt] = ucVal;if(g_ucEGroupBitCnt>5){IE0 = 0;IE1 = 0;EX1 = 1;EX0 = 1;g_ucPreambleFlag = 0;g_ucStoreGroupCnt= 0;g_ucEGroupBitCnt = 5;ManchestBuf[0] = 0;return;}g_ucEGroupBitCnt--;if(g_ucEGroupBitCnt==0){g_ucStoreGroupCnt++;if(g_ucStoreGroupCnt<11){IE0 = 0;IE1 = 0;EX1 = 1;EX0 = 1;g_ucEGroupBitCnt = 5;return;}if(g_ucStoreGroupCnt==11) //11组数据接收完成{EX0 = 0; //关中断EX1 = 0;TR1 = 0;g_ucTask |= 0X02; //置处理卡号标志return;}if(g_ucStoreGroupCnt>11){IE0 = 0;IE1 = 0;EX1 = 1;EX0 = 1;g_ucPreambleFlag = 0;g_ucEGroupBitCnt = 5;g_ucStoreGroupCnt= 0;ManchestBuf[0] = 0;return;}}else{IE0 = 0;IE1 = 0;EX1 = 1;EX0 = 1;} //11组字节收齐了?}else{if(PULSE){g_ucPreambleCount--;if(g_ucPreambleCount==0) //够不够9个1?{g_ucPreambleFlag = 1;g_ucStoreGroupCnt= 0;g_ucEGroupBitCnt = 5;g_ucPreambleCount= 9;}}else{g_ucPreambleCount = 9;}IE0 = 0;IE1 = 0;EX1 = 1;EX0 = 1;}}。