📄 51
字号:
ET0=0; //关定时器T0中断 TF0=0; //清除定时器溢出中断标志位 TR0=1; //启动定时器T0计时 SPI_REN(); //关定时器T0中断,开启INT0中断,准备接收数据 while (newdata==0&&spi_wdg!=0) //若数据接收没有结束,计时时间未到,等待 { if (TF0==1) //50ms到 { T0_evaluate(); //装载T0初值 TF0=0; //软件清除定时器溢出标志位 spi_wdg--; //计数值减1 } } TR0=0; //停止计数 SPI_RDIS(); //关闭外部中断INT0 if (newdata==0)return 255; //若未接收数据,返回0xff newdata=0; BCC_sum=spi_buffer[0]; //计算接收BCC码 for (i=1;i<(spi_buffer[2]+3);i++) { BCC_sum^=spi_buffer[i]; } if (BCC_sum==~spi_buffer[spi_buffer[2]+3]) //校验比较,正确返回 return 0; else return MI_CRCERR;}/*************Mifare卡询问操作函数**************/uchar request(uchar _Mode,uchar idata *_TagType){ spi_buffer[0]=0; //数据交换包的序号,ZLG500A中总为0 spi_buffer[1]=0x41; //'询问'命令字 spi_buffer[2]=0x01; //一个字节 spi_buffer[3]=_Mode; //ALL=0:请求天线范围内IDLE状态的卡(HALT状态的除外) //ALL=1:请求天线范围内的所有卡 if(zlg500cmd(4)!=0) //发送命令成功? return 255; if(spi_buffer[1]==MI_OK) //接收数据成功 { _TagType[0]=spi_buffer[3]; //低字节 _TagType[1]=spi_buffer[4]; //高字节 } return spi_buffer[1]; //返回状态值}/*************Mifare卡防冲突操作函数************/uchar anticoll(uchar _Bcnt,uchar idata *_SNR) { spi_buffer[0]=0; //数据交换包的序号 spi_buffer[1]=0x42; //'防冲突'命令字 spi_buffer[2]=0x01; //一个字节 spi_buffer[3]=_Bcnt; //为预选卡所分配的位的个数,通常Bcnt=0 if(zlg500cmd(4)!=0) //发送命令成功? return 255; if(spi_buffer[1]==MI_OK) //接收数据成功 { memcpy(_SNR,&spi_buffer[3],4); //存RC500序列号 } return spi_buffer[1]; //返回状态值}/***************Mifare卡选择函数****************/uchar select(uchar idata *_SNR,uchar idata *_Size){ spi_buffer[0]=0; //数据交换包的序号 spi_buffer[1]=0x43; //'选择'命令字 spi_buffer[2]=0x04; //四个字节 memcpy(&spi_buffer[3],_SNR,4); //存RC500序列号,_SNR中的数据存入spi_buffer中 if(zlg500cmd(7)!=0) //发送命令成功? return 255; if(spi_buffer[1]==MI_OK) //接收数据成功 { *_Size=spi_buffer[3]; //返回ATS字节 } return spi_buffer[1]; //返回状态值}/**************Mifare卡密码验证函数*************/uchar authKey(uchar _Mode,uchar _SecNr,uchar *_Key) { spi_buffer[0]=0; //数据交换包的序号 spi_buffer[1]=0x73; //'直接密码证实'命令字 spi_buffer[2]=0x08; //八个字节 spi_buffer[3]=_Mode; //AB=0利用密钥A进行验证 //AB=1利用密钥B进行验证 spi_buffer[4]=_SecNr; //所访问卡的扇区号 memcpy(&spi_buffer[5],_Key,6); //送入6个密码字节 if(zlg500cmd(11)!=0) //发送命令成功? return 255; return spi_buffer[1]; //返回状态值}/****************Mifare卡挂起函数***************/uchar halt(void) { spi_buffer[0]=0; //数据交换包的序号 spi_buffer[1]=0x45; //'暂停'命令字 spi_buffer[2]=0x00; //0个字节 if(zlg500cmd(3)!=0) //发送命令成功? return 255; return spi_buffer[1]; //返回状态值 }/***************Mifare卡块读取函数**************/uchar read(uchar _Adr,uchar idata *_Data) { spi_buffer[0]=0; //数据交换包的序号 spi_buffer[1]=0x46; //'读块'命令字 spi_buffer[2]=0x01; //1个字节 spi_buffer[3]=_Adr; //所读数据地址 if(zlg500cmd(4)!=0) //发送命令成功? return 255; if(spi_buffer[1]==MI_OK) //接收数据成功 { memcpy(_Data,&spi_buffer[3],16); //存所访问块的16个字节数据 } return spi_buffer[1]; //返回状态值 }/***************ZLG500序列号读取函数****************/uchar get_info(uchar idata *_Info) { spi_buffer[0]=0; //数据交换包的序号 spi_buffer[1]=0x4F; //'获取信息'命令字 spi_buffer[2]=0; //0个字节 if(zlg500cmd(3)!=0) //发送命令成功? return 255; if(spi_buffer[1]==MI_OK) //接收数据成功 { memcpy(_Info,&spi_buffer[3],spi_buffer[2]);//产品类型标识、序列号和软件版本信息的数组 } return spi_buffer[1]; //返回状态值}/***************ZLG500配置函数*******************/uchar config(void) { spi_buffer[0]=0; //数据交换包的序号 spi_buffer[1]=0x52; //'配置'命令字 spi_buffer[2]=0; //0个字节 if(zlg500cmd(3)!=0) //发送命令成功? return 255; return spi_buffer[1]; //返回状态值}/**************控制位置高电平函数***************/uchar set_cbit(void) { spi_buffer[0]=0; //数据交换包的序号 spi_buffer[1]=0x50; //置位控制位命令字 spi_buffer[2]=0; //0个字节 if(zlg500cmd(3)!=0) //发送命令成功? return 255; return spi_buffer[1]; //返回状态值}/**************控制位置低电平函数****************/uchar clr_cbit(void) { spi_buffer[0]=0; //数据交换包的序号 spi_buffer[1]=0x51; //清除控制位命令字 spi_buffer[2]=0; //0个字节 if(zlg500cmd(3)!=0) //发送命令成功? return 255; return spi_buffer[1]; //返回状态值}/*************无源蜂鸣器控制函数*****************/uchar buzzer(uchar _Frquence,uchar _10ms) //输出驱动无源蜂鸣器信号{ spi_buffer[0]=0; //数据交换包的序号 spi_buffer[1]=0x60; //'输出蜂鸣器信号'控制字 spi_buffer[2]=2; //2个字节 spi_buffer[3]=_Frquence; //存输出方波频率 spi_buffer[4]=_10ms; //存方波输出持续时间 if(zlg500cmd(5)!=0) //发送命令成功? return 255; return spi_buffer[1]; //返回状态值}/**************DS1302写字节函数******************/void DS1302InputByte(uchar d) { uchar i; ACC=d; for (i=8;i>0;i--) { DS1302_IO=ACC0; DS1302_CLK=1; DS1302_CLK=0; //发一个高跳变到低的脉冲 ACC=ACC>>1; }}/**************DS1302读字节函数******************/uchar DS1302OutputByte(void) { uchar i; for (i=8;i>0;i--) { ACC=ACC>>1; ACC7=DS1302_IO; DS1302_CLK=1; DS1302_CLK=0; //发一个高跳变到低的脉冲 } return(ACC);}/*****************DS1302写数据********************/void Write_1302(uchar ucAddr, uchar ucDa){ DS1302_RST=0; DS1302_CLK=0; DS1302_RST=1; DS1302InputByte(ucAddr); //地址,命令 DS1302InputByte(ucDa); //写1Byte数据 DS1302_CLK=1; DS1302_RST=0;}/******************DS1302读数据********************/uchar Read1302(uchar ucAddr){ uchar ucData; DS1302_RST=0; DS1302_CLK=0; DS1302_RST=1; //enable DS1302InputByte(ucAddr|0x01); //地址,命令 ucData=DS1302OutputByte(); //读1Byte数据 DS1302_CLK=1; DS1302_RST=0; return(ucData);}/****************DS1302写保护设定******************/void DS1302_SetProtect(bit flag){ if (flag) Write_1302(0x8E,0x10); //WP=1,不能写入 else Write_1302(0x8E,0x00); //WP=0,可以写入}/****************DS1302设置时间函数****************/void DS1302_SetTime(uchar Address, uchar Value) { DS1302_SetProtect(0); Write_1302(Address, ((Value/10)<<4|(Value%10)));//高4位为十位,低4位为个位}/*******************DS1302初始化********************/void Init_DS1302(void){ uchar Second=Read1302(DS1302_SECOND); if (Second&0x80) //启动时钟 DS1302_SetTime(DS1302_SECOND,0);}/*****************DS1302时间转换函数***************/void DS1302_GetTime(SYSTEMTIME *Time){ uchar ReadValue; ReadValue=Read1302(DS1302_MINUTE); Time->Minute=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F); //转换分 ReadValue=Read1302(DS1302_HOUR); Time->Hour=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F); //转换时}/********************I2C起始函数*******************/void Start_bit(void){ SCL=1;_nop_(); SDA=1;_nop_(); SDA=0;_nop_(); SCL=0;_nop_();}/*******************I2C停止函数********************/void Stop_bit(void){ SDA=0;_nop_(); SCL=1;_nop_(); SDA=1;_nop_();}/****************I2C总线写8位数据函数***************/bit Write_8bit(uchar ch){ uchar i=8; bit fan_w; SCL=0;_nop_(); while (i--) { SDA=(bit)(ch&0x80);_nop_(); ch<<=1; SCL=1;_nop_(); SCL=0;_nop_(); } SDA=1;_nop_(); SCL=1;_nop_(); fan_w=SDA; SCL=0;_nop_(); return(fan_w);}/*****************I2C总线页面写函数*****************/bit Page_wr(uchar firstw_ad,uchar counter,uchar *firstr_ad){ uchar *ufirstr_ad; ufirstr_ad=firstr_ad; Start_bit(); //启动I2C if (Write_8bit(0xA0)!=0) //发送2402器件地址 { Stop_bit(); //无应答,返回 return(0); } if (Write_8bit(firstw_ad)!=0) //写入数据的存储地址 { Stop_bit(); //无应答,返回 return(0); } while (counter--) //写入数据 { if (Write_8bit(*ufirstr_ad)!=0) //无应答,返回 { Stop_bit(); return(0); } ufirstr_ad++; //准备下一数据 } Stop_bit(); return(1); //写数据成功}/******************I2C总线页面写函数****************/bit Page_clr(void){ uchar i; Start_bit(); //启动I2C if (Write_8bit(0xA0)!=0) //发送2402器件地址 { Stop_bit(); //无应答,返回 return(0); } if (Write_8bit(0x00)!=0) //写入数据的存储起始地址 { Stop_bit(); //无应答,返回 return(0); } for(i=0;i<256;i++) { if (Write_8bit(0)!=0) //无应答,返回 { Stop_bit(); return(0); } } Stop_bit(); return(1); //写数据成功}/*******************初始化lcd函数*******************/void init_lcd(void){ rst=1; //液晶复位端无效 psb=0; //串行输出 wr_lcd (comm,0x30); //基本指令动作 wr_lcd (comm,0x01); //清屏,地址指针指向00H delay1(100); wr_lcd (comm,0x06); //光标的移动方向 右移 wr_lcd (comm,0x0c); //开显示,关游标}/**********************清DDRAM函数*******************/void clrram(void){ wr_lcd (comm,0x30); //基本指令动作 wr_lcd (comm,0x01); //清除显示,并将DDRAM清零 delay1(180); }/******************LCD数据写入函数******************/void wr_lcd(uchar dat_comm,uchar content){ uchar a,i,j; delay1(50); a=content; //指令码或数据码 cs=1; //发送数据 LCD_sclk=0; std=1; //发送5个"1",作为数据起始位 for(i=0;i<5;i++) { LCD_sclk=1; LCD_sclk=0; } std=0; //发送第6位,R/W=0,写数据 LCD_sclk=1; LCD_sclk=0; if(dat_comm) //发送第7位RS std=1; //若为高电平,发送数据 else std=0; //若为低电平,发送指令 LCD_sclk=1; LCD_sclk=0; std=0; //发送第8位"0" LCD_sclk=1; LCD_sclk=0; for(j=0;j<2;j++) //将数据位分两个字节发送 { for(i=0;i<4;i++) //发送数据高4位或低4位 { a=a<<1; std=CY; LCD_sclk=1; LCD_sclk=0; } std=0; for(i=0;i<4;i++) //发送4位"0" { LCD_sclk=1; LCD_sclk=0; } }}/***********************延时函数*********************/void delay1(uint us){ while(us--);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -