|
本帖最后由 feifeimao 于 2013-4-3 15:14 编辑
/*****************************************************
This program was produced by the
CodeWizardAVR V1.25.5 Standard
Automatic Program Generator
?Copyright 1998-2007 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com
Project :
Version :
Date : 2013-04-01
Author : F4CG
Company : F4CG
Comments:
Chip type : ATmega128
Program type : Application
Clock frequency : 7.372800 MHz
Memory model : Small
External SRAM size : 0
Data Stack size : 1024
*****************************************************/
#include <mega128.h>
#include "1602.c" //包含1602液晶函数文件
#include <delay.h>
//#define uchar unsigned char
//#define uint unsigned int
/******************RTC常量******************/
#define RTC_CLK PORTD.4
#define RTC_DATA PORTD.5
#define RTC_CS PORTD.6
//命令
#define RD 0x01
#define WR 0x00
#define C_SEC 0x80 //秒
#define C_MIN 0x82 //分
#define C_HR 0x84 //时
#define C_DAY 0x86 //日
#define C_MTH 0x88 //月
#define C_WK 0x8A //星期 DATE
#define C_YR 0x8C //年
#define C_WP 0x8E //控制(写保护)
#define C_CHARGE 0x90 //涓流充电
#define C_BURST 0xBE //时钟多字节
//配置
#define CLK_HALT 0x80 //停止时钟控制位 SECOND bit7
#define CLK_START 0x00 //启动时钟
#define M12_24 0x80 //12/24小时值选择位 HOUR bit7
#define PROTECT 0x80 //写保护控制位 CONTROL bit7
#define UPROTECT 0x00 //写保护控制位 CONTROL bit7
//涓流充电控制常量
#define TC_D1R2 0xA5 //high 1 Diode +2K Resistors
#define TC_D2R8 0xAB //low 2 Diodes+8K Resistors
#define TC_DISABLED 0x00 //Disabled(TCS<>1010 or DS=00 or RS=00)
//RAM 命令
#define C_RAMBASE 0xC0 //RAM0~RAM30<<1 地址需左移一位
/*******************************************
函数名称: DS1302_init
功 能: 初始化DS1302的数据接口
参 数: 无
返回值 : 无
/********************************************/
void DS1302_portinit(void)
{
DDRD=0x70; //将时钟端(RTC_CLK)数据端(RTC_DATA)片选端(RTC_CS)设置为输出
}
/*******************************************
函数名称: DS1302_writeB
功 能: 向DS1302写入一个字节数据(没有RST操作)
参 数: byte--要写入的数据
返回值 : 无
/********************************************/
void DS1302_writeB(uchar byte)
{
uchar i;
for(i=0;i<8;i++) //8位数据计数
{
RTC_CLK=0; //拉低时钟端
if(byte&0x01) //当前位是否是1
{
RTC_DATA=1; //当前位是1,拉高数据端
}
else
{
RTC_DATA=1; //当前位是0,拉低数据端
}
delay_us(10); //调整时钟和脉冲宽度
RTC_CLK=1; //时钟上升沿(DS1302采样数据)
byte>>=1; //数据右移1位,为送出新数据位做准备
}
}
/*******************************************
函数名称: DS1302_readB
功 能: 从DS1302读出一个字节数据(没有RST操作)
参 数: 无
返回值 : byte--读出的数据
/********************************************/
uchar DS1302_readB(void)
{
uchar i,byte=0;
DDRD=0xDF; //将数据端口设置为输入
PORTD=0xDF; //无上拉电阻
for(i=0;i<8;i++) //8位数据计数
{
byte>>=1; //保存读入的数据位
RTC_CLK=1; //时钟上升沿
delay_us(10); //延时,调整时钟脉冲宽度
RTC_CLK=0; //时钟下降沿,DS1302输出数据位
delay_us(10); //等待数据变化(MEGA16太快,必须等待DS1302的数据位输出,否则不能正确读出)
if(PIND&PORTD.5) //当前位是否是高电平
{
byte|=0x80; //是高电平就将返回数据的当前位置1
}
else
{
byte&=0x7F; //是低电平就将返回数据的当前位置0
}
}
DDRD=0xFF; //最后将数据端口设置为输出
return byte; //返回读出的数据
}
/*******************************************
函数名称: DS1302_writeD
功 能: 向DS1302的某个地址写入一个字节数据
参 数: addr--地址值(寄存器或RAM)
data--要写入的地址
返回值 : 无
/********************************************/
void DS1302_writeD(uchar addr,uchar data)
{
RTC_CS=0; //拉低片选端
RTC_CLK=0; //拉低时钟端
delay_us(10);
RTC_CS=1; //拉高片选端
delay_us(10); //调整片选脉冲
DS1302_writeB(addr); //写入操作命令(地址)
delay_us(10);
RTC_CLK=0; //拉低时钟端
delay_us(10);
DS1302_writeB(data); //写入数据
RTC_CLK=0; //拉低时钟端
delay_us(10); //调整片选脉冲
RTC_CS=0; //拉低片选端
}
/*******************************************
函数名称: DS1302_readD
功 能: 从DS1302的某个地址读出一个字节数据
参 数: addr--地址值(寄存器或RAM)
返回值 : data--读出的数据
/********************************************/
uchar DS1302_readD(uchar addr)
{
uchar data;
RTC_CS=0; //拉低片选端
RTC_CLK=0; //拉低时钟端
delay_us(10);
RTC_CS=1; //拉高片选端
delay_us(10); //调整片选脉冲
DS1302_writeB(addr); //写入操作命令(地址)
delay_us(10);
data=DS1302_readB(); //读出数据
delay_us(10);
RTC_CLK=0; //拉低时钟端
RTC_CS=0; //拉低片选端
return data; //返回读出的数据
}
/*******************************************
函数名称: DS1302_setT
功 能: 设置DS1302的时间
参 数: ptTimeD--设置时间数组指针
返回值 : 无
/********************************************/
void DS1302_setT(uchar ptTimeD[])
{
uchar i;
uchar addr = 0x80; //写入地址从秒寄存器开始
DS1302_writeD(C_WP|WR,UPROTECT); //控制命令,WP位为0,允许写操作
delay_ms(5);
for(i=0;i<7;i++)
{
DS1302_writeD(addr|WR,ptTimeD); // 秒 分 时 日 月 星期 年
addr+=2;
delay_ms(1);
}
DS1302_writeD(C_WP|WR,PROTECT); //控制命令,WP位为1,不允许写操作
}
/*******************************************
函数名称: DS1302_getT
功 能: 读取DS1302的当前时间
参 数: time[]--读取的时间数组
返回值 : 无
/********************************************/
void DS1302_getT(uchar time[])
{
uchar i;
////////下面的是单次读写//////////////////////////
uchar addr = 0x80; //读取地址从秒寄存器开始
for(i=0;i<7;i++)
{
time=DS1302_readD(addr|RD); // 秒 分 时 日 月 星期 年
addr+=2;
}
RTC_CLK=0; //拉低时钟端(时钟端在不操作时为低)
}
/*******************************************
函数名称: DS1302_init
功 能: 初始化DS1302
参 数: 无
返回值 : 无
/********************************************/
void DS1302_init(void)
{
DS1302_writeD(C_WP|WR,UPROTECT); //写入写允许命令
DS1302_writeD(C_SEC|WR,CLK_START); //启动振荡器,DS1302开始工作
DS1302_writeD(C_WP|WR,PROTECT); //控制命令,WP位为1,不允许写操作
}
/*******************************************
函数名称: BCD_ASCII
功 能: 将压缩BCD码转换成ascii码
参 数: BCD--将要转换的压缩BCD码
ptasc--转换后的ASCII码数组指针
返回值 : 无
/********************************************/
void BCD_ASCII(uchar BCD,uchar ptasc[])
{
ptasc[0]=BCD/16|0x30; //0X58 35 38 //转换十位
ptasc[1]=BCD&0x0F|0x30; //转换个位
}
/*******************************************
函数名称: Disp_time
功 能: 在1602液晶上显示当前时间(第1行格式:年-月-日 星期;第2行格式:时-分-秒)
参 数: time[]--时间数组
返回值 : 无
/********************************************/
void Disp_time(uchar time[])
{
uchar i,asc[2];
uchar line1[11]={0,0,'-',0,0,'-',0,0,' ',0,'\0'};//显示第1行的字符数组
uchar line2[9]={0,0,':',0,0,':',0,0,'\0'}; //显示第2行的字符数组
for(i=0;i<3;i++) //为第2行的字符数组赋值
{
BCD_ASCII(time[2-i],asc);
line2[i*3]=asc[0];
line2[i*3+1]=asc[1];
}
BCD_ASCII(time[6],asc); //为第1行的年赋值
line1[0]=asc[0];
line1[1]=asc[1];
BCD_ASCII(time[4],asc); //为第1行的月赋值
line1[3]=asc[0];
line1[4]=asc[1];
BCD_ASCII(time[3],asc); //为第1行的日赋值
line1[6]=asc[0];
line1[7]=asc[1];
BCD_ASCII(time[5],asc); //为第1行的星期赋值
line1[9]=asc[1];
displayROM(0X82,"20"); //第1行从第3个位置开始显示,将07年显示为2007的形式
displayRAM(0X84,line1);
displayRAM(0X80+0X44,line2); //第2行从第5个位置开始显示,/第2行显示
}
/*******************************************
函数名称: main
功 能: 1. 在1602液晶上显示当前时间 2.可以设置时间(M1-M9为数字0-9,M13为设置模式和显示模式选择,M14为当前设置位选择)
参 数: 无
返回值 : 无
/********************************************/
void main(void)
{
//uchar setadd,setdat,shift; //setadd指定将当前数值送入DS1302的哪个寄存器
//setdat是当前设置的数值,即被送入DS1302指定寄存器的数
//shift来实现十位和各位的设置相互独立(因为十位和个位是在一个寄存器里的)
//uchar dis_x,dis_y; //存储1602液晶当前光标的位置
uchar settime[7]={0x50,0x59,0x23,0x01,0x01,0x06,0x07};//设置的秒,分,时,日,月,星期,年
uchar gettime[7]={0x00,0x00,0x00,0x00,0x00,0x00,0x00};//保存当前时间的数
//初始化液晶
PORTA=0xFF;
DDRA=0xFF;
PORTB=0x07;
DDRB=0x07;
lcd_init();
DS1302_portinit(); //初始化DS1302的三根数据线
DS1302_init(); //启动振荡器,DS1302开始工作
DS1302_setT(settime); //设置初始时间
while(1) //以下程序完成显示和设置时间
{
DS1302_getT(gettime); //获得当前时间
Disp_time(gettime); //显示当前时间
}
} 这个1302的子函数有问题 在proteus显示 都是0 请教下 |
阿莫论坛20周年了!感谢大家的支持与爱护!!
知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)
|