|
//********************************************************************
//白光烙铁控制程序
//M16 150-52?200-58?250-64?300-70
//2011.6.27 取消按键调节部分代码,只留电位器调节
//********************************************************************
#include <iom16v.h>
#include <macros.h>
#pragma interrupt_handler Timer0Int:10
unsigned char DISP[3]={0x01,0x02,0x03}; //3位数字,高位在前,温度值:XXX℃
//显示状态切换,0-停止,1-加热,显示烙铁温度,2-调节,3-烙铁插错
unsigned char Mod;
unsigned char Num3; //轮流显示
unsigned int Num4; //设定延时切换,2s
unsigned int Ut; //热电偶电压
unsigned int U[64]; //热电偶电压均值计算
unsigned int Ua; //设定电压
unsigned int Tf; //上次设定值
unsigned char Tk; //计时
unsigned char Tr; //加热周期,0~4/5
unsigned int Ts; //设定温度值,160~410
unsigned int Tt; //实际温度值,0~410
const unsigned char DIG[]={0x14,0x77,0x4C,0x45,0x27,0x85,0x84,0x57,0x04,0x05,0x26,0xBC,0x8E};
//从高到低:B、F、A、G、C、DP、D、E
//数字编码:0、1、2、3、4、5、6、7、8、9、H(10)、L(11)、F(12)
/*****************************************
延时子程序
******************************************/
void Delay(unsigned int n)
{
unsigned int i ;
for(i=0;i<50*n;i++);
}
//--------------------------------------------------
//io_init:初始化IO子程序
//--------------------------------------------------
void io_init(void)
{
DDRA = 0xC2; //PA0\PA2\PA3\PA4\PA5为输入,其余均为输出
PORTA|=0x30; //拉高按键管脚
DDRB = 0xFF;
DDRC = 0xFC; //I2C管脚为定义为输入,再拉高
PORTC|=0x03;
DDRD = 0xF7; //PD3输入
PORTD|=0x08;
}
//-------------------------------------------------------------------
//TIMER_init:初始化定时器 5ms定时 无分频
//-------------------------------------------------------------------
void TIMER_init(void)
{
TCCR0 = 0x00; //stop
TCNT0 = 0x64; //set count
TCCR0 = 0x04; //start timer
MCUCR = 0x00;
GICR = 0x00;
TIMSK = 0x01; //timer interrupt sources 允许定时器零匹配和溢出中断
}
//-------------------------------------------------------------------
//TLT:A/D转换,烙铁温度
//-------------------------------------------------------------------
void TLT(void)
{
unsigned int tmp; //
unsigned char i; //
ADCSRA = 0x00; //disable adc
ADMUX = 0xEF; //2.56V内部基准,左对齐,通道ADC3、ADC2差分输入
ACSR = 0x80;
ADCSRA=0xC6; //ADC使能并开始转换,预分频64,8/64=125kHz(50~200)
while(!(ADCSRA&(1<<ADIF)));
ADCSRA|=(1<<ADSC)|(0<<ADIF); //第二次转换,更准确些
while(!(ADCSRA&(1<<ADIF)));
Ut=ADCH;
//if(Ut>127) Ut=0;
for(i=0;i<63;i++)U[i]=U[i+1];
U[63]=Ut;
Ut=0;
for(i=0;i<64;i++)Ut=Ut+U[i];
Ut>>=6;
if(Ut<34) Ut=34;
Tt=25*Ut/3-283;
}
//-------------------------------------------------------------------
//TSET:A/D转换,设定温度转换
//-------------------------------------------------------------------
void TSET(void)
{
unsigned int tmp; //
unsigned char i; //
ADCSRA = 0x00; //disable adc
ADMUX = 0x60; //AVCC,左对齐,通道ADC0单端输入
ACSR = 0x80;
ADCSRA=0xC6;
while(!(ADCSRA&(1<<ADIF)));
ADCSRA|=(1<<ADSC)|(0<<ADIF);
while(!(ADCSRA&(1<<ADIF)));
Ua=ADCH;
Tf=Ts;
Ts=Ua+155;
if((Tf>Ts && Tf-Ts>2)||(Ts>Tf && Ts-Tf>2))
{
Mod=2;
Num4=0;
}
if(Ts<160)Mod=0;
if(Mod==2 && Num4>500)
{
if(Ts<160)Mod=0;
else Mod=1;
}
}
//--------------------------------------------------
//主程序
//--------------------------------------------------
void main(void)
{
unsigned int m; //
io_init();
DDRC&=0Xcf;
PORTC|=0X30;
TIMER_init();
Mod=1;
Tr=1;
PORTA=0xF2;
Ts=200;
SEI(); // //开中断
while(1)
{
if(Ts<Tt)
{
Tr=2;
if(Ts>240)Tr=4;
//if(Ts>340)Tr=3;
}
else
{
m=(Ts-Tt);
if(m<11) Tr=4;
//if(m>5 && m<11) Tr=5;
if(m>10 && m<31) Tr=6;
//if(m>20 && m<31) Tr=10;
if(m>30 && m<51) Tr=8;
if(m>50) Tr=12;
}
}
}
//-------------------------------------------------------------------
//Timer0Int:定时中断子程序,用于显示输出及按键延时计时,5ms
//-------------------------------------------------------------------
void Timer0Int(void)
{
unsigned char n; //循环计数,0~19
unsigned char m; //
unsigned int p; //
TCNT0=0x64;//79次计数为10mS
Num3++; //轮显
Num4++; //状态转换
Tk++;
if(Tk>199)Tk=0;
n=Tk%20;
if(n==0)
{
PORTA|=0x02;
TLT(); //读温度转换
if(Tk%40==0) //0.2s刷新显示
{
TSET(); //设定电压
if(Mod==1)p=Tt;
if(Mod==2)p=Ts;
//p=Mod;
//p=Ua;
DISP[0]=p/100; //显示温度
DISP[1]=(p%100)/10;
DISP[2]=p%10;
if(Mod==0)
{
DISP[0]=0; //显示OFF
DISP[1]=12;
DISP[2]=12;
}
}
}
else
{
if(n<Tr+1 && Mod>0)PORTA&=0xFD; //n/20周期加热
else
PORTA|=0x02;
}
PORTD|=0x07;
n=Num3%3;
m=DIG[DISP[n]];
if(Mod==2) m&=0xFB; //设置温度状态
PORTB=m;
if(n==2)PORTD&=0xFE; //输出个位数字
if(n==1)PORTD&=0xFD; //输出十位数字
if(n==0)PORTD&=0xFB; //输出百位数字
}
取消了LM35环境温度测量,取消了按键调节,只支持电位器调节。调整了温度测量准确度,由于使用了内部差分输入,用放大了200倍,精度只有7位,加上测温范围的关系,温度准确度在10度左右。 |
|