在Win下编译VIM

不得不承认,我是一个有点贪新厌旧的人——前阵子才不断吹嘘Emacs的强大,但是这两个月来,又变成了忠实的VIMer。没办法……Emacs的UTF支持实在太难handle了。而且VIM有native的Python、Ruby支持,速度比Emacs快点,对于现在做coding那是再合适不过了。

我们从www.vim.org上下载的gvim.exe已经内置了Python支持,不过遗憾的是,Python的版本为2.4,而我机器上安装的是2.5版。要使用vim内置的python功能,就只好自己动手编译vim了:

系统需求:

Cygwin cvs,或者Wincvs

Visual Studio,用于编译源码

Vim Runtime Files(如果你没有安装过vim71的话)

 

下载源代码:

我们可以通过CVS下载VIM的源码(Vim from CVS):

cvs -z3 -d:pserver:anonymous@vim.cvs.sf.net:/cvsroot/vim checkout vim7

准备编译:

代码下载完成后,你可以在src目录下看到一个叫“bigvim.bat”的文件。没错!就是它,打开然后编辑吧。

 在我的机器上是这样设置的:nmake -f Make_mvc.mak GUI=yes OLE=no MBTYE=yes PERL=D:\perl DYNAMIC_PERL=yes PERL_VER=56 PYTHON=d:\Python25 DYNAMIC_PYTHON=yes PYTHON_VER=25 RUBY=d:\ruby DYNAMIC_RUBY=yes RUBY_VER=18 RUBY_VER_LONG=1.8 DYNAMIC_TCL=no %1 IME=yes GIME=yes CSCOPE=yes SNIFF=yes ICONV=yes GETTEXT=yes CPUNR=pentium4 DEBUG=no MAP=no FEATURES=HUGE

其中最重要的就是设置好 PYTHON与PYTHON_VER这两个变量,当然啦,Ruby和Perl的设置也大同小异。如果你想知道还有什么选项的话,不妨打开Make_mvc.mak看看。

在正式编译之前,还有一个小问题,就是修改Ruby的头文件。

D:\ruby\lib\ruby\1.8\i386-mswin32\config.h

 把这个文件的最顶端三行注释掉

/*#if _MSC_VER != 1200#error MSC version unmatch#endif*/

 Ready!

编译:

下面开始编译,打开一个dos窗口,切换到vim7\src目录。首先要确认你的Visual Studio的各环境变量都正确设置好了(如果不确定的话,可以运行vc\bin\vcvars32.bat),然后运行bigvim.bat。经过一段时间,编译完成。

编译完成后,你可以在vim7\src目录下找到gvim.exe这个文件,把它复制到你的vim安装目录下,覆盖同名文件。

Done~! 享受你的VIM吧~

On March 17, 2008 3:06 am Comments (3)

The GUI Toolkit, Framework Page

I’m now working on one of my homeworks, titled "C++ programing". The aim is to write a program that can check and correct syntax error like M$ Word. Here’s some GUI Framework to be chosen.

http://www.geocities.com/SiliconValley/Vista/7184/guitool.html

On January 31, 2007 8:26 pm Comments (0)

Gromacs 使用

1.       convert the pdb-file to a gromacs structure file(.gro / .pdb) and a gromacs topology file(.top)

这一步需要gromacs的预处理程序pdb2gmx

标准的输入命令应该是:

pdb2gmx -ignh -f speptide.pdb -p speptide.top -o speptide.gro

这个命令之后有一个force field 的选择 系统给出了11种力场,具体以后实际计算中如何选择力场还是应该多参阅文献和gromacs说明书的。

这步之后可以在屏幕看到:

                ——— PLEASE NOTE ————

You have succesfully generated a topology from: speptide.pdb.

The G43a1 force field and the spc water model are used.

Note that the default mechanism for selecting a force fields has

changed, starting from GROMACS version 3.2.0

                ——— ETON ESAELP ————

至此,完成了从pdbgrotop的转变。另外,我也看过有的作这一步命令时候并不进行top文件的转换,因为在genbox(对盒子加水溶剂化时还要对top文件进行修改)

2.       solvate the peptide in water

这一步需要用到editconfgenbox两个程序,命令的标准书写应该是:

# editconf -bt cubic -f speptide.gro -o speptide_box.gro -c -d 0.5

可以在屏幕上看到

Read 191 atoms

Volume: 8.17315 nm^3, corresponds to roughly 3600 electrons

No velocities found

    system size :  1.774  3.372  1.367 (nm)

    diameter    :  3.517               (nm)

    center      :  2.650  1.453  2.417 (nm)

    box vectors :  1.774  3.372  1.366 (nm)

    box angles  :  90.00  90.00  90.00 (degrees)

    box volume  :   8.17               (nm^3)

    shift       : -0.391  0.806 -0.158 (nm)

new center      :  2.259  2.259  2.259 (nm)

new box vectors :  4.517  4.517  4.517 (nm)

new box angles  :  90.00  90.00  90.00 (degrees)

new box volume  :  92.18               (nm^3)

 

因为程序的默认,所以这一步命令可以写作:

# editconf –f speptide –o –d 0.5

这里-f之后的sp文件是默认gro文件或者pdb文件,-o后面生成的output file是放入盒子的体系的gro文件 按照这样的格式,输出的文件被默认命名为-out.gro

 

体系放入盒子之后在盒子中注入水

# genbox -cp speptide_box.gro -cs -p speptide.top -o speptide_water.gro

也可简写为

# genbox –cp out –cs –p sprptide –o b4em

Screen–

Output configuration contains 9035 atoms in 2967 residues

Volume                 :     92.1813 (nm^3)

Density                :     994.449 (g/l)

Number of SOL molecules:   2948  

 

之后看加水之后的top文件 用命令 #  tail speptide.top

可以看到

 [ system ]

; Name

Protein in water

 

[ molecules ]

; Compound        #mols

Protein             1

SOL              2948

其中SOL后面的数字2948就是genbox加入盒子的水分子的数目。

Editconf程序的另一个用途是讲gro文件转化回pdb 这时可以讲speptide_water.gro转化回pdb观察

editconf –f speptide_water.gro –o speptide.pdb

拖回本机 spbdv或者vmd观察

The next step is to generate index file . in the tutor of  gromacs , we are told that there are a set of index groups to select, unfortunately, I didi not find them ,so I have to use make_ndx to generate one .

# make_ndx –f b4em

 

3.       perform an enery  minimization of the peptide in solvent

Now the simulation system is almost ready. Before we can start the dynamics, we must perform an energy minimization, to alleviate any bad contacts (atoms overlapping such that a significant repulsion would result, causing numerical problems in the simulation) that might be present in the system.

# grompp –v –f em.mdp –c speptide_water.gro –p speptide.top –o speptide_em.tpr

Or use this command for short:

# grompp –v –f em –c b4em –p speptide –o em

After this command ,the bad contacs have been removed .so we can do enery minimization now.

# mdrun –v –s speptide_em.tpr –o speptide_em.trr –c after_em.gro –g emlog.log

Or

# mdrun –v –s em –o em –c after_em –g emlog

From screen ,we can see these ——

 Steepest Descents:

   Tolerance (Fmax)   =  2.00000e+03

   Number of steps    =          100

Step=    0, Dmax= 1.0e-02 nm, Epot= -8.02562e+04 Fmax= 2.70468e+04, atom= 6792

Step=    1, Dmax= 1.0e-02 nm, Epot= -8.69641e+04 Fmax= 1.24531e+04, atom= 6657

Step=    2, Dmax= 1.2e-02 nm, Epot= -9.48067e+04 Fmax= 5.54072e+03, atom= 9009

Step=    3, Dmax= 1.4e-02 nm, Epot= -1.02743e+05 Fmax= 2.86957e+03, atom= 8766

Step=    4, Dmax= 1.7e-02 nm, Epot= -1.08941e+05 Fmax= 1.53075e+04, atom= 150

Step=    5, Dmax= 2.1e-02 nm, Epot= -1.10083e+05 Fmax= 1.31653e+04, atom= 150

Step=    6, Dmax= 2.5e-02 nm, Epot= -1.10564e+05 Fmax= 2.16454e+04, atom= 150

Step=    7, Dmax= 3.0e-02 nm, Epot= -1.11528e+05 Fmax= 1.82398e+04, atom= 150

Step=    9, Dmax= 1.8e-02 nm, Epot= -1.12767e+05 Fmax= 3.87548e+03, atom= 120

Step=   11, Dmax= 1.1e-02 nm, Epot= -1.13598e+05 Fmax= 1.23013e+04, atom= 120

Step=   12, Dmax= 1.3e-02 nm, Epot= -1.14464e+05 Fmax= 5.37656e+03, atom= 120

Step=   13, Dmax= 1.5e-02 nm, Epot= -1.14787e+05 Fmax= 1.74494e+04, atom= 120

Step=   14, Dmax= 1.9e-02 nm, Epot= -1.15874e+05 Fmax= 8.35820e+03, atom= 120

Step=   16, Dmax= 1.1e-02 nm, Epot= -1.16420e+05 Fmax= 6.65421e+03, atom= 120

Step=   17, Dmax= 1.3e-02 nm, Epot= -1.16807e+05 Fmax= 1.08106e+04, atom= 120

Step=   18, Dmax= 1.6e-02 nm, Epot= -1.17248e+05 Fmax= 1.12834e+04, atom= 120

Step=   19, Dmax= 1.9e-02 nm, Epot= -1.17425e+05 Fmax= 1.45145e+04, atom= 120

Step=   20, Dmax= 2.3e-02 nm, Epot= -1.17590e+05 Fmax= 1.67089e+04, atom= 120

Step=   22, Dmax= 1.4e-02 nm, Epot= -1.18845e+05 Fmax= 2.65542e+03, atom= 121

Step=   23, Dmax= 1.7e-02 nm, Epot= -1.19198e+05 Fmax= 2.39072e+04, atom= 120

Step=   24, Dmax= 2.0e-02 nm, Epot= -1.20588e+05 Fmax= 6.17310e+03, atom= 120

Step=   26, Dmax= 1.2e-02 nm, Epot= -1.20901e+05 Fmax= 1.04224e+04, atom= 120

Step=   27, Dmax= 1.4e-02 nm, Epot= -1.21229e+05 Fmax= 8.89909e+03, atom= 120

Step=   28, Dmax= 1.7e-02 nm, Epot= -1.21346e+05 Fmax= 1.51125e+04, atom= 120

Step=   29, Dmax= 2.1e-02 nm, Epot= -1.21686e+05 Fmax= 1.29390e+04, atom= 120

Step=   31, Dmax= 1.2e-02 nm, Epot= -1.22216e+05 Fmax= 3.21419e+03, atom= 120

Step=   33, Dmax= 7.5e-03 nm, Epot= -1.22523e+05 Fmax= 6.52631e+03, atom= 120

Step=   34, Dmax= 8.9e-03 nm, Epot= -1.22796e+05 Fmax= 6.31916e+03, atom= 120

Step=   35, Dmax= 1.1e-02 nm, Epot= -1.22998e+05 Fmax= 8.04922e+03, atom= 120

Step=   36, Dmax= 1.3e-02 nm, Epot= -1.23167e+05 Fmax= 9.93619e+03, atom= 120

Step=   37, Dmax= 1.5e-02 nm, Epot= -1.23317e+05 Fmax= 1.10029e+04, atom= 120

Step=   39, Dmax= 9.3e-03 nm, Epot= -1.23857e+05 Fmax= 1.88770e+03, atom= 810

 

writing lowest energy coordinates.

 

Steepest Descents converged to Fmax < 2000 in 40 steps

Potential Energy  = -1.2385705e+05

Maximum force     =  1.8876959e+03 on atom 81

Norm of force     =  1.3663420e+04

NOTICE!!!!!!!!!

If the potential enery after minimization is lower than -1.1e+05kJ/mol, it is acceptable and the structure can be used for MD caculations.

 

On January 17, 2007 8:16 pm Comments (1)

配置好Emacs了……

千辛万苦才用上雅黑体……但是AA的支持仿佛……

 

On October 25, 2006 5:28 pm Comments (0)

XeTex on Ubuntu

经过一番努力,终于把XeTex装好了,记录一下~

系统:Ubuntu Dapper 6.06 LTS

先安装 tetex-base, tetex-bin, tetex-extra, tetex-commom 这些基本的Tex系统。

sudo apt-get install  tetex-base tetex-bin tetex-extra tetex-commom

然后到这里下载XeTex的deb包,并安装。

sudo dpkg -i xdvipdfmx_0.3-1_i386.deb

sudo dpkg -i xetex_0.995-1_i386.deb

正常来说,安装第二个包的时候会报错, 说hyphen出错之类的,这是因为XeTex不支持其中的几种语言。为了正常安装,需要把这几种语言去掉。使用texconfig命令,进入"HYPHENATION"菜单,选择xelatex,把

magyar        huhyphn.tex

serbian        srhyphc.tex

这两句注释掉,然后再安装一次 xetex_0.995-1_i386.deb,成功!

下面是截图:

 

On October 21, 2006 3:22 pm Comments (0)

北大清华令人很灰心:美国数学大师点破中国学术死穴。

北大清华令人很灰心:美国数学大师点破中国学术死穴。

一个没有文化的国家,做不了好学问。能够学贯中西、博古通今固然好,但是,如果一个民族摒弃自身的文化背景,拥洋为重,最终只会失去身份认同,变得高不成、低不就。菲尔兹奖(Fields Medal)得主、华人数学大师丘成桐指出,中国学术界所面对的,正正就是这个窘境。丘成桐接受访问的时候,谈到中国学术界种种不良的风气,归根究底,所有问题都是源于19 66至1976年的“文化大革命”,摧毁中国多年良好的文化传统,大师给中国学术界点破死穴。

他解释:“自那时开始,中国人的价值观完全改变,是非观念和道德操守遭到扭曲,以致现在的学生和学校变得唯利是图,这种文化气候,是中国难以孕育一流学问的最主要原因。”

另一方面,父母崇洋的心态,也令孩子失去深厚的文化根基。丘成桐指出,中国许多父母都希望子女做一个黄皮肤黑眼睛的西方人,结果是中西文化都学不好,他更以“二不像”来形容这个现象。文化上的缺失,影响尤其广泛深刻,以致中   国的学术界,出现以下种种流弊。  

“中国的学生,读书的目的,只有两个,要么能够赚钱,要么当官,他们普遍有一种学而优则士的想法,认为只要当官,就可以过舒适的生活,所以,中国的学生,做学问达到一个地步,足够令他们找到一份安定的工作便会停下来,他们追求的东西只此而已,对学问根本没有热诚。” 丘成桐概叹,在中国,真正有心钻研纯科学的人实在不多,跟外国的学生真心以研究为目标相比,实在相去甚远。  

名牌大学只唯利是图除了部份学生以金钱挂帅外,有些学校的态度也是唯利是图的。某名牌大学的代表和一些中国官员曾经到哈佛大学取经,然而,他们问的问题,叫丘成桐感到非常失望,他说:“中国的大学一心只想赚钱,他们问哈佛大学如何图利,但当我告诉他们办学不能赚钱的时候,他们表现得相当失望。”   

对于中国教授的质素,丘成桐也不敢恭维:“即使是国内名牌大学老师的质素也没有保证,许多老师只懂讨论第三流的问题,学生不会钻研出第一流的学问。”   

除了质素差劣外,有些老师也没有做好本份教好学生。丘成桐举了一个很经典的例子: “哈佛大学数学系有一年录取了一个全北京大学最优秀的学生,当我们向北大核实学生的身份时,北大全数学系26个最资深的教授也不知道,最后一直问到副教授才能确定这个学生的身份。”丘成桐后来发现,有些老师教学生,原来从未见面,也不相往来,这倒是闻所未闻的稀奇事。      

丘成桐又批评中国只重量、不重质的风气:“只着重宣传生产多、数量大,领导便会高兴。以学术界为例,有些大学的教授,一人带着30个博士生,误以为教导愈多学生表示自己愈有能力,但结果是全无质素可言。在外国,一个教授只会带着2至5个学生,但是那些学生很多都会成为大教授,这就是质素。”   

除了教授迷信数字外,就连大学与大学之间,也在进行数字的角力。他说:“全国有500多个科学院院士,北京大学、清华大学以至各省的重点大学往往以院士的多寡去量度学校的质素,提拔人才的时候,又以那位教授在某个场合讲话最多为标准。中国人就是缺乏自信心,才会这样量度自己。”     

北大清华令人很灰心中国最著名的大学,以北京大学和清华大学为首,一个国家有高质素的大学,固然是好事,但是,丘成桐却指出,北京大学的势力范围,遍及全中国,当中的派系斗争,反而窒碍了学术界自由的发展。丘成桐直言:“北京大学和清华大学对中国其他大学的打压,令人很灰心。”  

=============牛==============

“我认识中山大学的一位学者,他对数学的认识,已经达到世界一流的标准,但是由于北京大学和清华大学对他的打压,令他的地位连边也沾不上,充其量只是在广州有一点名气而已。”丘成桐概叹,“这种社会风气令学者觉得学问不是最  重要的。既然单*阿庾奉承便可以得到重用,为何不抄小径?”   

=============================

人治观念强,是中国的文化特色之一。丘成桐指出,在这种文化气候底下,中国的学术界欠缺一个公平、公开的人才提拔机制;同时,学生的发展空间也受到很大的限制。     

丘成桐说:“在中国学术界最有影响力的,主要是院士,他们的平均年龄约70岁,虽然他们已经没有担当最前线的领导工作,但是国内学生的研究方向,仍然得以这些人的好恶来决定,假如他们不喜欢你的研究方向,你是做不成的。”   研究员只顾讨好上级中国的研究员,精力都花在讨好上级之上,对知识的渴求,似乎只是次要。丘成桐说:“在中国做研究的顾忌实在太多,对于相同的问题,不同的人会有不同的研究方向,并没有高低对错之分,但是,中国的学生永远不敢跟老师唱反调。”        

人治观念过重造成的另一个结果,就是出现任人为亲的情况。丘成桐说:“在中国,提拔人才的所谓“机制”,已经成为提拔自己亲信的工具。在美国,只要你有能力,20多岁已经可以当上大教授;但是在中国,假如你不是博士或领导出身,即使你有能力,别人也会借机打击你。”丘成桐当上史丹福大学数学系教授那一年,他才25岁。  理论科学的研究,是发展工业的基础,对一个国家的长远发展来说,相当重要,这就是丘成桐对理论科学的评价。他指出:“欧美几百年来钻研理论科学,根基深厚,有利发展任何工业。然而,中国却没有这个深厚的底子支持。”   

但是,丘成桐认为,中国政府有关部门看不到理论科学的重要性。他说:“中国投放在理论科学的教育经费实在太少,研究理论科学本来就是最省钱的,就以数学为例吧,根本不需要什么机器,研究一个数学的题目,所需经费很少。”   然而,由于理论科学的价值,不能立竿见影,所以往往容易被人忽略。丘成桐指出:“ 理论科学就好像礼、乐、射、御、书、数,在中国文化中也扮演着举足轻重的角色,但是,你说这些东西有没有用呢?”丘成桐强调,礼、乐、射、御、书、数建立的,是无形的文化资产,同样地,实用科学必须建基于理论科学之上,才能够站得住脚。  

由于对理论科学缺乏长远的眼光,加上部份学校亦有“做大做多”的倾向,所以有关部门愿意花百万元(人民币,下同)兴建教学楼和教师宿舍,只因为这些都是别人看得到的东西。  

然而,丘成桐批评,没有软体的配套,硬体做得再好也无用武之地。他曾经到访清华大学的图书馆,发现大学的图书经费,相当缺乏。丘成桐概叹:“别说一般大学,就连国内的名牌大学如清华大学的图书馆,也找不到数学界的期刊。”   丘成桐指出:“研究任何一个科目,期刊都是不可或缺的东西,但是,领导层认为期刊只是一本薄薄的小书,售价却要数千元,他们认为不值。期刊能够将第一手的资讯带给你,但是他们却看不到期刊的重要性,所以大学也得不到这方面的经费。”

丘教授的一个心愿 ,就是希望帮中国强大起来。这些年来,他先后为香港中文大学数学研究所、晨兴数学研究中心及浙江大学数学研究中心筹集资金逾一亿元。         

文化大革命的摧残,加上近代中国人对自身的文化认同不足,令中国做不了好学问。丘成桐概叹:“外国人都来学中国的文化,汉学在日本也很流行,偏偏就是中国人看不起自己的文化,其实,文化修养对一个人来说,是十分重要的。许多中国人每每面对困境都会显得手足无措,归根究底就是文化修养的问题。”   

对于未来中国学术界的发展,丘成桐很希望,中国人能够珍惜自己的文化传统,做好学问,因为只有解决最根本的问题,中国才有望发展世界一流的学府。然而,要改变中国人对自身文化的态度,要走的路,还多着呢。

On June 6, 2006 11:44 pm Comments (0)

FreeBSD下通过PoPToP实现远程访问VPN

FreeBSD下通过PoPToP实现远程访问VPN
对于构建VPN来说,网络隧道(Tunnelling)技术是个关键技术。网络隧道技术指的是利用一种网络协议来传输另一种网络协议,它主要利用网络隧道协议来实现这种功能。
现有两种类型的网络隧道协议,一种是二层隧道协议,用于传输二层网络协议,它主要应用于构建远程访问虚拟专网(Access VPN);另一种是三层隧道协议,用于传输三层网络协议,它主要应用于构建企业内部虚拟专网(Intranet VPN)和扩展的企业内部虚拟专网(Extranet VPN)。
FreeBSD下的PoPToP实现了二层隧道协议中的PPTP(Point to Point Tunneling Protocol)封装,利用它建立远程访问VPN服务,可以替代现有的电话长途拨号访问。
一、 环境
1. 一台PC服务器安装FreeBSD,双网卡连接内外两个网段,内部地址172.16.1.210/24,外部地址为固定合法IP地址。
2. 外地用户PC通过Internet和FreeBSD主机建立VPN连接连入局域网。
二、 安装
# cd /usr/ports/net/poptop
# make; make install
如果执行make不允许安装,编辑当前目录下的Makefile,将forbidden那行注释掉
三、 配置
a、 # vi /etc/syslog.conf,增加一行daemon.debug /var/log/pptpd.log
# kill –HUP (syslogd当前pid)
b、 # vi /etc/ppp/options
lock
debug
auth
+chap # chap认证方式
proxyarp
# vi /etc/ppp/chap-secrets
user * password * # 给VPN用户的用户名和密码
# vi /etc/ppp/ppp.conf
loop:
set timeout 0
set device localhost:pptp
set log phase
set dial
set login
# Server (local) IP address, Range for Clients, and Netmask
set ifaddr 172.16.1.210 172.16.1.225-172.16.1.254 255.255.255.0
set server /tmp/loop “” 0177
loop-in:
set timeout 0
allow mode direct
pptp:
load loop
enable proxy
accept dns
# DNS Servers to assign client
set dns 172.16.1.210
# NetBIOS/WINS Servers to assign client
# set nbns 172.16.1.200
set device !/etc/ppp/secure
# vi /etc/ppp/secure
#!/bin/sh
exec /usr/sbin/ppp -direct loop-in
c、 编辑/etc/local/etc/pptpd.conf
speed 115200
option /etc/ppp/ppp.conf
debug
localip 172.16.1.210
remoteip 172.16.1.225-254 # 连接上来的用户从中获取IP
四、 运行
# /usr/local/etc/rc.d/pptpd.sh start 或
# /usr/local/sbin/pptpd &
五、 测试
找个能连接Internet的windows 98se或win2000机器,创建一个VPN连接。服务器地址填FreeBSD的外部合法IP,用户名user,口令password,并禁用数据压缩属性。
注:windows 98se下建立VPN连接需先添加一个微软虚拟适配器,一个拨号适配器。
六、 其他
1、 VPN的连接速度取决于双方(服务器,用户端)接入Internet的速度。
2、 上述设置的PoPToP服务只实现了一个隧道封装,通过该隧道传输的数据并没有加密,所以并非严格意义上VPN连接。
3、 用户通过VPN连接上来后,相当于直接连入你的局域网。出于安全考虑,可以结合FreeBSD的防火墙(如ipf),设置一些规则来限制分配给VPN用户的那段IP地址的访问范围。
4、 如果连接失败,打开/var/log/pptpd.log、/var/log/ppp.log查看错误纪录。

On June 3, 2006 7:48 am Comments (0)

破解IC电话卡

IC卡内部基本情况:

计数方法:
在67-103地址单元中分为5个不可重置8单元计数器,芯片初始化时,72-103地址单元所对应
的4个较低的8单元计数器中可以放0到8个“1”而67-71地址单元所对应的第5个计数器可以
放0到5个“1”。所谓计数一次,就是将一个单元从“1”写成“0”。一个计数器中8位全为
“0”后,要计数,需借位操作,即将高位计数器的一位从“1”写成“0”而相应其低位计
数器整个字节从“0”擦除成“1”。可见4个8单元计数器如此逐一递减,其最大计数为8的4
次方=4096。第5个计数器中5个单元因处在最高位只能被写“0”无法擦成“1”。因此只能
计数5次。故芯片总计数为5X4096=20480。当全部计数单元(地址67-103)都被写成“0”
时,卡片就用完了,不过,芯片出厂初始化时,初置的计数值由国家不同和卡片面值不同而
不同,如100元卡初置计数值为1000。

举例: 100元(1000计数单元预置初始值).
——–

Byte9 Byte10 Byte11 Byte12 Byte13
————————————————————–
000000 - 00000001 - 01111111 - 00011111 - 00000000
————————————————————–
(3)octal (6)octal (7)octal (1)octal (2)octal
————————————————————–
Value = 0*8^4 + 1*8^3 + 7*8^2 + 5*8^1 + 0*8^
————————————————————–
总值 = 1000 Units
Ⅰ-5)内存数据:
字节 位 二进制 十六进制
+———–+—–+
1 1 –> 8 | | |
+———–+—–+
2 9 –> 16 | 0010 1111 | F | —> 德国
| 0011 0111 | | —> 西班牙
| 0011 1011 | B | —> 希腊
+———–+—–+
3 17 –> 24 | | |
4 25 –> 32 | | | —> 出厂编号(写保护)
5 33 –> 40 | | |
6 41 –> 48 | | |
7 49 –> 56 | | |
8 57 –> 64 | | |
+———–+—–+
9 65 –> 72 | | | —> c4096 )
10 73 –> 80 | | | —> c512 )
11 81 –> 88 | | | —> c64 ) 5个8进制计数区
12 89 –> 96 | | | —> c8 )
13 97 –> 104 | | | —> c0 )
+———–+—–+
14 105 –> 112 | 1111 1111 | $FF |
15 113 –> 120 | 1111 1111 | $FF | —> 所有位都为”1″
16 120 –> 128 | 1111 1111 | $FF |
+———–+—–+

自从80年代中期出现IC电话卡后,基本已取代了原来流行的电话磁卡,磁卡存在存在严重的
安全问题,已逐步淘汰。
即使IC电话卡,也不能算很安全,卡内所有数据只要有简单的读写装置并按时序操作都能读
取,事实上电话卡和信用卡一样内部没有什么秘密信息,仅仅是带串行输出的128位EPROM而
已(对二类卡是256位PROM),不要以为弄懂了它是怎么工作你就有办法重新对卡内数据重新
填充,其开始的64位是带写保护的,在出厂时其熔丝位已被编程,你已无法对其更改,其后
的40位计数单元受内部逻辑控制在写时只能减少不能增加直至到0为止,因此你想用一般的
IC电话卡打免费电话是不可能的,除非你能用微控制器(单片机)仿真它(如果你能读懂本文
介绍的所有内容)。IC电话卡是一种一次性使用的计数卡,以一次性的计数方式,从写满的
计数器中减“1”,直至存储单元减为空为止。
卡片每次消费计数的“单位价值”根据各种应用系统的实际需要而定。例如:对于中国IC电
话卡,如30元卡对应内部计数值为300,每单位值对应0.1元,IC 卡电话机每分钟产生一次
扣费信号,扣费值由当地IC电话管理系统设定,一般是价值0.5元或1元,卡片被计数5次和
10次。对于其它国家属于第一类IC电话卡而言也是如此,只是内部初始计数值不同,每次扣
除额度不一样罢了。其他对于公用加油卡,IC卡计费加油机每一公升(或一加仑)产生一次
扣费操作,卡片被操作一次扣2.5元等等,均属于等同原理。事实上,这类卡内部为128位
(16字节) NMOS存储器,按如下规律分布:

64 位 EPPOM(8字节) 写保护区(芯片数据代码区、发行数据代码区)
40 位 EEPROM(5字节)
24 位 为全“1”(3字节)
共16字节数据。
Ⅰ-2)引脚:
————-+————-
| 1 | 5 | 引 脚:
| | | ——-
+——-\ | /——-+
| 2 +—-+ + 6 | 1 : Vcc = 5V 5 : Gnd
| | | | 2 : Reset 6 : NC
+——–| |——–+ 3 : Clock 7 : I/O
| 3 | | 7 | 4 : NC 8 : NC
| +—-+—-+ |
+——-/ | \——-+ Vcc:电源 Gnd:地脚 Reset:复位
| 4 | 8 |
| | | Clock:时钟 I/O:数据 NC: 空脚
————-+————-
因有三个脚为空脚,目前一般有采用8脚和6脚封装的,6脚封装的无最下一排两个空脚

Ⅰ-3)主要特性:
-采用单一5V电源供电
-遵循ISO/IEC7816-3同步协议进行双向数据传输
-低功耗
-NMOS技术
-高可靠性,抗静电干扰能力>4KV

Ⅰ-4)时序图
复位:
为使地址计数器复位到0,先让Reset端变高。紧跟着一个Clock脉冲(从低到高再降到0),
Reset重新变低,把Clock脉冲包住。随着Reset端变低,地址0单元的数据从I/O上输出。对
应 Clock端的每个脉冲,其上升沿使地址计数器增加。其下降沿使被选通地址单元的数据从
I/O上输出。地址计数器增加到127后返回到0。

__________________
_____| |_____________________________________________ Reset
: :
: _____ : _____ _____ _____ _____
_____:_______| |____:_| |_____| |_____| |_____| |_ Clk
: : : : : : : : : : :
_____:_______:__________:_:_____:_____:_____:_____:_____:_____:_____:_
_____:___n___|_____0____:_|_____1_____|_____2_____|_____3_____|___4_:_ (Address)
: : : : : :
_____: :_______:___________:___________:___________:_
_____XXXXXXXXXXXXXXXXXXXX_______|___________|___________|___________|_ Data
Bit n Bit 0 Bit 1 Bit2 Bit3
写位:
在Reset和Clk端均为低的情况下,如果某地址单元允许写操作(64-103位,且该位必需为
1),则Reset端上的一个脉冲(即从低到高再回低)将允许芯片进行位写操作。在紧跟着的
时钟脉冲期间执行写操作,调整写操作维持时间至少10ms,在这个CLK脉冲期间,地址计数器
不会增加,在CLK写脉冲下降沿,数据0从I/O端输出。从Reset脉冲的上升沿到CLK写脉冲的
下降沿期间,I/O端的数据是无效的。在下一个才CLK脉冲,且Reset为低时,地址计数器又
增1,并在下降沿时,把选通的地址单元的数据送到I/O端。

_____ _____
_____________| |______________________________| |_______________ Reset
: :
___ : _____ ___ : _____
____| |____:__________| |_________| |_____:__________| |____ Clk
: : : : : : : : :
____:________:__________:_____:_________:___:_____:__________:_____:_____
n | n+1 | n+2 | : n+3 | :
(Address)
—-’——–:———-’—–:———’—:—–:———-’—–:—–
: : : : : : :
_________ _: : : ____________: ___: : :
_________XXX_XXXXXXXXXXXXXXXXXXX____________ XX___XXXXXXXXXXXXXXXXXXXXXXX I/O
n n+1 : : n+1 n+2 : :
: : : :
write write
借位写后的字节擦除:
对位地址72-103的字节单元来说,只要在每个字节的前面一位进行一次正常的写操作,就可
以对此字节后一字节进行字节擦除操作。也就是说,每向高一字节进行借位(即写一位
0),紧接着的擦除时序可以对后一字节按字节擦除(即整个字节写1)。被擦除的字节总是
比借位写的字节低一字节。从以下时序图可以看出,首先,完成一个“位写”操作,在CLK
的写脉冲结束后,在CLK为低电平时,在发一个Reset脉冲即启动字节擦除操作。在第二个
CLK脉冲完成字节擦除,脉冲维持时间整定为擦除周期时间(至少1ms)。芯片逻辑控制电路
验证了借位写确已完成从“1”写“0”后,才擦除其低位字节。从Reset的上升沿到擦除操
作的CLK脉冲的下降沿,I/O脚上的数据无效。地址计数器仍然停留在借位写的地址上。

_____ _____
______| |____________________| |_________________________________ Rst
: :
: _______ : _______ ___
______:___________| |______:_____________| |______| |______ Clk
: : : : : : : :
: : : : : : : :
< ————————- address n ————————>:< — n+1 ——
: : : : : : :
: : : : : : :
______: : :______: : :__________: _____
______XXXXXXXXXXXXXXXXXXXXX______XXXXXXXXXXXXXXXXXXXXXXX__________XX_____ I/O
: : n : : n n+1
: : : :
Write Erase

计数方法:
在67-103地址单元中分为5个不可重置8单元计数器,芯片初始化时,72-103地址单元所对应
的4个较低的8单元计数器中可以放0到8个“1”而67-71地址单元所对应的第5个计数器可以
放0到5个“1”。所谓计数一次,就是将一个单元从“1”写成“0”。一个计数器中8位全为
“0”后,要计数,需借位操作,即将高位计数器的一位从“1”写成“0”而相应其低位计
数器整个字节从“0”擦除成“1”。可见4个8单元计数器如此逐一递减,其最大计数为8的4
次方=4096。第5个计数器中5个单元因处在最高位只能被写“0”无法擦成“1”。因此只能
计数5次。故芯片总计数为5X4096=20480。当全部计数单元(地址67-103)都被写成“0”
时,卡片就用完了,不过,芯片出厂初始化时,初置的计数值由国家不同和卡片面值不同而
不同,如100元卡初置计数值为1000。

举例: 100元(1000计数单元预置初始值).
——–

Byte9 Byte10 Byte11 Byte12 Byte13
————————————————————–
000000 - 00000001 - 01111111 - 00011111 - 00000000
————————————————————–
(3)octal (6)octal (7)octal (1)octal (2)octal
————————————————————–
Value = 0*8^4 + 1*8^3 + 7*8^2 + 5*8^1 + 0*8^
————————————————————–
总值 = 1000 Units
Ⅰ-5)内存数据:
字节 位 二进制 十六进制
+———–+—–+
1 1 –> 8 | | |
+———–+—–+
2 9 –> 16 | 0010 1111 | F | —> 德国
| 0011 0111 | | —> 西班牙
| 0011 1011 | B | —> 希腊
+———–+—–+
3 17 –> 24 | | |
4 25 –> 32 | | | —> 出厂编号(写保护)
5 33 –> 40 | | |
6 41 –> 48 | | |
7 49 –> 56 | | |
8 57 –> 64 | | |
+———–+—–+
9 65 –> 72 | | | —> c4096 )
10 73 –> 80 | | | —> c512 )
11 81 –> 88 | | | —> c64 ) 5个8进制计数区
12 89 –> 96 | | | —> c8 )
13 97 –> 104 | | | —> c0 )
+———–+—–+
14 105 –> 112 | 1111 1111 | $FF |
15 113 –> 120 | 1111 1111 | $FF | —> 所有位都为”1″
16 120 –> 128 | 1111 1111 | $FF |
+———–+—–+

下面是一个高人写的程序,以前贴在c51论坛

;2313编程时要选择FSTRT,快速启动
;**** T E L E C A R D S Y S T E M A T T A C K E R ************************
;*
;* Title : TELECARD SIMULATION ROUTE
;* Version : 2.1 (new mode)
;* Last updated : 99.08.18 /99.10.6
;* Card Type : GPM103(Gemplus).SLE4406(Siemens).PCF7960
(Philips)
;*
;* Target : AT90S2313
;* DESCRIPTION
;* This program shows how to implement an AT90S2313
;* as an IC telephony card.
;*
;* Port Usage : PD2(INT0) —> CLK
;* PD3(INT1) —> RST
;* PD4(T0) —> SD
;* XTAL : 10MHz
;*
;***************************************************************************
;Ver 99.10.6
; 1. RST及CLK检测改为中断输入
; 2. 修改擦除过程中读出校验错误的问题(擦除进程ICDATA应右移一位)
(99.10.7)
; 3. RST上升沿使SD变为常高,直至RST下降沿(复位)或CLK下降沿(写/擦除)
; 4. 修正擦除后未清除ERSRDY标志的问题,避免擦除后输出不正确
;Ver 99.10.13
; 1. 仍未解决计费时出错问题,估计写脉冲后输出不对,有待改进
;Ver 99.10.14
; 1.测试:A)加电后,SD端输出为0直至复位后RST下降沿输出
; B)操作期间,RST正脉冲时SD输出为0,写操作时,RST下降沿输出
; 原位地址数据直至写CLK脉冲下降沿.
; C)位地址超过103时,SD输出为1,直至位地址超过127时才翻转为0,

; 即输出为16字节,后3字节为0xFF
; 2.改正程序以与测试结果相符
; 3.费用数据放入EEPROM
;Ver 99.11.10
; 4.擦除及写入后等待相应时间(4ms),此段时间不响应
;Ver 00.3.12
; 1.仔细分析了IC卡,可能用紫外光照射会擦除掉IC卡中EEPROM段信息,即利用

; 除掉浮栅上的负电荷,仍需实验,“路漫漫其修远兮,吾将上下而求索!”
; 2.2000/3/25 实验,结论: 悲哀—-不行 :( 阿门,救救我吧!!!!
;Ver 00.3.28
; 1.将写后延时缩短为2ms,嘻嘻嘻嘻嘻嘻。。哈哈。。。咳咳。。呃。 成
功!!!
;Ver 00.3.31
; 1.实验,可打通,但第二次计费时错误断线(打一分钟),估计计费操作之间
IC卡
; 已断电,造成数据不符,须加电池试之,也不排除写操作问题
;Ver 01.2.12
; 1.据说电话机内有金属探测器,须测试之 …….
;
;**** Includes ****

.include “2313def.inc”

;**** Interface pin define ****

.equ CLK = PD2
.equ RST = PD3
.equ SD = PD4
.equ datbuf = 3 ;data buffer pointe to r3
.equ datlgth = 16 ;data buffer length
;**** Global Register Variables ****

.def temp1 = r20 ; Temporary variable
.def temp2 = r21 ; Extra temporary variable
.def mask = r22 ; IC card flag register
.def badr = r23 ; IC card bit address
.def icdata = r24 ; IC card data register
.def status = r25 ; Status register

;mask register flag bit define:

.equ rstcomp = 0 ;Reset card complete
.equ wrtrdy = 1 ;Write ready
.equ wrtcomp = 2 ;Write complete
.equ ersrdy = 3 ;Erasure ready
.equ sdsave = 4 ;Save sd line state

;*******************************************************************************
*******
;IC卡帐号及金额数据区:
.eseg
.ORG 0x00
dat_tab:
.db
0x98,0x35,0x22,0x99,0x02,0x55,0x61,0xa0,0x00,0x00,0x7f,0x3f,0x0f,0xff
,0xff,0xff
; [ CHD ] [ ID ] [ COUNTER ]
; 7*64+6*8+4=497=
;*******************************************************************************
*******

;**** Interrupt Vectors **** code segment
.cseg
.org 00
rjmp RESET ; Reset handle
rjmp CLK_INT ; INT0 handle
rjmp RST_INT ; INT1 handle
; rjmp ICP_INT ; Input Capture1 Interrupt
; rjmp OC1_INT ; Output Compare1 Interrupt
; rjmp OVF1_INT ; Overflow1 Interrupt
; rjmp OVF0_INT ; Overflow0 Interrupt
; rjmp RX_END ; UART Receive Complete
; rjmp UDR_EMP ; UART Data Register Empty
; rjmp TX_END ; UART Transmit Complete
; rjmp AC_INT ; Analog Comparator

;***************************************************************************
;*
;* FUNCTION
;* CLK_INT
;*
;* DESCRIPTION
;* Detect ICcard reader’s CLK line
;*
;***************************************************************************
CLK_INT:
sbis PIND,CLK
rjmp CLK_fall
CLK_rise: ;CLK rising edge
sbic PIND,RST
rjmp IC_reset
sbrc mask,wrtrdy
rjmp IC_WRT
sbrc mask,ersrdy
rjmp IC_ERS
cbr mask,(1<
inc badr
cpi badr,8
brne CLK_riseret ; bit address =< 7,not
ready new data
clr badr
inc ZL
cpi ZL,datbuf+datlgth
brne rdydata
ldi ZL,datbuf
rdydata:
ld icdata,Z
rjmp CLK_riseret

IC_WRT:
lsr icdata ;right rotate
andi icdata,0b01111111 ;write 0 to current bit address
cbr mask,1<
sbr mask,1<
mov temp1,badr
inc temp1
ser temp2 ;temp2 <– 0xff
clc ;clr C flag
shift:
ror temp2
dec temp1
brne shift
ld temp1,Z
and temp1,temp2
st Z,temp1
rjmp WrtDelay

IC_ERS:
lsr icdata
andi icdata,0b01111111 ;write 0 to current bit address
mov temp1,ZL ;ZL –> temp1
ser temp2 ;temp2 < — 0xff
inc ZL
ers_nxt:
st Z+,temp2 ;(Z) <– 0xff, Z <– Z+1
cpi ZL,datbuf+datlgth
brne ers_nxt
mov ZL,temp1 ;ZL <– temp1
cbr mask,1<

WrtDelay: ;Write 1/0,delay 1ms
ldi temp1,100
WrtDelay1:
ldi temp2,33 ;1
WrtDelay2:
dec temp2 ;1
brne WrtDelay2 ;2 33(1+2)
dec temp1 ;1
brne WrtDelay1 ;2 [33(1+2)+1+2]
*100=10200*100ns=1.02ms

rjmp CLK_riseret

IC_reset: ;reset iccard
clr badr
clr ZH
ldi ZL,datbuf
ld icdata,Z
sbr mask,(1<
cbr mask,(1<<<<
CLK_riseret:
in temp1,MCUCR
cbr temp1,1<
out MCUCR,temp1 ;set INT1 to interrupt on
falling edge
reti

CLK_fall: ;CLK falling edge
sbrc mask,rstcomp
rjmp CLK_fallret
SD_out:
lsl icdata ;output data bit
brcs SD_high
cbi PORTD,SD
rjmp CLK_fallret
SD_high:
sbi PORTD,SD
CLK_fallret:
in temp1,MCUCR
sbr temp1,1<
out MCUCR,temp1 ;set INT1 to interrupt on
rising edge
reti

;***************************************************************************
;*
;* FUNCTION
;* RST_INT
;*
;* DESCRIPTION
;* Detect ICcard reader’s RST line
;*
;***************************************************************************
RST_INT:
sbic PIND,RST
rjmp RST_rise
RST_fall: ;RST falling edge interrupt
sbrs mask,rstcomp
rjmp Cmp_rst
cbr mask,(1<
lsl icdata ;rstcomp=1,output 1st bit
after reset
brcs setSD
cbi PORTD,SD
rjmp RST_fallret
setSD:
sbi PORTD,SD
RST_fallret:
in temp1,MCUCR
sbr temp1,(1<
out MCUCR,temp1
reti

Cmp_rst:
sbrc mask,wrtcomp
rjmp Cmp_rst1
sbr mask,(1<
cbi PORTD,SD ;output old bit
sbrc mask,sdsave
sbi PORTD,SD
rjmp RST_fallret
Cmp_rst1:
sbr mask,(1<
cbr mask,(1<
cbi PORTD,SD ;output old bit
sbrc mask,sdsave
sbi PORTD,SD
rjmp RST_fallret

RST_rise: ;RST rising edge interrupt
cbr mask,1<
sbic PIND,SD
sbr mask,1<
cbi PORTD,SD ;Active SD to low until CLK falling
edge
in temp1,MCUCR
cbr temp1,(1<
out MCUCR,temp1
reti

;***************************************************************************
;*
;* FUNCTION
;* ic_init/rd_tab
;*
;* DESCRIPTION
;* Initialization of port used by the IC interface
;* and get out data stored by EEPROM .
;*
;***************************************************************************

RESET:
ic_init:

cli ;disable all
interrupt
ldi temp1,low(RAMEND) ;initialize stack
out SPL,temp1

ldi temp1,(0<<<
out DDRD,temp1

ldi temp1,(0<<<
out PORTD,temp1

;*** read eeprom data table ***
rd_eeprom:
clr ZH
ldi ZL,datbuf ; Load low part of byte address into
ZL
clr temp1
loadbyte:
out EEAR,temp1
sbi EECR,EERE ;set EEPROM Read strobe
in temp2,EEDR ;get data
st Z+,temp2 ;store to SRAM (Z),Z <– Z+1
inc temp1
cpi ZL,datbuf+datlgth ;reached the end? (16bytes)
brne loadbyte ;if not, loop more

;**** Interrupt Initialization ****
ldi temp1,(1<<<<
INT0/INT1(rising edge)
out MCUCR,temp1
;

ldi temp1,(1<<

out GIFR,temp1

ldi temp1,(1<<
out GIMSK,temp1

;*** flag mask and register initialize ***
clr mask
ldi ZL,datbuf
clr badr
sei ;Enable global interrupt
LOOP: rjmp LOOP
—–此内容被jdog于2005-02-23,22:56:11编辑过

我公布元程序,是去年用CV写的,程序有些记不清了,所以没有注释

程序比较垃圾,有兴趣就看一下吧

用Tiny13,连接如下
,————+————,
| 8        |         4 |
+——\ | /——+
| 7 +—-+—-+ 3 |
+——-| |——-+
| 6 + +—-+     2  |
+——/ | \——+
| 5        |         1 |
‘————+————’
8-〉Tiny13.8
7-〉Tiny13.7
6-〉Tiny13.6
6-〉NC
4-〉Tiny13.4
3-〉Tiny13.1(Reset,仅在ISP时有用,平时不用)
2-〉Tiny13.5
1-〉NC

#include "tiny13.h"
#pragma regalloc-
register char index @4;
register char ibit @5;
register char rst @6;
register char temp @7;
register char deced @8;
#pragma regalloc+
//前8字节为地区IC卡数据,接着5字节为计数值,后3字节不用动
//所有字节均要倒序比如01001000B就要写00010010B
eeprom unsigned char card[16]={0x98,0x35,0x22,0x99,0x02,0x55,0x61,0xa0,0x00,0x00,0x7f,0x3f,0x0f,0xff,0xff,0xff};

interrupt [EXT_INT0] void ext_int0_isr(void)
{
#asm
CLI
in r7,0x16
bst r7,2
brtc notrst
clr r4
clr r5
clr r8
rjmp go
notrst:
mov r0,r6
dec r0
brpl decv
clr r8
INC R5

LDI R30,LOW(7)
CP r30,r5
BRSH noinc
CLR R5
INC R4
noinc:
LDI R30,LOW(15)
CP R30,r4
BRSH go
CLR R4
rjmp go
decv:
LDI r30,low(8)
cp r4,r30
brlo go
LDI r30,low(13)
cp r4,r30
brsh go
cp r4,r8
brne write
MOV R30,R4
SUBI R30,-LOW(1)
CLR R31
SUBI R30,LOW(-_card)
SBCI R31,HIGH(-_card)
MOVW R26,R30
ser R30
ST X,R30

mov r31,r4
inc r31
RCALL EEPROMWRB

clr r8
rjmp go
write:
LDI R30,LOW(1)
MOV R0,R5
rrl:
DEC R0
BRMI rok
LSL R30
rjmp rrl
rok:
MOV R7,R30
COM R7
MOV R30,R4
CLR R31
SUBI R30,LOW(-_card)
SBCI R31,HIGH(-_card)
PUSH R31
PUSH R30
LD R30,Z
AND R30,R7
POP R26
POP R27
ST X,R30
mov r8,r4

mov r31,r4
RCALL EEPROMWRB
go:
clr r6
sei
#endasm

}

// Pin change interrupt service routine
interrupt [PCINT0] void pin_change_isr(void)
{
#asm
sbic 0x16,2
inc r6
#endasm

}

// Declare your global variables here

void main(void)
{

OSCCAL=0x7f;

PORTB=0x00;
DDRB=0x1;

GIMSK=0x60;
MCUCR=0x03;
PCMSK=0x04;
GIFR=0x60;

ACSR=0x80;
#asm
LDI R30,LOW(16)
MOV R4,R30
CLR R0
CLR R5
CLR R8
LDI R26,LOW(_card)
ldi r30,low(8)
mov r6,r30
ldi r30,low(12)
mov r7,r30
load:
SBIC EECR,EEWE
RJMP load
OUT EEARL,R0
SBI EECR,EERE
IN R30,EEDR

cp r0,r6
brlo notv
cp r0,r7
brsh notv
or r5,r30

notv:
ST X,R30
INC R26
INC R0
CP R0,R4
BRSH loaded
RJMP load
loaded:
cp r5,r8
BRNE ready
subi r26,6
clr r27
ldi r30,low(254)
st x,r30
;要加钱了
ready:
clr R4
clr r5
clr r6
sei
#endasm

while (1)
{
temp=card[index];
temp>>=ibit;
#asm
bst r7,0
in r7, 0x18
bld r7,0
out 0x18,r7
#endasm

};
//R31:地址,R30:数据
#asm
EEPROMWRB:
SBIC EECR,EEWE
RJMP EEPROMWRB
IN R0,SREG
CLI
OUT EEARL,R31
SBI EECR,EERE
IN R7,EEDR
;CP R30,R7
;BREQ EEPROMWRB0
OUT EEDR,R30
SBI EECR,EEMWE
SBI EECR,EEWE
EEPROMWRB0:
OUT SREG,R0
ret
#endasm

On 7:45 am Comments (1)