/*****************************************/
/* Copyright (c) 2005, 通信工程学院 */
/* All rights reserved. */
/* 作 者:戴 佳 */
/*****************************************/
#include "RFICRdWr.h"
/* 延时t毫秒函数 */
void delay(uint t)
{
uint i;
while(t--)
{
/* 对于11.0592M时钟,约延时1ms */
for (i=0;i<125;i++)
{}
}
}
/* 定时器0中断服务子程序 */
void timer0() interrupt 1 using 1
{
TR0 = 0; // 停止计数
TH0 = -5000/256; // 重设计数初值
TL0 = -5000%256;
count++;
if (count>300) // 第一次检测到卡1.5s后
{
count = 0;
if(!flagok) // 如果检测到1.5s后读写标志还是失败,则蜂鸣器报警
{
BP = 0;
delay(2000); // 报警持续2s
BP = 1;
}
}
else
TR0 = 1; // 启动T0计数
}
/* 串口发送命令函数 */
void sendcmd(uchar *str)
{
while(*str != 0)
{
TI = 0; // 清发送标志位
SBUF = *str; // 发送数据
str++;
while(!TI); // 等待发送完成
}
}
/* 字符数组转换为16进制字符串函数,16进制字符串附接在给定字符串后,
参数byte为数组地址,len为数组长度,str为转换后字符串 */
void Byte2Hex(uchar *byte,uchar len,uchar *str)
{
uchar i, j;
uchar tmp;
j = strlen(str);
for(i=0; i<len; i++)
{
tmp = ((*byte)>>4)&0x0f; // 字节高位
if(tmp < 0x0a)
*(str+j) = tmp+0x30;
else
*(str+j) = tmp-0x0a+'a';
str++;
tmp = (*byte)&0x0f; // 字节低位
if(tmp < 0x0a)
*(str+j) = tmp+0x30;
else
*(str+j) = tmp-0x0a+'a';
str++;
}
*(str+j) = 0; // 字符串结束
}
/* 16进制字符串转换为字节数组函数,参数str为要转换的字符串,byte为
转换后数组地址,若str长度不为偶数,则转换后最后一个字节高位补0*/
void Hex2Byte(uchar *str, uchar *byte)
{
uchar tmp;
while(*str != 0)
{
tmp = ((*str)<<4)&0xf0; // 字节高位
str++;
if(*str == 0) // 若str长度为奇数,则转换后最后一个字节高位补0
{
*byte = (tmp>>4)&0x0f;
return;
}
tmp += (*str)&0x0f; // 字节低位
*byte = tmp;
byte++;
}
}
/* 串口初始化 */
void serial_init()
{
/* 9600,n,8,1,外部晶振11.0592MHz,查询方式 */
TMOD = 0x20; // T1使用工作方式2
TH1 = 250; // 设置T1初值
TL1 = 250;
TR1 = 1; // T1开始计数
PCON = 0x80; // SMOD = 1
SCON = 0x50; // 工作方式1,波特率9600bit/s,允许接收
ES = 0; // 关闭串行中断
}
/* H6152复位函数 */
void H6152Rst()
{
strcpy(hbuf,"x");
sendcmd(hbuf); // 发送命令"x"
delay(300); // 延时300ms确保H6152复位完毕
}
/* 卡片检测函数,检测到有卡在读写器有效区域内返回 */
void cardcheck()
{
strcpy(hbuf,"c");
sendcmd(hbuf); // 发送命令"c",命令进入“连续读”模式
delay(10); // 延时10ms
/* 一旦发现串口接收到数据就立即返回,
表示检测到读写器有效区域内有卡片 */
RI = 0;
while(!RI);
delay(10); // 延时10ms,消抖
RI = 0;
while(!RI);
/* 确认工作区内有卡片,返回 */
}
/* 停止卡片检测函数,即取消“连续读"模式 */
void endcheck()
{
strcpy(hbuf," ");
sendcmd(hbuf); // 发送" "取消”连续读“模式
delay(10); // 延时10ms
}
/* 自动选卡函数,读取所有卡片,随机选中并
返回其序列号,主要用于第一次选卡 */
uchar autoselect(uchar *buf)
{
uchar i;
strcpy(hbuf,"m\r");
sendcmd(hbuf); // 发送"m<CR>"
for(i=0;i<8;i++) // 接收第一张卡的序列号
{
RI = 0;
while(!RI);
*(hbuf+i) = SBUF;
/* 如果接收到错误信息则返回错误代码 */
if((*(hbuf+i)>0x39)&&(*(hbuf+i)<'a'))
return *(hbuf+i);
}
*(hbuf+i) = 0;
Hex2Byte(hbuf,buf); // 第一张卡片序列号由16进制字符串转换为字节数组
strcpy(hbuf,"m");
Byte2Hex(buf,4,hbuf);
delay(10);
sendcmd(hbuf); // 发送"m<SN>",选中第一张卡片
for(i=0;i<8;i++) // 接收选中卡片的序列号
{
RI = 0;
while(!RI);
*(hbuf+i) = SBUF;
/* 如果接收到错误信息则返回错误代码 */
if((*(hbuf+i)>0x39)&&(*(hbuf+i)<'a'))
return *(hbuf+i);
}
return 0; // 成功
}
/* 指定选卡函数,根据制定序列号选卡 */
uchar snselect(uchar *sn)
{
uchar i;
strcpy(hbuf,"m");
Byte2Hex(sn,4,hbuf); // 将序列号sn转换为16进制字符串
delay(10);
sendcmd(hbuf); // 发送"m<SN>",选中第一张卡片
for(i=0;i<8;i++) // 接收选中卡片的序列号
{
RI = 0;
while(!RI);
*(hbuf+i) = SBUF;
/* 如果接收到错误信息则返回错误代码 */
if((*(hbuf+i)>0x39)&&(*(hbuf+i)<'a'))
return *(hbuf+i);
}
return 0; // 成功
}
/* 登录扇区函数,参数sect为扇区号,keytype为密码类型,keyvalue为密码内容。
keyvalue为NULL时,表示使用默认密码;keytype为0x10~0x2f和0x30~0x4f
之间或者0xff时,程序忽略keyvalue的内容。 */
uchar loginsect(uchar sect,uchar keytype,uchar *keyvalue)
{
uchar tmp;
if(sect>16) // 扇区号超过16报错
return ERR_E;
strcpy(hbuf,"l");
Byte2Hex(§,1,hbuf); // 将sect转换为16进制字符串
if(((keytype>0x10)&&(keytype<0x2f))||((keytype>0x30)&&(keytype<0x4f)))
Byte2Hex(&keytype,1,hbuf); // "l<sect><reg>
else if((keytype==KEY_A)||(keytype==KEY_B)) // 使用密码A或B登录
{
Byte2Hex(&keytype,1,hbuf);
if (keyvalue==NULL)
strcat(hbuf,"\r"); // "l<sect>aa<CR>或"l<sect>bb<CR>"
else
Byte2Hex(keyvalue,6,hbuf); // "l<sect>aa<value>或"l<sect>bb<value>"
}
else if(keytype==KEY_DEFAULT) // 使用默认密码登录
strcat(hbuf,"\r"); // "l<sect><CR>
else
return ERR_U; // 未知错误
sendcmd(hbuf); // 发送命令
RI = 0;
while(!RI);
tmp = SBUF;
if(tmp=='L') // 登录成功
return 0;
else
return tmp; // 返回错误
}
/* 读块函数,将块中内容读至缓冲区,缓冲区长度应为16字节 */
uchar readblock(uchar block,uchar *buf)
{
uchar i;
if (block>64) // 块号超过64报错
return ERR_E;
strcpy(hbuf,"r");
Byte2Hex(&block,1,hbuf); // block转换为16进制字符串
sendcmd(hbuf); // "r<block>"
for (i=0;i<32;i++) // 接收块数据
{
RI = 0;
while(!RI);
*(hbuf+i) = SBUF;
/* 如果接收到错误信息则返回错误代码 */
if((*(hbuf+i)>0x39)&&(*(hbuf+i)<'a'))
return *(hbuf+i);
}
*(hbuf+32) = 0;
Hex2Byte(hbuf,buf); // 将块内容由16进制字符串转换为字节数组
return 0; // 成功
}
/* 写块函数,将缓冲区中内容写入块,缓冲区长度16字节 */
uchar writeblock(uchar block,uchar *buf)
{
uchar i;
if (block>64) // 块号超过64报错
return ERR_E;
strcpy(hbuf,"w");
Byte2Hex(&block,1,hbuf); // block转换为16进制字符串
Byte2Hex(buf,16,hbuf); // 将要写入块的内容转换为16进制字符串
sendcmd(hbuf); // "w<block><data>"
for (i=0;i<32;i++) // 接收返回数据,为写入的内容
{
RI = 0;
while(!RI);
*(hbuf+i) = SBUF;
/* 如果接收到错误信息则返回错误代码 */
if((*(hbuf+i)>0x39)&&(*(hbuf+i)<'a'))
return *(hbuf+i);
}
return 0; // 成功
}
/* 主程序,选取一张卡,将0~15共16个数写入扇区1的块0中,然后再从该扇区的
块0中读出这16个数,存入缓冲区block0buf,接着再将block0buf中的内容写入
该扇区的块1中,最后再从块1中读出16个数,存入缓冲区block1buf中。本程序
的主要功能是验证H6152模块对非接触式IC卡的读写 */
void main()
{
char sn[4];
uchar sectno,blockno; // 扇区号、块号
uchar blockbuf[16]; // 要写入块的内容缓冲区
uchar i;
sectno = 1; // 扇区1
blockno = 0; // 块0
flagok = 0;
flagfirst = 1;
flagselok = 0;
flaglogok = 0;
count = 0;
for (i=0;i<16;i++) // 写入0~15共16字节
blockbuf[i]=i;
CTRL = 0; // H6152正常工作
BP = 1; // 蜂鸣器不发声
EA = 1;
TMOD = 0x01; // 模式1,T0为16位定时/计数器
TH0 = -5000/256; // 设置计数初值
TL0 = -5000%256;
ET0 = 1; // 打开T0中断
serial_init(); // 串口初始化
H6152Rst(); // H6152复位
while(!flagok)
{
cardcheck(); // 卡片检测
endcheck(); // 停止检测
if (flagfirst) // 如果是第一次选卡
{
flagfirst = 0;
if (autoselect(sn)==0) // 第一张卡片选择成功,并保存序列号sn
{
flagselok = 1;
TR0 = 1; // T0开始计时
}
}
else
{
if(snselect(sn)==0) // 指定序列号sn的卡片选择成功
flagselok = 1;
}
if (flagselok)
{
if(loginsect(sectno,KEY_DEFAULT,NULL)=='L') // 登录成功
flaglogok = 1;
else
{
flagselok = 0
没有合适的资源?快使用搜索试试~ 我知道了~
51单片机C语言应用程序实例精讲(程序与电路图).rar
共414个文件
bak:62个
lnp:32个
sch:32个
需积分: 9 3 下载量 104 浏览量
2008-07-18
09:44:53
上传
评论
收藏 643KB RAR 举报
温馨提示
51单片机C语言应用程序实例精讲(程序与电路图).rar
资源推荐
资源详情
资源评论
收起资源包目录
51单片机C语言应用程序实例精讲(程序与电路图).rar (414个子文件)
485MonPro 10KB
7LEDShowPro 6KB
8LEDShowPro 6KB
STARTUP.A51 5KB
STARTUP.A51 5KB
STARTUP.A51 5KB
STARTUP.A51 5KB
STARTUP.A51 5KB
STARTUP.A51 5KB
DigAirPressPro_Uv2.Bak 2KB
DigThermoPro_Uv2.Bak 2KB
StepperPro_Uv2.Bak 2KB
PWLockPro_Uv2.Bak 2KB
BattChargerPro_Uv2.Bak 2KB
CalendarClkPro_Uv2.Bak 2KB
ParallelDACPro_Uv2.Bak 2KB
SerialDACPro_Uv2.Bak 2KB
DPRamCommPro_Uv2.Bak 2KB
MusInstruPro_Uv2.Bak 2KB
SerialADCPro_Uv2.Bak 2KB
RFICRdWrPro_Uv2.Bak 2KB
PMPDataRPro_Uv2.Bak 2KB
WirelessPro_Uv2.Bak 2KB
EthernetPro_Uv2.Bak 2KB
ICRdWrPro_Uv2.Bak 2KB
7LEDShowPro_Uv2.Bak 2KB
Lcd_Show_Uv2.Bak 2KB
GPSDataPro_Uv2.Bak 2KB
PPDataRPro_Uv2.Bak 2KB
PPDataTPro_Uv2.Bak 2KB
485MonPro_Uv2.Bak 2KB
WdTstPro_Uv2.Bak 2KB
VoicePro_Uv2.Bak 2KB
PWMPro_Uv2.Bak 2KB
I2CPro_Uv2.Bak 2KB
CRCPro_Uv2.Bak 2KB
SignalGenPro_Uv2.Bak 2KB
ParallelADCPro_Uv2.Bak 2KB
PMPDataTPro_Uv2.Bak 2KB
SignalGenPro_Opt.Bak 2KB
8DigitShowPro_Uv2.Bak 2KB
CRCPro_Opt.Bak 1KB
StepperPro_Opt.Bak 1KB
PWLockPro_Opt.Bak 1KB
CalendarClkPro_Opt.Bak 1KB
DPRamCommPro_Opt.Bak 1KB
RFICRdWrPro_Opt.Bak 1KB
WirelessPro_Opt.Bak 1KB
ICRdWrPro_Opt.Bak 1KB
PMPDataTPro_Opt.Bak 1KB
EthernetPro_Opt.Bak 1KB
SerialDACPro_Opt.Bak 1KB
PMPDataRPro_Opt.Bak 1KB
GPSDataPro_Opt.Bak 1KB
SerialADCPro_Opt.Bak 1KB
DigAirPressPro_Opt.Bak 1KB
BattChargerPro_Opt.Bak 1KB
MusInstruPro_Opt.Bak 1KB
7LEDShowPro_Opt.Bak 1KB
485MonPro_Opt.Bak 1KB
VoicePro_Opt.Bak 1KB
DigThermoPro_Opt.Bak 1KB
PPDataTPro_Opt.Bak 1KB
PPDataRPro_Opt.Bak 1KB
WdTstPro_Opt.Bak 1KB
I2CPro_Opt.Bak 1KB
ParallelDACPro_Opt.Bak 1KB
Lcd_Show_Opt.Bak 1KB
ParallelADCPro_Opt.Bak 1KB
PWMPro_Opt.Bak 1KB
8DigitShowPro_Opt.Bak 955B
BattChargerPro 3KB
RFICRdWr.c 9KB
PWLock.c 6KB
ICRdWr.c 5KB
CRC.c 4KB
DPRamComm.c 4KB
Ethernet.c 4KB
485Mon.c 3KB
wireless.c 3KB
I2C.c 3KB
GPSData.c 3KB
SerialDAC.c 3KB
MusInstru.c 3KB
PMPDataR.c 3KB
DigThermo.c 3KB
PMPDataT.c 2KB
8DigitShow.c 2KB
Stepper.c 2KB
PPDataR.c 2KB
lcd_show.c 2KB
PPDataT.c 2KB
7LEDShow.c 2KB
CalendarClk.c 2KB
Voice.c 2KB
PWM.c 2KB
BattCharger.c 1KB
SignalGen.c 1KB
DigAirPress.c 1KB
SerialADC.c 964B
共 414 条
- 1
- 2
- 3
- 4
- 5
资源评论
syscangodot
- 粉丝: 0
- 资源: 3
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功