软件环境: Keil uVision 4.10
硬件环境: CT107单片机综合实训平台 8051,12MHz
1.SPI:
//SPI.h
#ifndef __DS1302_H
#define __DS1302_H
#include
***it SCLK = P1^7;
***it RST = P1^3;
***it DSIO = P2^3;
void DS1302_WriteByte(unsigned char addr, unsigned char dat); //单字节写的时序
unsigned char DS1302_ReadByte(unsigned char addr); //单字节读的时序
#endif
//SPI.c
#include"SPI.h"
//单字节写的时序
void DS1302_WriteByte(unsigned char addr, unsigned char dat)
{
unsigned char n;
RST = 0;
_nop_();
SCLK = 0;
_nop_();
RST = 1;
_nop_();
for (n=0; n<8; n++) //发送要写入数据的内存地址
{
DSIO = addr & 0x01;
addr >>= 1;
SCLK = 1;
_nop_();
SCLK = 0;
_nop_();
}
for (n=0; n<8; n++) //将指定内容写入该地址的内存
{
DSIO = dat & 0x01;
dat >>= 1;
SCLK = 1;
_nop_();
SCLK = 0;
_nop_();
}
RST = 0;
_nop_();
}
//单字节读的时序
unsigned char DS1302_ReadByte(unsigned char addr)
{
unsigned char n,dat,tmp;
RST = 0;
_nop_();
SCLK = 0;
_nop_();
RST = 1;
_nop_();
for(n=0; n<8; n++) //发送要读出数据的内存地址
{
DSIO = addr & 0x01;
addr >>= 1;
SCLK = 1;
_nop_();
SCLK = 0;
_nop_();
}
for(n=0; n<8; n++) //读出该地址内存的数据
{
tmp = DSIO;
dat = (dat>>1) | (tmp<<7);
SCLK = 1;
_nop_();
SCLK = 0;
_nop_();
}
RST = 0;
_nop_();
SCLK = 1;
_nop_();
DSIO = 0;
_nop_();
DSIO = 1;
_nop_();
//dat = (((dat>>4)*10) | (dat%16));
return dat;
}
2.IIC:
//IIC.h
#ifndef __IIC_H
#define __IIC_H
#include
***it SDA = P2^1; //数据线
***it SCL = P2^0; //时钟线
void Delay_IIC(unsigned char t); //延时函数
void IIC_Start(void); //起始信号
void IIC_Stop(void); //停止信号
void IIC_Ack(unsigned char ackbit); //产生应答
bit IIC_WaitAck(void); //等待应答
void IIC_SendByte(unsigned char byte); //发送数据
unsigned char IIC_RecByte(void); //接收数据
#endif
//IIC.c
#include"IIC.h"
void Delay_IIC(unsigned char time)
{
while(time--);
}
void IIC_Start(void)
{
SDA = 1;
SCL = 1;
Delay_IIC(5);
SDA = 0; //在SCL高电平期间,SDA由高变低
Delay_IIC(5);
SCL = 0;
}
void IIC_Stop(void)
{
SDA = 0;
SCL = 1;
Delay_IIC(5);
SDA = 1; //在SCL高电平期间,SDA由高变低
Delay_IIC(5);
}
void IIC_Ack(unsigned char ackbit)
{
if(ackbit)
SDA = 0; //产生应答信号
else
SDA = 1; //产生非应答信号
Delay_IIC(5);
SCL = 1;
Delay_IIC(5); //第9个时钟周期
SCL = 0;
SDA = 1; //释放SDA线
Delay_IIC(5);
}
bit IIC_WaitAck(void)
{
SDA = 1;
Delay_IIC(5);
SCL = 1;
Delay_IIC(5);
if(SDA) //在SCL高电平期间,SDA为高电平,从机非应答。
{
SCL = 0;
IIC_Stop();
return 0;
}
else //在SCL高电平期间,SDA为低电平,从机有应答。
{
SCL = 0;
return 1;
}
}
void IIC_SendByte(unsigned char byt)
{
unsigned char i;
for(i=0;i<8;i++) //循环发送8位数据
{
if(byt & 0x80) //数据位是高电平
{
SDA = 1;
}
else //数据位是低电平
{
SDA = 0;
}
Delay_IIC(5);
SCL = 1; //SCL高电平期间,SDA的数据要保持稳定
byt <<= 1; //发送的数据左移,准备发送下一位
Delay_IIC(5); //等待SDA的数据被读取
SCL = 0;
}
}
unsigned char IIC_RecByte(void)
{
unsigned char da;
unsigned char i;
for(i=0;i<8;i++)
{
SCL = 1;
Delay_IIC(5); //在SCL高电平期间,读取SDA的数据
da <<= 1;
if(SDA)
da |= 0x01;
SCL = 0;
Delay_IIC(5);
}
return da;
}
3.Onewire:
//onewire.h
#ifndef _ONEWIRE_H
#define _ONEWIRE_H
#include
#define OW_SKIP_ROM 0xcc
#define DS18B20_CONVERT 0x44
#define DS18B20_READ 0xbe
//定义引脚
***it DQ = P1^4;
//函数声明
void Delay_OneWire(unsigned int t);
bit Init_DS18B20(void);
void Write_DS18B20(unsigned char dat);
unsigned char Read_DS18B20(void);
#endif
//onewire.c
#include"onewire.h"
//单总线延时函数
void Delay_OneWire(unsigned int t)
{
while(t--);
}
//DS18B20芯片初始化
bit Init_DS18B20(void)
{
bit initflag = 0;
DQ = 0;
Delay_OneWire(200); //拉低总线480us以上
DQ = 1; //然后释放总线
Delay_OneWire(20); //等待15—60us
initflag = DQ; //读取DS18B20复位应答信号
Delay_OneWire(100); //等待60—240us后释放总线
return initflag; //应答信号为低电平,表示复位成功
}
//DS18B20写操作
void Write_DS18B20(unsigned char dat)
{
unsigned char i;
for(i=0;i<8;i++)
{
DQ = 0; //将总线拉低10—15us
DQ = dat & 0x01; //想总线写数据
Delay_OneWire(20); //维持20—45us
DQ = 1; //释放总线
dat >>= 1; //右移一位,发送下一位数据
}
}
//DS18B20读时序
unsigned char Read_DS18B20(void)
{
unsigned char i,dat;
for(i=0;i<8;i++)
{
DQ = 0; //将总线拉低10—15us
dat >>= 1; //右移
DQ = 1; //释放总线
if(DQ) //读取总线上的电平,如果为高电平则读1
{
dat |= 0x80;
}
Delay_OneWire(20); //延时45us,再度下一位
}
return dat;
}
软件环境: Keil uVision 4.10
硬件环境: CT107单片机综合实训平台 8051,12MHz
1.SPI:
//SPI.h
#ifndef __DS1302_H
#define __DS1302_H
#include
***it SCLK = P1^7;
***it RST = P1^3;
***it DSIO = P2^3;
void DS1302_WriteByte(unsigned char addr, unsigned char dat); //单字节写的时序
unsigned char DS1302_ReadByte(unsigned char addr); //单字节读的时序
#endif
//SPI.c
#include"SPI.h"
//单字节写的时序
void DS1302_WriteByte(unsigned char addr, unsigned char dat)
{
unsigned char n;
RST = 0;
_nop_();
SCLK = 0;
_nop_();
RST = 1;
_nop_();
for (n=0; n<8; n++) //发送要写入数据的内存地址
{
DSIO = addr & 0x01;
addr >>= 1;
SCLK = 1;
_nop_();
SCLK = 0;
_nop_();
}
for (n=0; n<8; n++) //将指定内容写入该地址的内存
{
DSIO = dat & 0x01;
dat >>= 1;
SCLK = 1;
_nop_();
SCLK = 0;
_nop_();
}
RST = 0;
_nop_();
}
//单字节读的时序
unsigned char DS1302_ReadByte(unsigned char addr)
{
unsigned char n,dat,tmp;
RST = 0;
_nop_();
SCLK = 0;
_nop_();
RST = 1;
_nop_();
for(n=0; n<8; n++) //发送要读出数据的内存地址
{
DSIO = addr & 0x01;
addr >>= 1;
SCLK = 1;
_nop_();
SCLK = 0;
_nop_();
}
for(n=0; n<8; n++) //读出该地址内存的数据
{
tmp = DSIO;
dat = (dat>>1) | (tmp<<7);
SCLK = 1;
_nop_();
SCLK = 0;
_nop_();
}
RST = 0;
_nop_();
SCLK = 1;
_nop_();
DSIO = 0;
_nop_();
DSIO = 1;
_nop_();
//dat = (((dat>>4)*10) | (dat%16));
return dat;
}
2.IIC:
//IIC.h
#ifndef __IIC_H
#define __IIC_H
#include
***it SDA = P2^1; //数据线
***it SCL = P2^0; //时钟线
void Delay_IIC(unsigned char t); //延时函数
void IIC_Start(void); //起始信号
void IIC_Stop(void); //停止信号
void IIC_Ack(unsigned char ackbit); //产生应答
bit IIC_WaitAck(void); //等待应答
void IIC_SendByte(unsigned char byte); //发送数据
unsigned char IIC_RecByte(void); //接收数据
#endif
//IIC.c
#include"IIC.h"
void Delay_IIC(unsigned char time)
{
while(time--);
}
void IIC_Start(void)
{
SDA = 1;
SCL = 1;
Delay_IIC(5);
SDA = 0; //在SCL高电平期间,SDA由高变低
Delay_IIC(5);
SCL = 0;
}
void IIC_Stop(void)
{
SDA = 0;
SCL = 1;
Delay_IIC(5);
SDA = 1; //在SCL高电平期间,SDA由高变低
Delay_IIC(5);
}
void IIC_Ack(unsigned char ackbit)
{
if(ackbit)
SDA = 0; //产生应答信号
else
SDA = 1; //产生非应答信号
Delay_IIC(5);
SCL = 1;
Delay_IIC(5); //第9个时钟周期
SCL = 0;
SDA = 1; //释放SDA线
Delay_IIC(5);
}
bit IIC_WaitAck(void)
{
SDA = 1;
Delay_IIC(5);
SCL = 1;
Delay_IIC(5);
if(SDA) //在SCL高电平期间,SDA为高电平,从机非应答。
{
SCL = 0;
IIC_Stop();
return 0;
}
else //在SCL高电平期间,SDA为低电平,从机有应答。
{
SCL = 0;
return 1;
}
}
void IIC_SendByte(unsigned char byt)
{
unsigned char i;
for(i=0;i<8;i++) //循环发送8位数据
{
if(byt & 0x80) //数据位是高电平
{
SDA = 1;
}
else //数据位是低电平
{
SDA = 0;
}
Delay_IIC(5);
SCL = 1; //SCL高电平期间,SDA的数据要保持稳定
byt <<= 1; //发送的数据左移,准备发送下一位
Delay_IIC(5); //等待SDA的数据被读取
SCL = 0;
}
}
unsigned char IIC_RecByte(void)
{
unsigned char da;
unsigned char i;
for(i=0;i<8;i++)
{
SCL = 1;
Delay_IIC(5); //在SCL高电平期间,读取SDA的数据
da <<= 1;
if(SDA)
da |= 0x01;
SCL = 0;
Delay_IIC(5);
}
return da;
}
3.Onewire:
//onewire.h
#ifndef _ONEWIRE_H
#define _ONEWIRE_H
#include
#define OW_SKIP_ROM 0xcc
#define DS18B20_CONVERT 0x44
#define DS18B20_READ 0xbe
//定义引脚
***it DQ = P1^4;
//函数声明
void Delay_OneWire(unsigned int t);
bit Init_DS18B20(void);
void Write_DS18B20(unsigned char dat);
unsigned char Read_DS18B20(void);
#endif
//onewire.c
#include"onewire.h"
//单总线延时函数
void Delay_OneWire(unsigned int t)
{
while(t--);
}
//DS18B20芯片初始化
bit Init_DS18B20(void)
{
bit initflag = 0;
DQ = 0;
Delay_OneWire(200); //拉低总线480us以上
DQ = 1; //然后释放总线
Delay_OneWire(20); //等待15—60us
initflag = DQ; //读取DS18B20复位应答信号
Delay_OneWire(100); //等待60—240us后释放总线
return initflag; //应答信号为低电平,表示复位成功
}
//DS18B20写操作
void Write_DS18B20(unsigned char dat)
{
unsigned char i;
for(i=0;i<8;i++)
{
DQ = 0; //将总线拉低10—15us
DQ = dat & 0x01; //想总线写数据
Delay_OneWire(20); //维持20—45us
DQ = 1; //释放总线
dat >>= 1; //右移一位,发送下一位数据
}
}
//DS18B20读时序
unsigned char Read_DS18B20(void)
{
unsigned char i,dat;
for(i=0;i<8;i++)
{
DQ = 0; //将总线拉低10—15us
dat >>= 1; //右移
DQ = 1; //释放总线
if(DQ) //读取总线上的电平,如果为高电平则读1
{
dat |= 0x80;
}
Delay_OneWire(20); //延时45us,再度下一位
}
return dat;
}
举报