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

📄 operat_ds1302.c

📁 用AVR的mega64单片机控制DS1302
💻 C
字号:
//*****************************************************
//    mega64读/写实时时钟DS1302程序
//    作者:张鑫
//    时钟:11M
//    硬件:mega64L
//*****************************************************





#include "def.h"


//*************标准I/O功能**************************开始**
int uart_putchar(char c)
{
   if(c=='\n')
     uart_putchar('\r');
   
   loop_until_bit_is_set(UCSR1A,UDRE);
     
	 UDR1=c;

	 return 0;
}

int uart_getchar(void)
{
   loop_until_bit_is_set(UCSR1A,RXC);

   return UDR1;
}


void IO_init(void)
{
   UBRR1L=0x47;   //波特率设置
   UBRR1H&=0xf0;
   
   UCSR1B=(1<<RXEN)|(1<<TXEN);//禁止收发中断使能,收发使能

   UCSR1C=(1<<UCSZ11)|(1<<UCSZ10); //八位数据,异步模式,无校验

   fdevopen(uart_putchar,uart_getchar,0);

}

//*************标准I/O功能**************************结束**




//*************从DS1302读写一字节操作*****************************开始**

//******************
//  两线总线写一字节
//******************
void twi_write_byte(uint8 addr,uint8 data,uint8 clk_ram)
{
     uint8 i;
	 uint8 command;
     if(clk_ram==0)
	    command=CLK_ADDR+2*addr+TWI_W;
  else
        command=RAM_ADDR+2*addr+TWI_W;

     CLR_DS1302_CE;
	 asm("nop");
	 asm("nop");
	 asm("nop");
	 asm("nop");
	 asm("nop");
	 asm("nop");

     CLR_DS1302_SCL;
	 asm("nop");
	 asm("nop");
	 asm("nop");
	 asm("nop");
	 asm("nop");
	 asm("nop");

     SET_DS1302_CE;
	 asm("nop");
	 asm("nop");
	 asm("nop");
	 asm("nop");


	 for(i=0;i<8;i++)    //***********send command byte********************
	 {
	    if((command&0x01)==0x01)
		   SET_DS1302_SDA;
	  else
	       CLR_DS1302_SDA;

        command>>=1;
		asm("nop");
	    asm("nop");

        SET_DS1302_SCL;
	    asm("nop");
	    asm("nop");
        asm("nop");
	    asm("nop");
	 asm("nop");
	 asm("nop");
        
		CLR_DS1302_SCL;
	 asm("nop");
	 asm("nop");
	 asm("nop");
	 asm("nop");

	 }                  //**************send command byte end***************


	 for(i=0;i<8;i++)   //***********send data******************************
	 {
	    if((data&0x01)==0x01)
		   SET_DS1302_SDA;
	  else
	       CLR_DS1302_SDA;

        data>>=1;
		asm("nop");
	    asm("nop");

        SET_DS1302_SCL;
	    asm("nop");
	    asm("nop");
		asm("nop");
	    asm("nop");
        
		CLR_DS1302_SCL;
		asm("nop");
	    asm("nop");
	 	asm("nop");
	    asm("nop");

	 }                  //*************send data end************************

	 asm("nop");
	 CLR_DS1302_CE;
     
}




//******************
//  两线总线读一字节
//******************
uint8 twi_read_byte(uint8 addr,uint8 clk_ram)
{
     uint8 i;
	 uint8 command;
	 uint8 r_data=0;

     if(clk_ram==0)                           //准备command字节
	    command=CLK_ADDR+2*addr+TWI_R;
  else
        command=RAM_ADDR+2*addr+TWI_R;


     CLR_DS1302_CE;
	 asm("nop");
	 asm("nop");
	 asm("nop");
	 asm("nop");
	 asm("nop");
	 asm("nop");

     CLR_DS1302_SCL;
	 asm("nop");
	 asm("nop");
	 asm("nop");
	 asm("nop");
	 asm("nop");
	 asm("nop");

     SET_DS1302_CE;
	 asm("nop");
	 asm("nop");
	 asm("nop");
	 asm("nop");

	 for(i=0;i<8;i++)    //***********send command byte********************
	 {
	    if((command&0x01)==0x01)
		   SET_DS1302_SDA;
	  else
	       CLR_DS1302_SDA;

        command>>=1;
		asm("nop");
	    asm("nop");

        SET_DS1302_SCL;
	    asm("nop");
	    asm("nop");
	 asm("nop");
	 asm("nop");
	 asm("nop");
	 asm("nop");
        
		CLR_DS1302_SCL;
	 asm("nop");
	 asm("nop");
	 asm("nop");
	 asm("nop");
	 }                  //**************send command byte end***************

     DDRD&=~(0x02);


	 for(i=0;i<7;i++)//**************read data******************************
	 {
	    if((DATABIT)==0x02)
		   r_data|=0x80;
	  else
	       r_data|=0x00;

        r_data>>=1;

        SET_DS1302_SCL;
	    asm("nop");
	    asm("nop");
	 asm("nop");
	 asm("nop");
	 asm("nop");
	 asm("nop");
        
		CLR_DS1302_SCL;
	    asm("nop");
	    asm("nop");
	 asm("nop");
	 asm("nop");
	 asm("nop");
	 asm("nop");

	 }             
	   if((DATABIT)==0x02)
		   r_data|=0x80;
	  else
	       r_data|=0x00; //**************read data end************************


	 CLR_DS1302_CE;

      DDRD|=0x02;

	 return r_data;

}


//*************从DS1302读写一字节操作**********结束**





//**************DS1302初始化****************开始***********

void DS_init()
{
   DDRD|=0x03;
   PORTD=0x00;

   DDRG|=0x10;
   PORTG=0x00;   //端口设置

//   uint8 c;     测试用

   twi_write_byte(WP_R,0x00,0); //清除写保护位,使能数据传输

//   c=twi_read_byte(WP_R,0);

   twi_write_byte(HOUR_R,0x00,0);//设置为24小时格式

//   c=twi_read_byte(HOUR_R,0);

   twi_write_byte(TCS_R,0x00,0);//trickle-charge register 设置:无涓流充电

//   c=twi_read_byte(TCS_R,0);

   twi_write_byte(SECOND_R,0x00,0);//CH位清零,开始计时 

//   c=twi_read_byte(SECOND_R,0);

}

//**************DS1302初始化*****************结束************



//****************BCD到BIN转换***************开始**********
//****************************
//    BCD码转数据型
//****************************
uint8 BCDtoBIN(uint8 c)
{
     uint8 tmp;

	 tmp=c&(0x0F);

	 c&=(0x70);

	 c>>=4;

	 c*=10;

	 c+=tmp;

	 return c;

}



//****************************
//    数据型转BCD码
//****************************
uint8 BINtoBCD(uint8 c)
{
    uint8 tmp;

	c%=100;

    tmp=c;

	c/=10;

	tmp%=10;

	c<<=4;

	c+=tmp;

	c&=0x7F;

	return c;
}
//****************BCD到BIN转换***************结束**********






//*********************读取和设置DS1302数据*************开始
//************************
//    获得时间数据函数
//************************
void gettime_date()
{
    uint8 i;
	uint8 tmp[7];

	for(i=0;i<7;i++)
	{
	   tmp[i]=twi_read_byte(i,0);
	   g_getTime[i]=BCDtoBIN(tmp[i]);
	}
               
}



//************************
//    设置时间数据函数
//************************
void settime_date()
{
   uint8 i;
   uint8 tmp[7];

   for(i=0;i<7;i++)
   {
       tmp[i]=BINtoBCD(g_setTime[i]);
       twi_write_byte(i,tmp[i],0);
   }

   printf("%x %x %x %x %x %x %x\n",tmp[6],tmp[5],tmp[4],tmp[3],tmp[2],tmp[1],tmp[0]);

}
//*********************读取和设置DS1302数据*************结束



//********************主函数**************************************
int main(void)
{
    char c;

	uint8 i;

	int temp[7];    //设置数据缓冲区

	IO_init();      //标准IO初始化

	DS_init();      //DS1302初始化
    
	printf_P(PSTR("please enter command:g - print time and date, s - set time and date,	h - help\n"));

    while(1)
	{
	   scanf("%c",&c);

	   if(c=='g')
	   {
	      gettime_date();   //获得时间数据

		  printf_P(PSTR("%d year %d month %d day  %d %d:%d:%d\n"),g_getTime[6],\
		  g_getTime[4],g_getTime[3],g_getTime[5],g_getTime[2],g_getTime[1],g_getTime[0]);//输出时间数据
		}
     else if(c=='s')
	   {
          printf_P(PSTR("please enter data in this format: year month day week hour minute second\n"));
		  
		  scanf("%d,%d,%d,%d,%d,%d,%d",temp+6,temp+4,temp+3,temp+5,temp+2,temp+1,temp);


//测试用         printf("%d %d %d %d %d %d %d\n",temp[6],temp[4],temp[3],temp[5],temp[2],temp[1],temp[0]);

		  for(i=0;i<7;i++)
		  g_setTime[i]=(uint8)temp[i];

//测试用		  printf("%d %d %d %d %d %d %d\n",g_setTime[6],g_setTime[4],g_setTime[3],g_setTime[5],g_setTime[2],g_setTime[1],g_setTime[0]);

		  settime_date();   //设置数据函数

          printf_P(PSTR("Set finish!\n"));
	   }
     else if(c=='h')
	   {
	   //输出帮助信息
        printf_P(PSTR("please enter command:g - print time and date, s - set time and date,	h - help\n"));
	   }
	 }

	 return 0;

}

⌨️ 快捷键说明

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