www.pudn.com > pt100.rar > pt100.c, change:2008-09-19,size:4721b


/************************************* 
          简易温度测量系统 
文 件 名    :pt100.c				  
设    计    :毕京鹏					  
最后修改日期:2008.09.19		  
版    本    :V1.1				 	  
主控芯片    :ATMEGA48V					  
工作频率    :外部16MHz晶振 
备注        : 注意数据有可能超范围 
*************************************/ 
#include<iom48v.h> 
#include<macros.h> 
 
#define uchar unsigned char 
#define uint  unsigned int 
//过热值设定 
#define GR 500      
/*显示*/ 
const uchar distable[10]={0x27,0x2f,0x37,0x3f,0x67,0x6f,0x77,0x7f,0xa7,0xaf}; 
uchar count=0,dis1=0,dis2=0,dis3=0,dis4=0; 
/*时间变量*/ 
uchar ms400,ms500; 
/*转换结果*/ 
uint adresult=0; 
uchar temph,templ; 
float temperature; 
uint WdSave[4]={300,300,300,300}; 
/*键盘*/ 
uchar keybuf=0; 
/*过热相关*/ 
struct data 
       {unsigned bit0:1; 
	    unsigned bit1:1; 
		unsigned bit2:1; 
		unsigned bit3:1; 
		unsigned bit4:1; 
		unsigned bit5:1; 
		unsigned bit6:1; 
		unsigned bit7:1; 
	   }flag1;                //使用时为flag1.bitn 
uchar guore,flag;	    
//函数声明 
void Init(void); 
void convert(void); 
void keyscan(void); 
void delay_1ms(void); 
void delay_nms(uint n); 
 
#pragma interrupt_handler timer1_int:14 
#pragma interrupt_handler display_int:17 
void main(void) 
{ 
 CLI(); 
 Init(); 
 SEI(); 
 while(1) 
  { 
   while(flag==0) 
   {PORTB&=0xfd;  //1111 1101 
    if(ms400==40)  //400ms转换一次 
      {ms400=0; 
	   CLI(); 
	   ADCSRA|=(1<<ADSC); //开始转换 
       while(!(ADCSRA & (1 << ADIF)));	/*等待*/  
       //ADCSRA&=~(1<<ADEN); 
       ADCSRA|=(1<<ADIF); 
       templ=ADCL; 
       temph=ADCH; //先低位 后高位 
       adresult = (((uint)temph)<<8) + templ; //10 bit 
       temperature=((100*adresult)/1024.0)/0.39; 
       convert(); 
       SEI(); 
	  } 
   } 
   while(flag) 
   {PORTB|=0x02;   //断开继电器 
    if(ms500==50) 
	  {ms500=0; 
	   flag1.bit1=~flag1.bit1; 
	   if(flag1.bit1)  //不显示数值 
	       {TCCR0B=0x00; 
		    PORTC|=0x0e;  //0000 1110  
		   } 
	   else          //显示过热值 
	       {TCCR0B=0x05; 
		   }  
	  } 
	keyscan();   
	if(keybuf)   //按键解除 
	  {keybuf=0; 
	   CLI(); 
       Init(); 
	   WdSave[0]=GR;  //解除后重新工作以过热值为初值 
       WdSave[1]=GR; 
	   WdSave[2]=GR; 
	   WdSave[3]=GR; 
       SEI(); 
	  } 
   } 
  } 
} 
/***************中断函数*********************/ 
void display_int(void) 
{count++; 
 TCNT0=0xb0;  //重赋初值 
 PORTC|=0x0e;  //0000 1110 
 PORTD|=0xd8; //1101 1000 
 switch(count) 
 {case 1: 
  	   PORTC&=0xf1; //L6  1111 0001 
  	   PORTD&=distable[dis4]; 
  	   break; 
  case 2: 
  	   PORTC&=0xf3; //L5  1111 0011 
 	   PORTD&=distable[dis3]; 
 	   break; 
  case 3: 
  	   PORTC&=0xf5; //L4  1111 0101 
 	   PORTD&=distable[dis2]; 
 	   break; 
  case 4: 
       count=0; 
  	   PORTC&=0xf7; //L3  1111 0111 
 	   PORTD&=distable[dis1]; 
 	   break; 
	    
 } 
} 
void timer1_int(void) 
{TCNT1=0xfd8f; //重赋初值 
 if(ms400!=40)ms400++; 
 if(ms500!=50)ms500++;    
} 
/************子函数************************/ 
/*初始化函数*/ 
void Init(void) 
{flag1.bit0=0; //过热标志位  (不可用) 
 guore=0; 
 flag=0;       //过热标志位 
  
 ms400=0; 
 ms500=0; 
 flag1.bit1=0;//闪烁标志位 
 /*端口初始化*/ 
 DDRB|=0x02;    //0000 0010 //PB1 控制继电器 
 PORTB|=0x02;    //为1断开 
 DDRC|=0x0e;    //0000 1110 
 PORTC=0x00;                        
 DDRD=0xfb;    //1111 1011  PD2作为键盘输入      
 PORTD=0x00; 
 /*T/C0寄存器初始化*/ 
 TCCR0A=0x00; 
 TIMSK0=0x01; 
 TCNT0=0xb0;  //  5*1024us=5.120ms 
 TCCR0B=0x05; //   clk/1024 
 /*T/C1寄存器初始化*/ 
 TCCR1A=0x00; 
 TIMSK1=0x01; 
 TCNT1=0xfd8f;  //10ms 
 TCCR1B=0x04; //  clk/256 
 /*ADC初始化*/ 
 ADCSRA=0x87;   //1000 0111  128分频  查询 
 ADMUX =0x00;   //0000 0000  Vref=AREF 
 DIDR0 =0x01;   //ADC数字输入禁能 
} 
/*结果转换函数*/ 
void convert(void) 
{ 
 uchar i; 
 uint temp,sum=0; 
 temp=(uint)(temperature/0.1)-40;  //-40 
 if(temp>WdSave[0]) 
    {if((temp-WdSave[0])>3)temp=WdSave[0]+3; 
	} 
 else if(temp<WdSave[0]) 
    {if((WdSave[0]-temp)>3)temp=WdSave[0]-3; 
	} 
 for(i=3;i>=1;i--)WdSave[i]=WdSave[i-1]; 
 WdSave[0]=temp; 
 for(i=0;i<=3;i++)sum+=WdSave[i]; 
 temp=sum/4;       //温度测量四次取平均 
  
 if(temp>GR)guore++; 
 else guore=0; 
 if(guore==3)flag=1;//连续三次测得温度超限,置位过热标志 
 		 
 dis2=temp/100; 
 dis3=temp%100/10; 
 dis4=temp%10;                    
 /*dis2=(uint)(temperature/0.1)/100; 
 dis3=(uint)(temperature/0.1)%100/10; 
 dis4=(uint)(temperature/0.1)%10;*/ 
} 
/*键盘扫描函数*/ 
void keyscan(void)         //键盘扫描函数 
{if((PIND&0x04)==0)        //0000 0100 
  {delay_nms(10); 
   if((PIND&0x04)==0)keybuf=1; 
  } 
} 
/*延时函数*/ 
void delay_nms(uint n) 
{uint i; 
 for(i=0;i<n;i++) 
  delay_1ms(); 
} 
void delay_1ms(void) 
{uint i; 
 for(i=1;i<2286;i++) 
  ; 
}