STM32控制DS1302时钟模块获取实时时间

时间记录:2024/3/30

一、知识点

原理图
(1)读写数据时序(伪SPI协议)
读写时序
1.1 读写时序默认电平均为SCLK线低电平,CE线低电平
1.2 写数据,CE线拉高为高电平,开始传输数据,然后准备数据在SCLK线的上升沿DS1302读取数据,发送8位控制命令后,发送8位数据(低位先发)
1.3 读数据,CE线拉高为高电平,开始传输数据,然后在SCLK低电平时准备数据,上升沿发送数据,发送8位控制命令后,下一个下降沿开始读取数据(低位先发,低位先读)
(2)读写命令及数据格式
命令及数据格式
2.1 READ和WRITE的命令即为发送和读取数据前需要先发送的对应8位控制命令
2.2 秒数据的BIT7位CH决定时钟的开启/关闭
2.3 小时数据的BIT7位决定是12小时显示还是24小时显示
2.4 WP位决定开启写保护还是取消写保护,写入0取消写保护,写入1打开写保护
(3)数据转换
3.1 DS1302读取的数据为BCD编码格式,需要转为10进制,写入时10进制数据需要转为BCD格式
3.2 BCD->10进制,BCD/1610+BCD%16
3.3 10进制->BCD,10进制/10
16+10进制%10

二、示例代码

(1)头文件

#ifndef __DS1302_H__
#define __DS1302_H__
#include "stm32f10x.h"

void ds1302Init(void);
u8 ds1302_ReadRam(u8 addr);

#endif

(2)源文件

#include "ds1302.h"

static void datLineMode(u8 mode);
static void write(u8 addr,u8 data);

void ds1302Init(void)
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
    
    GPIO_InitTypeDef GPIO_InitStruct;
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_12;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA,&GPIO_InitStruct);
    GPIO_ResetBits(GPIOA,GPIO_Pin_12);
    
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA,&GPIO_InitStruct);
    GPIO_ResetBits(GPIOA,GPIO_Pin_10);
}

static void write(u8 addr,u8 data)
{
    //1.拉高CE片选线,开始通信
    GPIO_SetBits(GPIOA,GPIO_Pin_10);
    datLineMode(0);
    
    for(u8 i=0;i<8;i++) //写入命令字节
    {
        //2.拉低CLK线准备数据
        GPIO_ResetBits(GPIOA,GPIO_Pin_12);
        if(addr&0x01)
            GPIO_SetBits(GPIOA,GPIO_Pin_11);
        else
            GPIO_ResetBits(GPIOA,GPIO_Pin_11);
        //3.拉高CLK线将数据发送出去
        GPIO_SetBits(GPIOA,GPIO_Pin_12);
        addr>>=1;
    }
    
    for(u8 i=0;i<8;i++) //写入数据字节
    {
        //2.拉低CLK线准备数据
        GPIO_ResetBits(GPIOA,GPIO_Pin_12);
        if(data&0x01)
            GPIO_SetBits(GPIOA,GPIO_Pin_11);
        else
            GPIO_ResetBits(GPIOA,GPIO_Pin_11);
        //3.拉高CLK线将数据发送出去
        GPIO_SetBits(GPIOA,GPIO_Pin_12);
        data>>=1;
    }
    
    GPIO_ResetBits(GPIOA,GPIO_Pin_10);
    GPIO_ResetBits(GPIOA,GPIO_Pin_12);
}

u8 ds1302_ReadRam(u8 addr)
{
    //1.拉高CE片选线,开始通信
    GPIO_SetBits(GPIOA,GPIO_Pin_10);
    datLineMode(0);
    
    for(u8 i=0;i<8;i++) //写入命令字节
    {
        //2.拉低CLK线准备数据
        GPIO_ResetBits(GPIOA,GPIO_Pin_12);
        if(addr&0x01)
            GPIO_SetBits(GPIOA,GPIO_Pin_11);
        else
            GPIO_ResetBits(GPIOA,GPIO_Pin_11);
        //3.拉高CLK线将数据发送出去
        GPIO_SetBits(GPIOA,GPIO_Pin_12);
        addr>>=1;
    }
    
    u8 data = 0x00;
    
    datLineMode(1);
    for(u8 i=0;i<8;i++) // 读取数据
    {
        //产生下降沿,然后读出数据
        data >>= 1; // 第一位数据为控制位
        GPIO_ResetBits(GPIOA,GPIO_Pin_12);
        if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_11)) //读取数据
        {
            data |= 0x80;
        }
        GPIO_SetBits(GPIOA,GPIO_Pin_12);
    }
    
    GPIO_ResetBits(GPIOA,GPIO_Pin_10);
    GPIO_ResetBits(GPIOA,GPIO_Pin_12);
    
    return data;
}

static void datLineMode(u8 mode)
{
    GPIO_InitTypeDef GPIO_InitStruct;
    
    if(mode==0)
    {
        GPIO_InitTypeDef GPIO_InitStruct;
        GPIO_InitStruct.GPIO_Pin = GPIO_Pin_11;
        GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
        GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOA,&GPIO_InitStruct);
    }
    else if(mode==1)
    {
        GPIO_InitTypeDef GPIO_InitStruct;
        GPIO_InitStruct.GPIO_Pin = GPIO_Pin_11;
        GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
        GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOA,&GPIO_InitStruct);
    }
}

相关推荐

  1. 时钟DS1302LCD

    2024-05-02 09:14:01       38 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-05-02 09:14:01       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-05-02 09:14:01       106 阅读
  3. 在Django里面运行非项目文件

    2024-05-02 09:14:01       87 阅读
  4. Python语言-面向对象

    2024-05-02 09:14:01       96 阅读

热门阅读

  1. springboot基础

    2024-05-02 09:14:01       31 阅读
  2. 5-用户权限控制(前端)

    2024-05-02 09:14:01       29 阅读
  3. 我选择哪个区块链平台将作品转化为NFT最合适?

    2024-05-02 09:14:01       35 阅读
  4. 设计模式-03 设计模式-依赖倒转原则案例分析

    2024-05-02 09:14:01       30 阅读
  5. Spring-MVC从入门到精通

    2024-05-02 09:14:01       22 阅读
  6. CAN测试工具

    2024-05-02 09:14:01       33 阅读
  7. CKEditor编辑器的简单使用方法,取值,赋值

    2024-05-02 09:14:01       29 阅读
  8. Github 2024-05-01 开源项目日报Top10

    2024-05-02 09:14:01       33 阅读
  9. map和set

    map和set

    2024-05-02 09:14:01      28 阅读
  10. 如何在Dlib库中实现目标跟踪

    2024-05-02 09:14:01       29 阅读
  11. C\#工控行业中的视觉技术栈

    2024-05-02 09:14:01       35 阅读
  12. 【Unity Consoler Redirection】Unity Log 跳转重定向

    2024-05-02 09:14:01       30 阅读
  13. golang netpoller揭秘

    2024-05-02 09:14:01       22 阅读
  14. 经济效益分析:等保测评的成本与回报

    2024-05-02 09:14:01       27 阅读