周立功教授新书《面向AMetal框架与接口的编程(上)》,对AMetal框架进行了详细介绍,通过阅读这本书,你可以学到高度复用的软件设计原则和面向接口编程的开发思想,聚焦自己的“核心域”,改变自己的编程思维,实现企业和个人的共同进步。
第六章为重用外设驱动代码,本文内容包含6.3 RTC 实时时钟中的后两个小节:
6.3.6 RX8025T
6.3.7 DS1302
6.3 RTC 实时时钟
>>> 6.3.6 RX8025T
在MicroPort 系列扩展模块中,除主芯片为PCF85063 的RTC 模块外,还有RX8025T模块和DS1302 模块,它们都是RTC 扩展模块,其主要区别详见表6.14。
表6.14 RTC 芯片对比
表中,“√”表示对应器件支持该功能,“×”表示对应器件不支持该功能。
1. 器件简介
RX8025T 是一款内置高稳定度的32.768KHz 的 DTCXO(数字温度补偿晶体振荡器)的I2C总线接口方式的实时时钟芯片,它提供了时间日期的设置与获取、闹钟中断、时间更新中断、固定周期中断、温度补偿等功能。所有地址和数据通过I2C总线来传输,最大总线速率可达到400kbps。
RX8025T 引脚封装详见图6.6,其中的SCL 和SDA 为I2C接口引脚,VDD 和VSS 分别为电源和地;CLKOUT 为时钟输出引脚,可用于输出时钟信号;T1(CE)、TEST、T2(Vpp)引脚仅供厂家测试使用,NC 为无需连接的引脚,实际使用时,这些引脚直接悬空即可;INT 为中断引脚,主要用于闹钟等功能;CLK_EN 为时钟输出使能引脚, 用于控制CLKOUT 时钟的输出。
图6.6 RX8025T 引脚定义
RX8025T 的7 位I2C从机地址为0x32,模块原理图详见图6.7。若将MicroPort-RX8025T模块通过MicroPort 接口与AM824-Core 相连,则SCL 和SDA 分别与PIO0_16 和PIO0_18连接,INT 引脚与PIO0_1 连接,FOE 与PIO0_10 连接。
图6.7 RX8025T 模块电路
2. 器件初始化
在使用RX8025T 前,必须完成RX8025T 的初始化操作,以获取对应的操作句柄,进而才能使用RX8025T 的各种功能,初始化函数(am_rx8025t.h)的原型为:
该函数意在获取RX8025T 器件的实例句柄,其中,p_dev 为指向am_rx8025t_dev_t 类型实例的指针,p_devinfo 为指向am_rx8025t_devinfo_t 类型的实例信息的指针。
(1)实例
定义am_rx8025t_dev_t 类型(am_rx8025t.h)实例如下:
其中,g_rx8025t_dev 为用户自定义的实例,其地址作为p_dev 的实参传递。
(2)实例信息
实例信息主要描述了具体器件的固有信息,即RX8025T 的CLK_EN、INT 引脚与微处理器引脚的连接信息。其类型am_rx8025t_devinfo_t 的定义(am_rx8025t.h)如下:
当MicroPort-RX8025T 模块通过MicroPort 接口与AM824-Core 相连时, INT和CLK_EN和分别与PIO0_1 和PIO0_10 连接。其实例信息定义如下:
其中,g_rx8025t_devinfo 为用户自定义的实例信息,其地址作为p_devinfo 的实参传递。
(3)I2C句柄i2c_handle
以I2C1 为例,其实例初始化函数am_lpc82x_i2c1_inst_init ()的返回值将作为实参传递给i2c_handle。即:
(4)实例句柄
RX8025T 初始化函数am_rx8025t_init ()的返回值,作为实参传递给其它功能接口函数的第一个参数(handle)。am_rx8025t_handle_t 类型的定义(am_rx8025t.h)如下:
若返回值为NULL,说明初始化失败;若返回值不为NULL,说明返回值handle 有效。
基于模块化编程思想,将初始化相关的实例、实例信息等的定义存放到对应的配置文件中,通过头文件引出实例初始化函数接口,源文件和头文件的程序范例分别详见程序清单6.39 和程序清单6.40。
程序清单6.71 实例初始化函数实现(am_hwconf_rx8025t.c)
程序清单6.72 实例初始化函数声明(am_hwconf_rx8025t.h)
后续只需要使用无参数的实例初始化函数,即可获取到RX8025T 的实例句柄。即:
3. 使用RTC 功能
使用RTC 功能即使用RTC 通用接口操作RX8025T 进行时间的设置和获取,在使用RTC通用接口前,需要获取一个am_rtc_handle_t 类型的RTC 句柄。RX8025T 的驱动提供了相应的接口用于获取RX8025T 的RTC 句柄,以便用户通过RTC 通用接口操作RX8025T,其函数原型为:
该函数意在获取RTC 句柄,其中,RX8025T 实例的句柄(rx8025t_handle)作为实参传递给handle,p_rtc 为指向am_rtc_serv_t 类型实例的指针,无实例信息。定义am_rtc_serv_t类型(am_rtc.h)实例如下
其中,g_rx8025t_rtc 为用户自定义的实例,其地址作为p_rtc 的实参传递。
基于模块化编程思想,将初始化相关的实例定义存放到对应的配置文件中,通过头文件引出实例初始化函数接口,源文件和头文件分别详见程序清单6.73 和程序清单6.74。
程序清单6.73 新增RX8025T 的RTC 实例初始化函数(am_hwconf_rx8025t.c)
程序清单6.74 am_hwconf_rx8025t.h 文件内容更新(1)
后续只需要使用无参数的RTC 实例初始化函数,即可获取RTC 实例句柄。即:
获取到handle 后,由于基于RTC 通用接口编写的应用程序是可以跨平台复用的,因此可以直接基于RX8025T 启动如程序清单6.45 所示的RTC 时间显示应用程序,详见程序清单6.75。
程序清单6.75 启动RTC 应用程序(基于RX8025T)
显然,若将RTC 模块由PCF85063 更换为RX8025T,应用程序核心代码无需修改。
4. 使用闹钟功能
使用闹钟功能即使用闹钟通用接口操作RX8025T。在使用闹钟通用接口前,需要获取到一个am_alarm_clk_handle_t 类型的闹钟句柄。RX8025T 的驱动提供了相应的接口用于获取RX8025T 的闹钟句柄,便于用户通过闹钟通用接口操作RX8025T,其函数原型为:
该函数意在获取闹钟句柄,其中,RX8025T 实例的句柄(rx8025t_handle)作为实参传递给handle,p_alarm_clk 为指向am_alarm_clk_serv_t 类型实例的指针,无实例信息。定义am_alarm_clk_serv_t 类型(am_alarm_clk.h)实例如下:
其中,g_rx8025t_alarm_clk 为用户自定义的实例,其地址作为p_alarm_clk 的实参传递。
基于模块化编程思想,将初始化相关的实例定义存放到对应的配置文件中,通过头文件引出实例初始化函数接口,源文件和头文件分别详见程序清单6.76 和程序清单6.77。
程序清单6.76 新增RX8025T 的闹钟实例初始化函数(am_hwconf_rx8025t.c)
程序清单6.77 am_hwconf_rx8025t.h 文件内容更新(2)
后续只需要使用无参数的闹钟实例初始化函数,即可获取闹钟实例句柄。即:
获取到handle 后,由于基于闹钟通用接口编写的应用程序是可以跨平台复用的,因此可以直接基于RX8025T 启动如程序清单6.54 所示的闹钟测试应用程序,详见程序清单6.78。
程序清单6.78 启动闹钟测试应用程序(基于RX8025T)
显然,若将RTC 模块由PCF85063 更换为RX8025T,闹钟应用程序核心代码无需修改。
5. 为系统时间提供RTC 服务
若需要使用RX8025T 为系统时间提供RTC 服务,只需要在初始化系统时间时,将从RX8025T 中获取的RTC 句柄作为系统时间初始化函数的rtc_handle 参数。即:
为方便使用,将初始化函数的调用添加到配置文件中,通过头文件引出系统时间的实例初始化函数接口,详见程序清单6.79 和程序清单6.80。
程序清单6.79 RX8025T 用作系统时间的实例初始化(am_hwconf_rx8025t.c)
程序清单6.80 am_hwconf_rx8025t.h 文件内容更新(3)
后续只需要简单的调用该无参函数,即可完成系统时间的初始化。即:
系统时间初始化后,由于基于系统时间通用接口编写的应用程序是可以跨平台复用的,因此可以直接基于RX8025T 启动如程序清单6.65 所示的系统时间测试应用程序,详见程序清单6.81。
程序清单6.81 启动系统时间测试应用程序(基于RX8025T)
显然,若将RTC 模块由PCF85063 更换为RX8025T,使用系统时间的应用程序无需修改。
6. 特殊功能控制接口
对于RX8025T,除典型的时钟和闹钟功能外,还具有一些特殊功能,比如,定时器、时钟输出、1 字节RAM 等。这些功能由于不是通用功能,只能使用RX8025T 相应的接口进行操作。以读写1 字节RAM 为例,其相应的接口函数详见表6.15。
表6.15 读写RAM 接口函数(am_rx8025t.h)
(1)写入RAM
该函数用于写入1 字节数据到RX8025T 的RAM 中,其函数原型为:
其中,handle 为RX8025T 实例句柄,data 为写入的单字节数据。若返回AM_OK,表示数据写入成功,反之失败,写入0x55 至RAM 中的范例程序详见程序清单6.82。
程序清单6.82 写入RAM 范例程序
(2)读取RAM
该函数用于读取存于RX8025T 的单字节RAM 中的数据,其函数原型为:
其中,handle 为RX8025T 实例句柄,p_data 为输出参数,用于返回读取的单字节数据。
返回AM_OK,表示读取成功,反之失败,范例程序详见程序清单6.83。
程序清单6.83 读取RAM 范例程序
可以使用读写RAM 接口简单验证RX8025T 是否正常,详见程序清单6.84。
程序清单6.84 读写RAM 数据范例程序
若读写数据出错,则点亮LED0。由此可见,虽然该程序的逻辑与程序清单6.70 所示的应用程序基本一致,但由于使用的接口是特殊功能控制接口,与具体芯片相关,因此并不能直接像RTC 应用程序和闹钟应用程序那样直接跨平台复用。
>>> 6.3.7 DS1302
1. 器件简介
DS1302 是一款涓流充电计时芯片,它包含一个实时时钟和31 字节的静态 RAM,能够提供年、月、日、时、分、秒等信息,具有闰年校正功能。
DS1302 被设计工作在非常低的电能下,在低于1μW 时还能保持数据和时钟信息。除了基本计时功能以外,DS1302 还具有其它一些特点,比如,双管脚主电源和备用电源,可编程涓流充电器VCC1。
DS1302 通过简单的串行接口与微处理器通讯,使用同步串行通讯简化了 DS1302 与微处理器的接口,通讯只需要三根线:CE、I/O(数据线)、SCLK(串行时钟)。DS1302 的引脚封装图详见图6.8。
图6.8 DS1302 引脚定义
其中,X1 和X2 为外接晶振的引脚,需要连接标准的32.768kHz 的石英晶体。SCLK、CE、I/O 为与微处理器的串行通信引脚。GND 为电源地,VCC1 和VCC2为电源引脚,这也是DS1302 具有特色的地方,即:双管脚主电源和备用电源,在双管脚中,VCC2 是主电源,VCC1 是备用电源,一般接充电电池。DS1302 是由VCC1 或VCC2 两者中的较大者供电。当VCC2 大于VCC1+0.2V,VCC2 给芯片供电。当VCC2 小于VCC1 时,芯片由VCC1 供电。当芯片由VCC2 供电时,VCC1 不供电,同时,还可以通过可编程涓流充电器,使VCC2 向VCC1 流入很小的电流,以便为连接到VCC1 的电池充电。当然,VCC1可以不接可充电电池,此时,只需要通过控制可编程涓流充电器,使VCC2 不向VCC1 流入电流即可。
DS1032 模块的原理图详见图6.9,若将MicroPort-DS1302 模块通过MicroPort 接口AM824-Core 相连,则SCLK、I/O 和CE 分别与PIO0_15、PIO0_13 和PIO0_14 连接。
图6.9 DS1302 模块电路
2. 器件初始化
在使用DS1302 前,必须完成DS1302 的初始化操作,以获取对应的操作句柄,进而才能使用DS1302 的各种功能,初始化函数的原型(am_ds1302.h)为:
该函数意在获取DS1302 器件的实例句柄,其中,p_dev 为指向am_ds1302_gpio_dev_t类型实例的指针,p_devinfo 为指向am_ds1302_gpio_devinfo_t 类型的实例信息的指针。
(1)实例
定义am_ds1302_gpio_dev_t 类型(am_ds1302.h)实例如下:
其中,g_ds1302_gpio_dev 为用户自定义的实例,其地址作为p_dev 的实参传递。
(2)实例信息
实例信息主要描述了具体器件的固有信息,即DS1302 的SCLK、I/O、CE 引脚与微处理器引脚的连接信息。其类型am_ds1302_gpio_devinfo_t 的定义(am_ds1302.h)如下:
当MicroPort-DS1302 模块通过MicroPort 接口与AM824-Core 相连时, SCLK、I/O 和CE 分别与PIO0_15、PIO0_13 和PIO0_14 连接。其实例信息定义如下:
其中,g_ds1302_gpio_devinfo 为用户自定义的实例信息,其地址作为p_devinfo 的实参传递。
(3)实例句柄
DS1302 的初始化函数am_ds1302_gpio_init()的返回值,作为实参传递给其它功能接口函数的第一个参数(handle)。am_ds1302_handle_t 类型的定义(am_ds1302.h)如下:
若返回值为NULL,说明初始化失败;若返回值不为NULL,说明返回值handle 有效。
基于模块化编程思想,将初始化相关的实例、实例信息等的定义存放到对应的配置文件中,通过头文件引出实例初始化函数接口,源文件和头文件的程序范例分别详见程序清单6.85 和程序清单6.86。
程序清单6.85 实例初始化函数实现(am_hwconf_ds1302.c)
程序清单6.86 实例初始化函数声明(am_hwconf_ds1302.h)
后续只需要使用无参数的实例初始化函数,即可获取到DS1302 的实例句柄。即:
3. 使用RTC 功能
使用RTC 功能即可使用RTC 通用接口操作DS1302 设置和获取时间,在使用RTC 通用接口前,需要获取一个am_rtc_handle_t 类型的RTC 句柄。DS1302 的驱动提供了相应的接口用于获取DS1302 的RTC 句柄,便于用户通过RTC 通用接口操作DS1302,其函数原型为:
该函数意在获取RTC 句柄,其中,DS1302 实例的句柄(ds1302_handle)作为实参传递给handle,p_rtc 为指向am_rtc_serv_t 类型实例的指针,无实例信息。定义am_rtc_serv_t 类型(am_rtc.h)实例如下:
其中,g_ds1302_rtc 为用户自定义的实例,其地址作为p_rtc 的实参传递。
基于模块化编程思想,将初始化相关的实例定义存放到对应的配置文件中,通过头文件引出实例初始化函数接口,源文件和头文件分别详见程序清单6.87 和程序清单6.88。
程序清单6.87 新增DS1302 的RTC 实例初始化函数(am_hwconf_ds1302.c)
程序清单6.88 am_hwconf_ds1302.h 文件内容更新(1)
后续只需要使用无参数的RTC 实例初始化函数,即可获取RTC 实例句柄。即:
获取handle 后,由于基于RTC 通用接口编写的应用程序是可以跨平台复用的,因此可以直接基于DS1302 启动如程序清单6.45 所示的RTC 时间显示应用程序。
程序清单6.89 启动RTC 应用程序(基于DS1302)
由此可见,若将RTC 模块由PCF85063 更换为DS1302,则应用程序核心代码无需修改。
4. 为系统时间提供RTC 服务
由于DS1302 不支持闹钟功能,因此不能使用通用闹钟接口操作DS1302。若需要使用DS1302 为系统时间提供RTC 服务,只需要在初始化系统时间时,将从 DS1302 中获取的RTC 句柄作为系统时间初始化函数的rtc_handle 参数。即:
为方便使用特将初始化函数的调用添加到配置文件中,通过头文件引出系统时间的实例初始化函数接口,详见程序清单6.90 和程序清单6.91。
程序清单6.90 DS1302 用作系统时间的实例初始化(am_hwconf_ds1302.c)
程序清单6.91 am_hwconf_ds1302.h 文件内容更新(2)
后续只需要简单的调用该无参函数,即可完成系统时间的初始化。即:
系统时间初始化后,由于基于系统时间通用接口编写的应用程序是可重用的,因此可以直接基于DS1302 启动如程序清单6.65 所示的系统时间测试应用程序,详见程序清单6.92。
程序清单6.92 启动系统时间测试应用程序(基于DS1302)
显然,若将RTC 模块由PCF85063 更换为DS1302,使用系统时间的应用程序无需修改。
5. 特殊功能控制接口
除典型的实时时钟功能外,DS1302 还具有一些特殊功能,比如,涓流充电功能、31 字节RAM 等。这些功能由于不是通用功能,只能使用DS1302 相应的接口操作。以读写RAM和涓流充电功能为例,其相应的接口函数详见表6.16。
表6.16 DS1302 特殊功能控制接口(am_ds1302.h)
(1)写入RAM
该函数用于写入数据到DS1302 的RAM 中(最多可写入31 字节数据),其函数原型为:
其中,handle 为DS1302 实例句柄,p_data 指向待写入数据的首地址,data_len 指定写入数据的字节数,最大为31 字节,pos 指定了写入RAM 的起始地址,DS1302 的RAM 空间大小为31 字节,对应的地址为0 ~ 30,pos 的有效范围即为0 ~ 30。若返回AM_OK,表示数据写入成功,反之失败,写入31 字节数据至RAM 中的范例程序详见程序清单6.93。
程序清单6.93 写入RAM 范例程序
(2)读取RAM
该函数用于读取存于DS1302 的 RAM 中的数据,其函数原型为:
其中,handle 为DS1302 实例句柄,p_data 为输出参数,用于返回读取的数据,data_len表示读取数据的字节数,pos 表示读取数据的起始地址(0 ~ 30)。若返回AM_OK,表示读取成功,反之失败,范例程序详见程序清单6.94。
程序清单6.94 读取RAM 范例程序
可以使用读写RAM 接口简单验证DS1302 是否正常,详见程序清单6.95。
程序清单6.95 读写RAM 数据范例程序
(3)使能涓流充电
DS1302 具有双电源供电,当芯片由VCC2 供电时,可以通过可编程涓流充电器,使VCC2向VCC1 流入很小的电流,以便为连接到VCC1 的电池充电。使能涓流充电的函数原型为:
其中,handle 为DS1302 实例句柄,set_val 为可编程涓流充电器的控制参数,可以控制充电的电流。充电电路的示意图详见图6.10。
图6.10 DS1302 充电电路示意图
当总开关打开后,充电电流的大小是由选择的二极管个数(1 个或2 个)和电阻阻值(2KΩ、4KΩ 或8KΩ)决定的。二极管的个数决定了电压的压降,电流的计算公式为:
set_val 可用的值已经使用宏进行了定义,详见表6.17实际使用时,应该根据需要的电流大小选择其中一个宏作为set_val 的值。
表6.17 充电电路设置标志
比如,若选择1 个二极管、2K电阻,则应该将set_val 的值设置为:
AM_DS1302_TRICKLE_1D_2K
由于在MicroPort-DS1302 中,VCC2 的值为3.3V,因此此时的实际电流计算公式为:
当VCC1 为0 时(电池电量完全耗尽)时,则电流达到最大值,其值为:
这就要求电池支持的最大充电电流为1.3mA。实际中,随着对电池的充电,电池电量增加,VCC1 会逐渐增加,充电电流也随之逐渐减小。范例程序详见程序清单6.96。
程序清单6.96 使能涓流充电范例程序
(3)禁能涓流充电
当不需要充电时,如使用的非充电电池,可以使用该接口禁能涓流充电,其函数原型为:
其中,handle 为DS1302 实例句柄,范例程序详见程序清单6.97。
程序清单6.97 禁能涓流充电范例程序
-
DS1302
+关注
关注
8文章
449浏览量
50684 -
RTC
+关注
关注
2文章
538浏览量
66502 -
周立功
+关注
关注
38文章
130浏览量
37624
原文标题:周立功:重用外设驱动代码—— RTC 实时时钟(2)
文章出处:【微信号:Zlgmcu7890,微信公众号:周立功单片机】欢迎添加关注!文章转载请注明出处。
发布评论请先 登录
相关推荐
评论