?? u2270.c
字號:
/*H4001只讀卡讀碼程序*/
/******************頭文件********************/
#include <sst89x5xxrd2.h>
#include <absacc.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit RF_DATA_IN = P3^4; //接收來至U2270B的數據"Output"
sbit SO = P3^1; //單片機輸出數據到用戶接口
sbit SCK= P1^0; //同步時鐘輸出
sbit CP= P1^7; //卡存在信號輸出
sbit MSEL= P1^2; //數據發送方式選擇
sbit WATCHDOG = P2^1; //看門狗
sbit DD = P2^0; //蜂鳴器
/****************全局變量***********************/
uchar data Read_RF_Data[11]; //暫存從U2270B上接收的數據
uchar data ID_Data[6]; //暫存經效驗后的正確數據
uint data TIMER_1=0;
bit Check_Data_bit; //效驗請求標志位
/****************函數列表***********************/
void Recive_RF_Data(void);
void Check_Data(void);
void Clern_Number(void);
void Send_RS232net(uchar Data[],uchar Num);
void delay0_2ms(uint count);
void delay1ms(uint count);
void dida(uchar j);
void Data_start(void)
{
TMOD=0x21; //T0方式1,T1工作于方式2
TH1=0x00; //初始化T1計時器
TL1=0x00;
TR1=0;
SCON=0x50; //串行口初始化
PCON=0x80; //SMOD位設置
TH0=0x00; //初始化T0計時器
TL0=0x04;
TR0=0;
ES=1; //開放串行口中斷
EA=1; //開放總中斷
}
/**********************************************/
/*主函數*/
/**********************************************/
void main(void)
{
delay1ms(100);
Data_start();
while(1)
{
WATCHDOG=~WATCHDOG;
Recive_RF_Data(); //調用接收RF數據函數
if(Check_Data_bit==1) //如果此位為1,有一組數據申請效驗
{
Check_Data(); //調用數據效驗函數
Check_Data_bit=0;
}
}
}
/*********************************************/
/*接收RF數據*/
/*********************************************/
void Recive_RF_Data(void)
{
/////////////////////定義局部變量
uchar header,pc;
uchar temp;
uchar temp1;
uint temp2;
uchar ByteCounter; //字節計數器
uchar *PData;
uchar BitCounter; //位計數器
////////////////////初始化變量值
header=0;pc=4;
PData=Read_RF_Data;
temp=0;
temp1=0;
ByteCounter=0;
BitCounter=5;
/////////////////////檢測一個穩定的低電平
str:
WATCHDOG=~WATCHDOG;
if(RF_DATA_IN==0)
if(RF_DATA_IN==0)
if(RF_DATA_IN==0)
if(RF_DATA_IN==0)
if(RF_DATA_IN==0)
{
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
////////////////////檢測一個起始位電平
while(RF_DATA_IN==0); //當電平由低向高跳變時啟動計時器
TR0=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
////////////////////檢測9個"header"
while(RF_DATA_IN==1);
TR0=0;
TF0=0;
TIMER_1=TH0;
TIMER_1=(TIMER_1<<8)+TL0;
TH0=0x00;
TL0=0x04;
temp2=0x1e3;
if(TIMER_1>temp2) // >520us
{
goto str;
}
temp2=0x1c8;
if(TIMER_1<temp2) // <490us
{
goto str;
}
do
{
WATCHDOG=~WATCHDOG;
TIMER_1=0;
while(RF_DATA_IN==0);
TR0=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
while(RF_DATA_IN==1);
TR0=0;
TF0=0;
TIMER_1=TH0;
TIMER_1=(TIMER_1<<8)+TL0;
TH0=0x00;
TL0=0x04;
temp2=0x106;
if(TIMER_1>temp2)// >280us
{
header=0;
goto str;
}
temp2=0xd8;
if(TIMER_1<temp2)// <230us
{
header=0;
goto str;
}
header++;
}while(header<8);
TR0=0;
TF0=0;
///////////////////如果9個"header"都對,開始接收卡內數據
TH0=0xfe; //time:300us
TL0=0xeb;
TR0=1;
if(header==8)
{
do
{
do
{
while(TF0==0); //等待一個位周期
TF0=0;
if(RF_DATA_IN==1) temp=1;
else temp=0;
while(RF_DATA_IN==temp) //檢測電平跳變否?
{
if(TF0==1) //如果300us計時到還未跳變,視為非法電平!!!
{
TR0=0;
TF0=0;
goto str;
}
}
TH0=0xfe; //time:300us
TL0=0xeb;
temp=~RF_DATA_IN;
temp1=(temp1<<1)|temp;
BitCounter--;
}while(BitCounter); //一個字節完否
*(PData+ByteCounter)=temp1; //將一字節數據存入緩存數組
temp1=0;
BitCounter=5;
ByteCounter++;
WATCHDOG=~WATCHDOG;
}while(ByteCounter<10);
do
{
WATCHDOG=~WATCHDOG;
while(TF0==0); //等待一個位周期
TF0=0;
if(RF_DATA_IN==1) temp=1;
else temp=0;
while(RF_DATA_IN==temp) //檢測電平跳變否?
{
if(TF0==1) //如果300us計時到還未跳變,視為非法電平!!!
{
TR0=0;
TF0=0;
goto str;
}
}
TH0=0xfe; //time:300us
TL0=0xeb;
temp=~RF_DATA_IN;
temp1=(temp1<<1)|temp;
pc--;
}while(pc); //一個字節完否
Read_RF_Data[10]=temp1; //將一字節數據存入緩存數組
///////////////////檢測最后一個停止位
while(TF0==0);
TR0=0;
TF0=0;
if(RF_DATA_IN==1) temp=1;
else temp=0;
while(RF_DATA_IN==temp) //檢測電平跳變否?
{
if(TF0==1) //如果300us計時到還未跳變,視為非法電平!!!
{
TR0=0;
TF0=0;
goto str;
}
}
temp=~RF_DATA_IN;
if(temp==0) //如果停止位正確
{
Check_Data_bit=1; //置效驗請求標志
}
else //如果停止位不正確
{
Clern_Number(); //清除
}
}
}
}
/*********************************************/
/*效驗數據*/
/*********************************************/
void Check_Data(void)
{
/////////////////////定義局部變量
uchar temp;
uchar temp1;
uchar ByteCounter; //數組計數器
uchar ByteCounter1;
uchar *PData;
uchar *PData1;
////////////////////初如化變量值
PData=Read_RF_Data;
PData1=ID_Data;
temp=0;
temp1=0;
ByteCounter=0;
ByteCounter1=0;
/////////////////////循環效驗
WATCHDOG=~WATCHDOG;
/////////////////////行校驗
for(ByteCounter1=0;ByteCounter1<5;ByteCounter1++)//有5個字節數據
{
temp=(((*(PData+ByteCounter))&0x10)>>4)+(((*(PData+ByteCounter))&0x08)>>3)+(((*(PData+ByteCounter))&0x04)>>2)+(((*(PData+ByteCounter))&0x02)>>1);
if((temp&0x01)==((*(PData+ByteCounter))&0x01))//效驗高4位
{
temp1=(*(PData+ByteCounter)&0xfe)<<3;
ByteCounter++;
temp=(((*(PData+ByteCounter))&0x10)>>4)+(((*(PData+ByteCounter))&0x08)>>3)+(((*(PData+ByteCounter))&0x04)>>2)+(((*(PData+ByteCounter))&0x02)>>1);
if((temp&0x01)==((*(PData+ByteCounter))&0x01))//效驗高4位
{
*(PData1+ByteCounter1)=temp1|((*(PData+ByteCounter)&0xfe)>>1);//高低位生成一個字節存入數組
ByteCounter++;
}
else
{
ByteCounter1=5;//只要有一組不對則退出效驗
Clern_Number();//并清所有數據
}
}
else
{
ByteCounter1=5;//只要有一組不對則退出效驗
Clern_Number();//并清所有數據
}
WATCHDOG=~WATCHDOG;
}
/////////////////////列校驗
//......因沒有必要所以先省略此處.........//
/////////////////////生成校驗和,并發送出去
if(ByteCounter==10)
{
ID_Data[5]=ID_Data[0]+ID_Data[1]+ID_Data[2]+ID_Data[3]+ID_Data[4];//生成校驗和
if(MSEL==0) //此腳如果為低電位,為異步通信方式發送數據
{
CP=0;
delay0_2ms(1);
Send_RS232net(ID_Data,6); //調用串口發送函數
delay0_2ms(1);
CP=1;
}
Clern_Number();
dida(1);
delay0_2ms(1000);//*****(正確讀取一張卡號后要等待約一秒后再重新掃描)*****
}
}
//************************************************************
/*清暫存器*/
//************************************************************
void Clern_Number(void)
{
WATCHDOG=~WATCHDOG;
Read_RF_Data[0]=0;
Read_RF_Data[1]=0;
Read_RF_Data[2]=0;
Read_RF_Data[3]=0;
Read_RF_Data[4]=0;
Read_RF_Data[5]=0;
Read_RF_Data[6]=0;
Read_RF_Data[7]=0;
Read_RF_Data[8]=0;
Read_RF_Data[9]=0;
Read_RF_Data[10]=0;
ID_Data[0]=0;
ID_Data[1]=0;
ID_Data[2]=0;
ID_Data[3]=0;
ID_Data[4]=0;
ID_Data[5]=0;
}
//**********************************************************
/*串行口發送,接收程序*/
//**********************************************************
void Send_RS232net(uchar Data[],uchar Num) //串行口數據發送
{
uchar i=0;
uchar *PData;
PData=Data;
WATCHDOG=~WATCHDOG;
TH1=0xf3; //串行口波特率2400b/s
TL1=0xf3;
TR1=1;
for(i=0;i<Num;i++)//有Num組號碼要發送
{
SBUF=*(PData+i);
while(TI==0);TI=0;//等待數據發送出去
delay0_2ms(1);//等待后再發送
}
TR1=0;
}
//*****************************************************
/*延時0.2ms*count*/
//*****************************************************
void delay0_2ms(uint count)
{
uint k;
while(count--!=0)
{
for(k=0;k<50;k++)
{
WATCHDOG=~WATCHDOG;
}
}
}
void delay1ms(uint count)
{
uint k;
while(count--!=0)
{
for(k=0;k<250;k++)
{
WATCHDOG=~WATCHDOG;
}
}
}
//*****************************************************
/*鳴叫聲*/
//*****************************************************
void dida(uchar j)
{
uchar i;
for(i=0;i<j;i++)
{
DD=~DD;
delay1ms(30);
DD=~DD;
delay1ms(30);
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -