长汀无线电厂交流论坛

 找回密码
 注册
查看: 12276|回复: 44
打印 上一主题 下一主题

用M16控制白光烙铁温度

  [复制链接]
楼主
发表于 2011-2-6 11:50:39 | 只看该作者
程序得用哪个下载器下载?
回复 支持 反对

使用道具 举报

沙发
 楼主| 发表于 2011-1-26 16:33:26 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 zhouchs 于 2011-2-18 07:50 编辑

设计了白光T12温度控制电路,调试中

LED显示温度,设定时显示的温度3个小数点都亮,可按键设定,也可电位器设定
调试成功后再贴程序源码
回复

使用道具 举报

板凳
发表于 2011-1-26 17:22:20 | 只看该作者
支持楼主…祝你早日成功…呵呵!好共享
回复 支持 反对

使用道具 举报

地板
发表于 2011-1-26 21:00:59 | 只看该作者
大作品,得支持,顶一顶,学习
回复 支持 反对

使用道具 举报

5#
 楼主| 发表于 2011-2-6 13:27:57 | 只看该作者
源程序用ICC AVR编译,用AVR_fighter烧写,USBasp下载
回复 支持 反对

使用道具 举报

6#
发表于 2011-1-31 13:39:53 | 只看该作者
祝楼主成功 希望楼主马上成功  俺也能借光 学习下   谢谢啦
回复 支持 反对

使用道具 举报

7#
发表于 2011-1-31 23:41:43 | 只看该作者
我怎么没想到用光耦呢?
回复 支持 反对

使用道具 举报

8#
发表于 2011-1-31 23:45:28 | 只看该作者
LM35用来干什么呢?AVCC AREF都没接?光耦出来的电压是和输入电压同向还是反向呢?
回复 支持 反对

使用道具 举报

9#
 楼主| 发表于 2011-2-4 22:03:40 | 只看该作者
//********************************************************************
//白光烙铁控制程序
//M16
//2011.2.4
//********************************************************************

#include <iom16v.h>
#include <macros.h>
#pragma interrupt_handler Timer0Int:10

#define twi_stop() TWCR=0x94   
#define twi_start() TWCR=0xa4      
#define check_TWINT() while(!(TWCR & (1<<TWINT)))  //轮询等待TEINT置位
unsigned char TwiStatus;

unsigned char DISP[3]={0x01,0x02,0x03};        //3位数字,高位在前,温度值:XXX℃

unsigned char KDelay;                //按键延时定值,快慢变化
unsigned char Set;                        //设定方式,0-电位器设定,1-按键设定
unsigned char Mod;                        //显示状态切换,0-停,显示环境温度,1-加热,显示烙铁温度,2-调节
unsigned char Suc;                        //I2C返回值
unsigned int Ns;                        //按键计数快慢,40-200ms,4-20ms
unsigned int Num1;                        //按键延时计数1
unsigned char Num2;                        //按键延时计数2
unsigned char Num3;                        //轮流显示
unsigned int Num4;                        //设定延时切换,2s
unsigned int Ut;                        //热电偶电压
unsigned int U[110];                        //热电偶电压均值计算
unsigned int Ua;                        //设定电压
unsigned int Tf;                        //上次设定值
unsigned char Tc;                        //环境温度数据
unsigned char Tk;                        //计时
unsigned char Tr;                        //加热周期,0~4/5
unsigned int Ts;                        //设定温度值,160~430
unsigned int Tt;                        //实际温度值,0~430

const unsigned char DIG[]={0x14,0x77,0x4C,0x45,0x27,0x85,0x84,0x57,0x04,0x05,0x26,0xBC};       
//从高到低:B、F、A、G、C、DP、D、E       
//数字编码:0、1、2、3、4、5、6、7、8、9、H(10)、L(11)



/*****************************************
              延时子程序
******************************************/
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 允许定时器零匹配和溢出中断
}

//-------------------------------------------------------------------
//U10:A/D转换
//-------------------------------------------------------------------
void U10(void)
{
        unsigned int tmp;                        //
        unsigned char i;                        //
        if(Set==0)
        {
          ADCSRA = 0x00; //disable adc
          ADMUX = 0xC0; //2.56V内部基准,右对齐,通道ADC0单端输入
          ACSR  = 0x80;
          ADCSRA=0xC6;
          while(!(ADCSRA&(1<<ADIF)));
          ADCSRA|=(1<<ADSC)|(0<<ADIF);
          while(!(ADCSRA&(1<<ADIF)));       
          Ua=ADCL;
          Ua=ADCH*256+Ua;       
          Tf=Ts;
          Ts=(2*Ua+1590)/10;
          if(Ts>340)Ts=340;
       
          if((Tf>Ts && Tf-Ts>2)||(Ts>Tf && Ts-Tf>2))
          {
                 Mod=2;
                 Num4=0;
          }
        }
       
        ADCSRA = 0x00; //disable adc
        ADMUX = 0xCF; //2.56V内部基准,右对齐,通道ADC0单端输入
        ACSR  = 0x80;
        ADCSRA=0xC6;
        while(!(ADCSRA&(1<<ADIF)));
        ADCSRA|=(1<<ADSC)|(0<<ADIF);
        while(!(ADCSRA&(1<<ADIF)));
        Ut=ADCL;
        Ut=ADCH*256+Ut;
        for(i=0;i<99;i++)U[i]=U[i+1];
        U[99]=Ut;
        Ut=0;
        for(i=0;i<100;i++)Ut=Ut+U[i];
        Ut=Ut/100;
       

       
//考虑环境温度
//        tmp=74*(Ut+Tc+37);       
        tmp=156*Ut+80*Tc;
        if(tmp>26400)tmp=tmp-26400;
        else tmp=0;       
        Tt=tmp/100;
}

/*****************************************
          TWI主接收方式子程序
          读取LM75的TEMP寄存器的值
******************************************/

void TWITempRead(unsigned char ReadDeviceAddr,unsigned char WriteDeviceAddr,unsigned char RegAddr)  
{  
    unsigned int j;
        Delay(100);
         
    while (TwiStatus != 0x08)   //检验TWSR,屏蔽预分频位   
    {
         twi_start();           //发送START信号
         Delay(1);
         TwiStatus=TWSR & 0xF8;  
   }  
    while (TwiStatus != 0x18)  //检验TWSR,SLA+W已发出,并收到ACK
    {
         TWDR = WriteDeviceAddr;//设备地址(写)  
         TWCR=0x84;
         Delay(1);
         TwiStatus=TWSR & 0xF8;   
   }     
   while (TwiStatus != 0x28) //DATA已发出,并收到ACK      
   {
         TWDR = RegAddr;  //写入LM75的TEMP寄存器的地址  
         TWCR=0x84;   
         Delay(1);
         TwiStatus=TWSR & 0xF8;  
   }
   
   while (TwiStatus != 0x10)  //REPEATED START信号已发出
   {
         twi_start();  //发REPEATED START信号
         Delay(1);
         TwiStatus=TWSR & 0xF8;  
   }
   
   while (TwiStatus != 0x40)  //检验TWSR,SLA+R已发出,并收到ACK
   {
         TWDR =ReadDeviceAddr;  //设备地址(读)
         TWCR=0x84;   
         Delay(1);
         TwiStatus=TWSR & 0xF8;  
   }
   TwiStatus=0x00;  
   while (TwiStatus != 0x50)  //DATA已收到,ACK已发出
   {
         TWCR=0xc4;           //接收高8位数据,发送ACK
         Delay(50);
         Tc=TWDR;
         TwiStatus=TWSR & 0xF8;  
   }
   while(TwiStatus != 0x58)    //DATA已收到,nACK已发出     
   {
         TwiStatus=TWSR & 0xF8;  
         TWCR=0x84;          //接收低8位数据,发送nACK
                 Delay(50);
//         TempLow=TWDR;
   }
   twi_stop();            //发送STOP 信号   
}  



//--------------------------------------------------
//主程序
//--------------------------------------------------
void main(void)
{
        unsigned int m;                        //
        io_init();
         
        DDRC&=0Xcf;
        PORTC|=0X30;
    TWCR= 0X00; //disable twi
    TWBR= 0x12; //set bit rate
    TWSR= 0x01; //set prescale
    TWCR= 0x04; //enable twi        
        TIMER_init();
        Tr=1;
        PORTA=0xF2;
        Ts=200;       
        Ns=40;
        SEI(); //                                        //开中断
        Set=0;
        if(PIND & 0x08)        Set=1;
       
        while(1)
        {
                 if(Set==1)
                {
                    if((PINA & 0x10)==0)
                         {
                                  Num2=0;
                                  Num4=0;
                                Mod=2;
                                Ts++;
                                if(Ts>430)Ts=430;
                                while(Num2<Ns);
                        }
                            if((PINA & 0x20)==0)
                          {
                              Num2=0;
                                  Num4=0;
                                Mod=2;
                                Ts--;
                                if(Ts<160)Ts=160;
                                while(Num2<Ns);
                        }
                }
               
                if(Mod>1 && Num4>500)
                {
                         if(Ts<160)Mod=0;
                        else Mod=1;
                        Num4=0;
                }
       
                TWITempRead(0x91,0x90,0);
                if(Ts<Tt)
                {
                          Tr=1;
                          if(Ts>240)Tr=2;
                          if(Ts>340)Tr=3;
                }
                else
                {
                           m=(Ts-Tt);
                           if(m<6) Tr=3;
                           if(m>5 && m<11) Tr=5;
                           if(m>10 && m<21) Tr=8;
                           if(m>20 && m<31) Tr=10;
                           if(m>30 && m<41) Tr=13;
                           if(m>40) Tr=16;
                        if(Ts>240 && m<21)Tr*=2;
                        if(Ts>340 && m<21)Tr+=4;
                }
        }

}

//-------------------------------------------------------------------
//Timer0Int:定时中断子程序,用于显示输出及按键延时计时,5ms
//-------------------------------------------------------------------
void Timer0Int(void)
{       
        unsigned char n;                        //循环计数,0~19
        unsigned char m;                        //
        unsigned int p;                        //
        TCNT0=0x64;//79次计数为10mS
        if(((PINA & 0x20)==0) || ((PINA & 0x10)==0))Num1++;                //按键延时计数
        else
        {
                Num1=0;
                Ns=40;
        }
        if(Num1>400)Ns=4;                //按键加速
       
        Num2++;                                                //按键延时计数
        Num3++;                                                //轮显
        Num4++;                                                //按键延时计数2
        Tk++;
        n=Tk%20;
        if(n==0)
        {
                PORTA|=0x02;
                U10();                                            //读温度转换电压       
                if(Tk%40==0)                        //0.2s刷新显示
                {
                         p=Tc;
                         if(Mod==1)p=Tt;
                         if(Mod==2)p=Ts;       
                        DISP[0]=p/100;                          //显示温度
                        DISP[1]=(p%100)/10;
                        DISP[2]=p%10;
                }
        }
        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;                //输出百位数字
}

初步能用了,温度和采集电压的关系暂时没办法仔细校。图中3.3V为5V,LM75A用于测参考温度,矫正热偶温度用的,光耦用于低压驱动高压的隔离,更安全些,直接驱动也行,可能会损坏单片机。调试有改动时再补充,欢迎共同测试,好有改进。


回复 支持 反对

使用道具 举报

10#
发表于 2011-2-17 12:01:16 | 只看该作者
是用M16做的控制器,很不错,能发个原理图吗
回复 支持 反对

使用道具 举报

11#
发表于 2011-2-17 13:05:23 | 只看该作者
不错,早日成品
回复 支持 反对

使用道具 举报

12#
发表于 2011-2-17 16:06:54 | 只看该作者
祝你早日成功…呵呵!好共享
回复 支持 反对

使用道具 举报

13#
发表于 2011-2-17 17:26:18 | 只看该作者
本帖最后由 Ly7 于 2011-2-17 17:27 编辑

个人感觉,用m16实在没有性价比啊,不如用12c5410ad来做,这里就有一个厂家用12c5410ad来做的产品,国产942
http://item.taobao.com/auction/item_detail.htm?item_num_id=8310667044
回复 支持 反对

使用道具 举报

14#
发表于 2011-3-9 16:19:31 | 只看该作者
很棒,继续加油。 期待你的完美版。
回复 支持 反对

使用道具 举报

15#
发表于 2011-4-10 11:38:14 | 只看该作者
很好,值得关注
回复 支持 反对

使用道具 举报

16#
发表于 2011-4-11 09:54:48 | 只看该作者
好奇心出来顶,说明贴子有份量,楼主继续
回复 支持 反对

使用道具 举报

17#
发表于 2011-4-11 10:22:27 | 只看该作者
楼主说说制作的效果怎么样啊。
回复 支持 反对

使用道具 举报

18#
发表于 2011-4-28 16:13:10 | 只看该作者
我也建议用STC的MCU,便宜,更有性价比。开源,体现楼主的无私,敬佩!
回复 支持 反对

使用道具 举报

19#
发表于 2011-5-21 00:23:26 | 只看该作者
提示: 作者被禁止或删除 内容自动屏蔽
回复 支持 反对

使用道具 举报

20#
发表于 2011-6-6 14:24:51 | 只看该作者
记号一个.仿个试试
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|手机版|小黑屋|Archiver|长汀无线电厂交流论坛  

GMT+8, 2024-5-1 17:29 , Processed in 0.430765 second(s), 20 queries .

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表