2025 Make Blocks阶段2 - 使用MCP7940N完成实时时钟模块设计
该项目使用了MCP7940N,实现了实时时钟模块的设计,它的主要功能为:可以输出时间和日历信息。
标签
实时时钟模块
Make Blocks
MCP7940N
戈壁滩上的辉煌
更新2025-09-17
13

任务介绍

考虑到第一期做的模块,为了能和他配合起来,我们这次采用自定义的方式做了一个可以和他引脚配合的扩展模块,目前这个扩展模块增加的是实时时钟部分,其实也可以算是做了一个实时时钟模块的任务,就是尺寸上我们选择的是和上一期相配合的大小。

设计思路

目前的要求是设计一款实时时钟模块,由于想要和前面的模块可以关联上,这次我们通过在CubeMX中找到对应的IIC接口,然后在这个基础上进行的,使用的是和之前兼容的结构,选择一款超有性价比的实时时钟芯片。

为了和之前的模块能够关联这,这次虽然板子比较大,不过目前只有一个功能模块,接口是满足LaunchPad接口需求的,使用两个2*10的排母进行外接。

设计框图如下:


0

功能介绍

本次设计的是一个实时时钟模块,通过IIC接口进行通信控制,可以输出时间和日历。

硬件介绍

本次设计的扩展模块主要基于MCP7940N-I/SN进行设计,MCP7940N-I/SN是由Microchip Technology制造的一款实时时钟(RTC)芯片,采用I²C接口标准,兼容表面贴装(SMT)技术。该芯片专为需要高精度时间计数的电子设备设计。其核心参数包括:工作电压范围为1.8V至5.5V,工作温度区间为-40°C至+85°C。内置64B SRAM存储容量,支持HH:MM格式的时间显示(可选12/24小时制),日期格式为YY-MM-DD-DD(年-月-日-星期)。接口类型采用I²C(2线串行)通信协议。主要功能涵盖自动闰年调整、可编程闹钟功能、方波输出接口以及内置日历功能(含月份天数智能计算)。该芯片广泛应用于工业控制、智能家居系统、仪表仪器等领域,适用于智能手表、温控设备、数据记录仪等需精确时间计时的设备。

原理图和PCB模块介绍


0

原理图


0

PCB

实时时钟单元提供精准的计时功能,所以需要32.768kHz的晶振提供基准,实时时钟可以在主电断点的情况下继续进行计时,主要是因为备电的存在,我们也添加了一个2032的电池座作为备电,主要的接口就是IIC接口,用的引脚数量相对比较少。


0

实物图

软件调试

软件方面的调试工作主要是为了验证模块功能是否正常,这里我们选用最便捷的arduino来进行,加载的是MCP7940库,确实很方便,驱动代码如下:


#include <MCP7940.h> // Include the MCP7940 RTC library

const uint32_t SERIAL_SPEED = 115200; ///< Set the baud rate for Serial I/O
const uint8_t LED_PIN = 13; ///< Arduino built-in LED pin number
const uint8_t SPRINTF_BUFFER_SIZE = 32; ///< Buffer size for sprintf()
const uint8_t MCP7940_MEMORY_SIZE = 64; ///< Number of bytes in memory
/***************************************************************************************************
** Declare global variables and instantiate classes **
***************************************************************************************************/
MCP7940_Class MCP7940; ///< Create an instance of the MCP7940
char inputBuffer[SPRINTF_BUFFER_SIZE]; ///< Buffer for sprintf()/sscanf()

void setup() {
/*!
@brief Arduino method called once upon start or restart.
*/
Serial.begin(SERIAL_SPEED);
#ifdef __AVR_ATmega32U4__ // If on a 32U4 processor, wait 3s for serial interface to initialize
delay(3000);
#endif
Serial.print(F("\nStarting AccessMemory program\n"));
Serial.print(F("- Compiled with c++ version "));
Serial.print(F(__VERSION__));
Serial.print(F("\n- On "));
Serial.print(F(__DATE__));
Serial.print(F(" at "));
Serial.print(F(__TIME__));
Serial.print(F("\n"));
while (!MCP7940.begin()) // Initialize I2C communications with RTC
{
Serial.println(F("Unable to find MCP7940M. Checking again in 3s."));
delay(3000);
} // of loop until device is located
Serial.println(F("MCP7940 initialized."));
while (!MCP7940.deviceStatus()) // Turn oscillator on if necessary
{
Serial.println(F("Oscillator is off, turning it on."));
bool deviceStatus = MCP7940.deviceStart(); // Start oscillator and return new state
if (!deviceStatus) {
Serial.println(F("Oscillator did not start, trying again."));
delay(1000);
} // of if-then oscillator didn't start
} // of while the oscillator is off
MCP7940.adjust(); // Set Date/time to that of compile
Serial.println(F("Enter any text in the serial monitor and hit send"));
pinMode(LED_PIN, OUTPUT);
} // of method setup()

void loop() {
/*!
@brief Arduino method called after setup() which loops forever
*/
static uint8_t secs = 0;
static uint8_t memoryAddress = 0;
DateTime now = MCP7940.now(); // get the current time
if (secs != now.second()) // Output only if the seconds have changed
{
sprintf(inputBuffer, "%04d-%02d-%02d %02d:%02d:%02d", now.year(), now.month(), now.day(),
now.hour(), now.minute(), now.second());
if (secs % 10 == 0) Serial.println(inputBuffer); // Only Display every 10 seconds
secs = now.second();
digitalWrite(LED_PIN, !digitalRead(LED_PIN)); // Toggle the LED
} // of if the seconds have changed
if (Serial.available()) // Check for serial port data
{
uint8_t dataByte = Serial.read(); // read the byte from serial
if (dataByte == 0x0A) // If the user hit return/enter
{
MCP7940.writeRAM(memoryAddress++, 0); // Terminate the string
char dataBuffer[MCP7940_MEMORY_SIZE]; // Memory size value
uint8_t x = MCP7940.readRAM(0, dataBuffer); // Read all the memory
Serial.print("Retrieved ");
Serial.print(x);
Serial.print(" bytes from memory,\nstring is \"");
Serial.print(dataBuffer);
Serial.println("\"");
memoryAddress = 0;
} else {
if (dataByte != 13) // Write to memory and increment
{
MCP7940.writeRAM(memoryAddress++, dataByte); // counter if the value is not LF
} // of if-then we have a valid character to write
} // of if-then-else we have a LF
} // of if-then we have something to read from the serial port
} // of method loop()

运行效果


0

心得体会

本次通过最便捷的方式进行了一下实时时钟模块的功能验证,主要也是验证硬件是否可行,本次使用的实时时钟芯片封装也非常普通,这样的器件肯定更加受欢迎,至少我们学习的人是这样的,好焊接调试,接口相对来说也比较简单的,感谢论坛和得捷对本次活动的大力支持,不断的让工程师接触更多的新知识。

附件下载
H5-MCP7940.zip
H5-实时时钟(MCP7940N).kicad_pcb
H5-实时时钟(MCP7940N).kicad_sch
团队介绍
评论
0 / 100
查看更多
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号