OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 5938|回复: 5

STM32F1读写时钟芯片DS1307总结

[复制链接]

4

主题

25

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
489
金钱
489
注册时间
2015-4-20
在线时间
52 小时
发表于 2020-10-5 17:44:21 | 显示全部楼层 |阅读模式
本帖最后由 imxuheng 于 2020-10-5 17:43 编辑

1 前言
    这个帖子是个人学习STM32IIC通信的一个小总结,实现了STM32F103C8读写DS1307。
    多年前买了原子哥的战舰开发板学习STM32,后来种种原因停滞了几年。前不久重新学习STM32,在空暇之余按照原子哥的不完全手册依次学习芯片各个自带资源,不过进度倒是比较慢了。
    学习IIC通信花了不少时间,这期间吃了亏,并再一次意识到看芯片手册的重要性。这里把操作DS1307的一些要点按自己的理解总结出来,希望需要的人少走弯路。

2 DS1307
    图1截图自DS1307芯片手册。展示了主机写、DS1307接收模式时的数据流。一般是主机修改ds1307内储存的时间实现校时。步骤为:
1.        主机发送起始(start)信号
2.        主机发送DS1307器件地址(0XD0);
3.        主机等待DS1307响应ack
4.        主机发送要写入的DS1307内部寄存器的起始地址(秒的地址为0x00,星期的地址是0x04)
5.        主机等待DS1307响应ack
6.        主机依次发送DS1307内部寄存器的新数据
7.        主机等待DS1307响应ack
8.        主机发送停止(stop)信号

    上述过程中,
  • l如果主机只发送1个DS1307内部寄存器的新数据,之后就发送停止信号,那么就只修改了起始地址的数据。比如这个起始地址是0x01(分钟地址),新数据是0x32,那么分钟寄存器的值就更新为0x32。
  • l如果主机发送n个DS1307内部寄存器的新数据,那么就修改起始地址以及起始地址之后n-1个寄存器的数据,比如这个起始地址是0x02,新数据是{0x08,0x22,0x03},寄存器0x02、0x03、0x04的值都会被修改,即小时、日、星期寄存器的新值就分别是0x08、0x22、0x03

写一字节函数:
void Ds1307writeByte(u8 addr,u8 dat)
{
         u8 ack, i=0;
         IIC_soft_start();
         IIC_soft_write_byte(0xd0);
         IIC_wait_ack();
         IIC_soft_write_byte(addr);
         IIC_wait_ack();
         IIC_soft_write_byte(dat);
         IIC_wait_ack();
         IIC_soft_stop();
}

初始化DS1307函数,实际是就是多字节写入DS1307的函数
void InitDS1307(void)
{
         u8 i,ack;
         u8 InitTime[7] ={0x00,0x32,0x08,0x04,0x01,0x10,0x20};//2020-10-1 THU 08:32:00
         IIC_soft_start();
         IIC_soft_write_byte(0xd0);
         IIC_wait_ack();
         IIC_soft_write_byte(0x00);
         IIC_wait_ack();
         for(i=0;i<7;i++)
         {
                   Ds1307writeByte(i,InitTime);
                   IIC_wait_ack();
         }
         IIC_soft_stop();
}

3 DS1307
    图2展示了主机读、DS1307发送模式时的数据流。一般是主机读取ds1307内储存的时间数据。步骤为:
1.        主机发送起始(start)信号
2.        主机发送DS1307器件地址(0XD0);
3.        主机等待DS1307响应ack
4.        主机发送要读取的DS1307内部寄存器的起始地址
5.        主机等待DS1307响应ack
6.        主机再次发送起始(start)信号(图中红圈部分)
7.        主机发送读命令(0XD1);
8.        主机等待DS1307响应ack
9.        主机依次接收n字节DS1307内部寄存器的数据(每接收1字节数据,就发送响应ack一次),读最后一个字节后发送响应nack一次表示通知DS1307不要再发送数据了;
10.    主机发送停止(stop)信号

    上述过程中,
  • l主机接收的字节数实际由主机自己决定,接收1个字节就发送停止信号,那么久相当于只读取了一个字节数据;接收6个字节就发送停止信号,那么就相当于读取了6个字节数据。
  • l假设发送的起始地址是0x01,接收了5个字节就发送停止信号,就相当于读取了寄存器0x01、0x02、0x03、0x04、0x05这5个寄存器的值


读一字节函数:
u8 DS1307_read_one_byte(u8 addr)
{
         u8 dat,ack;
         IIC_soft_start();
         IIC_soft_write_byte(0xd0);
         ack=IIC_wait_ack();
         IIC_soft_write_byte(addr);
         ack=IIC_wait_ack();
         IIC_soft_start();
         IIC_soft_write_byte(0xd1);
         ack=IIC_wait_ack();
         dat=IIC_soft_read_byte(1); //参数1—发送nack
         IIC_soft_stop();
         return dat;
}
读取多个字节
void DS1307_read_n_bytes(u8 addr_start,u8 byte_count,u8 *buf)
{
         u8 ack,i;
         IIC_soft_start();
         IIC_soft_write_byte(0xd0);
         ack=IIC_wait_ack();
         IIC_soft_write_byte(addr_start);
         ack=IIC_wait_ack();
         IIC_soft_start();
         IIC_soft_write_byte(0xd1);
         ack=IIC_wait_ack();
         for(i=0;i<byte_count-1;i++)
         {
                   *buf++=IIC_soft_read_byte(0);//参数0—发送ack
         }
         *buf =IIC_soft_read_byte(1);     //参数1—发送nack
         IIC_soft_stop();
}

4 总结
    实现IIC通信是最重要的一步,不过这里只说IIC应用,具体通信方式参考原子哥的不完全手册就行了。说句题外话,不完全手册是以读写AT24C02为例子进行说明的,要是读写AT24C32及更大容量的系列芯片,需要将地址分高低字节分别写入才能正确通信。
还有一点就是关于STM32引脚配置的问题,我本次使用PB4/PB5作为驱动IO,由于复位后PB4是作为JTAG的一个引脚,因此需要将PB4配置为普通IO口,参看复用重映射和调试I/O配置寄存器(AFIO_MAPR)的SWJ_CFG位,配置值的作用如图3所示。

    我使用的是一个最小系统,需要使用SW的下载功能,因此只关闭JTAG,配置代码如下:
         RCC->APB2ENR |=1<<0;//开启引脚复用时钟
         AFIO->MAPR |=2<<24; //010:禁止JTAG-DP,启用SW-DP;

    最后效果如图4所示,时钟模块是“YX65412-DS1307时钟模块”,带有AT24C32储存,读写DS1307的时候必须5v供电。读写AT24C32的时候3.3v供电即可。


图1 写DS1307

图1 写DS1307

图2 读DS1307

图2 读DS1307

图3 配置AFIO_MAPR

图3 配置AFIO_MAPR

图4 效果展示

图4 效果展示
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

5

主题

353

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4300
金钱
4300
注册时间
2019-4-30
在线时间
877 小时
发表于 2020-10-8 18:39:12 | 显示全部楼层
回复 支持 反对

使用道具 举报

0

主题

3

帖子

0

精华

新手入门

积分
5
金钱
5
注册时间
2021-5-12
在线时间
1 小时
发表于 2021-5-12 22:43:34 | 显示全部楼层
大神求一份源码邮箱594874132@QQ.COM
回复 支持 反对

使用道具 举报

5

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
129
金钱
129
注册时间
2019-12-30
在线时间
22 小时
发表于 2021-6-14 18:32:42 | 显示全部楼层
楼主求个源码,resumebb@163.com
回复 支持 反对

使用道具 举报

0

主题

98

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
343
金钱
343
注册时间
2018-3-20
在线时间
74 小时
发表于 2021-7-27 11:08:28 | 显示全部楼层
大佬可否分享源码呢?
回复 支持 反对

使用道具 举报

1

主题

28

帖子

0

精华

初级会员

Rank: 2

积分
168
金钱
168
注册时间
2022-11-1
在线时间
25 小时
发表于 2024-1-16 15:29:36 | 显示全部楼层
感谢大神分享,求源码一份 adsionshm@126.com
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-23 13:10

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表