标题:
51单片机程序:出入库管理系统的编辑
[打印本页]
作者:
dongfangh2008
时间:
2019-3-12 08:19
标题:
51单片机程序:出入库管理系统的编辑
单片机源程序如下:
#include <reg51.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#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 right 1 //正确
#define error 0 //错误
typedef struct SYSTEMTIME
{
uchar Second;
uchar Minute;
uchar Hour;
uchar Week;
uchar Day;
uchar Month;
uchar Year;
uchar DateString[9];
uchar TimeString[9];
}SYSTEMTIME; //定义的时间类型
sbit ACC0=ACC^0;
sbit ACC7=ACC^7;
sbit DQ=P1^0; //DS1990A数据线引脚
sbit SDA=P1^1; //2402数据线引脚
sbit SCL=P1^2; //2402时钟线引脚
sbit DS1302_RST=P1^3; //DS1302复位线引脚
sbit DS1302_CLK=P1^4; //DS1302时钟线引脚
sbit DS1302_IO=P1^5; //DS1302数据线引脚
sbit din=P2^0; //MAX7221数据线引脚
sbit load=P2^1; //MAX7221控制线引脚
sbit clk=P2^2; //MAX7221时钟线引脚
sbit Lock=P2^3; //电子锁控制线引脚
uchar code CrcTable[256]={
0,94,188,226,97,63,221,131,194,156,126,32,163,253,31,65,
157,195,33,127,252,162,64,30,95,1,227,189,62,96,130,220,
35,125,159,193,66,28,254,160,225,191,93,3,128,222,60,98,
190,224,2,92,223,129,99,61,124,34,192,158,29,67,161,255,
70,24,250,164,39,121,155,197,132,218,56,102,229,187,89,7,
219,133,103,57,186,228,6,88,25,71,165,251,120,38,196,154,
101,59,217,135,4,90,184,230,167,249,27,69,198,152,122,36,
248,166,68,26,153,199,37,123,58,100,134,216,91,5,231,185,
140,210,48,110,237,179,81,15,78,16,242,172,47,113,147,205,
17,79,173,243,112,46,204,146,211,141,111,49,178,236,14,80,
175,241,19,77,206,144,114,44,109,51,209,143,12,82,176,238,
50,108,142,208,83,13,239,177,240,174,76,18,145,207,45,115,
202,148,118,40,171,245,23,73,8,86,180,234,105,55,213,139,
87,9,235,181,54,104,138,212,149,203,41,119,244,170,72,22,
233,183,85,11,136,214,52,106,43,117,151,201,74,20,246,168,
116,42,200,150,21,75,169,247,182,232,10,84,215,137,107,53
}; //校验码查询表
uchar code ID[]={
0x01,0x2c,0xc5,0xb8,
0x00,0x00,0x00,0x8b}; //默认访问者身份ID
uchar code dispcode[]={
0x7e,0x30,0x6d,0x79,
0x33,0x5b,0x5f,0x70,
0x7f,0x7b,0x77,0x1f,
0x4e,0x3d,0x4f,0x47}; //共阴极显示代码
bit flag=0;
uchar CRCbyte,num=200,da_ad=0x00; //CRC校验码,2402存储地址
uchar SN[8],time[6];
uchar buf[]={0,0,0,0,0,0,0,0};
SYSTEMTIME time1;
/******************函数声明*******************/
void Init_DS1302(void); //DS1302初始化
void Init_DS1990(void); //DS1990初始化
void Init_T0(void); //定时器T0初始化
void DS1302InputByte(uchar d); //DS1302
void 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 Init_MAX7221(void); //MAX7221初始化
void Write_7221(uchar com,uchar da);//MAX7221写字节程序
void Delay(uint i); //延时函数
void Writebyte(uchar dat); //向DS1990A写一个字节函数
void Record(void); //记录访问时间
void Start_bit(void); //I2C起始函数
void Stop_bit(void); //I2C停止函数
bit Compare(void); //验证身份函数
bit Read1990(void); //读身份信息函数
bit Write_8bit(uchar ch); //I2C总线写8位数据函数
uchar DS1302OutputByte(void); //DS1302读一个字节
uchar Read1302(uchar ucAddr); //DS1302读数据
uchar CRC(uchar j); //DS1990A校验位计算函数
uchar Readbyte(void); //从DS1990A读一个字节函数
uchar Page_wr(uchar firstw_ad,uchar counter,uchar *firstr_ad);//I2C总线页面写函数
/******************主函数*******************/
void main()
{
uchar i;
Init_MAX7221();
Init_DS1302();
Init_T0();
P2=0;
while (1)
{
if(Compare()==1) //身份验证一致
{
Lock=1; //闭合继电器
TR0=1; //定时器T0启动
Record(); //记录访问时间
for(i=1;i<9;i++)
{
Write_7221(i,0x01);
}
if(da_ad==248)
da_ad=0; //判断存储内容是否已经满
else
da_ad+=8; //修改2402存储地址
while(Compare());
}
else
{
DS1302_time(); //显示当前时间
}
}
}
/**************T0定时器初始化******************/
void Init_T0(void)
{
TMOD=0x01; //工作方式1
TH0=(65536-50000)/256; //定时时间为0.5ms
TL0=(65536-50000)%256;
EA=1; //开总中断
ET0=1; //允许定时器T0中断
}
/**************T0定时器服务程序******************/
void timer0(void) interrupt 1
{
TH0=(65536-50000)/256; //重载初值
TL0=(65536-50000)%256;
num--;
if(num==0) //5秒定时到
{
TR0=0; //关定时器T0
num=200; //重载时间计数器
Lock=0; //断开继电器
}
}
/**************DS1302一个写字节******************/
void DS1302InputByte(uchar d) //实时时钟写入一字节(内部函数)
{
uchar i;
ACC=d;
for (i=8;i>0;i--)
{
DS1302_IO=ACC0; //相当于汇编中的 RRC
DS1302_CLK=1;
DS1302_CLK=0; //发一个高跳变到低的脉冲
ACC=ACC>>1;
}
}
/**************DS1302读一个字节******************/
uchar DS1302OutputByte(void) //实时时钟读取一字节(内部函数)
{
uchar i;
for (i=8;i>0;i--)
{
ACC=ACC>>1; //相当于汇编中的 RRC
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) //读取DS1302某地址的数据
{
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) //如果第七为1(表明没有启动), 则启动时钟
DS1302_SetTime(DS1302_SECOND,0);
}
/**************DS1302时间转换函数***************/
void DS1302_GetTime(SYSTEMTIME *Time)
{
uchar ReadValue;
ReadValue=Read1302(DS1302_SECOND);
Time->Second=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F); //转换秒
ReadValue=Read1302(DS1302_MINUTE);
Time->Minute=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F); //转换分
ReadValue=Read1302(DS1302_HOUR);
Time->Hour=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F); //转换时
ReadValue=Read1302(DS1302_DAY);
Time->Day=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F); //转换日
ReadValue=Read1302(DS1302_WEEK);
Time->Week=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F); //转换星期
ReadValue=Read1302(DS1302_MONTH);
Time->Month=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F); //转换月
ReadValue=Read1302(DS1302_YEAR);
Time->Year=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F); //转换年
}
/*****************MAX7221初始化***************/
void Init_MAX7221(void)
{
Write_7221(0x0c,0x01); //正常工作状态,关断模式
Write_7221(0x09,0x00); //译码选择,非BCD码
Write_7221(0x0a,0x0f); //亮度调节
Write_7221(0x0b,0x07); //显示位数
}
/**************MAX7221写字节程序*************/
void Write_7221(uchar com,uchar da)
{
uchar temp,i,j;
load=0;
clk=0;
for (i=0;i<8;i++) //发送命令
{
temp=com;
if ((temp&(0x80>>i))!=0)
din=1;
else din=0;
clk=1;
for (j=0;j<5;j++);
clk=0;
}
for (i=0;i<8;i++) //发送数据
{
temp=da;
if ((temp&(0x80>>i))!=0)
din=1;
else din=0;
clk=1;
for (j=0;j<5;j++);
clk=0;
}
load=1;
}
/**************时间显示函数*******************/
void DS1302_time(void)
{
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;
Write_7221(0x08,dispcode[buf[7]]);
Write_7221(0x07,dispcode[buf[6]]);
Write_7221(0x06,0x01);
Write_7221(0x05,dispcode[buf[4]]);
Write_7221(0x04,dispcode[buf[3]]);
Write_7221(0x03,0x01);
Write_7221(0x02,dispcode[buf[1]]);
Write_7221(0x01,dispcode[buf[0]]);
}
/**************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总线页面写函数**************/
uchar 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); //写数据成功
}
/*****************延时函数******************/
void Delay(uint i)
{
while (i--);
}
/***********DS1990A校验位计算函数***********/
uchar CRC(uchar j)
{
uchar i,crc_data=0;
for (i=0;i<j;i++) //查表校验
crc_data=CrcTable[crc_data^SN[i]];
return(crc_data);
}
/*************DS1990A初始化函数*************/
void Init_DS1990(void)
{
uchar i,x=0;
DQ=0; //置低
Delay(60); //延时480us
DQ=1; //释放
Delay(10); //延时85us
for (i=0;i<10;i++)
{
if (DQ==0) //如果拉低
{
flag=1;
break;
}
}
Delay(20);
}
/***********从DS1990A读一个字节函数*********/
uchar Readbyte(void)
{
uchar i=0;
uchar temp=0;
for (i=0;i<8;i++)
{
DQ=0;
temp>>=1;
DQ=1;
_nop_();
if (DQ)temp|=0x80;
Delay(8);
}
return(temp);
}
/**********向DS1990A写一个字节函数**********/
void Writebyte(uchar dat)
{
uchar i=0,send;
for (i=0;i<8;i++)
{
DQ=0;
send=dat&0x01;
if (send==0x01)
{
DQ=1;
Delay(15);
}
else
{
Delay(15);
DQ=1;
}
dat>>=1;
}
Delay(8);
}
/*************读身份信息函数****************/
bit Read1990(void)
{
uchar i;
Init_DS1990();
if (flag==1)
{
while (DQ==0);
flag=0;
Writebyte(0x33);
for (i=0;i<8;i++)
SN[i]=Readbyte();
CRCbyte=CRC(7);
if (CRCbyte==SN[7])
{
return(right);
}
else
return(error);
}
else
return(error);
}
/****************验证身份函数***************/
bit Compare(void)
{
uchar i;
if (Read1990()==1) //若身份验证正确返回1,错误返回0
{
for (i=0;i<8;i++)
{
if (SN[i]!=ID[i])return(error);
}
return(right);
}
else
return(error);
}
/****************记录访问时间***************/
void Record(void)
{
DS1302_GetTime(&time1); //获取访问时间
time[0]=time1.Second; //将访问时间信息存入缓冲区
time[1]=time1.Minute;
time[2]=time1.Hour;
time[3]=time1.Day;
time[4]=time1.Month;
time[5]=time1.Year;
while(Page_wr(da_ad,6,time)==0); //等待写入成功
}
复制代码
所有资料51hei提供下载:
出入管理系统.zip
(62.01 KB, 下载次数: 8)
2019-3-12 08:19 上传
点击文件名下载附件
下载积分: 黑币 -5
作者:
admin
时间:
2019-3-12 14:49
本帖需要重新编辑补全电路原理图,源码,详细说明与图片即可获得100+黑币(帖子下方有编辑按钮)
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1