找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 417|回复: 9
打印 上一主题 下一主题
收起左侧

AI8051U单片机回流焊加热台C语言程序带恒温加热

[复制链接]
跳转到指定楼层
楼主
ID:1002055 发表于 2026-9-28 22:21 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
程序说明:加热台主控芯片AI8051U34k64,系统频率24Mz,用旋转编码器按键控制加热,单击按键启/停加热,长按
        控制回流和恒温模式,在恒温模式下转动旋转编码器调节温度,停止转动2秒自动返回显示实际温度界面,测温
        用K型热电偶,MAX6675测温,单片机读取MAX6675数据控制PWM加热,PID控温,回流焊初次预热100度保持90秒
        后升温至150度再保持90s,然后升温至245度保持40秒停止加热。回流焊高温保护265度,恒温加热最高温度
        400度。
回流焊加热台.zip (211.5 KB, 下载次数: 0)

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏6 分享淘帖 顶顶 踩踩
回复

使用道具 举报

沙发
ID:1002055 发表于 2026-9-28 22:29 | 只看该作者
原理图:

加热台原理图.pdf (196.22 KB, 下载次数: 0)


回复

使用道具 举报

板凳
ID:1002055 发表于 2026-9-28 22:32 | 只看该作者

回复

使用道具 举报

地板
ID:1002055 发表于 2026-9-28 22:42 | 只看该作者

这是恒温180度。我用电烙铁测试的。


下面的是回流焊显示界面


下面是恒温显示界面


旋转编码器设置温度


回复

使用道具 举报

5#
ID:71535 发表于 2026-10-1 19:43 | 只看该作者
制作不易,调试温控时费不少劲,谢谢分享
回复

使用道具 举报

6#
ID:1002055 发表于 2026-10-7 22:56 | 只看该作者
经过修改增加了恒温模式下延时30分钟自动停止加热,和恒温模式下自动保存设置温度,下次开机默认上次的设置温度。
主函数:
#include "CONFIG.H"
/*------------
本程序根据嘉立创开源广场恒温加热台改编,利用 4位共阳数码管显示,具有恒温和回流焊两种功能,编码器控制加热开关,数码管前三位显示温度,
后一位显示恒温和回流标志,旋转编码器开关短按控制加热开/关,长按切换恒温和回流模式,在恒温模式下,
旋转编码器右转设置温度增加,左转设置温度减小.在回流模式下,双击控制回流状态切换,从预热温度-预热时间-回流
焊温度-回流焊时间之间切换,在各模式下旋转旋转编码器可以调整参数,调整完之后2秒自动转移到显示实际温度,短按开关键
开始加热,
------------*/

#define ENCODER_IDLE_TIME  40                //
#define MAX_RUN_SEC  (30*60)   //30分钟;工作限时,修改数字即可

//----------数码管应用变量-----------

sbit HEAT = P3^4;                //pwm控制引脚

u16 Seg_Slow_Down;                                //数码管减速变量
u8 Seg_Buf[4] = {10,10,10,10};        //显示缓冲数组
u8 Seg_Point[4] = {0,0,0,0};        //小数点显示数组
u8 Seg_Pos=0;                                        //数码管扫描变量

u8 Display_Timer=0;                                //编码器空闲计时,用于超时自动退出设置界面
/*------------显示界面状态枚举---------------*/
typedef enum
{
        SCR_REFLOW,
        SCR_CONSTCUR,
        SCR_SETTING
}SCR_MODE;

SCR_MODE ScrState;        //当前显示界面


bit last_mode_sw;    //记录上一次模式状态,检测切换

bit Systim_Mode = 0;        //系统模式,0 - 回流模式(按键长按切换加热模式),1- 恒温模式,
bit Systim_ON_OFF = 0;        //系统开关,0- 关机,1- 开机

u16 run_timer_sec;      //启动之后的累计秒计时
bit auto_shutdown_flag; //自动关机触发标记

//----------按键应用变量-----------
u8 Key_Val=0;                                //按键值
u8 Key_Slow_Down;                        //按键消抖

u8 Cnt_1ms = 0;
u8 Cnt_2ms = 0;
bit B_1msFlag=0;

u8 Cnt_200ms=0;                        //用于读取温度值
bit B_200msFlag=0;
u8 Cnt_50ms = 0;                        //50ms计时,用于旋转编码器扫描计时
bit B_50msFlag=0;
u8 Cnt_1s = 0;                        //计时1S用于回流焊时序计时                       
bit B_1sFlag=0;

u16 Cnt_500ms = 0;                //小数点闪烁计时
bit B_500msFlag=0;
bit Blink_Flag;                        //小数点闪烁标志
bit ThermFault;                        //热电偶故障标记

//==================== EEPROM ====================
#define         EE_ADDRESS                 0x0000        //EEPROM 地址变量
u8 idata tmp[10];                                        // 临时数组
bit B_Save;                                        //存储标志

//==================== 温度 ====================
int  temp_raw;
float NowTemp, SetTemp;
float Manual_SetTemp;                //恒温模式下手动设置温度变量
//==================== PID ====================
float err, last_err;
float integral;   //积分累加值
float Kp = 5.0f;
float Ki = 0.02f;
float Kd = 0.0f;
float PID_Out;
u16   heat_pwm;

//==================== 回流焊 ====================
u8  run_flag = 0;                //回流焊运行标志
u8  stage    = 0;                //回流曲线索引
u16 stage_time = 0;                //回流焊曲线计时

// 标准SMT回流焊曲线
code u8  temp_curve[3] = {80, 130, 220};
code u16 time_curve[3] = {90, 90, 40};

bit stage_wait_temp=0 ;         //回流焊等待温度达标标志

/*------------------------数码管显示函数----------------*/

void Display()        //数码管显示函数
{
        u16 t;
       
        if(Seg_Slow_Down)return;
                Seg_Slow_Down=1;
       
        if(ThermFault == 1)                //热电偶故障显示E0
    {
        //E的段码0x86
        Seg_Buf[0]=11;
        Seg_Buf[1]=11;
        Seg_Buf[2]=15;
        Seg_Buf[3]=0;
        return;
    }
    t = (u16)NowTemp;

        switch(ScrState)
        {
                case SCR_REFLOW:                                        //回流焊显示界面
                                       
                                Seg_Buf[0] = (t / 100) %10;
                                Seg_Buf[1] = (t / 10) %10;
                                Seg_Buf[2] = t %10;
                                Seg_Buf[3] = 13;
                                       
                break;
                case SCR_CONSTCUR:                                        //恒温加热显示界面
                       
                                Seg_Buf[0] = (t / 100) %10;
                                Seg_Buf[1] = (t / 10) %10;
                                Seg_Buf[2] = t %10;
                                Seg_Buf[3] = 14;
                                               
                break;
                case SCR_SETTING:                                        //恒温设置界面
                       
                                t = (u16)Manual_SetTemp;               
                                Seg_Buf[0] = (t / 100) %10;
                                Seg_Buf[1] = (t / 10) %10;
                                Seg_Buf[2] = t %10;
                                Seg_Buf[3] = 10;                                                       
                                               
                break;
                default:
                        ScrState = SCR_REFLOW;                        //开机显示回流焊界面
                break;
               
        }
       
        if(HEAT==1 && Blink_Flag==1)                //开始加热第三位数码管小数点闪烁
        {
               
                Seg_Point[2]=1;
        }
        else Seg_Point[2]=0;
        if(        Systim_ON_OFF)
        Seg_Point[3]=1;       
        else Seg_Point[3]=0;
}
/*------------------------按键处理函数----------------*/
void Key_Proc()
{
        if(Key_Slow_Down)return;                //用于按键消抖
                Key_Slow_Down=1;
       
                Key_Val = KEY_Read();        //读取按键值
                if(Key_Val==Single_KEY)                                        //短按切换,加热/关闭
                {
                        Systim_ON_OFF ^=1;
                       
                }               
                if(Key_Val==Long_KEY)        //长按开始切换加热模式,0- 回流焊,1- 恒温加热
                {
                        Systim_Mode ^= 1;
                       
                        if(Systim_Mode==0)
                        {
                                ScrState = SCR_REFLOW;                //回流焊界面
                        }
                        else
                        {
                                ScrState = SCR_CONSTCUR;        //恒温界面
                        }
                       
                }
                Key_Val=0;
}
/*------------------------函数声明----------------*/

void reflow(void);
void heat_ctrl(void);
void PID_Calc(void);

/*------------------------主函数----------------*/
void main()
{
        static u8 Last_Systim_ON_OFF = 0;        //记录上一次开关状态
       
       
        SystemInit();                //系统初始化
    Timer0_Init();      //定时器0初始化
        Rotary_Init();      //旋转编码器初始化
         KEY_Driver();      //按键驱动函数
       
       
    EA = 1;                                                                                       
       
        HEAT = 0;
    run_flag = 0;
    stage = 0;
    stage_time = 0;
        integral = 0;
        //上电读取EEPROM存储的数据
        EEPROM_Read_n(EE_ADDRESS,tmp,10);//EEPRON读数据 (u16 EE_Address,u8 *DataAddress,u16 Number)
       
        if((tmp[0]==~tmp[4])&&(tmp[1] == ~tmp[5])&&(tmp[2] == ~tmp[6])&&(tmp[3] == ~tmp[7]))//数据校验正确
        {
                Manual_SetTemp = ((float *)&tmp)[0];                                //读出上次设置的温度
                if(Manual_SetTemp < 40.0f)Manual_SetTemp = 150.0f;
                if(Manual_SetTemp > 400.0f)Manual_SetTemp = 150.0f;               
        }
        else Manual_SetTemp = 150.0f;
       
        Display();                //调用温度显示函数
       
        while(1)
        {                               
                Key_Proc();                //按键处理函数
               
                //检测开关是否打开
                if(Systim_ON_OFF==1&&Last_Systim_ON_OFF==0)                //加热开关打开
                {
                        run_flag = 1;
                       
                        ThermFault = 0;        //热电偶断线标志
            stage = 0;
            stage_time = 0;
                        integral = 0;   //启动清零积分,消除上次残留
                        stage_wait_temp = 1;
                        run_timer_sec = 0;    //【新增】启动时清零总运行计时
                        auto_shutdown_flag = 0;         //开关延时标志
                }
                else if(Systim_ON_OFF==0&&Last_Systim_ON_OFF==1)        //加热开关关闭
                {
                        run_flag = 0;
                        HEAT = 0;

                }
                Last_Systim_ON_OFF=Systim_ON_OFF;                //存储上一次的开关状态
               
                 //检测模式发生切换:立刻停机,清零积分防止冲温
        if(last_mode_sw != Systim_Mode)
        {
            Systim_ON_OFF = 0;
            run_flag = 0;
            HEAT =0;
            integral = 0;
            stage =0;
            stage_time=0;

        }
                last_mode_sw = Systim_Mode;                        //存储上一次的模式状态
               
                //温度设置
                if(Systim_Mode==1)                //恒温模式下,旋转编码器设置温度
                {
                        if(B_50msFlag==1)
                        {
                                B_50msFlag=0;
                                if(Rotary_Read_Data!=0)                                                        //旋转编码器控制
                                {
                                        if(ScrState != SCR_SETTING)
                                        {
                                                ScrState = SCR_SETTING;                //如果不是设置界面,转到设置界面
                                                Display_Timer=0;
                                        }
                                        else
                                        {                               
                                                Manual_SetTemp += (float)Rotary_Read_Data*5;
                                       
                                                if(Manual_SetTemp > 400.0f)        Manual_SetTemp = 400.0f;        //设置最高400度
                                                if(Manual_SetTemp < 40.0f)        Manual_SetTemp = 40.0f;                //最低40度
                                                B_Save = 1;                                        //请求保存
                                               
                                        }
                                        Rotary_Read_Data=0;
                                       
                                }
                                else
                                {                                       
                                        Display_Timer++;                                                //设置界面显示延时时间
                                        if(Display_Timer==ENCODER_IDLE_TIME)
                                        {
                                                Display_Timer=0;
                                                ScrState = SCR_CONSTCUR;
                                        }                               
                                }
                        }                                               
                }
                //保存设置温度
                if(B_Save)
                {
                        B_Save = 0;
                        ((float *)&tmp)[0] = Manual_SetTemp;
                        tmp[4] = ~tmp[0];
                        tmp[5] = ~tmp[1];
                        tmp[6] = ~tmp[2];
                        tmp[7] = ~tmp[3];
                        EEPROM_SectorErase(EE_ADDRESS);                //EEPROM擦除扇区
                        EEPROM_Write_n(EE_ADDRESS,tmp,10);        //写入数据
                }
               
                //读取温度
                if(B_200msFlag)
                {
                        B_200msFlag=0;
                        temp_raw = Read_MAX6675();
                        if(temp_raw == -1)
                        {
                                ThermFault = 1;
                                run_flag = 0;
                                HEAT = 0;
                        }
                        else
                        {
                                ThermFault = 0;
                                NowTemp = (float)temp_raw * 0.25f;
                        }

                }
               

                //超温锁死故障
        if(Systim_Mode==0)                //回流模式高温限制
                {
                        if(NowTemp >= 265.0f)
                        {
                                run_flag = 0;
                                HEAT = 0;
                        }
                }
               

                Display();
                PID_Calc();
                reflow();
               
        }
}


/*--------------PID----------------*/
void PID_Calc(void)
{
       
    err = SetTemp - NowTemp;

        if(fabs(err) < 100.0)
        {
                integral += err;
        }
    //积分限幅,抗积分饱和,非常重要!
    if(integral > 800)  integral = 800;
    if(integral < -800) integral = -800;

    PID_Out = Kp*err + Ki*integral + Kd*(err - last_err);

    last_err = err;

    if(PID_Out > 100.0f) PID_Out = 100.0f;
    if(PID_Out < 0.0f)   PID_Out = 0.0f;
    heat_pwm = (u16)PID_Out;
}
/*--------------PWM 加热控制----------------*/

void heat_ctrl(void)
{
    static u16 pwm_cnt = 0;
    pwm_cnt++;
    if(pwm_cnt >= 100)   
        pwm_cnt = 0;
                /* 限幅保护,防止溢出导致持续加热 */
                if(heat_pwm > 100) heat_pwm = 100;
               

    if(Systim_Mode==0)
        {
                if(run_flag && NowTemp < 265 && heat_pwm > pwm_cnt && (!ThermFault))
                        HEAT = 1;
                else
                        HEAT = 0;
        }
        else if(Systim_Mode==1)
        {
                if(run_flag && NowTemp < 400 && heat_pwm > pwm_cnt && (!ThermFault))
                        HEAT = 1;
                else
                        HEAT = 0;
        }
}
/*--------------回流焊----------------*/

void reflow(void)
{
    if(!run_flag) return;

        if(Systim_Mode==0)
        {
         //回流焊模式才跑阶段计时
                if(B_1sFlag)
                {
                        B_1sFlag = 0;
                       
                        if(stage_wait_temp==0)        //回流焊温度达标开始计时
                                {
                                        stage_time++;
                                }
                       
                }
                SetTemp = temp_curve[stage];
                if(stage_wait_temp==1)
                {
                        if(NowTemp>=temp_curve[stage])        //温度达标,清零标志位开始计时
                        {
                                stage_wait_temp = 0;
                                stage_time = 0;
                        }
                }
                                
                else if(stage_time >= time_curve[stage])
                        {
                                stage_time = 0;
                                stage_wait_temp=1;
                                stage++;
                                if(stage >= 3)
                                {
                                        run_flag = 0;
                                        stage = 0;
                                        stage_wait_temp = 0;                //回流焊等待温度达标标志
                                }
                        }
               
    }
    else if(Systim_Mode)
        {
                if(auto_shutdown_flag == 0)                //延时关机标志
                {
                        if(B_1sFlag)
                        {
                                B_1sFlag = 0;
                               
                                run_timer_sec++;       //累计运行秒数+1
                        }
                               
                }
                        // 判断总运行时间是否达到30分钟(1800s),强制停机
                                if(run_timer_sec >= MAX_RUN_SEC)
                                {
                                        auto_shutdown_flag = 1;
                                        run_flag = 0;          //停止回流焊流程
                                        Systim_ON_OFF = 0;    //系统运行标记清零
                                        HEAT = 0;              //关闭加热
                //            //可以选择打开风机冷却一会,复用cool_delay_run
                //            cool_delay_time =60;
                //            cool_delay_run =1;
                //            FAN =1;
                                }
               
               
                 //恒温模式:直接使用手动设定温度,不跑阶段时序
        SetTemp = Manual_SetTemp;
        return;
        }
       
}

/*--------------定时器0中断服务函数----------------*/

void Timer0_Isr(void) interrupt 1
{
       
                if(++Cnt_50ms==50)
                {
                        Cnt_50ms=0;
                        B_50msFlag=1;
                        if(++Cnt_200ms==4)
                        {
                                Cnt_200ms = 0;
                                B_200msFlag=1;
                                       
                        }
                        if(++Cnt_500ms==10)
                        {
                                Cnt_500ms=0;
                                B_500msFlag=1;
                                Blink_Flag ^= 1;
                                if(++Cnt_1s==2)
                                {
                                        Cnt_1s=0;
                                        B_1sFlag=1;
                                       
                                }
                        }
                }
       
       
        if(++Key_Slow_Down==10)Key_Slow_Down=0;                //按键消抖
       
        if(++Seg_Slow_Down==500)Seg_Slow_Down=0;
       
        if(++Cnt_2ms==2)                //数码管动态扫描
        {
                Cnt_2ms=0;
                if(++ Seg_Pos==4)Seg_Pos=0;                                       
                Seg_Display(Seg_Buf[Seg_Pos],Seg_Pos,Seg_Point[Seg_Pos]);
        }
       
        heat_ctrl();
        Rotary_Scan();
}

回流焊加热台-2.zip (369.48 KB, 下载次数: 0)

回复

使用道具 举报

7#
ID:1002055 发表于 2026-10-9 08:29 | 只看该作者
chj1966 发表于 2026-10-7 22:56
经过修改增加了恒温模式下延时30分钟自动停止加热,和恒温模式下自动保存设置温度,下次开机默认上次的设置 ...

操作说明,开机数码管显示回流焊实时温度,短按按键开始加热,数码管第三位小数点闪烁,代表加热,第四位数码管小数点长亮代表处于开机状态。长按按键切换到恒温加热模式,此时旋转编码器可以设置温度高低,短按按键开始加热,恒温模式下30分钟无操作停止加热。下次开机保持上次设置的温度。
回复

使用道具 举报

8#
ID:17340 发表于 2026-10-10 08:20 | 只看该作者
不错,学习AI8051很不错的资料。学习了
回复

使用道具 举报

9#
ID:1002055 发表于 2026-10-11 16:39 | 只看该作者

,


做的成品, 奔着废物利用的原则,用坏的热水壶的加热盘加热,嘉立创打的控制板,加热部分用废的电路板搭的电路,MOC3061加BT137控制220V 加热。温度控制基本能满足要求,回流焊温度控制不太好,温度过冲,PID 的参数还需要调整,调了很久还不太满意,后面还需要调整。

回复

使用道具 举报

10#
ID:1002055 发表于 2026-10-11 16:44 | 只看该作者
下面是控制板的打板文件,用嘉立创EDA 画的。
Gerber_PCB1_2026-10-11.zip (127.77 KB, 下载次数: 0)

回复

使用道具 举报

11#
无效楼层,该帖已经被删除
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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