MEGA8-T2-CTC产生125KHz方波,ICP中断方式读125KHz的RFID卡(EM4100系列)成功,发贴祝贺!
ATMEGA8,11.0592MHZ,T2工作于CTC模式,OC2生产125.673KHz的方波,8050/8550两个三极管放大,358调制出来的信号加到M8的ICP脚上。串口输出读卡信息。效果不错。现在有效距离5CM,有空再调一下电感,距离应该可以达到15CM,因为以前调到过,只是程序没写好。
晶振如果用16M/8M/4M的能生产准确的125KHz方波。
先把程序拿来晒晒。原理图稍后上传。实物是自己用万用板搭的,就不照了。
另:现在程序中只用的行奇偶校验,还未用列奇偶校验,后面会加上。
补上原理图:
原理图-Protel99SE格式ourdev_393898.rar(文件大小:14K) (原文件名:m8_rfid.rar)
原理图-JPG格式,清析ourdev_393896.jpg(文件大小:523K,只有300K以内的图片才能直接显示) (原文件名:all-good.jpg)
http://cache.amobbs.com/bbs_upload782111/files_10/ourdev_393897.jpg
原理图-RF部分 (原文件名:jb.jpg)
//包含所需头文件
#include <avr/io.h>
#include <avr/interrupt.h>
/*------宏定义------*/
#define BIT(x) (1<<(x))
void put_c(unsigned char dat);
void put_s(unsigned char *dat,unsigned char enter);
void find_start(void);
volatile unsigned char bit_array;
volatile unsigned char test_end = 0;
//端口初始化
void port_init(void)
{
PORTB = 0x00;
DDRB= 0x08;
PORTC = 0x00;
DDRC= 0x00;
PORTD = 0x03;
DDRD= 0x02;
}
//定时T1初始化
void timer1_init(void)
{
TCCR1B = 0x00;//停止定时器
TIMSK |= 0x20;//中断允许
TCNT1H = 0xFF;
TCNT1L = 0xF8;//初始值
TCCR1A = 0x00;
TCCR1B = 0xC5;//启动定时器
}
//定时器T1输入捕捉中断服务程序
ISR(TIMER1_CAPT_vect)
{
static unsigned char tr = 0;
static unsigned char bit_no = 0;
static unsigned char one_time = 0;
TCCR1B = 0;
TCNT1 = 0;
if(ICR1 > 6)
{
bit_no = 0;
}
if(test_end == 0)
{
if(tr == 1)
{
bit_array = 1;
bit_no++;
if(bit_no == 0)
{
test_end = 1;
}
if(ICR1L > 4)
{
bit_array = 1;
bit_no++;
if(bit_no == 0)
{
test_end = 1;
}
}
TCCR1B = 0xC5; //上升沿触发
tr = 0;
}
else
{
bit_array = 0;
bit_no++;
if(bit_no == 0)
{
test_end = 1;
}
if(ICR1L > 4)
{
bit_array = 0;
bit_no++;
if(bit_no == 0)
{
test_end = 1;
}
}
TCCR1B = 0x85; //下降沿触发
tr = 1;
}
}
}
//定时器T2初始化
void timer2_init(void)
{
TCCR2= 0x00;//停止定时器
ASSR = 0x00;//异步时钟模式
TCNT2= 0x00;//初始值
OCR2 = 0x2B;//匹配值
TIMSK |= 0x00;//中断允许
TCCR2= 0x19;//启动定时器
}
//串口通信初始化
void usart_init(void)
{
UCSRB = 0x00;//禁止中断
UCSRA = 0x00;
UCSRC = BIT(URSEL) | 0x06;
UBRRL = 0x05;
UBRRH = 0x00;
UCSRB = 0x98;
}
void put_c(unsigned char dat)
{
while(!(UCSRA & (1 << UDRE)));
UDR = dat;
}
void put_s(unsigned char *dat,unsigned char enter)
{
while(*dat)
{
put_c(*dat);
dat++;
}
if(enter == 1)
{
put_c(0x0d);
put_c(0x0a);
}
}
void put_long(unsigned long dat)
{
unsigned long temp = 1000000000;
unsigned char i = 0;
unsigned char out = 0;
for(i = 0;i < 10;i++)
{
out = dat / temp;
dat %= temp;
temp /= 10;
put_c(out + 48);
}
// out = dat % temp;
// put_c(out + 48);
}
void init_devices(void)
{
cli(); //禁止所有中断
MCUCR= 0x00;
MCUCSR = 0x80;//禁止JTAG
GICR = 0x00;
port_init();
timer1_init();
timer2_init();
usart_init();
sei();//开全局中断
}
//主函数
int main(void)
{
unsigned char i = 0;
init_devices();
//在这继续添加你的代码
put_s("RFID Card Reader",1);
while(1)
{
if(test_end == 1)
{
decode();
test_end = 0;
}
}
return 0;
}
void decode(void)
{
unsigned char i,j,k;
unsigned char id_code = {0,0,0,0,0,0,0,0,0,0,0};
unsigned char col_parity = 0;
unsigned char row_parity = 0;
unsigned char temp = 0;
unsigned char start_data = {1,0,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1};
unsigned long rfid = 0;
for(i = 0;i < 128;i++)
{
for(j = 0;j < 20;j++)
{
if(bit_array != start_data)
{
break;
}
}
if(j == 20)
{
put_s("",1);
put_s("Find RFID Card.",1);
i += 20;
for(k = 0;k < 11;k++)
{
row_parity = 0;
// 读出五位数据
temp = 0;
for(j = 0;j < 5;j++)
{
temp <<= 1;
if((bit_array == 0) && (bit_array == 1))
{
temp |= 0x01;
if(j < 4)
{
row_parity += 1;
}
}
else if((bit_array == 1) && (bit_array == 0))
{
temp &= 0xfe;
}
else
{
return;
}
i += 2;
}
id_code = (temp >> 1);
temp &= 0x01;
row_parity %= 2;
if(k < 10)
{
if(row_parity != temp)
{
return;
}
}
else
{
if(temp != 0)
{
return;
}
}
}
if(k == 11)
{
put_s("ID Card :",0);
for(j = 2;j < 10;j++)
{
rfid += (((unsigned long)(id_code)) << (4 * (9 - j)));
}
}
put_long(rfid);
return;
}
}
} 先占个位。
回去睡觉了。 以加入原理图,更新到楼主位。 楼主继续,我发的那个简单的分立电路,距离都可以到5cm 还是上两张图吧。
http://cache.amobbs.com/bbs_upload782111/files_10/ourdev_405928.jpg
(原文件名:nEO_IMG_IMG_0112.jpg)
http://cache.amobbs.com/bbs_upload782111/files_10/ourdev_405929.jpg
(原文件名:nEO_IMG_IMG_0114.jpg)
http://cache.amobbs.com/bbs_upload782111/files_10/ourdev_405930.jpg
(原文件名:nEO_IMG_IMG_0115.jpg) 记号 顶一下,学习中 up mark 强人啊 楼主帮忙扫扫盲,就是读取的流程是什么:
发送125.673KHz信号-->RFID感应到电流--> ..............
用ICP1捕捉感应出的信号,L1 代表天线??? 我用MEGA48做过更简单的.也是5CM..
直接用两路正交的PWM驱动线圈.一个三极管.和简单的低通滤波,然后是MEGA48内置的模拟比较器.
不过我这人懒没画电路图.
板子是万能板焊的.都不知道丢哪了.因为感觉太近没什么实用的意义.
程序汇编写的 我以前看见过坛里有个不用运放检波的电路,超简单不知是怎么做到的。
找到了原来是【3楼】 whimsy 发的那个电路,再请教一下【3楼】 whimsy ,接比较器的那两个电阻怎么理解。看了半天没看懂
http://cache.amobbs.com/bbs_upload782111/files_10/ourdev_406828.jpg
(原文件名:未命名.jpg) 你搭个电路,用示波器一看就懂 如果我没有猜错的话,这个电路应该和楼主的最后移一级一样,是为了实现迟滞比较的,或类似的功能,
还有没看出来125K的载波是从那里虑除的,再请教一下 COOL! good...... 各位大虾提供的方案大都是读卡,请问写卡方案(电路和程序)是如何设计的,请介绍一下设计思路,谢谢! 还是看不懂
看来还有去学习模电去!! ding cool 分析 R12 C8 C9 为第一级滤波,C11 R13为第二级滤波。因为有D3的原因,经过D3后实际上只剩下半波,故只能采用电阻与电容并联滤波,检波实际上可理解为由C7取出 取出后经C11 R13滤波后再送运放,放大400倍后由比较器整形输出。 第一级滤波的截止频率大概是4.2K,第二级为417 HZ 。难道码率这么低?? 本人没研究过RFID 高人指教!
拙见,欢迎拍砖 回17楼,读卡和写卡的硬件电路是一样的,能实现读,就能实现写,
写的过程,是通过通断125KHz载波来发送写的指令,具体看ATA5557读写卡手册 有做过13M的么?
本贴被 wangguanfu 编辑过,最后修改时间:2008-12-31,01:08:55. 13M的你要省钱,就用FM1702SL,比飞利浦的便宜,整个范例电路都有 谢谢无私分享,感谢这么长时间以来有众多好心人在论坛交流和分享经验,收获很多,
新的一年就要来到,预祝各位新年好运,永远健康快乐 记号 Cool 好 记号。。。。 上传RFID芯片资料,里面有编码方式等~~~
点击此处下载 ourdev_569684.pdf(文件大小:79K) (原文件名:EM4100DS.pdf) 标记一下.一定要玩一玩. 好帖 请问楼主,你的天线设计是什么规格的啊?谢谢~ 有什么方法可以是电路对天线不是十分挑剔? 记号 记号。 厉害啊 ,南京地铁票是不是这个东西啊 厉害 mark,这要用到这个东西 ID卡开发,记录 厉害 呵呵,楼主强啊 我也弄出来了,用中断读的。 我是用pwm产生125KHz频率,然后通过外部中断来读取数据,在中断中判断时间长度来判断为0或者1。 楼主可以分析下后面的模拟部分是怎样工作的吗?谢谢 楼主还在吗 有哪个用此电路做成功了吗?我按照楼主的电路搭了个板子,发现有时能找到卡 有时找不到啊而且大多数是找不到卡 mark 顶 用楼主的方案已经实现,能够正确读卡,也是用万用板搭的电路,目前寻卡距离4CM左右,可能是我天线的问题,据网上说加大两个三极管的电压可以提高发射功率,从而寻卡距离变大。
PS:楼主提供的代码,有个地方写反了,导致读得的卡号老是不对,仔细阅读了代码,查了曼彻斯特编码解码的有关资料才发现原因,从而读的卡号正确。下次,上传点效果图 呵呵!
捕捉解码代码修改如下:
//定时器T1输入捕捉中断服务程序
ISR(TIMER1_CAPT_vect)
{
static unsigned char tr = 0;
static unsigned char bit_no = 0;
static unsigned char one_time = 0;
TCCR1B = 0;
TCNT1 = 0;
if(ICR1 > 6)
{
bit_no = 0;
}
if(test_end == 0)
{
if(tr == 1)
{
bit_array = 0; /***************楼主此处写反***********/
bit_no++;
if(bit_no == 0)
{
test_end = 1;
}
if(ICR1L > 4)
{
bit_array = 0; /***************楼主此处写反***********/
bit_no++;
if(bit_no == 0)
{
test_end = 1;
}
}
TCCR1B = 0xC5; //上升沿触发
tr = 0;
}
else
{
bit_array = 1; /***************楼主此处写反***********/
bit_no++;
if(bit_no == 0)
{
test_end = 1;
}
if(ICR1L > 4)
{
bit_array = 1; /***************楼主此处写反***********/
bit_no++;
if(bit_no == 0)
{
test_end = 1;
}
}
TCCR1B = 0x85; //下降沿触发
tr = 1;
}
}
} 效果图来了,显示的是ID卡背面的10位卡号
http://cache.amobbs.com/bbs_upload782111/files_23/ourdev_513069.jpg
(原文件名:1.jpg) 学习 记号~~ mark 好东西 我发现我什么都不懂 mark 重新绕制了下线圈,现在读卡距离9CM以上 呵呵 测试发现,加大那个隔直电容可以增大寻卡距离 强人 sunyouyuan 苹果 上几实物张图吧?能不能把后面的模拟部分解释下啊? 先谢谢了。 不好意思我是初学者 问个很低级的问题那个地方是天线呀?(从个地方哪引出来的) 顶 楼主,这个可以读M1卡么? 实物图来了
http://cache.amobbs.com/bbs_upload782111/files_23/ourdev_518100.jpg
(原文件名:20091224(001).jpg)
http://cache.amobbs.com/bbs_upload782111/files_23/ourdev_518101.jpg
(原文件名:20091224(002).jpg) 不好意思我是初学者 问个很低级的问题那个地方是天线呀?(从个地方哪引出来的)
——————
那个电感就是天线 楼主,这个可以读M1卡么?
——————————
不是楼主,也可以回答你的问题吧?呵呵
这个不能读M1卡的,M1卡工作在13.56MHZ 可读可写,这个只能读125K的ID卡卡号 mark Mark mark max202cpe用4个瓷片电容(104)能行么?datasheet上好像是极性电容器!但傻孩子的书上(深入浅出avr单片机)用的是瓷片! 回复【65楼】sunyouyuan 苹果
不好意思我是初学者 问个很低级的问题那个地方是天线呀?(从个地方哪引出来的)——————那个电感就是天线
-----------------------------------------------------------------------
天线是和电感并联吗?能不能解释下后面的模拟部分的工作原理呀? 天线是和电感并联吗?能不能解释下后面的模拟部分的工作原理呀?
————————————————————————————————————
不是并联,天线本身就是个电感线圈,不是上面都有实物图嘛
模拟部分我本身也不是很熟,按照我的理解说话吧
单片机的OC2比较输出125K的方波,经两三极管推挽放大输入到天线,由于L1、C10的谐振频率刚好是125K,因此产生谐振,此时线圈电流最大,通电线圈磁通量也就最大,若有卡在附近,由于ID卡里面也集成了线圈,两线圈耦合,ID卡返回卡号数据。经线圈接收,R10限流,再到二极管检波,由于经过二极管后的波形只有正半周,股需要RC并联滤波,R12、C8、C9构成一级滤波,C7是隔直电容,C11、R13构成二级滤波,主要是为了滤掉125K频率的载波信号,得到有用的125K/64的卡号信息,滤波后 经过LM358组成的放大、比较器后输入到单片机的捕捉口。 拙见,错误之处望指正! 好东西,学习一下. 不错,买过一个现成的模块,但距离太近。这个有空试试 mark 学习 学习一下 学习一下 mark MARK mark thanks mark 请问ID卡上的号码是按什么原理读出来的呢,能不能解释下原理,谢谢 MARK ding 一定要记住! mark 顶一下 好资料,封存 MARK MARK 好东西,rfid MARK 回复【1楼】rainbow 老陈
-----------------------------------------------------------------------
不错,我前段时间也想做一个 RF卡的售货机呢,最后改成IC卡,RF怕搞不定,或者耽误工期。学习了。你这个方案能读写RF卡吗? mark mark
mark一下,频率产生器。 和线圈谐振的电容使用什么类型的电容,难道是普通的瓷片电容?! mark