|
前几前收了一台高频焊台,一不小心就把里面的M8程序给擦除了,刚收回就变砖头了,不甘心啊,到处搜索,到处问人看有没M8的软体程序,可惜,找不到
找不到怎么办,只好自己动手丰衣足食了
搜索关于高频焊台的原理,发现只要提供400KHz的信号就可以发热了。说干就干,再搜索M8的资料,第一次用AVR,第一次正式写程序(以前的都是在开发板上跑跑demo)
电路图可以参考meinhard8的,好像高频焊台都差不多的电路
http://www.amobbs.com/forum.php? ... mp;highlight=400KHZ
有个问题,程序有时会跑飞,我也不知什么问题,就这水平了,高手帮看看。。。。
开发环境ICCAVR
//使用CTC模式从PB1输出400K的PWM
//CPU ATMEGA8
//内部晶振8M
#include <iom8v.h>
#include <macros.h>
#define Set_Bit(val, bitn) (val |=(1<<(bitn))) //设置端口状态,高
#define Clr_Bit(val, bitn) (val&=~(1<<(bitn))) //设置端口状态,低
#define Get_Bit(val, bitn) (val &(1<<(bitn)) ) //获取端口状态
unsigned int sum_adc[64]={0};
//0,1,2,3,4,5,6,7,8,9,A,b,C,d,E,F,-
unsigned char discode[18]={0x0A,0x9F,0x4C,0x68,0xB8,0x29,0x09,0x7A,0x08,0x38,0x18,0x89,0x0F,0xC8,0x0D,0x1D,0x98,0xFD};
unsigned int SetTemp;//设定的温度
unsigned int Temperature;//烙铁温度
unsigned int Shining_Time;//闪耀计数器
unsigned char ADC_Num;//ADC
unsigned int Down;//按键是否按定
unsigned int Key_Num;//按键按定计数器
unsigned int S3_Down;//S3按键是否按下
unsigned int Stop;//停止加热
//延时函数
void delay(unsigned char t)
{
unsigned char i;
unsigned char n;
for(i=0;i<t;i++)
{
for(n=0;n<255;n++);
}
}//end
//数码管,百位L3,十位L2,个位L1
void LED(int L3,int L2,int L1)
{
PORTD=discode[L3];
Set_Bit(PORTC,1);
Clr_Bit(PORTC,4);
Clr_Bit(PORTC,5);
delay(10);
PORTD=discode[L2];
Set_Bit(PORTC,4);
Clr_Bit(PORTC,1);
Clr_Bit(PORTC,5);
delay(10);
PORTD=discode[L1];
Set_Bit(PORTC,5);
Clr_Bit(PORTC,4);
Clr_Bit(PORTC,1);
delay(10);
}//end
//显示函数
void Display(void)
{
int i;
int LED3;
int LED2;
int LED1;
int Temp3;
int Temp2;
int Temp1;
//1095是表示检测不到温度探头,显示出错信息E-E
if(Temperature==1095)
{
DDRB &= (0 << PB1);//停止加热
Stop=1;//停止加热
LED3=14;
LED2=17;
LED1=14;
Temp3=14;
Temp2=17;
Temp1=14;
}
else
{
//设定的温度
i=SetTemp;
LED3=i/100;//百位
i=i%100;
LED2=i/10;//十位
i=i%10;
LED1=i;//个位
//烙铁温度
i=Temperature;
Temp3=i/100;//百位
i=i%100;
Temp2=i/10;//十位
i=i%10;
Temp1=i;//个位
}
if (Temperature>SetTemp)
{
//停止加热
if(Stop==0)
{
Stop=1;
DDRB &= (0 << PB1);
}
}
else
{
//继续加热
if(Stop==1)
{
Stop=0;
DDRB |= (1 << PB1);
}
}
if(S3_Down==1)
{
Shining_Time++;
if(Shining_Time>100)
{
Clr_Bit(PORTC,1);
Clr_Bit(PORTC,4);
Clr_Bit(PORTC,5);
delay(10);
if(Shining_Time>200)Shining_Time=0;
}
else
{
LED(LED3,LED2,LED1);
delay(10);
}
}
else
{
if (Temperature>SetTemp)
{
LED(LED3,LED2,LED1);
}
else
{
Shining_Time++;
if(Shining_Time>100)
{
LED(Temp3,Temp2,Temp1);
if(Shining_Time>200)Shining_Time=0;
delay(10);
}
else
{
LED(LED3,LED2,LED1);
delay(10);
}
}
}
}//end
//按键延时函数
void KeyDelay(void)
{
delay(10);
Display();
delay(10);
Display();
delay(10);
Display();
delay(10);
Display();
delay(10);
Display();
delay(10);
Display();
delay(10);
Display();
delay(10);
Display();
delay(10);
Display();
delay(10);
delay(10);
Display();
delay(10);
Display();
delay(10);
Display();
delay(10);
Display();
delay(10);
Display();
delay(10);
Display();
delay(10);
Display();
delay(10);
Display();
delay(10);
Display();
delay(10);
}//end
//按键处理
void Get_Key(void)
{
//S1键,减
if(Get_Bit(PINB,4)==0 && S3_Down==1) //PB4 按键处理函数
{
Display();
while(!(Get_Bit(PINB,4)))//等待按键松开
{
Key_Num++;
Display(); //显示作为延时程序
if(Key_Num>30)
{
Key_Num=0;
Down=1;
if(SetTemp>50)
{
SetTemp--;
}
else
{
SetTemp=50;
}
}
}
KeyDelay();
if(Down==1)
{
Down=0;
}
else
{
if(SetTemp>50)
{
SetTemp--;
}
else
{
SetTemp=50;
}
}
}
//S2键,加
if(Get_Bit(PINB,3)==0 && S3_Down==1) //PB3 按键处理函数
{
Display();
while(!(Get_Bit(PINB,3)))//等待按键松开
{
Key_Num++;
Display(); //显示作为延时程序
if(Key_Num>30)
{
Key_Num=0;
Down=1;
if(SetTemp<600)
{
SetTemp++;
}
else
{
SetTemp=600;
}
}
}
KeyDelay();
if(Down==1)
{
Down=0;
}
else
{
if(SetTemp<600)
{
SetTemp++;
}
else
{
SetTemp=600;
}
}
}
//S3键,*键,设置键
if(Get_Bit(PINB,5)==0) //PB5 按键处理函数
{
int i;
int LED3;
int LED2;
int LED1;
i=SetTemp;
LED3=i/100;
i=i%100;
LED2=i/10;
i=i%10;
LED1=i;
Display();
while(!Get_Bit(PINB,5)) //等待按键松开
{
Display();
}
KeyDelay();
if(S3_Down==0)
{
S3_Down=1;
}
else
{
S3_Down=0;
Shining_Time=0;
//保存温度到内部EEPROM
Write_EEprom(LED3,0);
Write_EEprom(LED2,1);
Write_EEprom(LED1,2);
}
}
}//end void
//读内部EEPROM函数
unsigned char Read_EEprom(unsigned int address)
{
unsigned char j;
if(EECR&0x01)delay(100);
EEARH=address>>8;
EEARL=address&0x00ff;
EECR=EECR|0x01;
delay(100);
j=EEDR;
return(j);
}//end
//写入EEPORM函数
void Write_EEprom(unsigned char data,unsigned int address)
{
if(EECR&0x20)delay(100);
EEARH=address>>8;
EEARL=address&0x00ff;
EEDR=data;
EECR=EECR|0x04;
EECR=EECR|0x02;
delay(100);
}//end
//ADC中断
#pragma interrupt_handler adc_isr:iv_ADC
void adc_isr(void)
{
unsigned long int i;
unsigned char disbuf[5]={0,0,0,0,0};
unsigned char f;
unsigned long sum_aver_adc=0;
unsigned int temp;
ADMUX =(1<<REFS0)|(1<<REFS1)|(1<<MUX0)|(1<<MUX1)|(0<<MUX2)|(0<<MUX3);//内部2.56基准,PC3 AD3输入
ADCSRA|=(1<<ADSC);//启动AD转换
sum_adc[ADC_Num]=ADC_Convert();
ADC_Num++;
if(ADC_Num>=64)
{
ADC_Num=0;
for(f=0;f<64;f++)
{
sum_aver_adc=sum_aver_adc+sum_adc[f]; //总的加起来
}
sum_aver_adc=(sum_aver_adc/64); //除下,算平均
i=(25600* sum_aver_adc)/1023; //算出电压
disbuf[4]=i/10000;
i=i%10000;
disbuf[3]=i/1000;
i=i%1000;
disbuf[2]=i/100;
i=i%100;
disbuf[1]=i/10;
i=i%10;
disbuf[0]=i;
//电压[4].[3][2][1][0]V
temp=(unsigned int )disbuf[4]*1000+(unsigned int )disbuf[3]*100+(unsigned int )disbuf[2]*10+(unsigned int )disbuf[1];
Temperature=temp/2.336;
}
}//end
unsigned int ADC_Convert(void)
{
unsigned int temp1,temp2;
temp1=(unsigned int)ADCL;
temp2=(unsigned int)ADCH;
temp2=(temp2<<8)+temp1;//10位精度
return(temp2);
}
void main(void)
{
int SetTemp1;
int SetTemp2;
int SetTemp3;
PORTB=0xFF;
DDRB |= (1 << PB1)|(0<<PB3)|(0<<PB4)|(0<<PB5);//设置PB3,PB4,PB5为输入口,PB1为输出口
//8M晶振 1分频 方波频率=8000000/2*1(1+9)=400K
ICR1 = 9;
//OC1A匹配取反
TCCR1A |= (1 << COM1A0);
//CTC OCR1A模式,1分频
TCCR1B |= (1 << WGM13) | (1 << WGM12) | (1 << CS10);
DDRC |= (1 << PC1)|(1<<PC4)|(1<<PC5)|(0<<PC3);//设置为输入输出口
DDRD=0xFF;//设置为输出口
//读取内部EEPROM的温度数据
SetTemp1=Read_EEprom(0);
SetTemp2=Read_EEprom(1);
SetTemp3=Read_EEprom(2);
//没有设置的记录,默认为200度
if(SetTemp1==255 && SetTemp2==255 && SetTemp3==255)
{
SetTemp=200;
//保存温度到内部EEPROM
Write_EEprom(2,0);
Write_EEprom(0,1);
Write_EEprom(0,2);
}
else
{
SetTemp=SetTemp1*100+SetTemp2*10+SetTemp3;
}
//采集温度,ADC3口
ADCSRA=0X00;
ADMUX =(1<<REFS0)|(1<<REFS1)|(0<<MUX0)|(0<<MUX1)|(0<<MUX2)|(0<<MUX3); //采用内部5参考电压,ADC0输入
ADCSRA=(1<<ADEN)|(1<<ADSC)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS1) ;//ADC转换 64分频
SEI();
while(1)
{
Get_Key();
Display();
}
}
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?注册
x
阿莫论坛20周年了!感谢大家的支持与爱护!!
知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)
|