⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 51

📁 51单片机应用系统典型模块开发大全
💻
📖 第 1 页 / 共 2 页
字号:
#include <reg52.h>#include <string.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned int#define ulong unsigned long#define	IDLE 0#define KEYA 0x00#define SPI_REN()IE0=0;EX0=1						//关闭所有中断后,开启外部中断INT0#define	SPI_RDIS()EX0=0								//关闭外部中断INT0#define MI_OK 0#define MI_CRCERR 2#define DS1302_SECOND	0x80						//秒寄存器#define DS1302_MINUTE	0x82						//分寄存器#define DS1302_HOUR		0x84						//小时寄存器#define DS1302_WEEK		0x8A						//星期寄存器#define DS1302_DAY		0x86						//日寄存器#define DS1302_MONTH	0x88						//月寄存器#define DS1302_YEAR		0x8C						//年寄存器#define EER   0xff#define REP   0x80#define x1    0x80								  	//第一行坐标#define x2    0x88									//第三行坐标#define x3    0x90									//第二行坐标#define x4    0x98									//第四行坐标#define comm  0										//指令标志#define dat   1										//数据标志sbit ACC0=ACC^0;sbit ACC7=ACC^7;sbit SCLK=P1^0;										//zlg500时钟脚sbit SDATA=P1^1;									//zlg500数据脚sbit SS=P3^2;										//zlg500传输启动线sbit zlg500_RST=P1^2;								//zlg500复位脚sbit SDA=P1^3;										//2402数据线引脚sbit SCL=P1^4;										//2402时钟线引脚sbit DS1302_RST=P1^5;								//DS1302复位线引脚sbit DS1302_CLK=P1^6;								//DS1302时钟线引脚sbit DS1302_IO=P1^7;								//DS1302数据线引脚sbit cs= P2^2;										//高电平为数据,低电平为指令sbit std= P2^3;										//数据输出位sbit LCD_sclk= P2^4;								//时钟sbit psb= P2^5;   									//H=并口; L=串口;sbit rst= P2^6;   									//Reset Signal 低电平有效typedef struct SYSTEMTIME{    uchar Second;    uchar Minute;    uchar Hour;    uchar Week;    uchar Day;    uchar Month;    uchar Year;}SYSTEMTIME;										//定义的时间类型uchar code tab[]={"身份错误!"};uchar code tab1[]={"重复打卡!"};uchar code tab2[]={"打卡成功!"};uchar code tab3[]={"考勤系统"};uchar code table[]={"0123456789-"};long idata value=1;uchar idata tt[2];									//存tagtypeuchar idata card_snr[4];							//存卡的序列号uchar idata size,ad_stor=0,ad2402=0,num=0;uchar idata bankdata[16];							//块数据缓冲区uchar idata spi_buffer[26];							//SPI数据接收发送缓冲区						uchar idata time[4];								//时间缓冲区uchar idata status[8];								//考勤状态uchar code Nkey_b[6]={								//证实的密码    0xFF,0xFF,0xFF,0xFF,    0xFF,0xFF};uchar buf[8]={0,0,10,0,0,10,0,0};					//时间显示缓冲区SYSTEMTIME time1;bit bdata newdata=0;bit tim,FLAG;void spi_init(void);								//SPI初始化函数void T0_evaluate(void);								//T0载入初值函数void init_zlg500(void);								//初始化zlg500函数void delay(void);									//延时函数void zlg500_rst(void);								//zlg500复位函数uchar request(uchar _Mode,uchar idata *_TagType);//Mifare卡询问操作函数uchar anticoll(uchar _Bcnt,uchar idata *_SNR);	//Mifare卡防冲突操作函数uchar select(uchar idata *_SNR,uchar idata *_Size);//Mifare卡选择函数uchar authKey(uchar _Mode,uchar _SecNr,uchar *_Key);//Mifare卡密码验证函数uchar halt(void);								//Mifare卡挂起函数uchar read(uchar _Adr,uchar idata *_Data);		//Mifare卡块读取函数uchar config(void);							//ZLG500配置函数uchar get_info(uchar idata *_Info);			//ZLG500序列号读取函数uchar set_cbit(void);					//控制位置高电平函数uchar clr_cbit(void);					//控制位置低电平函数uchar buzzer(uchar _Frquence,uchar _10ms);		//无源蜂鸣器控制函数uchar spi_send(uchar idata *dp,uchar lenght);		//SPI数据发送函数uchar spi_rcv(uchar idata *dp);						//SPI数据接收函数uchar zlg500cmd(uchar _length);						//ZLG500A指令操作函数void Init_DS1302(void);								//DS1302初始化void DS1302InputByte(uchar d);						//DS1302void Write_1302(uchar ucAddr, uchar ucDa);			//DS1302写数据void DS1302_SetProtect(bit flag);					//DS1302写保护设定void DS1302_SetTime(uchar Address, uchar Value);	//DS1302设置时间函数void DS1302_GetTime(SYSTEMTIME *Time);				//DS1302时间转换函数//void DS1302_time(void);								//DS1302时间显示函数void Start_bit(void);								//I2C起始函数void Stop_bit(void);								//I2C停止函数bit Write_8bit(uchar ch);							//I2C总线写8位数据函数uchar DS1302OutputByte(void);						//DS1302读一个字节uchar Read1302(uchar ucAddr);						//DS1302读数据bit Page_wr(uchar firstw_ad,uchar counter,uchar *firstr_ad);//I2C总线页面写函数bit Page_clr(void);									//清除EEPROM寄存器内容函数void wr_lcd(uchar dat_comm,uchar content);			//串行传输数据void delay1(uint us);                          		//延时void init_lcd(void);                           		//初始化lcdvoid chn_disp(uchar code *chn,uchar j);				//显示汉字或字符void chn_disp1(void);								//显示串口送入数据void clrram(void);									//清DDRAMvoid record(void);									//考勤记录函数uchar compare(void);								//身份比对函数void ad_2402(void);									//存储地址修改函数void disp(void);									//显示函数/*************************************************************/main(){    init_zlg500();									//初始化zlg500    Init_DS1302();									//初始化DS1302    spi_init();										//初始化SPI    init_lcd();										//初始化LCD    while (1)    {		while (request(IDLE,tt)!=0)disp();			//请求        if (anticoll(0,card_snr)!=0)continue;		//防碰撞操作        if (select(card_snr,&size)!=0)continue;		//选择卡        if (authKey(KEYA,5,Nkey_b)!=0)continue;		//直接密码证实        if (read(1,bankdata)!=0)continue;			//读出块值16字节,地址是块20的数据        halt();										//使卡进入HALT状态        clr_cbit();									//清除MIFARE读卡器中的控制位        set_cbit();									//设置MIFARE读卡器中的控制位        record();									//记录考勤信息        buzzer(198,20);								//蜂鸣器口输出2KHz方波持续200毫秒		ad_2402();									//修改存储地址    }}/*******************显示函数*****************/void disp(void){	uchar i;	DS1302_GetTime(&time1);							//获取当前时间	buf[7]=(time1.Second)%10;	buf[6]=(time1.Second)/10;	buf[4]=(time1.Minute)%10;	buf[3]=(time1.Minute)/10;	buf[1]=(time1.Hour)%10;	buf[0]=(time1.Hour)/10;	if(num++==0)	{		clrram();									//清屏		wr_lcd(comm,0x30);			   				//基本指令动作		wr_lcd(comm,x1);			   				//设定DDRAM地址至10H        for (i=0;i<4;i++)        {            wr_lcd(dat,tab3[i]); 					//将显示码送入第1行显示        }	}	wr_lcd(comm,0x30);			   					//基本指令动作	wr_lcd(comm,x4);	for (i=0;i<8;i++)    {        wr_lcd(dat,tab[buf[i]]); 					//在第四行显示时间    }}/***************存储地址修改函数***************/void ad_2402(void){    DS1302_GetTime(&time1);							//获取时间    time[0]=time1.Second;							//秒    time[1]=time1.Minute;							//分    time[2]=time1.Hour;								//时    time[3]=time1.Day;								//日    if (((time[3]==1)|(time[3]==16))&(time[0]==1)&(time[1]==0)&(time[2]==0))														{		Page_clr();									//1号定时清EEPROM		ad_stor=0;									//修改存储地址	}    if ((time[0]==1)&(time[1]==0)&(time[2]==12))	//12:00:01	{		tim=0;										//下午考勤		ad_stor+=8;		ad2402=ad_stor;								//修改存储地址												}	else if((time[0]==1)&(time[1]==0)&(time[2]==6))	//06:00:01	{		tim=1;										//上午考勤		ad_stor+=8;		ad2402=ad_stor;								//修改存储地址		}}/*******************延时函数********************/void delay(void){    uchar i,j;    for (i=255;i>0;i--)        for (j=255;j>0;j--);						//延时}/*******************身份比对函数****************/uchar compare(void){    uchar n;    for (n=0;n<8;n++)    {        if (tab[n]==bankdata[0])					//对比身份        {            if ((status[n]&0x01)==0)            {                status[n]|=n;						//记录工号                return n;            }            else            {                return REP;            }        }    }    return EER;}/*******************考勤记录函数******************/void record(void){    uchar temp,i;    temp=compare();    if (temp==EER)    {        wr_lcd(comm,0x30);			   				//基本指令动作        wr_lcd(comm,x3);			   				//设定DDRAM地址至10H        for (i=0;i<4;i++)        {            wr_lcd(dat,tab[i]); 					//将显示码送入第二行显示        }		num=255;	}	if (temp==REP)	{		wr_lcd(comm,0x30);			   				//基本指令动作		wr_lcd(comm,x3);			   				//设定DDRAM地址至10H		for (i=0;i<4;i++)		{			wr_lcd(dat,tab1[i]); 					//将显示码送入第二行显示		}			num=255;	}	if (temp<10)	{		wr_lcd(comm,0x30);			   				//基本指令动作		wr_lcd(comm,x3);			   				//设定DDRAM地址至10H		for (i=0;i<4;i++)		{			wr_lcd(dat,tab2[i]); 					//将显示码送入第二行显示		}		DS1302_GetTime(&time1);						//获取访问时间		time[0]=time1.Minute;		time[1]=time1.Hour;		if(tim==1)		{			if(time[1]>8)							//8点以后上班			{				status[temp]|=0x10;					//迟到			}			else			{				status[temp]|=0x20;					//正常到岗			}		}		if(tim==0)					{			if(time[1]>14)							//14点以后上班			{				status[temp]|=0x10;					//迟到			}			else			{				status[temp]|=0x20;					//正常到岗			}		}		while(Page_wr(ad2402,1,time)==0);			//等待写入成功		num=255;	}}/******************T0载入初值函数********************/void T0_evaluate(void){    TH0=0x4c;										//载入初值    TL0=0x00;}/*****************初始化zlg500函数****************/void init_zlg500(void){	zlg500_rst();									//zlg500A复位	while((config())!=MI_OK);						//配置RC500	while((get_info(bankdata))!=MI_OK);				//读取信息	while((clr_cbit())!=MI_OK);						//清除MIFARE读卡器中的控制位	while((set_cbit())!=MI_OK);						//设置MIFARE读卡器中的控制位}/******************zlg500A复位函数****************/void zlg500_rst(void){	zlg500_RST=1;									//复位	delay();    zlg500_RST=0;	delay();}/*****************SPI数据接收函数*****************/uchar spi_rcv(uchar idata *dp){	uchar dat1,i,j;	SCLK=0;    SDATA=1;										//主机响应    while (!SS)    {        for (i=0;i<8;i++)        {            SCLK=1;            _nop_();_nop_();            dat1<<=1;            if (SDATA)dat1=dat1|0x80;            _nop_();_nop_();            SCLK=0;        }        *(dp+j)=dat1;    }    SDATA=0;    return 0;}/*****************SPI初始化函数******************/void spi_init(void){    SS=1;											//主机空闲,释放控制线    SDATA=0;										//数据线置低    SCLK=0;											//时钟线置低    TMOD=0x01;										//工作方式为方式1    PT0=1;											//T0中断优先级最高    IT0=1;											//INT0为下降沿触发方式    ET0=1;											//开T0中断    EA=1;											//开总中断}/****************SPI数据发送函数*****************/uchar spi_send(uchar idata *dp,uchar lenght){    uchar dat1,j,i=0;    FLAG=0;    ET0=1;											//开T0中断    TR0=1;											//启动计时    EX0=0;											//关外部INT0中断    SDATA=1;										//数据传输开始请求    SCLK=0;    while (SDATA);									//等待    SS=0;    while (!SDATA);									//等待从机响应    while ((FLAG!=1)&&(i<lenght))					//连续发送lenght个数据    {        dat1=*(dp+i++);        for (j=0;j<8;j++)        {            if ((dat1&0x80)==0x80)                SDATA=1;            else                SDATA=0;            _nop_();_nop_();_nop_();_nop_();            SCLK=1;            dat1<<=1;            _nop_();_nop_();_nop_();_nop_();            SCLK=0;        }    }    SS=1;    SDATA=0;    TR0=0;    if (FLAG==1)        return 0xff;    else        return 0;}/*****************软件看门狗函数*****************/void WDG(void) interrupt 1							//50ms未发送完毕触发中断{		    TR0=0;											//停止计数    FLAG=1;											//置错误标志位}/******************INT0中断函数******************/void spi_int(void) interrupt 0 using 1{    spi_rcv(spi_buffer);							//接收数据送入spi_buffer缓冲区    newdata=1;										//newdata置1}/**************ZLG500A指令操作函数***************/uchar zlg500cmd(uchar _length){    uchar spi_wdg=10;								//软件计时器置数    uchar i,BCC_sum;    spi_buffer[_length]=spi_buffer[0];				//发送BCC校验码计算    for (i=1;i<_length;i++)    {        spi_buffer[_length]^=spi_buffer[i];    }    spi_buffer[_length]=~spi_buffer[_length];    T0_evaluate();									//装载T0初值    if (spi_send(spi_buffer,_length+1)!=0)			//若发送失败,返回0xff        return 255;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -