MSP430 DS1302 驱动

news/2024/11/23 9:29:54/

sys.h里面需要一些延时函数。

ds1302.h


#ifndef __DS1302_H
#define __DS1302_H#include "msp430.h"
#include "sys.h"struct ds1302time
{int	year;unsigned char	mouth;unsigned char	day;unsigned char	week;unsigned char	hour;unsigned char	minute;unsigned char	second;
};void DS1302_read_time( struct ds1302time *p );//获取时间
void DS1302_write_time( struct ds1302time *p );//写入时间
int getWeekdayByYearday( int iY, int iM, int iD );//获取星期几#endif

ds1302.c

#include "DS1302.h"/**************宏定义***************/
#define DS_RST		BIT7    /* DS_RST = P2.7 */
#define DS_SCL		BIT5    /* DS_SCL = P2.5 */
#define DS_SDA		BIT6    /* DS_SDA = P2.6 */
#define DS_RST_IN	P2DIR	&= ~DS_RST
#define DS_RST_OUT	P2DIR	|= DS_RST
#define DS_RST0		P2OUT	&= ~DS_RST
#define DS_RST1		P2OUT	|= DS_RST
#define DS_SCL_IN	P2DIR	&= ~DS_SCL
#define DS_SCL_OUT	P2DIR	|= DS_SCL
#define DS_SCL0		P2OUT	&= ~DS_SCL
#define DS_SCL1		P2OUT	|= DS_SCL
#define DS_SDA_IN	P2DIR	&= ~DS_SDA
#define DS_SDA_OUT	P2DIR	|= DS_SDA
#define DS_SDA0		P2OUT	&= ~DS_SDA
#define DS_SDA1		P2OUT	|= DS_SDA
#define DS_SDA_BIT	(P2IN & DS_SDA)/* DS1302地址定义 */
#define ds1302_sec_add		0x80    /* 秒数据地址 */
#define ds1302_min_add		0x82    /* 分数据地址 */
#define ds1302_hr_add		0x84    /* 时数据地址 */
#define ds1302_date_add		0x86    /* 日数据地址 */
#define ds1302_month_add	0x88    /* 月数据地址 */
#define ds1302_day_add		0x8a    /* 星期数据地址 */
#define ds1302_year_add		0x8c    /* 年数据地址 */
#define ds1302_control_add	0x8e    /* 控制数据地址 */
#define ds1302_charger_add	0x90
#define ds1302_clkburst_add	0xbe/* 向DS1302写入一个字节数据 */
void W_Data( unsigned char addr, unsigned char data )
{unsigned char i;DS_RST_OUT;DS_SCL_OUT;DS_SDA_OUT;DS_RST0;            /* 停止DS1302总线 */DS_SCL0;            /* 清零时钟线 */delay_us( 10 );DS_RST1;            /* 启动DS1302总线 */addr		= addr & 0xFE;  /* 最低位置零,写数据 */DS_SDA_OUT;for ( i = 0; i < 8; i++ )       /* 写地址 */{DS_SCL0;if ( addr & 0x01 )DS_SDA1;elseDS_SDA0;addr		= addr >> 1;DS_SCL1;    /* 产生时钟在上升沿输出数据到DS1302 */delay_us( 9 );}for ( i = 0; i < 8; i++ )       /* 写数据 */{DS_SCL0;if ( data & 0x01 )DS_SDA1;elseDS_SDA0;data		= data >> 1;DS_SCL1;    /* 产生时钟在上升沿输出数据到DS1302 */delay_us( 9 );}DS_RST0;                 /* 停止DS1302总线 */
}/* 从DS1302读出一个字节数据 */
unsigned char R_Data( unsigned char addr )
{unsigned char i, temp;DS_RST_OUT;DS_SCL_OUT;DS_SDA_OUT;DS_RST0;            /* 停止DS1302总线 */DS_SCL0;            /* 清零时钟线 */delay_us( 10 );DS_RST1;            /* 启动DS1302总线 */addr		= addr | 0x01;  /* 最低位置高,读数据 */DS_SDA_OUT;for ( i = 0; i < 8; i++ )       /* 写地址 */{DS_SCL0;if ( addr & 0x01 )DS_SDA1;elseDS_SDA0;addr		= addr >> 1;DS_SCL1;    /* 产生时钟在上升沿输出数据到DS1302 */delay_us( 9 );}DS_SDA_IN;for ( i = 0; i < 8; i++ )       /* 读数据 */{if ( DS_SDA_BIT )temp |= 0x80;elsetemp &= 0x7F;DS_SCL1;    /* 产生时钟在下升沿输出数据到DS1302 */temp		= temp >> 1;DS_SCL0;delay_us( 9 );}DS_RST0;                 /* 停止DS1302总线 */return(temp);
}/******************************************** 函数名称:Set_DS1302* 功    能:设置DS1302内部的时间* 参    数:ptr--指向存放数据地址的指针* 返回值  :无* 说明    :写入数据的格式:*          秒 分 时 日 月 星期 年  【共7个字节】********************************************/
void Set_DS1302( unsigned char *ptr )
{unsigned char	i;unsigned char	addr = 0x80;W_Data( 0x8e, 0x00 );                           /* 允许写入 */for ( i = 7; i > 0; i-- ){W_Data( addr, *ptr++ );addr += 2;}W_Data( 0x8e, 0x80 );                           /* 禁止 */
}/* 从DS302读出时钟数据 */
void DS1302_Read_Time( unsigned char *ptr )
{ptr[1]	= R_Data( ds1302_year_add );            /* 年 */ptr[2]	= R_Data( ds1302_month_add );           /* 月 */ptr[3]	= R_Data( ds1302_date_add );            /* 日 */ptr[4]	= R_Data( ds1302_hr_add );              /* 时 */ptr[5]	= R_Data( ds1302_min_add );             /* 分 */ptr[6]	= (R_Data( ds1302_sec_add ) ) & 0x7f;   /* 秒,屏蔽秒的第7位,避免超出59 */ptr[7]	= R_Data( ds1302_day_add );             /* 周 */
}/* 获取时间 */
void DS1302_read_time( struct ds1302time *p )
{/* 年月日 时分秒 星期 */unsigned char time_buf[8] = { 0x20, 0x20, 0x03, 0x03, 0x23, 0x59, 0x55, 0x02 };DS1302_Read_Time( time_buf ); /* 读取 */p->year		= 2000 + (time_buf[1] >> 4) * 10 + (time_buf[1] & 0x0f);p->mouth	= (time_buf[2] >> 4) * 10 + (time_buf[2] & 0x0f);p->day		= (time_buf[3] >> 4) * 10 + (time_buf[3] & 0x0f);p->hour		= (time_buf[4] >> 4) * 10 + (time_buf[4] & 0x0f);p->minute	= (time_buf[5] >> 4) * 10 + (time_buf[5] & 0x0f);p->second	= (time_buf[6] >> 4) * 10 + (time_buf[6] & 0x0f);p->week = (time_buf[7] >> 4) * 10 + (time_buf[7] & 0x0f);
}/* 写入时间 */
void DS1302_write_time( struct ds1302time *p )
{/* 年月日 时分秒 星期 */unsigned char time_buf[8] = { 0x20, 0x20, 0x03, 0x03, 0x23, 0x59, 0x55, 0x02 };time_buf[1]	= p->year % 100 / 10 * 16 + p->year % 100 % 10;time_buf[2]	= p->mouth % 100 / 10 * 16 + p->mouth % 100 % 10;time_buf[3]	= p->day % 100 / 10 * 16 + p->day % 100 % 10;time_buf[4]	= p->hour % 100 / 10 * 16 + p->hour % 100 % 10;time_buf[5]	= p->minute % 100 / 10 * 16 + p->minute % 100 % 10;time_buf[6]	= p->second % 100 / 10 * 16 + p->second % 100 % 10;time_buf[7]	= p->week % 100 / 10 * 16 + p->week % 100 % 10;W_Data( ds1302_control_add, 0x00 );             /* 关闭写保护 */W_Data( ds1302_sec_add, 0x80 );                 /* 暂停时钟 *//* DS1302_Write_Byte(ds1302_charger_add, 0xA9);      //涓流充电 */W_Data( ds1302_year_add, time_buf[1] );         /* 年 */W_Data( ds1302_month_add, time_buf[2] );        /* 月 */W_Data( ds1302_date_add, time_buf[3] );         /* 日 */W_Data( ds1302_hr_add, time_buf[4] );           /* 时 */W_Data( ds1302_min_add, time_buf[5] );          /* 分 */W_Data( ds1302_sec_add, time_buf[6] );          /* 秒 */W_Data( ds1302_day_add, time_buf[7] );          /* 周 */W_Data( ds1302_control_add, 0x80 );             /* 打开写保护 */
}/** 由年月日获取星期 https://www.cnblogs.com/fengbohello/p/3264300.html* 返回1到7 代表星期一到星期天*/
int getWeekdayByYearday( int iY, int iM, int iD )
{int iWeekDay = -1;if ( 1 == iM || 2 == iM ){iM += 12;iY--;}iWeekDay = (iD + 1 + 2 * iM + 3 * (iM + 1) / 5 + iY + iY / 4 - iY / 100 + iY / 400) % 7;if ( iWeekDay == 0 )iWeekDay = 7;return(iWeekDay);
}

使用:
定义时间变量结构体:

struct ds1302time	time;           /* DS1302时间 */

写入时间:

    time.year	= 2020;time.mouth	= 3;time.day	= 13;time.hour	= 12;time.minute	= 55;time.second	= 55;time.week	= getWeekdayByYearday( time.year, time.mouth, time.day );DS1302_write_time( &time );                                             /* 写入时间 */

更新时间time:

DS1302_read_time( &time );//读取时间
time.week = getWeekdayByYearday( time.year, time.mouth, time.day );//

http://www.ppmy.cn/news/200353.html

相关文章

【DS1302驱动】

DS1302ZN 实时时钟芯片驱动 正文 最近使用了DS1302ZN 实时时钟芯片&#xff0c;浅浅分享一下我写的驱动。代码也是从其他的博主那改过来的&#xff0c;只是将格式和一些小细节优化了一下。具体的原理懒得写了&#xff0c;其他博主那有很详细的。 说明 使用的平台的STM32F10…

常见摄像头接口USB、DVP、MIPI接口的对比

常见摄像头接口DVP、MIPI、USB的比较 引言 摄像头传感器已经广泛用于嵌入式设备了&#xff0c;现在的手机很多都支持多个摄像头。 在物联网领域&#xff0c;摄像头传感器也越来越被广泛使用。今天就来简单聊一聊几种常见的摄像头接口。 传感器与主控设备进行通信&#xff0…

Windows安装Dolby Vision 杜比视界插件

前言 使用普通的播放器播放杜比视界视频时会出现发紫和发绿&#xff0c;两者来回切换的情况&#xff0c;要么使用专门的播放器&#xff0c;要么使用Windows自带播放器加上安装相应拓展 在使用Windows自带的“电影和电视”播放杜比视界(Dolby Vision)的视频时&#xff0c;需要安…

DCMI接口之OV2640摄像头

一、OV2640简介 OV2640是OmniVision公司生产的一颗1/4寸的CMOS UXGA&#xff08;1632 * 1232&#xff09;图像传感器。该传感器体积小、工作电压低&#xff0c;提供单片UXGA摄像头和影像处理器的所有功能。通过SCCB 总线控制&#xff0c;可以输出整帧、子采样、缩放和取窗口等…

DV2020T 综合

在这里插入代码片//audio内存泄漏 //audio pts //ENCInterface.h //绿条 //没有设备时崩 //接口 //如何把硬件编码对接webrtc中 //video/audio开启或关闭 //码率分辨率帧率控制 //导播离开房间重进房间 网络中途断开socket.io重连&#xff0c;srs->close 重联成功srs->st…

基于android的条码识别技术,基于Android手机的条码识别系统研究

摘要&#xff1a; 当前,条码技术在商品管理、生产自动化、邮政系统、交通运输等领域得到了广泛的应用。与此同时,随着网络信息技术的发展,尤其是近几年以智能手机为代表的智能终端设备的兴起,移动互联网获得了蓬勃发展,为条码技术提供了新的发展机遇和更大的发展空间,从而为促进…

4g android 手机排行榜,全球最结实的4G安卓手机开卖

致力于打造结实手机的制造商Sonim发起了一项Indiegogo众筹活动&#xff0c;这个活动的主角是Sonim XP7 Extreme新款智能手机。这款手机被称为“全球最结实的LTE安卓智能手机”&#xff0c;用户群体是运动爱好者&#xff0c;号称是滑雪、爬山、自行车骑行、钓鱼、徒步远行划船等…

条码防伪检测技术介绍,如何通过扫描商品条码判断产品的真伪-鸿顺捷条码防伪技术介绍

条码防伪检测技术的典型应用 经常有人问:如何通过条形码判断一个产品的真伪&#xff1f;(此处条形码应指商品代码) 这可能是对条形码功能的误解。一般来说&#xff0c;不能单纯通过商品上的条形码来判断商品的真伪。 商品编码是国家为使商品在公开市场(如商场、超市)上能被公开…