}
//初始化,主机发送复位脉冲,从机如果存在则发送存在的应答脉冲
bitrst1bus(void)
{
bitf;
DQ=1;//准备阶段
DQ=0;//将DQ线拉低
delay1(65);//延时500us,主机发送复位脉冲:
480us至960us的低电平
DQ=1;//将DQ线拉高
delay1(3);//延时40us;//主机释放总线:
15us至60us的高电平
f=DQ;//从机如果存在则60us至240us内回复低电平
delay1(10);//延时100us;
DQ=1;
delay1(40);//延时350us;//结束阶段
return(f);//f=0:
从设备存在;f=1:
从设备不存在
}
//位写入函数:
每次写1位数据
voidwritebit(bitx)
{
DQ=1;//准备阶段
DQ=0;
_nop_();//延时2us,主机发送15us的低电平
_nop_();
DQ=x;
delay1(6);//延时60us,从机DS18B20在至少60us内完成采样
DQ=1;//结束阶段
_nop_();//延时1us;
}
//写字节函数:
每次写8位数据,即1字节数据;低位在前,高位在后
voidwritebyte(unsignedcharx)
{
bitf;
unsignedchari;
for(i=0;i<8;i++)
{
f=(bit)(x&0x01);
x=x>>1;
writebit(f);//写1位数据;低位在前,高位在后
}
}
//位读出函数:
每次读1位数据
bitreadbit(void)
{
bitf;
DQ=1;//准备阶段
DQ=0;//1us的低电平
_nop_();//延时2us;
_nop_();
DQ=1;//线与的条件
delay5us();//延时10us;//主机释放总线15us
delay5us();
f=DQ;//主机采样DS18B20的线与运算
delay1(4);//延时45us;
DQ=1;//结束阶段
_nop_();//延时1us;
return(f);
}
//读字节函数:
每次读8位数据,即1字节数据;低位在前,高位在后
//返回值为单字节变量
unsignedcharreadbyte(void)
{
bitf;
unsignedchari,x=0;
for(i=0;i<8;i++)
{
x=x>>1;
f=readbit();
if(f==1)
x=x|0x80;//读1位数据;低位在前,高位在后
}
return(x);
}
voidds18b20(void)
{
unsignedcharf1,f2,g;
f1=rst1bus();//将DS18B20的初始化赋给f1
if(f1==0)//f==0有设备存在,复位成功
{
writebyte(0xcc);//跳跃ROM指令
writebyte(0x44);//发送温度转换指令
g=readbit();
while(!
g)
{
g=readbit();//为0,还没转换完成;为1:
温度转换完成
}
f2=rst1bus();//第二次将DS18B20的初始化赋给f2
if(f2==0)//f==0有设备存在,复位成功
{
writebyte(0xcc);//跳跃ROM指令
writebyte(0xBE);//发送读取RAM指令
a=readbyte();//读低八位
b=readbyte();//读高八位
}
}
}
3、at24c02.h
sbitsda=P2^0;
sbitscl=P2^1;
unsignedcharcodetable[]={3,5,0,1,1,2,0,3,3,5,0,1,1,1,0,9};
unsignedcharcodetab[]={0x00,0x01,0x02,0x03,0x04,0x05,0x07,0x23,0x12,0x14,0x16,0x34,0x35,0x38,0x44,0x46};
//开始信号
/*SCL为高电平时,SDA由高电平向低电平跳变,开始传送数据。
*/
voidi2cstart(void)
{
scl=0;
sda=1;
scl=1;
sda=0;
scl=0;
}
//停止信号
/*SCL为高电平时,SDA由低电平向高电平跳变,结束传送数据。
*/
voidi2cstop(void)
{
scl=0;
sda=0;
scl=1;
sda=1;
}
//上升沿写入数据
voidwrite(unsignedcharx)//上升沿写入数据,高位在前,低位在后
{
unsignedchary,i;
y=x;
CY=0;//位信号
scl=0;
for(i=0;i<8;i++)
{
y=y<<1;
sda=CY;//准备数据
scl=1;//上升沿
scl=0;//为第二次发送数据作准备
}
}//scl低电平时,准备好要写入的位数据;scl上升为高电平时,写入一位
//下降沿读出数据
unsignedcharread(void)//下降沿读取数据
{
unsignedcharx,i;
bitf;
x=0;
for(i=0;i<8;i++)
{
sda=1;//主机释放总线,准备接收从机发送的位数据
x=x<<1;//向左移动接收一个信号
scl=1;
f=sda;//读取数据(线与操作)
scl=0;//下降沿
x=x+(unsignedchar)f;//把数据放在x的最低位,接收8位
}
return(x);
}
/*从机应答——主机发送一个数据后,从机在主机发送第9个时钟时应答:
收到,应答0;没收到,应答1*/
bitack(void)
{
bitf;
sda=1;//主机释放总线,准备接收从机的应答
scl=1;
f=sda;//读取数据
scl=0;//下降沿
return(f);//返回的应答信号
}
/*主机应答——从机发送一个数据后,主机在主机发送第9个时钟时应答:
收到并且需要另外的数据,应答0;收到并且不需要另外的数据,应答1*/
voidnoack(bitf)//f为0或者为1
{
sda=f;//准备数据
scl=1;//上升沿
scl=0;
}
//忙检测
/*写操作需要一定的时间,或采用忙检测:
0——完成写;1——正在进行写*/
voidi2cbusy(void)//忙检测
{
bitf;
do
{
i2cstart();//启动信号
write(0xa0);//芯片地址
f=ack();//f=0不忙,f=1正在忙
}while(f);
}
//学字节操作
/*字节写:
x--器件地址;y--单元地址;z--数据*/
voidwriteby(unsignedcharx,unsignedchary,unsignedcharz)
{
i2cstart();//启动信号
write(x&0xfe);//最低位必须为0,芯片地址
ack();//从机应答
write(y);//芯片单元地址
ack();//从机应答
write(z);//写一个具体的数据
ack();//从机应答
i2cstop();//停止信号
i2cbusy();
}
/*随机读操作:
x--器件地址;y--单元地址;返回读取的数据*/
unsignedcharrandomread(unsignedcharx,unsignedchary)//随机读操作
{
unsignedcharz;
i2cstart();
write(x&0xfe);//最低位必须为0(假的写操作)
ack();//从机应答
write(y);
ack();//从机应答
//伪写操作
i2cstart();
write(x|0x01);//最低位必须为1
ack();//从机应答
z=read();
noack
(1);//主机应答(1--不需要其他数据)
i2cstop();
return(z);
}
4、lcd1602.h
sbitLcdRS=P1^0;//寄存器选择高-->数据存储器,低-->指令存储器
sbitLcdRW=P1^1;//读写操作高-->读操作,低-->写操作
sbitLcdEN=P2^5;//片选高电平/下降沿触发
sfrLcdIO=0x80;
voiddelay(void)//延时
{
inti,j;
for(i=0;i<10;i++)
for(j=0;j<100;j++);
}
//写指令(RS=0,RW=0,EN=下降沿触发)
voidwritecom(unsignedcharx)
{
//准备阶段
LcdRS=1;
LcdRW=1;
LcdEN=0;
//运行阶段
LcdRS=0;
LcdRW=0;
LcdEN=1;
LcdIO=x;
delay();
LcdEN=0;
//结束阶段
LcdRS=1;
LcdRW=1;
LcdEN=0;
}
//写数据(RS=1,RW=0,EN=下降沿触发)
voidwritedate(unsignedcharx)
{
//准备阶段
LcdRS=0;
LcdRW=1;
LcdEN=0;
//运行阶段
LcdRS=1;
LcdRW=0;
LcdEN=1;
LcdIO=x;
delay();
LcdEN=0;
//结束阶段
LcdRS=0;
LcdRW=1;
LcdEN=0;
}
//读状态(RS=0,RW=1,EN=1)
unsignedcharreadsta()
{
//准备阶段
unsignedcharx;
LcdRS=1;
LcdRW=0;
LcdEN=0;
//运行阶段
LcdRS=0;
LcdRW=1;
LcdEN=1;
x=LcdIO;
delay();
//结束阶段
LcdRS=1;
LcdEN=0;
LcdRW=0;
return(x);
}
//忙检测
voidbusy(void)//忙检测
{
unsignedchary;
bitf;
y=readsta();
f=(bit)(y>>7);//强制转换
while(f==1)//忙检测
{
y=readsta();
f=(bit)(y>>7);
}
}
voidlcd1602()
{
busy();
writecom(0x38);//设置5*716行2列显示屏
busy();
writecom(0x08);//清屏显示:
busy();
writecom(0x01);//设置显示:
光标打开
busy();
writecom(0x06);//设置指针加1
busy();
writecom(0x0c);//清屏显示:
}
5、key.h
unsignedcharkey0()
{
unsignedchari=0,x=0;
while(i<1)
{
P3=0xfe;//控制扫描哪一行行(11111110)
x=P3;
x=x&0xf0;//e用来判断按键的按下(是用来取高四位)
if(x!
=0xf0)//表示有按键按下进入按键赋值状态
{
x=P3;
break;
}
i=i+1;
}
returnx;
}
unsignedcharkey1()
{
unsignedchari=0,x=0;
while(i<1)
{
P3=0xfd;//控制扫描哪一行行(11111101)
x=P3;
x=x&0xf0;//e用来判断按键的按下(是用来取高四位)
if(x!
=0xf0)//表示有按键按下进入按键赋值状态
{
x=P3;
break;
}
i=i+1;
}
returnx;
}
unsignedcharkey2()
{
unsignedchari=0,x=0;
while(i<1)
{
P3=0xfb;//控制扫描哪一行行(11111011)
x=P3;
x=x&0xf0;//e用来判断按键的按下(是用来取高四位)
if(x!
=0xf0)//表示有按键按下进入按键赋值状态
{
x=P3;
break;
}
i=i+1;
}
returnx;
}
unsignedcharkey3()
{
unsignedchari=0,x=0;
while(i<1)
{
P3=0xf7;//控制扫描哪一行行(11110111)
x=P3;
x=x&0xf0;//e用来判断按键的按下(是用来取高四位)
if(x!
=0xf0)//表示有按键按下进入按键赋值状态
{
x=P3;
break;
}
i=i+1;
}
returnx;
}
unsignedchargetkey(void)//获取按键值
{
unsignedchark0,k1,k2,k3,answer=16;
intb=0;
if(b==0)
{
k0=key0();
k1=key1();
k2=key2();
k3=key3();
switch(k0)
{
case0xee:
answer=0;break;
case0xde:
answer=1;break;
case0xbe:
answer=2;break;
case0x7e:
answer=3;break;
}
switch(k1)
{
case0xed:
answer=4;break;
case0xdd:
answer=5;break;
case0xbd:
answer=6;break;
case0x7d:
answer=7;break;
}
switch(k2)
{
case0xeb:
answer=8;break;
case0xdb:
answer=9;break;
case0xbb:
answer=10;break;
case0x7b:
answer=11;break;
}
switch(k3)
{
case0xe7:
answer=12;break;
case0xd7:
answer=13;break;
case0xb7:
answer=14;break;
case0x77:
answer=15;break;
}
if(answer!
=16)
returnanswer;//表示按下的键是哪一个
else
return16;//表示没有按键按下
}
}
6、ds1302.h
#definesecond0x80//秒钟寄存器地址
#defineminute0x82//分钟寄存器地址
#definehour0x84//小时寄存器地址
#definedate0x86//日期寄存器地址
#definemouth0x88//月寄存器地址
#defineweekday0x8a//星期寄存器地址
#defineyear0x8c//年寄存器地址
#defineprotect0x8e//写保护寄存器地址
#definechange0x90//充电寄存器地址
sbitrst=P2^4;
sbitsclk=P2^1;
sbitio=P2^0;
unsignedcharcodetab3[2][17]={"Setupringbell","timer0000:
00:
00"};
unsignedcharcodetab1[]={0x00,0x01,0x02,0x03};//自定义字符数据地址
unsignedcharcodetab0[]={0x0f,0x1f,0x02,0x0f,0x0a,0x1f,0x02,0x00,0x0f,0x09,0x0f,0x09,0x0f,0x09,0x13,0x00,0x0f,0x09,0x09,0x0f,0x09,0x09,0x0f,0x00,0x00,0x0f,0x09,0x09,0x09,0x09,0x1b,0x1b};
unsignedchartab2[2][17]={"2013-09-03W2","23:
59:
50+28.5C"};//固定显示数字
unsignedchars[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};//定义显示0-9和显示“.”
unsignedchara1=0;
//写函数
voidwrite_ds1302(unsignedcharx)//有一个参数,无返回值
{
unsignedchari;
for(i=0;i<8;i++)
{
sclk=0;
io=(bit)(x&01);//
x=x>>1;//xzouyiyiwei
sclk=1;//
}
}
//读函数
unsignedcharread_ds1302(void)//无参数,有返回值
{
inti;
uns