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

📄 hardware.c

📁 利用ATmega64实现了对测温芯片DS18B20
💻 C
字号:
#include "hardware.h"
#include "display.h"


const prog_uchar flash_array[]={0x57,0x65,0x6c,0x63,0x6f,0x6d,0x65,0x20,0x74,0x6f,0x20,\
                                0x75,0x73,0x65,0x20,0x4c,0x43,0x44,0x21};  //开机显示在LCD上的文字

//uint8 DDram_Adr=0x00;               //当前DD ram 的地址
//uint8 CGram_Adr=0x00;               //当前CG ram 的地址



//****************************
//       短延时函数
//****************************
void shortdelay()
{
  uint16 i;
  for(i=0;i<200;i++)
     asm("nop");
}

//****************************
//       微秒延时函数
//****************************
void delay_us(int time)
{

  do
    time--;
  while(time>1);
 

}
//****************LCD部分**********************************************
//****************************
//        向LCD写命令
//****************************
void Write_command(uint8 cmd)
{
//write command to lcd register
//   while(Is_Busy());

   LCD_RS_REG;
   LCD_W;

   DATAOUT=cmd;

   shortdelay();


   CLR_LCD_E;
   shortdelay();

   SET_LCD_E;  

   LCD_R_N;
   LCD_RS_RAM;

}


//******************************
//       向LCD写数据
//******************************
void Write_data(uint8 addr,uint8 dat)
{
//write data to lcd ram

   Write_command(addr);

//   while(Is_Busy());

   LCD_W;

   DATAOUT=dat;

   shortdelay();

   CLR_LCD_E;

   shortdelay();
   SET_LCD_E;


   LCD_R_N;

}


//***************************
//     LCD的Busy函数
//****************************
uint8 Is_Busy()
{
//check whether is busy
   uint8 c;

   DDRA=0x00;
   PORTA=0x00;

   LCD_RS_REG;
   shortdelay();

   CLR_LCD_E;

   shortdelay(); 

   c=DATAIN;
   SET_LCD_E;


   LCD_RS_RAM;

   DDRA=0xFF;
   PORTA=0xFF;

   if((c&0x80)==0x80)
      return 1;
else
      return 0;
}




//*************************
//       从LCD读数据函数
//*************************
uint8 Read_data()
{
//read data from lcd
   uint8 c;

//   while(Is_Busy());

   DDRA=0x00;
   PORTA=0x00;


   CLR_LCD_E;
   shortdelay();

   c=DATAIN;
   SET_LCD_E;


   DDRA=0xFF;
   PORTA=0xFF;

   return c;
}



//**************************
//     设置光标位置
//**************************
void gotoxy(uint8 x,uint8 y)
{
   switch(x)
         {
          case 0:  DDram_Adr=y;
	               break;

          case 1:  DDram_Adr=64+y;	            
	               break;   
    
	      default: LCD_clear();
		           break;
          }
   
}




//**************************
//     LCD欢迎词
//**************************
void Welcome()
{
//add welcome words
  uint8 i;
  uint8 wleword[]={'P','l','e','a','s','e',' ','s','e','t',' ','D','A','T','A','!'};
  for(i=0;i<16;i++)
  LCD_display(wleword[i]);

}
//********************LCD部分结束*********************************************





//**************DS1302部分*************************************************

//*************从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部分结束*************************************************




//*************DS18B20部分*****************************************************

//***************************
//  检测ds18b20是否存在
//***************************
uint8 ds18b20_ack()                 
{
   uint8 ack;

   DDRE|=0x80;    //PORTE.7输出

   B20DATA_CLR;   //输出LOW

   delay_us(300); //500

//   B20DATA_SET;   //输出HIGH

   DDRE&=0x7F;    //PORTE.7输入

   B20DATA_SET;   //输出HIGH

   delay_us(30);  //45

   ack=B20DATABIT;  //获得ds18b20的响应

   delay_us(100);

   return ack;


}




//************************************
//    转换是否完成(电源引脚供电时有效)
//************************************
void Is_ds18b20_done()
{
   uint8 temp=0x00;
   do
   {
     DDRE|=0x80;    //PORTE.7输出

     B20DATA_CLR;   //输出LOW

     delay_us(2);   //3

	 DDRE&=0x7F;    //PORTE.7输入

     B20DATA_SET;   //输出HIGH

     delay_us(7);  //10

	 temp=B20DATABIT;
	 }
	 while(temp!=0x80);
}






//***************************
//  ds18b20读一字节操作
//***************************
uint8 ds18b20_read()                
{
   uint8 i,byte,temp;

   byte=0x00;

   for(i=0;i<8;i++)
      {
	   DDRE|=0x80;    //PORTE.7输出

       B20DATA_CLR;   //输出LOW

       delay_us(2);   //3

	   DDRE&=0x7F;    //PORTE.7输入

       B20DATA_SET;   //输出HIGH


       delay_us(7);  //10

	   temp=B20DATABIT;
	   
	   if(temp!=0x00)
	      byte|=0x80;
       if(i<7)
	      byte=byte>>1;

       delay_us(40);  //100



 //      delay_us(3);    //5

	   }

	 DDRE|=0x80;
	 return byte;
    
}

//***************************
//  ds18b20写一字节操作
//***************************
void ds18b20_write(uint8 cmd)       
{
   uint8 i,j;

   DDRE|=0x80;    //PORTE.7输出

   for(j=0;j<8;j++)
      {
	   i=cmd&0x01;

       if(i==0x01)
	     {
          B20DATA_CLR;   //输出LOW

          delay_us(4);  //10

          B20DATA_SET;   //输出HIGH

		  delay_us(50);  //100
		  }
        else
		{
          B20DATA_CLR;   //输出LOW

          delay_us(50);  //100

          B20DATA_SET;   //输出HIGH

		  delay_us(4);   //10
		  }

		cmd=cmd>>1;
		}

}

//*************DS18B20部分结束*************************************************





//***********初始化部分********************************************

//*****************************************
//          DS1302初始化
//*****************************************
void DS_init()
{
   

//   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);

}


//*******************************
//    串口初始化
//*******************************
void uart_init()
{
   UBRR1L = 0x47;                     //  波特率9600
   UBRR1H &= 0xf0;  
   UCSR1C = (1<<UCSZ11)|(1<<UCSZ10);  //八位数据,无奇偶校验,一位停止位
   UCSR1C &= 0x87;
   UCSR1B &= 0x18;                    //禁止中断
               
   UCSR1B = (1<<RXEN1)|(1<<TXEN1)|(1<<RXCIE1);   //收发使能, 使能接收中断
     
}



//***************************
//     LCD初始化
//***************************
void LCD_init()
{
//initial the lcd
  Write_command(0x38);  //set Function set

  Write_command(0x06);  //set Entry Mode Set

  Write_command(0x0c);  //Display on/off   no curse

  Write_command(0x01);  //Clear display
}


//***************************
//     端口初始化
//***************************
void port_init()
{
//initial avr port
   DDRA|=0xFF;
   PORTA=0xFF;

   DDRB|=0xF0;
   PORTB|=0xF0;
   PORTB&=0x00;

   DDRF|=0x0E;
   PORTF|=0x0E;

   DDRG|=0x08;
   PORTG|=0x08;

   DDRD|=0x03;   //DS1302数据与时钟输出0
   PORTD=0x00;

   DDRG|=0x10;
   PORTG=0x00;   //DS1302禁止


   DDRE|=0x80;   //DS18B20数据线,初始输出
   PORTE|=0x80;  //DS18B20数据初始为高

  
}





//*****************************************
//          DS1302初始化
//*****************************************
void DS18B20_init()
{
     uint8 i;

     do
	   i=ds18b20_ack();
     while(i==1);
     ds18b20_write(0x33);
	 for(i=0;i<8;i++)
	     ROM_CODE[i]=ds18b20_read();

}





//***************************
//     定时器0初始化
//***************************
void timer0_init()                      
{
    TCCR0 = 0x00; 
	TCCR0 &= ~(1 << WGM00); 								  
	TCCR0 |=(1<<WGM01)|(1<<CS02)|(1<<CS00)|(1<<CS01); //1024分频   
	OCR0 = 0xFF;	
}
//***********初始化部分********************************************



⌨️ 快捷键说明

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