⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rtc._c

📁 12864菜单
💻 _C
📖 第 1 页 / 共 2 页
字号:
/*******************************************
  文件:RTC.C
  环境:编译为ICC AVR6.25A,仿真为AVR Studio4.10 
  硬件:ATMEGA16芯片
  日期:2006年12月10日 
  功能:驱动开发板上的DS1302时钟芯片
  备注:参考《AVR系列单片机C语言编程与应用实例》(清华大学出版社)
/******************************************/
//#include <iom16v.h>			//包含型号头文件
//#include <macros.h>			//包含"位"操作头文件
//#include <stdio.h>			//标准输入输出头文件

//#include <AVR_PQ1A.h>		//包含自定义常量头文件
//#include "YJ12864.C"
//#include "YJ1602.C"			//包含1602液晶函数文件
//#include "MKEY.C"			//包含矩阵键盘函数文件


/*******************************************
函数名称: DS1302_init
功    能: 初始化DS1302的数据接口
参    数: 无
返回值  : 无
/********************************************/
void DS1302_portinit(void)		  
{
 DDRB|=BIT(RTC_CLK)|BIT(RTC_DATA)|BIT(RTC_CS);//将时钟端(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位数据计数
 {
  PORTB&=~BIT(RTC_CLK);		  //拉低时钟端
  if(byte&0x01)				  //当前位是否是1
  {
   PORTB|=BIT(RTC_DATA);	  //当前位是1,拉高数据端
  }
  else						  
  {
   PORTB&=~BIT(RTC_DATA);	  //当前位是0,拉低数据端
  }  
  Delayus(10);				  //调整时钟和脉冲宽度
  PORTB|=BIT(RTC_CLK);		  //时钟上升沿(DS1302采样数据)
  byte>>=1;					  //数据右移1位,为送出新数据位做准备
 }
}
/*******************************************
函数名称: DS1302_readB
功    能: 从DS1302读出一个字节数据(没有RST操作)
参    数: 无
返回值  : byte--读出的数据
/********************************************/
uchar DS1302_readB(void)
{
 uchar i,byte=0;
 DDRB&=~BIT(RTC_DATA);		 //将数据端口设置为输入		  
 PORTB&=~BIT(RTC_DATA);		 //无上拉电阻
 for(i=0;i<8;i++)			 //8位数据计数
 {
  byte>>=1;  				 //保存读入的数据位
  PORTB|=BIT(RTC_CLK);		 //时钟上升沿
  Delayus(10);				 //延时,调整时钟脉冲宽度
  PORTB&=~BIT(RTC_CLK);		 //时钟下降沿,DS1302输出数据位
  Delayus(10);				 //等待数据变化(MEGA16太快,必须等待DS1302的数据位输出,否则不能正确读出)
  if(PINB&BIT(RTC_DATA))	 //当前位是否是高电平
  {
   byte|=BIT(PB7);			 //是高电平就将返回数据的当前位置1
  }
  else
  {
   byte&=~BIT(PB7);			 //是低电平就将返回数据的当前位置0
  }
 }
 DDRB|=BIT(RTC_DATA);		 //最后将数据端口设置为输出
 return byte;				 //返回读出的数据
}
/*******************************************
函数名称: DS1302_writeD
功    能: 向DS1302的某个地址写入一个字节数据
参    数: addr--地址值(寄存器或RAM)
	  	  data--要写入的地址
返回值  : 无
/********************************************/
void DS1302_writeD(uchar addr,uchar data)
{
 PORTC&=~BIT(RTC_CS);	 //拉低片选端
 PORTB&=~BIT(RTC_CLK);	 //拉低时钟端
 Delayus(10);
 PORTC|=BIT(RTC_CS);	 //拉高片选端
 Delayus(10); 			 //调整片选脉冲
 DS1302_writeB(addr);	 //写入操作命令(地址)
 Delayus(10);
 PORTB&=~BIT(RTC_CLK);	 //拉低时钟端
 Delayus(10);
 DS1302_writeB(data);	 //写入数据
 PORTB&=~BIT(RTC_CLK);	 //拉低时钟端
 Delayus(10);			 //调整片选脉冲
 PORTC&=~BIT(RTC_CS);	 //拉低片选端
}
/*******************************************
函数名称: DS1302_readD
功    能: 从DS1302的某个地址读出一个字节数据
参    数: addr--地址值(寄存器或RAM)
返回值  : data--读出的数据
/********************************************/
uchar DS1302_readD(uchar addr)
{
 uchar data;
 PORTC&=~BIT(RTC_CS);	 //拉低片选端
 PORTB&=~BIT(RTC_CLK);	 //拉低时钟端
 Delayus(10);
 PORTC|=BIT(RTC_CS);	 //拉高片选端
 Delayus(10); 			 //调整片选脉冲
 DS1302_writeB(addr);	 //写入操作命令(地址)
 Delayus(10);
 data=DS1302_readB();	 //读出数据
 Delayus(10);
 PORTB&=~BIT(RTC_CLK);	 //拉低时钟端
 PORTC&=~BIT(RTC_CS); 	 //拉低片选端
 return data;			 //返回读出的数据
}
/*******************************************
函数名称: DS1302_setT
功    能: 设置DS1302的时间
参    数: ptTimeD--设置时间数组指针
返回值  : 无
/********************************************/
void DS1302_setT(uchar ptTimeD[])
{
    uchar i;
    uchar addr = 0x80; 			 	  //写入地址从秒寄存器开始
    DS1302_writeD(C_WP|WR,UPROTECT); //控制命令,WP位为0,允许写操作
	Delayms(5);
    for(i=0;i<7;i++)
    {
        DS1302_writeD(addr|WR,ptTimeD[i]);   // 秒 分 时 日 月 星期 年         
        addr+=2;
		Delayms(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[i]=DS1302_readD(addr|RD);    // 秒 分 时 日 月 星期 年        
        addr+=2;
    }
    PORTB&=~BIT(RTC_CLK);	 				  //拉低时钟端(时钟端在不操作时为低)
}
/*******************************************
函数名称: DS1302_check
功    能: 检测DS1302是否正常工作
参    数: 无
返回值  : exist--为TRUE为检测到DS1302,为FALSE为没检测到
/********************************************/
uchar DS1302_check(void)
{
	uchar exist;
    DS1302_writeD(C_WP|WR,UPROTECT);		  //写入写允许命令
    DS1302_writeD(C_RAMBASE|WR,0xA5);		  //RAM0写入0xA5
    exist=DS1302_readD(C_RAMBASE|RD);		  //读取RAM0
    if(exist==0xA5)	
	{
	 exist=TRUE;							  //如果读取值与写入值相等,返回TRUE
	}
    else 	
	{
	 exist=FALSE;							  //如果读取值与写入值不相等,返回FALSE
	}	
	return exist;
}
/*******************************************
函数名称: 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=BCD/16|0x30;		   //转换十位
	*(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行的字符数组

 
  uchar linex1[5]={' ','0',' ','0','\0'};//显示第1行的字符数组
  uchar linex1_1[5]={' ','0',' ','0','\0'};//显示第1行的字符数组
  uchar linex2[5]={' ',0,' ',0,'\0'};//显示第1行的字符数组
   uchar linex2_2[3]={' ','0','\0'};//显示第1行的字符数组
  uchar linex3[17]={' ',0,' ',0,' ',':',' ','0',' ','0',' ',':',' ','0',' ','0','\0'};//显示第1行的字符数组
 // uchar linex4[11]={'\0'};//显示第1行的字符数组
  
 
/* 
 for(i=0;i<3;i++)								  //为第2行的字符数组赋值
  {
   BCD_ASCII(time[2-i],asc);
   line2[i*3]=asc[0]&0x7F;
   line2[i*3+1]=asc[1];
  } */
   
  BCD_ASCII(time[0],asc);   		//秒			  //为第1行的年赋值
  linex3[13]=asc[0];
  linex3[15]=asc[1];
 
   BCD_ASCII(time[1],asc);   		//分				  //为第1行的年赋值
  linex3[7]=asc[0];
  linex3[9]=asc[1];
 
   BCD_ASCII(time[2],asc);   		//时			  //为第1行的年赋值
  linex3[1]=asc[0];
  linex3[3]=asc[1];
 
 
   BCD_ASCII(time[6],asc);   		//年			  //为第1行的年赋值
 linex1[1]=asc[0];
 linex1[3]=asc[1];
 
   BCD_ASCII(time[4],asc);   		//月				  //为第1行的年赋值
 linex1_1[1]=asc[0];
 linex1_1[3]=asc[1];
 
   BCD_ASCII(time[3],asc);   		//日			  //为第1行的年赋值
 linex2[1]=asc[0];
 linex2[3]=asc[1];
 
 
 BCD_ASCII(time[5],asc);   		//星期			  //为第1行的年赋值
 linex2_2[1]=asc[1];
 
 
  while(LCD12864_readBF());
  LCD12864_gotoXY(1,0);	   					  //第1行,第1列显示
 // Delayms(200); 
  LCD12864_sendstr(" 2 0");	
  LCD12864_sendstr(linex1);	
  LCD12864_sendstr("年");	
  LCD12864_sendstr(linex1_1);	
  LCD12864_sendstr("月");	 
  
  // while(LCD12864_readBF());
  LCD12864_gotoXY(2,0);		  			  	  //第2行,第3列显示
  // Delayms(200);
  LCD12864_sendstr(linex2);	
  LCD12864_sendstr("号");
  LCD12864_sendstr("  星期");
  LCD12864_sendstr(linex2_2);
    // while(LCD12864_readBF());
  LCD12864_gotoXY(3,0);		  			  	  //第2行,第3列显示
  // Delayms(200);
  LCD12864_sendstr(linex3);	
     while(LCD12864_readBF());
  LCD12864_gotoXY(4,2);		  			  	  //第2行,第3列显示
  // Delayms(200);
  LCD12864_sendstr("4 取消");	
 
  
 /*
 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];
 
 
 while(LCD12864_readBF());
  LCD12864_gotoXY(2,1);	   					  //第1行,第1列显示
 // Delayms(200); 
  LCD12864_sendstr("20");	
  LCD12864_sendstr(line1);	 
   while(LCD12864_readBF());
  LCD12864_gotoXY(3,2);		  			  	  //第2行,第3列显示
  // Delayms(200);
  LCD12864_sendstr(line2);	

    LCD12864_gotoXY(4,2);		  			  	  //第2行,第3列显示
  // Delayms(200);
  LCD12864_sendstr("4 取消");	
  
 */ 
 /*
 
 while(LCD1602_readBF());
 LCD1602_gotoXY(1,2);	 						  //第1行从第3个位置开始显示
 LCD1602_sendstr("20");							  //将07年显示为2007的形式
 LCD1602_sendstr(line1); 						  //第1行显示
 while(LCD1602_readBF());
 LCD1602_gotoXY(2,4); 	 						  //第2行从第5个位置开始显示
 LCD1602_sendstr(line2);						  //第2行显示
*/
}
/*******************************************
函数名称: main

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -