打印
[PIC®/AVR®/dsPIC®产品]

【CuriosityNano测评报告】04.I2C通讯实验及驱动DS1307日历模块

[复制链接]
85102|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
#申请原创#
    之前多次测试PIC及AVR的核心板都是使用模拟I2C来对DS1307日历模块进行读写操作,感觉硬件I2C操控起来不知从何处下手,没有模拟I2C那么得心应手。为了熟悉和掌握硬件I2C的使用,本次就没有使用模拟I2C,直接进行硬件I2C的测试。
    在用MCC进行配置的时候,可以添加一个I2C使用的范例文件:


    在这个范例文件中为我们提供了几个I2C读写操作的函数:


    在以前的评测中我也曾经尝试过使用硬件I2C,但从来设有成功过。经过多次测试和分析,后来明白了在使用这些函数时,I2C器件的地址要用7位而不是我习惯的8位,因为在读写操作时,函数会将7位地址左移1位然后再加上读写操作码。
    关于DS1307日历模块网上有很多的资料,这里只是简单介绍一下数据的储存方式和读写操作:


    开机时一般先读入地址0的数据,若CH(位7)为1,则表明日历模块尚未启动,应该对其设置日期及时间,因此我们要用上读指定地址一个字节数据的函数;
    设置日期及时间需要连续写入7~8个字节的数据,因此我们需要使用写多个字节数据的函数;
    同样,在读取日历模块的日期及时间需要使用读多个字节的函数:
    在测试过程中,读取一个字节数据的函数没有问题,一次调试即成功:
/****************************************************************************************** 
* 函数名称:        DS1307_Init()
* 功能说明: 用当前日期(yesr,month,day,hour,minute,second)初始化DS1307
* 输    入: 无
* 输    出: 无
******************************************************************************************/
void DS1307_Init(void)
{
    uint8_t i;
   
    i = I2C1_Read1ByteRegister(DS1307_Addr_7,0);
   
//    LCD_write_value(0,3,3,0,0,i);//监测读取值
    if(i > 127){
        year = 2021;
        month = 5;
        day = 31;
        week = 1;
        hour = 14;
        minute = 30;
        second = 0;
        DS1307_write_date();
//         I2C1_WriteNBytes(DS1307_Addr_7,DS_Buff,8);
    }
    else
        DS1307_read_date();
}


    开始测试时,初始化日期写操作使用的是I2C1_WriterNBytes()函数(也就是上面代码中注释行),但读取时日期数据不正确,通过使用逻辑分析仪抓取时序,发现基本操作是符合要求的,但实际写入的数据却大相径庭,完全不是数组中的值:


    我将要写入的数据与实际写入的数据进行了对比,两者之间没有规律,不知道是什么原因造成的,也许是数据传递过程中出了问题吧:


    之后我测试了单个数据的写入函数,写入正确,于是是只好通过循环,依次将数组中的数据写入,下面是最后通过的写操作函数:
/****************************************************************************************** 
* 函数名称:        DS1307_write_date()
* 功能说明: 读取DS1307日期时间数据
* 输    入: 无
* 输    出: 无
******************************************************************************************/
void DS1307_write_date(void)
{
    uint8_t i;
    DS_Buff[0] = 0;                                             //秒
    DS_Buff[1] = ((minute/10)<<4|(minute%10)); //分
    DS_Buff[2] = ((hour/10)<<4|(hour%10));       //时
    DS_Buff[3] = week;                                       //星期
    DS_Buff[4] = ((day/10)<<4|(day%10));          //日
    DS_Buff[5] = ((month/10)<<4|(month%10));   //月
    DS_Buff[6] = ((year%100)/10<<4|(year%10)); //年
    DS_Buff[7] = 16;                                          //0001 0000 = 允许按1Hz输出方波,低电平触发

    for(i=0; i<8; i++ ){
        I2C1_Write1ByteRegister(DS1307_Addr_7,i,DS_Buff[i]);  //写入8个字节数据
    }
}


    读操作的函数测试很顺利,没有什么时周折:
/****************************************************************************************** 
* 函数名称:        DS1307_read_date()
* 功能说明: 读取DS1307日期时间数据
* 输    入: 无
* 输    出: 无
******************************************************************************************/
void DS1307_read_date(void)
{
    I2C1_ReadDataBlock(DS1307_Addr_7,0,DS_Buff,7);         //读取前7个字节数据
   
    second = ((DS_Buff[0]&0x70)>>4)*10 + (DS_Buff[0]&0x0F);//秒,屏蔽秒的第7位的标志
    minute = ((DS_Buff[1]&0x70)>>4)*10 + (DS_Buff[1]&0x0F);//分(取低7位)
    hour = ((DS_Buff[2]&0x30)>>4)*10 + (DS_Buff[2]&0x0F);  //时(取低6位)
    week = (DS_Buff[3]&0x07);                              //周(取低3位)
    day = ((DS_Buff[4]&0x30)>>4)*10 + (DS_Buff[4]&0x0F);   //日(取低6位)
    month = ((DS_Buff[5]&0x10)>>4)*10 + (DS_Buff[5]&0x0F); //月(取低5位)
    year = 2000 + (DS_Buff[6]>>4)*10 + (DS_Buff[6]&0x0F);  //年
   
}


    这是测试过程的照片:


    这是LCD日历显示的效果:


    这是测试项目的压缩包:
MyTest.X.rar (1.23 MB)

使用特权

评论回复
沙发
pzsh| | 2021-6-3 20:16 | 只看该作者
本帖最后由 pzsh 于 2021-6-3 20:45 编辑

这个是使用的Q40上的I2C外设直接实现的?

使用特权

评论回复
板凳
hu9jj|  楼主 | 2021-6-3 21:12 | 只看该作者
pzsh 发表于 2021-6-3 20:16
这个是使用的Q40上的I2C外设直接实现的?

是的,使用硬件I2C进行读写DS1307.

使用特权

评论回复
地板
weifeng90| | 2021-6-3 21:26 | 只看该作者
模拟效率不高

使用特权

评论回复
5
hu9jj|  楼主 | 2021-6-4 08:59 | 只看该作者

    不一定吧?模拟I2C只要仔细调整延时,让时序在标准范围内,可以达到同样的效率,只不过调整起来比较费时间。

使用特权

评论回复
6
yangjiaxu| | 2021-6-4 14:56 | 只看该作者
真挺好 讲的很详细

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

认证:Microchip
简介:让我们来为您提供帮助。我们可提供各种资源来帮助您解决一切问题。是否需要与我们的客户支持团队联系?您可以通过电话、在线聊天功能或电子邮件与他们联系。

151

主题

1059

帖子

11

粉丝