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

📄 ds18b20._c

📁 DS18B20温度监控程序
💻 _C
字号:
/*************************************
          ds18b20测温程序
文 件 名    :ds18b20.c				 
设    计    :毕京鹏					 
最后修改日期:2008.11.13		 
版    本    :V1.0				 	 
主控芯片    :ATMEGA48V					 
工作频率    :外部16MHz晶振
备注        : 初步:实时测温并显示
              1.读数据时的处理方式
			  2.数据口上需带上拉(5.1K)
			  3.配置成9位时后三位始终为0,以此类推
			  4.1s更新一次
*************************************/
#include<iom48v.h>
#include<macros.h>

#define uchar unsigned char
#define uint  unsigned int
/*DQ 接在PC0上*/
#define  DQ(x)  x ? (PORTC |= 0x01) : (PORTC &= 0xfe)
#define  DRC(y)  y ? (DDRC |= 0x01 ) : (DDRC &= 0xfe)
uchar flag;
void Init_1wire(void);
void WriteByte_1wire(uchar data);
uchar ReadByte_1wire(void);

void PortInit(void);
void delay_1us(void); 
void delay_10us(uchar n);
/*显示有关*/
#pragma interrupt_handler display_int:17
const uchar distable[]={0x27,0x2f,0x37,0x3f,0x67,0x6f,0x77,0x7f,0xa7,0xaf};
                      // 0    1    2    3    4     5   6     7    8    9
uchar time1,time2;
uchar count2=0;
uchar timeb1,timeb2,timeb3,timeb4,timeb5,timeb6;
void convert(void);
/*定时有关*/
uchar count1=0;
#pragma interrupt_handler timer1_int:14
/*通信有关*/
uchar Rece[2],Send[3];
uchar count3=0;
uchar flag1=0;
void UartInit(void);
void UartSend(uchar a[],uchar length);
#pragma interrupt_handler UartRece_int:19
/*******************主函数********************************/
main()
{ uchar tempH,tempL;
  PortInit();
  /***********此部分在初次配置完成后可略去*****************/
  Init_1wire(); 
  WriteByte_1wire(0xcc);
  WriteByte_1wire(0x4e);   //Write Scratchpad
  WriteByte_1wire(0x7f);   //TH
  WriteByte_1wire(0xff);   //TL
  WriteByte_1wire(0x1f);   //CONFIGURATION REGISTER  9位
  
  Init_1wire(); 
  WriteByte_1wire(0xcc);
  WriteByte_1wire(0x48);  //Copy Scratchpad
  /***********************************************/
  SEI();
  while(1)
    {if(count1==100)
	   {count1=0;
	    Init_1wire();
  		WriteByte_1wire(0xcc);
  		WriteByte_1wire(0x44);
  		DRC(0);                       //判断转换是否完成
  		if(!(PINC&0x01));
  		Init_1wire();
  		WriteByte_1wire(0xcc);
  		WriteByte_1wire(0xbe);
  		tempL = ReadByte_1wire();
  		tempH = ReadByte_1wire();
 
  		time1=tempH;
  		time2=tempL;
  		convert();
	   }
	 if(flag1==1)
	   {flag1=0;
	    if((Rece[0]=='S')&&(Rece[1]=='T'))
		  {Send[0]='#'
		   Send[1]=tempH;
		   Send[2]=tempL;
		   UartSend(Send,3);            //向上位机发送数据
		  }
	   }  
	}
}
/*******************中断函数****************************/
/*定时中断*/
void timer1_int(void)
{TCNT1=0xfd8f; //重赋初值
 if(count1!=100)count1++;
}
/*显示中断*/
void display_int(void)
{count2++;
 TCNT0=0xce;  //重赋初值
 PORTC|=0x0e;  //0000 1110
 PORTD|=0xd8; //1101 1000
 switch(count2)
 {case 1:
  	   PORTC&=0xf1; //L6  1111 0001
  	   PORTD&=distable[timeb6];
  	   break;
  case 2:
  	   PORTC&=0xf3; //L5  1111 0011
 	   PORTD&=distable[timeb5];
 	   break;
  case 3:
  	   PORTC&=0xf5; //L4  1111 0101
 	   PORTD&=distable[timeb4];
 	   break;
  case 4:
       PORTC&=0xf7; //L3  1111 0111
 	   PORTD&=distable[timeb3];
 	   break;
  case 5:
       PORTC&=0xf9; //L2  1111 1001
 	   PORTD&=distable[timeb2];
 	   break;
  case 6:
       count2=0;
  	   PORTC&=0xfb; //L1  1111 1011
 	   PORTD&=distable[timeb1];
 	   break;	      
 }
}
/*******************子函数***********************************/
/*端口及中断初始化*/
void PortInit(void)
{DDRC = 0xff;
 PORTC=0xff;
 DDRD=0xff;
 PORTD=0x00;
 /*T/C0*/
 TCCR0A=0x00;
 TIMSK0=0x01;
 TCNT0=0xce;  //  (1024/16,000,000)*50=3.2ms
 TCCR0B=0x05; //   clk/1024
 /*T/C1*/
 TCCR1A=0x00;
 TIMSK1=0x01;
 TCNT1=0xfd8f;  //10ms
 TCCR1B=0x04; //  clk/256
 /*通信口初始化*/
 UartInit();
}
/*数据转换函数*/
void convert(void)
{timeb1=time1/100;
 timeb2=time1%100/10;
 timeb3=time1%10;
 timeb4=time2/100;
 timeb5=time2%100/10;
 timeb6=time2%10;
}
/*****************单总线时序**************/
/*初始化*/
void Init_1wire(void)
{flag = SREG;				/*中断保护*/
 CLI();	
 					/*关中断*/
 DRC(1);              //Out
 DQ(1);
 NOP();    //DQ拉低480-960US,接着将数据线拉高15-60US
 DQ(0);
 delay_10us(56);   
 DQ(1);
 DRC(0);        //In  释放总线  此时上拉电阻使能
 delay_10us(7);            
 while(PINC & 0x01);
 delay_10us(50);     //presence pulse 60-240us  480us min
 
 if (flag & 0x80) 
   {SEI();  /*恢复中断状态*/
   }
}
/*写字节*/                    
void WriteByte_1wire(uchar data)
{uchar i,temp;
 temp=data;
 
 flag = SREG;				/*中断保护*/
 CLI();	
 
 DRC(1);
 for(i=0;i<8;i++)
  {DQ(1);
   NOP();
   DQ(0);               //写时间隙开始
   delay_10us(1);
   if(temp&0x01)DQ(1);
   //else DQ(0);
   temp>>=1;             //LSB First
   delay_10us(7);
  }
 DQ(1);
 
 if (flag & 0x80) 
   {SEI();  /*恢复中断状态*/
   }  
}
/*读字节*/                   
uchar ReadByte_1wire(void)
{uchar i,data=0;

 flag = SREG;				/*中断保护*/
 CLI();
 
 for(i=0;i<8;i++)
  {data>>=1;            //处理方法:先右移  后将最高位与 0x80相或 !!!
   DRC(1);              
   DQ(1);
   NOP();
   DQ(0);
   delay_1us();        //delay 3us
   delay_1us();
   //DQ(1);
   DRC(0);
   delay_10us(1);
   if(PINC&0x01)data|=0x80;
   delay_10us(6);
   
  }
 DRC(1);
 DQ(1);
 
 if (flag & 0x80) 
   {SEI();  /*恢复中断状态*/
   } 
 return(data);   
}
/********************************************************/

/* n*10us  
 通过AVR Studio仿真*/
void delay_10us(uchar n)
{uchar i,j;
 for(i=0;i<n;i++)
   for(j=0;j<38;j++);
}
/* 1.75us */
void delay_1us(void)
{uchar i;
 for(i=0;i<4;i++);
}
/********************************通信部分*************************/
void UartRece_int(void)
{if(count3<2)Rece[count3++]=UDR0;
 else 
   {count3=0;
    flag1=1;
   }                	
}
/**************串口初始化函数*****************/
void UartInit(void)
{
 /* 设置波特率*/
 UBRR0H = 0x00;   /*9600 U2X0=0  103*/
 UBRR0L = 0x67;
 /* 接收中断使能  接收器与发送器使能*/
 UCSR0B = (1<<RXCIE0)|(1<<RXEN0)|(1<<TXEN0);
 /* 设置帧格式: 8 个数据位, 1 个停止位 */
 UCSR0C = (3<<UCSZ00);
}
/****************串行发送函数****************/
void UartSend(uchar a[],uchar length)
{uchar i;
 for(i=0;i<length;i++)
  {/* 等待发送缓冲器为空*/
   while ( !( UCSR0A & (1<<UDRE0)) );
   /* 将数据放入缓冲器,发送数据*/
   UDR0=a[i];
  }
}

⌨️ 快捷键说明

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