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

📄 18b20.c

📁 在Proteu环境下的DS18b20测温软件与硬件设计.
💻 C
字号:
//ICC-AVR application builder : 2007-10-14 10:47:26
// Target : M8
// Crystal: 1.0000Mhz
//PC0 做检验使用哦
 
#include <iom8v.h>
#include <macros.h>

#define dq_high PORTD|=(1<<PD6)          //dq is zhe io_data
#define dq_low  PORTD&=~(1<<PD6)
#define dq_out  DDRD|=(1<<PD6)
#define dq_in   DDRD&=~(1<<PD6)
#define uch  unsigned char
#define uint unsigned int
uch disp_buffer[]={0,0,0,0,0,0,0};
uch ling=0;
//uch b[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};        //显示数
uch  b[]={0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xe6};       //显示数

//_____________________________________________________________

//TIMER1 initialize - prescale:256
// WGM: 0) Normal, TOP=0xFFFF
// desired value: 1Sec
// actual value:  1.000Sec (0.0%)
void timer1_init(void)
{
 TCCR1B = 0x00; //stop
 TCNT1H = 0xF0; //setup
 TCNT1L = 0xBE;
 OCR1AH = 0x0F;
 OCR1AL = 0x42;
 OCR1BH = 0x0F;
 OCR1BL = 0x42;
 ICR1H  = 0x0F;
 ICR1L  = 0x42;
 TCCR1A = 0x00;
 TCCR1B = 0x04; //start Timer
}

#pragma interrupt_handler timer1_ovf_isr:9
void timer1_ovf_isr(void)
{
 //TIMER1 has overflowed
 TCNT1H = 0xF0; //reload counter high value
 TCNT1L = 0xBE; //reload counter low value
 ling=1;
}

//SPI initialize
// clock rate: 7812hz
void spi_init(void)
{
 PORTB = 0xFF;
 DDRB  = 0xFF;
 SPCR = 0x73; //setup SPI
 SPSR = 0x00; //setup SPI
}

//_____________________________________________________________
void delay_10us()  //delay 10us
{
 asm("nop");asm("nop");asm("nop");		
}
void delay_ms(void)   //delay_130n+60us  n=7时延时970us n=8 1100us
{
 uch i,j;
 for(i=0;i<7 ;i++)
 for(j=0;j<8;j++)
 	{
	delay_10us();
	}		
}
void delay_10ms(void)  //delay 9925 us ~~10ms
{
 uch i;
 for(i=0;i<11;i++)
  delay_ms();
}

void rest_delay(uch data)   //delay  480~960us
{
  uch i,j;
  for(i=0;i<data ;i++)
  for(j=0;j<8;j++)
 	{
	 delay_10us();
	}	
}

void bcd_change(unsigned char data1,unsigned int data2)//data1低位,data2高位
{
 unsigned char fu,data3;//正负标志,fu=0正,fu=1负
 if(data2&0xf8)
  {
   disp_buffer[0]=0b00000010;//负标志位
   data1=~data1;
   data2=~data2;
   data1+=1;
   if(data1==0x00)data2+=1;//若低八位溢出,向高八位进位
   fu=1;
   }
    else 
	 {
	  fu=0;
	  disp_buffer[0]=0x00;
	   }
	  // data2=7;
 data3=data1;
 data1=(data1>>4)|(data2<<4);
 data2=data3&0x0f;
 data2=data2*625;
 disp_buffer[6]=b[data2%10];
 disp_buffer[5]=b[(data2/10)%10];
 disp_buffer[4]=b[(data2/100)%10];
 disp_buffer[3]=b[data2/1000];
 disp_buffer[2]=b[data1%10];
 disp_buffer[1]=b[(data1/10)%10];
 if(!fu) 
  if(data1>100)
   disp_buffer[0]=b[data1/100];
 disp_buffer[2]|=0x01;
}
void spi_trans(void)
{
 //uch *p=&disp_buffer[0];    //放在后面使用哦
 uch i;
 for(i=7;i>0;i--)
 {
  SPDR=disp_buffer[i-1];
  while(!(SPSR&(1<<SPIF)))  ;  //等待传诵结束哦
  //p++;   //循环发送法
 }
}

void no_b20 (void)
{
 uch j;
 for(j=0;j<4;j++)
 	{			 
	 SPDR=0xEE;      //disp A
	 while(!(SPSR&(1<<SPIF)))  ;
	} 
}


//_______________________________________________________________

char init_1820(void)    //返回枝如果是1则说明有响应 否则找不到b20
{ 
  uch flag;
  dq_out;     //设置为输出
  dq_low;
  rest_delay(5);   //480us以上  500us  5*130+60=710us  (480~960)
  dq_high;
  dq_in;    //in_put
  delay_10us();   //15~60us
  delay_10us();
  delay_10us();
  delay_10us();
  delay_10us();
  delay_10us();
  delay_10us();
  if(!(PIND&(1<<PD6)))	//RE_decide
  {
   delay_10us();
   delay_10us();
   if(!(PIND&(1<<PD6)))
   		flag=1;		
	
		   
  }
  else
  {
   flag=0;	
  }
  rest_delay(4);    //at least 480us 
  return flag;
}
//__________________________________18b20 有回应


void write_1820(uch data)
{  
  uch m;
  dq_out;	
  for(m=0;m<8;m++)
  {
   	
	asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");	  
    if(data&(1<<m))   //写数据,从低位开始
    	{
		  dq_low;
		 delay_10us();
		 dq_high;
		 delay_10us();   //delay  15 us
		 asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");
		 delay_10us();
		 delay_10us();
		 asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");
		}
    else
    	{
		 dq_low;         //at least 60 us
		 delay_10us();   //delay  15 us
		 delay_10us();  
		 delay_10us(); 
		 delay_10us(); 
		 delay_10us(); 
		 delay_10us(); 
		 //delay_10us();  
		 dq_high;
		} 
    dq_high;
	delay_10us();  //恢复
  }

}



uch read_1820(void)
{  
  uch temp,k,n;
      temp=0;
  for(n=0;n<8;n++)
    {
	 temp>>=1;
	 dq_out;     //out put
     dq_low;  
	 asm("nop");asm("nop");asm("nop");asm("nop");asm("nop"); 
	 delay_10us();
     dq_in;  //in put
     asm("nop");asm("nop");asm("nop");asm("nop");
  //读数据,从低位开始
     if(PIND&(1<<PD6))
	 	 { 	 
     	  temp|=0X80;
		 } 
	  else
	  	  {
		   temp|=0x00;
		   PORTC^=(1<<PC5);
		  }	 
     delay_10us();
	 delay_10us();
	 delay_10us();
	 delay_10us();
	 delay_10us();     //read at least 60 us
	 dq_high;
	 delay_10us();    //wait for recovery;
     }
  return (temp);
}

//_____________________________________________________


//call this routine to initialize all peripherals
void main(void)
{
 uch b_20=0;
 uch c[]={0,0};
 int  result;
 uch tem;
  //PORTC=0X00;
  //PORTC^=(1<<PC5);
 //stop errant interrupts until set up
 CLI(); //disable all interrupts
 timer1_init();
 spi_init();
 
 MCUCR = 0x00;
 GICR  = 0x00;
 TIMSK = 0x04; //timer interrupt sources
 SEI(); //re-enable interrupts
 //all peripherals are now initialized
 	   while(1)
	   {	
	   		
	   		b_20=init_1820();  
			//________________________________________________需要改正的地方
			if (b_20==0)    //如果不存在则显示为A
			   {
			   	no_b20();
				while(ling==0);
				ling=0;
				
			   }
			else         //tere is b20;存在b20,下一步开始启动并读数
				{   
				 tem=init_1820();
				 write_1820(0xcc);   //条过rom
				 write_1820(0x44);  //启动转换
				 while(ling==0);
				 ling=0;
				 while(ling==0);
				 ling=0;				 
				 tem=init_1820();     //reset
	   			 write_1820(0xcc);    //条过ROM
				 write_1820(0xBE);  //READ 闪存
				 c[0]=read_1820();
				 c[1]=read_1820();	
				 bcd_change(c[0],c[1]);	
				 spi_trans();		 
				 }
			
	    }
}




⌨️ 快捷键说明

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