[MM32软件] 【MM32 eMiniBoard测评报告】+启用I2C驱动DS1307日历模块

[复制链接]
 楼主| hu9jj 发表于 2020-5-27 18:24 | 显示全部楼层 |阅读模式
    昨天开始尝试驱动DS1302模块,这是非标准的I2C通讯接口,因为其不需要指定器件的地址,直接进行I2C操作,我配置了2 个空闲引脚,再加上LED3引脚作RST,测试了半天并动用了逻辑分析仪,最后发现模块的SDA口有问题,写数据时一直无法拉低电平,怀疑模块故障。今天改用DS1307日历模块,这是标准的I2C通讯,器件的地址为0xD0。起初将1.3版本的I2C_POLL_RW_EEPROM中的代码复制到测试程序中,但编译总是出错,最后才知道是与1.2的版本不兼容,只好将整个文件夹复制过来,重新修改为测试项目。
    厂家的例程虽然能编译通过,但整个EEPROM测试代码全在main.c文件中,连宏定义都没有独立到头文件中,似乎有点太粗糙,不规范。
i2c_1.jpg



    我可能有点强迫症,花了不少时间将这些代码分解成i2c.c和i2c.h文件,并逐个函数分析,加上中文注释:
i2c_2.jpg


    通过整理代码和注释,参照例程中提供的EEPROM测试代码,移植好DS1307日历模块的驱动代码。
i2c_3.jpg


    在分析代码的过程中,我对I2C的初始化代码还有点迷惑,例程中对引脚先后进行了两次配置,首先配置成普通输出模式,在设置好I2C参数后再配置成I2C模式,不知道为何要如此配置?
i2c_4.jpg

    从测试的过程看,灵动的HAL库I2C的使用比STM方便的多,设置好器件地址后只要给出要操作的起始地址,数组、长度三个参数就能完成读写操作。下面是相应的代码:
  1. /******************************************************************************************
  2. * 函数名称: DS1307_I2C_Read()
  3. * 功能说明: 读DS1307的日历数据,并转换为各自的变量值
  4. * 输    入: 无
  5. * 输    出: 无
  6. ******************************************************************************************/
  7. void DS1307_I2C_Read(void)
  8. {
  9.     //Set the DS1307 address
  10.     I2C_SetDeviceAddr(I2C1, 0x00D0);
  11.         I2CRead(0x00, DS_Buff, 0x08);
  12.        
  13.     DS1307_BuffToData();
  14. }


  15. /******************************************************************************************
  16. * 函数名称: DS1307_I2C_Write()
  17. * 功能说明: 将当前的日历数据写入DS1307
  18. * 输    入: 无
  19. * 输    出: 无
  20. ******************************************************************************************/
  21. void DS1307_I2C_Write(void)
  22. {
  23.     DS1307_DataToBuff();           //时间日期数据转换存入Buff数组中
  24.     I2C_SetDeviceAddr(I2C1, 0x00D0);
  25.         I2CWrite(0x00, DS_Buff, 0x08);
  26. }


  27. /******************************************************************************************
  28. * 函数名称: DS1307_Init()
  29. * 功能说明: 检查DS1307是否已经初始化,若未初始化则用特写日期进行初始化
  30. * 输    入: 无
  31. * 输    出: 无
  32. ******************************************************************************************/
  33. void DS1307_Init(void)
  34. {
  35.     I2C_SetDeviceAddr(I2C1, 0x00D0);
  36.         I2CRead(0x00, DS_Buff, 0x08);
  37.     if(DS_Buff[0]> 127){
  38.         year = 2020;
  39.         month = 5;
  40.         day = 27;
  41.         week = 3;
  42.         hour = 16;
  43.         minute = 21;
  44.                
  45.         DS1307_DataToBuff();
  46.         I2CWrite(0x00, DS_Buff, 0x08);
  47.     }
  48. }

  49. /******************************************************************************************
  50. * 函数名称: DS1307_DataToBuff()
  51. * 功能说明: 将时间日期变量数据转换到数组Buff中
  52. * 输    入: 无
  53. * 输    出: 无
  54. ******************************************************************************************/
  55. void DS1307_DataToBuff(void)
  56. {
  57.     uint8_t temp;
  58.     DS_Buff[0] = 0;                  //秒
  59.     temp = ((minute/10)<<4|(minute%10));
  60.     DS_Buff[1] = temp;               //分
  61.     temp = ((hour/10)<<4|(hour%10));
  62.     DS_Buff[2] = temp;               //时

  63.     DS_Buff[3] = week;               //星期

  64.     temp = ((day/10)<<4|(day%10));
  65.     DS_Buff[4] = temp;               //日
  66.     temp = ((month/10)<<4|(month%10));
  67.     DS_Buff[5] = temp;               //月
  68.     temp = ((year%100)/10<<4|(year%10));
  69.     DS_Buff[6] = temp;               //年
  70.     DS_Buff[7] = 32;                 //0010 0000 = 允许按1Hz输出方波
  71. }


  72. /******************************************************************************************
  73. * 函数名称: DS1307_BuffToData()
  74. * 功能说明: 将数组Buff数据转换到时间日期变量中
  75. * 输    入: 无
  76. * 输    出: 无
  77. ******************************************************************************************/
  78. void DS1307_BuffToData(void)
  79. {
  80.     second = ((DS_Buff[0]&0x70)>>4)*10 + (DS_Buff[0]&0x0F);//秒,屏蔽秒的第7位的标志
  81.     minute = ((DS_Buff[1]&0x70)>>4)*10 + (DS_Buff[1]&0x0F);//分(取低7位)
  82.     hour = ((DS_Buff[2]&0x30)>>4)*10 + (DS_Buff[2]&0x0F);  //时(取低5位)
  83.     week = (DS_Buff[3]&0x07);                              //周(取低3位)
  84.     day = ((DS_Buff[4]&0x30)>>4)*10 + (DS_Buff[4]&0x0F);   //日(取低6位)
  85.     month = ((DS_Buff[5]&0x10)>>4)*10 + (DS_Buff[5]&0x0F); //月(取低5位)
  86.     year = 2000 + (DS_Buff[6]>>4)*10 + (DS_Buff[6]&0x0F);  //年
  87. }





    这是测试过程:
ds1307_1.jpg



    这是LCD显示的效果,因位置有限年份和日月交替显示:
ds1307_2.jpg


    这是通过串口发送到电脑上的数据:
ds1307_3.jpg


    最后是测试项目的打包文件:
test3.rar (4.04 MB, 下载次数: 41)

您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

151

主题

1063

帖子

11

粉丝
快速回复 在线客服 返回列表 返回顶部