📄 pt100.c
字号:
/*************************************
简易温度测量系统
文 件 名 :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++)
;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -