📄 main.c
字号:
/******************************************************************************************\
============================================================================================
/*******************************************************************************************/
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
#define TIME_OF 127 //22.1184M 254 11.0592M 127
#define DELAY_VAL 57 //22.1184M时晶振的值,可用软件模拟准确产生延时115 114 11.0592M 57
/*******************************************************************************************/
uchar buf[16];
uchar rxbuf[64];
uchar rxs;
ulong SN;
uchar *s;
/*******************************************************************************************/
sbit BEEP=P1^0;
//sbit IN_2270 BIT P1.5 ;2051
sbit Manchester_IN=P1^5; //曼彻斯特码输入端
sbit CFE = P1^4;
sbit MODE = P1^6;
sbit green=P3^7;
/*******************************************************************************************/
void Inituart(void);
void Delay(uchar n);
void TxData(uchar x);
void com();
void spk(uchar x);
void spkl(uchar x);
void readid();
ulong Read_Card();//尝试读十次卡,无卡则返回0,有卡则返回卡号
/*******************************************************************************************/
//function main();
/*******************************************************************************************/
void main(void)
{
Inituart(); // initialize 232 uart
spkl(1);
while(1) // circulation
{
if (rxs>3)
{
com();
}
else
{
readid();
}
}
}
void com_isr(void) interrupt 4 // 串口中断
{
uint ook;
ES=0;
ook=0;
while(ook<556)
{
rxbuf[rxs]=SBUF;
RI=0;
rxs++;
ook=0;
while(RI==0)
{if(ook++>555)break;}
}
ES=1;
}
/*******************************************************************************************/
//function Inituart();
/*******************************************************************************************/
void Inituart(void)
{
TMOD = 0x20; //timer1 working mode 1
TL1 = 0xfd; //f7=9600 for 16mhz Fosc,and ...
TH1 = 0xfd; //...fd=19200 for 11.0592mhz Fosc
SCON = 0x50; //uart mode 3,ren==1
PCON = 0x00; //smod=0
TR1 = 1; //start timer1
ES=1; //串口中断
EA=1;
MODE=0;
CFE=0;
}
/*******************************************************************************************/
//function Delay100us();Delay 100us
/*******************************************************************************************/
void Delay(uchar n)
{
uint i;
while(n--)
{for(i=0;i<80;i++); }
}
/*******************************************************************************************/
//Function TxData ();
/*******************************************************************************************/
void TxData(uchar x)
{uint ook;
ES=0;
SBUF=x;
while(TI==0){if(ook++>65530){return ;} }
TI=0;
ES=1;
}
uchar rxdata()
{ uchar temp,i;
ES=0;
temp=rxbuf[0];
rxs--;
for (i=0;i<rxs;i++)
{
rxbuf[i]=rxbuf[i+1];
}
ES=1;
return temp;
}
/*******************************************************************************************/
void com() //232串口接收 处理
{ uchar i,j,crc,temp,orde;
uint ook;
temp=rxdata();
RI=0;
if(temp!=0xfe){return ;}
ook=0001;
while(rxs==0){if(ook++>65530){spk(3);return ;} }
buf[10]=rxdata();
RI=0;
ook=0001;
while(rxs==0){if(ook++>65530){spk(3);return ;} }
buf[11]=rxdata();
RI=0;
ook=0001;
while(rxs==0){if(ook++>65530){spk(3);return ;} }
orde=rxdata();
RI=0;
ook=0001;
while(rxs==0){if(ook++>65530){spk(3);return ;} }
j=rxdata();
RI=0;
crc=j+orde+buf[11]+buf[10];
for (i=0;i<j;i++)
{ ook=0001;
while(rxs==0){if(ook++>65530){spk(3);return ;} }
buf[i]=rxdata();
RI=0;
crc=crc+buf[i];
}
ook=0001;
while(rxs==0){if(ook++>65530){spk(3);return ;} }
temp=rxdata();
RI=0;
if(temp!=crc){spk(3);return ;}
ook=0001;
while(rxs==0){if(ook++>65530){spk(3);return ;} }
temp=rxdata();
RI=0;
if(temp!=0xfd){spk(3);return ;}
switch(orde)
{
case 02:
spk(buf[0]);
break;
case 03: //FE 00 00 04 00 04 FD
TxData(0xfe);
TxData(0x00);
TxData(0x00);
TxData(0x04);
TxData(0x00);
TxData(0x04);
TxData(0xfd);
spk(1);
break;
default: break;
} //end switch
}
void spk(uchar x)
{
while(x--)
{
BEEP=0;
green=0;
Delay(100);
BEEP=1;
green=1;
Delay(50);
}
}
void spkl(uchar x)
{
while(x--)
{
BEEP=0;
green=0;
Delay(255);
BEEP=1;
green=1;
Delay(200);
}
}
//精确的384us延时,此延时可以不严格,但要大于256us小于512us
void Delay384us()
{
uchar i=DELAY_VAL;
while(i--);
}
void readid()
{ uchar i,j,k;
SN=Read_Card();
if(SN)
{ ///FE 00 00 01 04 01 02 03 04 12 FD
s=&SN;
for(i=0;i<4;i++)
{
buf[10+i]=*s;
s++;
}
SN=Read_Card();
if(SN==0)SN=Read_Card();
if(SN==0)SN=Read_Card();
if(SN==0)SN=Read_Card();
if(SN==0)SN=Read_Card();
if(SN)
{ s=&SN;
for(i=0;i<4;i++)
{
buf[i]=*s;
s++;
}
for(i=0;i<4;i++)
{
if (buf[i]!=buf[10+i])return;
}
TxData(0xfe);
TxData(0x00);
TxData(0x00);
TxData(0x01);
TxData(0x04);
k=0x05;
for(i=0;i<4;i++)
{
TxData(buf[i]);
k=k+buf[i];
}
TxData(k);
TxData(0xfd);
spkl(1);
Delay(255);
Delay(255);
Delay(255);
SN=0;
}
}
}
//读取卡号,
ulong Read_Card()
{
uchar i=0; //起始为的计数值
uchar error; //时间溢出的计数值
uchar error_flag; //时间溢出标志
uchar row,col; //行列寄存器
uchar row_parity; //行校验寄存器
uchar col_parity[5]; //列校验寄存器
uchar _data; //数据寄存器
ulong temp; //卡号寄存器
ulong timeout=0; //搜索次数寄存器
while(1)
{
if(timeout==10)return 0;//尝试10次搜索,如没有责返回0
else timeout++;
error=0;
while(Manchester_IN==0)//等高电平
{
if(error==TIME_OF)break;//超时退出
else error++;
}
if(error==100)continue;//结束本次主循环
else error=0;
Delay384us();
if(Manchester_IN)//寻找真正的1起始位,利用01的波形确定1起始位,即最后一位加第一位
{
for(i=0;i<8;i++)//判断是否是真的起始位
{
error=0; //限定等待时间
while(Manchester_IN)
{
if(error==TIME_OF)
{
error_flag=1;//时间溢出
break; //退出
}
else error++;
}
Delay384us(); //延时至下一码原
if(Manchester_IN&&error_flag==0); //判断下一位是否为1 和是否没有时间溢出
else break; //不是1退出,溢出退出
}
if(error_flag)//因时间溢出造成的本次主循环退出
{
error_flag=0;
continue; //退出本次循环
}
else;
if(i==8) //起始位接受完并且正确后开始接受数据
{
error_flag=0;
error=0; //限定等待时间
while(Manchester_IN)
{
if(error==TIME_OF)
{
error_flag=0;
break; //时间溢出造成的出错
}
else error++;
}
if(error_flag)
{
error_flag=0;
continue; //因等待待第一个正式数据错误引起的本次主循环退出
}
else;
//所有列校验清零
col_parity[0]=col_parity[1]=col_parity[2]=col_parity[3]=col_parity[4]=0;
for(row=0;row<11;row++) //共11行数据
{
for(col=0,row_parity=0/*行校验清零*/;col<5;col++)//共5列数据
{
Delay384us(); //延时至下一码原
if(Manchester_IN)_data=1; //数据为1
else _data=0; //数据为0
if(col<4&&row<10) //数据区的接受,后四个字节
{
temp<<=1; //左移一位
temp+=(ulong)_data; //数据相加
}
else;
row_parity+=_data; //行校验加入数据
col_parity[col]+=_data; //相应列校验加入数据 虽最后一列没有校验但为了方便也加上
error=0; //限定等待时间清零
while(Manchester_IN==(bit)_data)
{
if(error==TIME_OF) //由于时间溢出造成的数据出错
{
error_flag=1;
break; //退出本while循环
}
else error++;
}
if(error_flag)break; //出错退出内层for循环
else;
}
if(row<10)//最后一行没有校验所以要加限制
{
if((row_parity&0x01)||error_flag) //出错退出外for循环
{
temp=0;
error_flag=1;
break; //退出
}
else;
}
else;
}
//对最后接收的列校验进行判断,及对来自上面数据错误error_flag处理以结束本次主循环
if(error_flag||((col_parity[0]&0x01)&&(col_parity[1]&0x01)&&(col_parity[2]&0x01)&&(col_parity[3]&0x01)))
{ //最后一列没有校验
error_flag=0;
temp=0;
continue; //退出本次循环
}
else return temp;//将正确的数据返回
}
continue;
}
continue;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -