P3口除作为一般I/O口外,还有其他一些复用功能,如表6所示:
表6
P3.0 P3.1 P3.2 P3.3 P3.4 P3.5 P3.6 P3.7 引脚号 RXD(串行输入口) TXD(串行输出口) INT0(外部中断0) INT1(外部中断1) T0(定时器0的外部输入) T1(定时器1的外部输入) WR(外部数据存储器写选通) RD(外部数据存储器读选通) ?RST(9引脚):复位输入。当输入连续两个机器周期以上高电平时为有效,用来完成单片机单片机的复位初始化操作。看门狗计时完成后,RST引脚输出96个晶振周期的高电平。特殊寄存器AUXR(地址8EH)上的DISRTO位可以使此功能无效。DISRTO默认状态下,复位高电平有效。
?ALE/PROG(30引脚):地址锁存控制信号(ALE)是访问外部程序存储器时,锁存低8位地址的输出脉冲。在Flash编程时,此引脚(PROG)也用作编程输入脉冲。在一般情况下,ALE以晶振六分之一的固定频率输出脉冲,可用来作为外部定时器或时钟使用。然而,特别强调,在每次访问外部数据存储器时,ALE脉冲将会跳过。如果需要,通过将地址位8EH的SFR的第0位置“1”,ALE操作将无效。这一位置“1”,ALE仅在执行MOVXP或MOV指令时有效。否则,ALE将被微弱拉高。这个ALE使能标志位(地址位8EH的SFR的第0位)的设置对微控制器处于外部执行模式下无效。
?PSEN(29引脚):外部程序存储器选通信号(PSEN)是外部程序存储器选通信号。当AT89C51RC从外部程序存储器执行外部代码时,PSEN在每个机器周期被激活两次,而访问外部数据存储器时,PSEN将不被激活。
?EA/VPP(31引脚):访问外部程序存储器控制信号。为使能从0000H到FFFFH的外部程序存储器读取指令,EA必须接GND。注意加密方式1时,EA将内部锁定位RESET。为了执行内部程序指令,EA应该接VCC。在Flash编程期间,EA也接收12伏VPP电压。
?XTAL1(19引脚):振荡器反相放大器和内部时钟发生电路的输入端。 ?XTAL2(18引脚):振荡器反相放大器的输入端。
16
六LCD1602芯片
(1)工业字符型液晶,能够同时显示16x02即32个字符。(16列2行) 1602液晶也叫1602字符型液晶,它是一种专门用来显示字母、数字、符号等的点阵型液晶模块。它由若干个5X7或者5X11等点阵字符位组成,每个点阵字符位都可以显示一个字符,每位之间有一个点距的间隔,每行之间也有间隔,起到了字符间距和行间距的作用,正因为如此所以它不能很好地显示图形(用自定义CGRAM,显示效果也不好)。
1602LCD是指显示的内容为16X2,即可以显示两行,每行16个字符液晶模块(显示字符和数字)。
(2)引脚图
12345678910111213141516VSSVCCVORSR/WEDB0DB1DB2DB3DB4DB5DB6DB7BLABLK
LCD1602
17
(3)1602采用标准的16脚接口,其中:
? 第1脚:VSS为电源地
?第2脚:VCC接5V电源正极
?第3脚:V0为液晶显示器对比度调整端,接正电源时对比度最弱,接地电源时对比度最高(对比度过高时会 产生“鬼影”,使用时可以通过一个10K的电位器调整对比度)。
?第4脚:RS为寄存器选择,高电平1时选择数据寄存器、低电平0时选择指令
寄存器。
?第5脚:RW为读写信号线,高电平(1)时进行读操作,低电平(0)时进行写操作。
?第6脚:E(或EN)端为使能(enable)端,高电平(1)时读取信息,负跳变时执行指令。
?第7~14脚:D0~D7为8位双向数据端。
?第15~16脚:空脚或背灯电源。15脚背光正极,16脚背光负极。 七、软件设计 MAIN.C
#include \#include \#include \#include
//M1卡的某一块写为如下格式,则该块为钱包,可接收扣款和充值命令
//4字节金额(低字节在前)+4字节金额取反+4字节金额+1字节块地址+1字节块地址取反+1字节块地址+1字节块地址取反
unsigned char code data2[4] = {0x12,0,0,0};
unsigned char code DefaultKey[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};//校验密码 unsigned char g_ucTempbuf[20]; unsigned char idata MLastSelectedSnr[4]; unsigned char idata RevBuffer[30]; unsigned char data SerBuffer[20];
unsigned char data money[20]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,50};//最后的50就是卡上的金额可以修改
void com(unsigned char com); void dat(unsigned char dat); void delay(unsigned char x); bit CmdValid;
18
unsigned char status;
///////////////////////////////////////////////////////////////////// //系统初始化
///////////////////////////////////////////////////////////////////// void InitializeSystem() {
P0 = 0xFF; P1 = 0xFF; P3 = 0xFF;
ET2 = 0; //80c52比80C51多一个定时器T2 ET2为定时计数器2的溢出中断允许位 T2CON = 0x04;//外部中断1的中断触发方式控制位 边沿触发方式 下降沿有效触发
PCON = 0x80; //电源控制寄存器波特率的选择位SOMD=1 ,波特率在原来的基础上加倍
SCON = 0x70; //串行口控制寄存器SM0 SM1=01工作与方式1 10位异步收发
TMOD = 0x21; //TMOD = 0x22; 定时器工作于方式2 ,波特率发生方式
TH0 = 0x60;
//通过初值设定可知初值
TL0 = 0x60;
ET0=0;
LED_GREEN = 1; L
PcdReset();
19
TH1 = BAUD_9600; //波特率为9600位每秒 方式2的波特率为定值 TL1 = TH1;
//自动重装TH1=TL1
TR1 = 1; // 波特率发生器
TR0 = 0; //定时器运行控制位
//中断允许位 //中断允许总控制位 //外部中断0中断允许位 //定时器2起停控制位
ET1=0; EA=1;
EX0=1; TR2=0;
IT0 = 1; //外部中断0触发方式控制位 边沿触发方式 下降沿有效触发 ES = 1; //串行口中断允许位 CmdValid=0;
//设置 LED的显示初值
PcdAntennaOff(); PcdAntennaOn(); }
///////////////////////////////////////////////////////////////////// //用T2做延时子程序
/////////////////////////////////////////////////////////////////////
/************************************/ void main( ) {
unsigned char baud,t=0,flag=5; InitializeSystem( );
LCDinit(); xs();
status= PcdRequest(0x26,&RevBuffer[2]);//寻卡 if(status==MI_OK) {
status = PcdAnticoll(&RevBuffer[2]);//防冲撞 memcpy(MLastSelectedSnr,&RevBuffer[2],4); if(status==MI_OK) {
status = PcdSelect(&RevBuffer[2]);//选定卡片 if(status==MI_OK) {
status = PcdAuthState(0x60, 1, DefaultKey, MLastSelectedSnr);// 校验
if(status==MI_OK) {
status =PcdRead(0x01,&RevBuffer[2]); //读卡 if (status == MI_OK) {
status =PcdWrite(0x01,money);
20
M500PcdConfigISOType( 'A' );
while (1) {
卡密码
//写卡