×
单片机 > 单片机程序设计 > 详情

DS3231温度读取实验 附单片机源程序

发布时间:2020-12-29 发布时间:
|

DS3231作为一个走时精准的RTC芯片,内部带有温度补偿电路,此例将读取其中11H和12H寄存器,提取测得的温度值并传送到串口输出。

类似程序网上非常之多,不再赘述,在此重新提说几处需要注意的地方。
1.根据DS3231的芯片手册,其温度传感器的精度为±3℃,毕竟不是专用的温度传感器,在使用中可以作为一个参考,且仅此而已。


2.根据DS3231的芯片手册,其温度分辨率为±0.25℃,所以其小数部分读出的值只能是.00、.25、.50、.75这四种,如果读出的值不是这四种,则数据处理有误。


3.本实验使用一个float型数据直接接收了转换的温度值,没有对补码的符号位进行判断等。

注明:本程序没有使用CONV位进行强制转换,但是实际上温度值的刷新速度还是很令人满意(用手按住芯片,温度值更改速度很快,下面的测试图片是恒温下检测的,故无变化)。
测试程序:


#include

#include"stdio.h"

#include

//位定义

sbit DS3231_SDA=P3^3;

sbit DS3231_SCL=P3^2;


//运行数组

unsigned char DS3231_Time_Buffer[7]={0x00,0x48,0x11,0x02,0x12,0x02,0x19};

unsigned char temp[2]={0,0};

char buf[20]={0};

//运行标志位

bit busy=0;

//运行变量

float v;


/*##############################################################################

编写/测试:凌净清河

日期:2019年2月12日

测试平台:IAP15W4K58S4


鸣谢:DS3231部分驱动函数借用了51黑论坛上某位的程序,但是时间太久忘记是谁的了。

并未修改原作者的写法,如果原作者认出,鄙人在此表示感谢,或可联系我提名。

##############################################################################*/


/*###################以下为给DS3231定义的IIC通信函数################*/

void DS3231_Delay()//使用空操作进行短暂的延时

{

        _nop_();

        _nop_();

        _nop_();

        _nop_();

}


void DS3231_IIC_Start()//IIC总线的开始信号

{

        DS3231_SCL=1;

        DS3231_SDA=1;

        DS3231_Delay();

        DS3231_SDA=0;

        DS3231_Delay();

        DS3231_SCL=0;

}


void DS3231_IIC_Stop()//IIC总线的停止信号

{

        DS3231_SCL=0;

        DS3231_SDA=0;

        DS3231_Delay();

        DS3231_SCL=1;

        DS3231_Delay();

        DS3231_SDA=1;

        DS3231_Delay();

}


bit DS3231_IIC_Send_Byte(unsigned char dat)//写操作

{

        unsigned char mask;//定义一个掩码用于进行按位发送数据的操作

        bit ack;


        for(mask=0x80;mask!=0;mask>>=1)

        {

                if((mask&dat)==0)

                        DS3231_SDA=0;

                else

                        DS3231_SDA=1;

                DS3231_Delay();

                DS3231_SCL=1;

                DS3231_Delay();

                DS3231_SCL=0;

        }

        DS3231_SDA=1;

        DS3231_Delay();

        DS3231_SCL=1;

        ack=DS3231_SDA;

        DS3231_Delay();

        DS3231_SCL=0;


        return (~ack);

}


unsigned char DS3231_IIC_Read_Byte_NAK()//读操作+非应答

{

        unsigned char mask;//定义一个用于累加的位存储临时变量

        unsigned char dat;


        DS3231_SDA=1;

        for(mask=0x80;mask!=0;mask>>=1)

        {

                DS3231_Delay();

                DS3231_SCL=1;

                if(DS3231_SDA==0)

                        dat&=~mask;

                else

                        dat|=mask;

                DS3231_Delay();

                DS3231_SCL=0;

        }

        DS3231_SDA=1;

        DS3231_Delay();

        DS3231_SCL=1;

        DS3231_Delay();

        DS3231_SCL=0;


        return dat;

}


unsigned char DS3231_IIC_Read_Byte_ACK()//读操作+应答

{

        unsigned char mask;//定义一个用于累加的位存储临时变量

        unsigned char dat;


        DS3231_SDA=1;

        for(mask=0x80;mask!=0;mask>>=1)

        {

                DS3231_Delay();

                DS3231_SCL=1;

                if(DS3231_SDA==0)

                        dat&=~mask;

                else

                        dat|=mask;

                DS3231_Delay();

                DS3231_SCL=0;

        }

        DS3231_SDA=0;

        DS3231_Delay();

        DS3231_SCL=1;

        DS3231_Delay();

        DS3231_SCL=0;


        return dat;

}

/*#################以下为给DS3231封装的寄存器通信函数###############*/


void DS3231_Read_Registers(unsigned char *buf,unsigned char addr,unsigned char len)//读EEPROM中多个字节

{

        do{

                DS3231_IIC_Start();

                if(DS3231_IIC_Send_Byte(0xD0))

                {

                        break;

                }

                DS3231_IIC_Stop();

          }while(1);

        DS3231_IIC_Send_Byte(addr);

        DS3231_IIC_Start();

        DS3231_IIC_Send_Byte((0xD0)|0x01);//寻址,读操作

        while(len>1)

        {

                *buf++=DS3231_IIC_Read_Byte_ACK();

                len--;

        }

        *buf=DS3231_IIC_Read_Byte_NAK();//读一个字节

        DS3231_IIC_Stop();

}


void DS3231_Write_Registers(unsigned char *buf,unsigned char addr,unsigned char len)//写寄存器,传入待写入数组

{

        while(len>0)

        {        

                do{

                        DS3231_IIC_Start();

                        if(DS3231_IIC_Send_Byte(0xD0))

                        {

                                break;

                        }

                        DS3231_IIC_Stop();

                  }while(1);


                DS3231_IIC_Send_Byte(addr);

                while(len>0)

                {

                        DS3231_IIC_Send_Byte(*buf++);

                        len--;

                        addr++;

                        if((addr&0x07)==0)

                        {

                                break;

                        }

                }

                DS3231_IIC_Stop();

        }

}


void SendData(unsigned char dat)//串口1发送一个字节数据

{

        while(busy);

        busy=1;

        SBUF=dat;

}


void SendString(char *p)//串口发送一个字符串

{

        while(*p!='')

        {



『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
ARM基础知识八