中级会员
- 积分
- 273
- 金钱
- 273
- 注册时间
- 2015-11-3
- 在线时间
- 39 小时
|
发表于 2017-1-6 10:07:38
|
显示全部楼层
sbit SCL=P4^1; //串行时钟
sbit SDA=P3^6; //串行数据
/********************************************************************************************************
** DS3231常数定义
********************************************************************************************************/
#define DS3231_WriteAddress 0xD0 //器件写地址
#define DS3231_ReadAddress 0xD1 //器件读地址
#define DS3231_SECOND 0x00 //秒
#define DS3231_MINUTE 0x01 //分
#define DS3231_HOUR 0x02 //时
#define DS3231_WEEK 0x03 //星期
#define DS3231_DAY 0x04 //日
#define DS3231_MONTH 0x05 //月
#define DS3231_YEAR 0x06 //年
#define uchar unsigned char
#define uint unsigned int
#define NACK 1
#define ACK 0
char Dhour,minute,second;
uchar TH3231;
bit ack; //应答标志位
void Delay5US() //
{
_nop_(); _nop_(); _nop_(); _nop_(); _nop_();
}
/**********************************************
//IIC Start
**********************************************/
void IIC_Start()
{
SCL = 1;
SDA = 1;
SDA = 0;
SCL = 0;
}
/**********************************************
//IIC Stop
**********************************************/
void IIC_Stop()
{
SCL = 0;
SDA = 0;
SCL = 1;
SDA = 1;
}
/********************************************************************************************************
** 3231
********************************************************************************************************/
uchar BCD2HEX(uchar val)
{
return ((val>>4)*10)+(val&0x0f);
}
uchar HEX2BCD(uchar val)
{
return (((val%100)/10)<<4)|(val%10);
}
void SendByte(uchar c)
{
uchar BitCnt;
for(BitCnt=0;BitCnt<8;BitCnt++) //要传送的数据长度为8位
{
if((c<<BitCnt)&0x80)
SDA=1; //判断发送位
else
SDA=0;
SCL=1; //置时钟线为高,通知被控器开始接收数据位
Delay5US(); //保证时钟高电平周期大于4μs
SCL=0;
}
SDA=1; //8位发送完后释放数据线,准备接收应答位
SCL=1;
Delay5US();
Delay5US();
if(SDA==1)
ack=0;
else
ack=1; //判断是否接收到应答信号
SCL=0;
Delay5US();
}
uchar RcvByte()
{
uchar retc;
uchar BitCnt;
retc=0;
SDA=1; //置数据线为输入方式
for(BitCnt=0;BitCnt<8;BitCnt++)
{
SCL=0; //置时钟线为低,准备接收数据位
Delay5US(); //时钟低电平周期大于4.7μs
SCL=1; //置时钟线为高使数据线上数据有效
Delay5US();
Delay5US();
retc=retc<<1;
if(SDA==1)
retc=retc+1; //读数据位,接收的数据位放入retc中
Delay5US();
}
SCL=0;
return(retc);
}
void Ack_I2C(bit a)
{
SDA = a;
SCL=1;
Delay5US(); //时钟低电平周期大于4us
SCL=0; //清时钟线,钳住I2C总线以便继续接收
Delay5US();
}
uchar write_byte(uchar addr, uchar write_data)
{
IIC_Start();
SendByte(DS3231_WriteAddress);
if (ack == 0)
return 0;
SendByte(addr);
if (ack == 0)
return 0;
SendByte(write_data);
if (ack == 0)
return 0;
IIC_Stop();
Delay5US();
Delay5US();
return 1;
}
uchar read_current()
{
uchar read_data;
IIC_Start();
SendByte(DS3231_ReadAddress);
if(ack==0)
return(0);
read_data = RcvByte();
Ack_I2C(1);
IIC_Stop();
return read_data;
}
uchar read_random(uchar random_addr) //读数据
{
uchar Tmp;
IIC_Start();
SendByte(DS3231_WriteAddress);
if(ack==0)
return(0);
SendByte(random_addr);
if(ack==0)
return(0);
Tmp=read_current();
if(random_addr==DS3231_HOUR)
Tmp&=0x3f;
return(BCD2HEX(Tmp));//都转10进制输出
}
void ModifyTime(uchar hou,uchar min,uchar sec) // uint year,uchar month,uchar day,uchar week,
{
uchar temp=0;
// temp=HEX2BCD(year);
// write_byte(DS3231_YEAR,temp); //修改时
//
// temp=HEX2BCD(month);
// write_byte(DS3231_MONTH,temp); //修改分
//
// temp=HEX2BCD(day);
// write_byte(DS3231_DAY,temp); //修改秒
//
// temp=HEX2BCD(week);
// write_byte(DS3231_WEEK,temp); //修改秒
temp=HEX2BCD(hou);
write_byte(DS3231_HOUR,temp); //修改时
temp=HEX2BCD(min);
write_byte(DS3231_MINUTE,temp); //修改分
temp=HEX2BCD(sec);
write_byte(DS3231_SECOND,temp); //修改秒
}
//uint read_temp()
//{
// int itemp;
// float ftemp;
// //温度数据是以2 进制格式存储的并不需要数制转换
// write_byte(0x0e,0x20);//0x0e寄存器的CONV位置1开启温度转换
//
// itemp = ( (int) read_random(0x11) << 5 ); //放大32倍
// itemp += ( read_random(0x12)>> 3);
// IIC_Stop();
// if(itemp & 0x1000)
// itemp += 0xe000;
//
// ftemp = 0.4145 * (float) itemp+0.5; //放大10倍 0.3125 * (float) itemp+0.5;
// return (uint) ftemp;
//}
|
|