文件:DS1302.C
环境:编余哪译为ICC AVR6.25A,仿真为AVR Studio4.10
硬件:ATMEGA64L芯片
日期:2008年3月7日
功能:驱动时钟芯片DS1302
备注:
*******************************************************************************/
/*=======================硬件说明迅敏===============================================
指令 指令码 功能
==============================================================================*/
//=======================头文件=================================================
#include <iom64v.h>
#include <macros.h>
#include <signal.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include "main.h"
#include "Variable.h"
#include "DS1302.h"
//==============================================================================
/****************************************************************
* 名称 : void Reset_3wire(void)
* 功能描述: reset and enable the 3-wire interfaT_CE
* 输入参量: 无
* 输出参量: 无
* 调用子程: 无
* 使用方法: 对3-wire *** 作的话,首先要使能
-------------------------------------------------*/
void Reset_3wire(void)
{
DS1302_RST_OUT// 输出
DS1302_CLK_OUT
DS1302_IO_OUT
DS1302_CLK_LOW
Delay_nus(10)
DS1302_RST_LOW
Delay_nus(10)
DS1302_RST_HIGH
Delay_nus(10)
}
/****************************************************************
* 名称 : void Write_Byte_3W(unsigned char W_Byte)
* 功能描述: write one byte to the deviT_CE
* 输入参量: 需要写的字竖昌码节
* 输出参量: 无
* 调用子程: 无
* 使用方法: 无论读写,都首先要写东西
-------------------------------------------------*/
void Write_Byte_3W(unsigned char W_Byte)
{
unsigned char i
for(i = 0i <8i++)
{
DS1302_IO_LOW
if(W_Byte &0x01)
{
DS1302_IO_HIGH /* set port pin high to read data */
}
Delay_nus(10)
DS1302_CLK_LOW
Delay_nus(10)
DS1302_CLK_HIGH
Delay_nus(10)
W_Byte >>= 1
}
}
//****************************************************************
/****************************************************************
* 名称 : unsigned char Read_Byte_3W()
* 功能描述: read one byte from the deviT_CE
* 输入参量: 需要写的字节
* 输出参量: 读出的数据
* 调用子程: 无
* 使用方法: 从3 线器件读数据
----------------------------*/
unsigned char Read_Byte_3W(void)
{
unsigned char i
unsigned char R_Byte
unsigned char TmpByte
R_Byte = 0x00
DS1302_IO_IN //0xF7//改变io 口的方向为输入
Delay_nus(10)
for(i = 0i <8i++)
{
DS1302_CLK_HIGH
Delay_nus(10)
DS1302_CLK_LOW //下降沿数据有效
Delay_nus(10)
if(READ_DS1302_IO)
TmpByte=1//位 *** 作要小心
else
TmpByte=0
TmpByte <<= 7
R_Byte >>= 1
R_Byte |= TmpByte
}
return R_Byte
}
//******************************************************************
/****************************************************************
* 名称 : Get_Time
* 功能描述: 读取DS1302 当前时间
* 输入参量: ucCurtime: 保存当前时间地址。当前时间格式为: 秒 分 时 日 月 星期 年
7Byte (BCD 码) 1B 1B 1B 1B 1B 1B 1B
* 输出参量: 无
* 调用子程: 无
* 使用方法:
----------------------------*/
void DS1302_Get_Time(unsigned char ucCurtime[])
{
unsigned char i
Reset_3wire()
Write_Byte_3W(0xBF)/* clock burst */
for(i=0i<7i++)
ucCurtime[i]=Read_Byte_3W()
//Reset_3wire()
DS1302_RST_LOW
}
/****************************************************************
* 名称 : Set_Time
* 功能描述: initialize time &date from user entries
* 输入参量: unsigned char yr, mn, date, dy, hr, min, sec, day设置时间并启动
* 输出参量: OK--- 设置成功
* ERROR --- 时间格式错误,无法设置
* 调用子程: 无
* 使用方法:
----------------------------*/
unsigned char DS1302_Set_Time(unsigned char *pClock)
{
unsigned char i
i = Check_Time(pClock)
if(i == ERROR)
return ERROR
pClock[5] = Get_Day(pClock[6],pClock[4],pClock[3])//取星期
//hr = hr &0x3f/* forT_CE clock to 24 hour mode */
Reset_3wire()
Write_Byte_3W(0x8e)/* control register */
Write_Byte_3W(0)/* disable write protect */
Reset_3wire()
//Write_Byte_3W(0x90)/* trickle charger register */
//Write_Byte_3W(0xab)/* enable, 2 dT IOdes, 8K resistor */
//Reset_3wire()
Write_Byte_3W(0xbe)/* clock burst write (eight registers) */
for(i=0i<7i++)
{
Write_Byte_3W(*(pClock++))
}
Write_Byte_3W(0)/* must write control register in burst mode */
//Reset_3wire()
DS1302_RST_LOW
return OK
}//******************************************************************
//------------------------------------------------------------------------------
//函数名称:Get_Day
//函数功能:根据年月日算出星期
//函数参数:year --- 年
// month --- 月
// date --- 日
//函数返回:day --- 星期
//------------------------------------------------------------------------------
//计算公式使用著名的蔡勒(Zeller)公式。即:
//w=y+[y/4]+[c/4]-2c+[26(m+1)/10]+d-1
//公式中的符号含义如下,
//w:星期;
//c:世纪-1;
//y:年(两位数);
//m:月(m大于等于3,小于等于14,即在蔡勒公式中,
// 某年的1、2月要看作上一年的 13、14月来计算,
// 比如2003年1月1日要看作2002年的13月1日来计算);
//d:日;[ ]代表取整,即只要整数部分。
//C是世纪数减一,y是年份后两位,M是月份,d是日数。
//1月和2月要按上一年的13月和 14月来算,这时C和y均按上一 年取值。
//------------------------------------------------------------------------------
unsigned char Get_Day(unsigned char year,unsigned char month,unsigned char date)
{
unsigned char day
unsigned int temp
unsigned char century
year = Hex_To_Decimal(year)
month = Hex_To_Decimal(month)
date = Hex_To_Decimal(date)
century = 20
if(month <3)
{
month += 12
if(year == 0)
{
year = 99
century --
}
else
year --
}
temp = (month + 1) * 26
temp = temp / 10
temp += year
temp += (year >>2)
temp += (century >>2)
temp -= (century <<1)
temp += date
temp --
day = temp % 7
if(day == 0)
day = 7
return day
}
//=======================函数===============================================
//函数名称:Check_Time
//函数功能:检查时间格式是否正确,只能检查2000-2099年
//函数参数:buffer --- 时间:字节从高到低,年 星期 月 日 时 分 秒
//函数返回:result --- OK: 格式正确
// ERROR:格式错误
//==============================================================================
unsigned char Check_Time(unsigned char *buffer)
{
unsigned char year
unsigned char month
unsigned char date
unsigned char hour
unsigned char minute
unsigned char second
year = Hex_To_Decimal(buffer[6])
month = Hex_To_Decimal(buffer[4])
date = Hex_To_Decimal(buffer[3])
hour = Hex_To_Decimal(buffer[2])
minute = Hex_To_Decimal(buffer[1])
second = Hex_To_Decimal(buffer[0])
if(second >= 60)
buffer[0] = 0x30
if(minute >= 60)
return ERROR
if(hour >= 24)
return ERROR
if(month >= 13)
return ERROR
if(month &1)
{
if(date >= 32)
return ERROR
}
else if(month == 2)
{
if(year % 4)
{
if(date >= 29)
return ERROR
}
else
{
if(date >= 30)
return ERROR
}
}
else
{
if(date >= 31)
return ERROR
}
return OK
}
一、AVR系列单片机开发板本开发板可使用于多种型号的AVR单片机,本板主配ATmega16单片机。除了丰富的硬件资源外,还配有仿真器,可以很方便的调试硬件,大大减小调试周期。所有IO口全部引出,用户可以任意扩展功能。
二、AVR_PQ1A开发桐蠢板实例程序(演示程序)
( 1 ) LED LED灯驱动程序,两种演示方式
( 2 ) SMG 数码管驱动程序,循环滚动显示数字1-6
( 3 ) 1602 1602液晶驱动程序,除正常显示ASCII码外,还教如何显示中文
( 4 ) 12864 12864液晶驱动程序,显示汉字和图形。液晶为带字库的 ST7920控制器的液晶。
( 5 ) SKEY 4个独立按键驱动程序,采用查询方式驱动
( 6 ) SKEY_INT 利用按键产生外部中断,教你中断程序的编写
( 7 ) MKEY 4x4矩阵按键驱动程序,教你如何扫描矩阵按键
( 8 ) TIMER0INT 定时器0驱动程序,教你如何使用定时器
( 9 ) AD Mega16自带的AD的驱动程局神陪序
( 10 ) DA SPI接口的8位DA驱动程序,利用Mega16的硬SPI接口
( 11 ) DS18B20 数字温度传感器驱动程序,教你如何显示小数
( 12 ) TWI( IIC ) IIC接口数字电位器驱动程序,利用Mega16的硬件IIC接口
( 13 ) BEEP 蜂鸣器唱歌程序,教你如何唱出好听的歌曲
( 14 ) PWM Mega16的定时器1驱动程序,实现PWM输出功能
( 15 ) RELAY 继电器驱动程序,利用Mega16的I/O口直接驱瞎腊动继电器
( 16 ) UART Mega16的异步串口驱动程序,教你如何实现串口通信
( 17 ) RTC 时钟芯片驱动程序,可以显示和利用按键设定时间
( 18 ) EEPROM Mega16的EEPROM驱动程序,读写内部EEPROM
( 19 ) PS2 标准PS2键盘驱动程序,教你如何读入扫描码并译成ASCII码
( 20 ) USB USBD12固件程序,教你实现枚举过程和数据传输
( 21 )uC/OS-II 移植好的 *** 作系统,执行两个任务,编译后,占用Mega16的26%资源。
/***时钟芯片DS1302驱动——火柴天堂作品-20120610***//***源程序硬件环境:52单片机,12MHz晶振,P34接时钟芯片IO脚,P35接芯片RST/CE脚,P36接芯片CLK脚***/
/******/
#define DS1302_H
#include"reg52.h" //包含52头文件
#include"DS1302.h" //包含DS1302宏定义文件
sbit DS1302_CLK=P3^6 //定义 CLK 接口
sbit DS1302_IO=P3^4 //定义 IO 接口
sbit DS1302_nRST=P3^5 //定义 RST 接口
#define RST_En DS1302_nRST=1 //使能
#define RST_Dis DS1302_nRST=0 //禁止
void DS1302_Init() //SD1302端口初始化函数
{
RST_Dis //禁止 *** 作扒蠢穗
DS1302_CLK=0 //时钟接口置 低常态
DS1302_IO=1 //数据接口置 高常态
}
uchar DS1302_ReadByte(uchar read_addr) //SD1302读函数,形参为 读地址
{
uchar i,read_data=0
RST_Dis //禁止 *** 作
DS1302_CLK=0 //时钟接口置 低常态
RST_En //允许 *** 作
for(i=0i<8i++) //输入8位地址
{
DS1302_CLK=0
if(read_addr &(1<<i)) DS1302_IO=1 //转换地址相应位,并输出至数据接口
else DS1302_IO=0 //转换地址相应位,并输出至数据接口
DS1302_CLK=1 //上升沿数据被DS1302接收
}
for(i=0i<8i++) //输出8位数据
{
DS1302_CLK=0 //下降沿,数据从DS1302输出
if(DS1302_IO) read_data|=1<<i //读取数据,并送往数据寄存器相应位
DS1302_CLK=1
}
RST_Dis //禁止 *** 作
DS1302_CLK=0 //时钟接口置 低常态
return read_data //返回读取数据
}
void DS1302_ReadDate(uchar *buf_p,uchar store_start) //DS1302读时间函数,返回十进制格式"年月日周时分春卜秒",共占7个uchar空间
{
buf_p+=store_start
*buf_p=DS1302_ReadByte(Read_Year) //年
*buf_p=(*buf_p>>4)*10+(*buf_p &0x0f) //BCD转Hex
*++buf_p=DS1302_ReadByte(Read_Month) //月
*buf_p=(*buf_p>>4 &0x01)*10+(*buf_p &0x0f) //BCD转Hex
*++buf_p=DS1302_ReadByte(Read_Day) //日
*buf_p=(*buf_p>>4 &0x03)*10+(*buf_p &0x0f) //BCD转Hex
*++buf_p=DS1302_ReadByte(Read_Week) //周
*buf_p&=0x07 //BCD转Hex
//*buf_p%=7 //0-6格式表示周
*++buf_p=DS1302_ReadByte(Read_Hour) //时
*buf_p=(*buf_p>>4 &0x03)*10+(*buf_p &0x0f) //BCD转Hex
*++buf_p=DS1302_ReadByte(Read_Min) //分
*buf_p=(*buf_p>>4 &0x07)*10+(*buf_p &0x0f) //BCD转Hex
*++buf_p=DS1302_ReadByte(Read_Sec) //秒
*buf_p=(*buf_p>>4 &0x07)*10+(*buf_p &0x0f) //BCD转Hex
}
//void DS1302_WriteByte(uchar write_com,uchar write_data) //DS132写函数,形参write_com为 *** 作指令,write_data为 *** 作数据
//{
// uchar i
// RST_Dis //禁止 *** 作
// DS1302_CLK=0 //时钟接口置 低常态档闷
// RST_En //允许 *** 作
// for(i=0i<8i++) //输入8位地址
// {
// if(write_com &1<<i) DS1302_IO=1 //转换指令相应位,并输出至数据接口
// else DS1302_IO=0 //转换指令相应位,并输出至数据接口
// DS1302_CLK=1 //上升沿数据被DS1302接收
// DS1302_CLK=0
// }
// for(i=0i<8i++) //输入8位地址
// {
// if(write_data &(1<<i)) DS1302_IO=1 //转换数据相应位,并输出至数据接口
// else DS1302_IO=0 //转换指令相应位,并输出至数据接口
// DS1302_CLK=1 //上升沿数据被DS1302接收
// DS1302_CLK=0
// }
// RST_Dis //禁止 *** 作
//}
//void DS1302_TimesInit(uint year,uchar month,uchar day,uchar week,uchar hour,uchar min,uchar sec,uchar hour_mode,uchar clock_state) //时间初始化函数
//{
// if(hour_mode!=H12_Mode &&hour_mode!=H24_Mode) hour_mode=H24_Mode //默认24小时制模式
// if(clock_state!=ClockHalt &&clock_state!=ClockStart) clock_state=ClockStart //默认时钟启动状态
// year%=100 //百年历
// switch(month) //月份判断
// {
// case 2: //2月
// if(year%4 &&day>28) day=28 //平年,日期最大值为28
// else if(day>29) day=29 //闰年,日期最大值为29
// break
// case 1:case 3:case 5:case 7:case 8:case 10:case 12:if(day>31) day=31break //大月,日期最大值为31
// case 4:case 6:case 9:case 11:if(day>30) day=30break //小月,日期最大值为30
// default: //错误月份
// month=1 //默认1月
// day=1 //默认1日
// break
// }
// if(!day) day=1 //日期最小值为1
// if(!week || week>7) week=1 //周 范围1-7,错误周,默认 周1
// if(hour_mode==H12_Mode &&hour>=12) hour=11 //12小时制,时最大值为11
// else if(hour_mode==H24_Mode &&hour>=24) hour=23 //24小时制,时最大值为23
// if(min>=60) min=59 //分最大值为59
// if(sec>=60) sec=59 //秒最大值为59
//
// year=((year/10)<<4) | (year%10) //转成 BCD码
// month=((month/10)<<4) | (month%10) //转成 BCD码
// day=((day/10)<<4) | (day%10) //转成 BCD码
// hour=((hour/10)<<4) | (hour%10) //转成 BCD码
// if(hour_mode==H12_Mode) hour|=H12_Mode //选择 12小时制
// else hour&=H24_Mode //选择 24小时制
// min=((min/10)<<4) | (min%10) //转成 BCD码
// sec=((sec/10)<<4) | (sec%10) //转成 BCD码
// if(clock_state==ClockHalt) sec|=ClockHalt //选择 时钟停止状态
// else sec&=ClockStart //选择 时钟启动状态
//
// DS1302_WriteByte(Write_Protect,ProtectDis) //取消写保护
// DS1302_WriteByte(Write_Year,year) //输入 BCD码 格式年
// DS1302_WriteByte(Write_Month,month) //输入 BCD码 格式月
// DS1302_WriteByte(Write_Day,day) //输入 BCD码 格式日
// DS1302_WriteByte(Write_Week,week) //输入 BCD码 格式周
// DS1302_WriteByte(Write_Hour,hour) //输入 BCD码 格式时
// DS1302_WriteByte(Write_Min,min) //输入 BCD码 格式分
// DS1302_WriteByte(Write_Sec,sec) //输入 BCD码 格式秒
// DS1302_WriteByte(Write_Protect,ProtectEn) //开启写保护
//}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)