数码之家

 找回密码
 立即注册
搜索
查看: 6534|回复: 19

[工仪] 旧瓶装新酒,彻底修复宜华8786D焊台

[复制链接]
发表于 2020-12-10 16:53:27 | 显示全部楼层 |阅读模式
我的宜华8786D焊台坏了!热风枪失控,温度飙升,加上电烙铁升温慢,大焊点费劲,一直放在吃灰,天天看着各位大侠组焊台,我也手痒,于是翻出彻底修复:根据手里的资源,保留原热风枪,换成T12的烙铁,3位LED换成4位,基本功能和操作保持不变,于是就成了这个样子:


Next

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

打赏

参与人数 2家元 +150 收起 理由
hshgc + 50 優秀文章
家睦 + 100

查看全部打赏

 楼主| 发表于 2020-12-10 17:00:14 | 显示全部楼层
把原来的主板全部换掉,重新设计电路和板子,主控用的STC15W408AS,用山寨的T12通用手柄。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-12-10 17:03:35 | 显示全部楼层
原来的变压器电压太高,空载能耗也大,为了绿色发展换成了旧的24v电源,3D打印了一个架子装上!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-12-10 17:09:24 | 显示全部楼层
最后感谢https://www.mydigit.cn/forum.php?mod=viewthread&tid=132209http://bbs.mydigit.cn/read.php?tid=999987&page=1以及http://bbs.mydigit.cn/read.php?tid=2005505的作者和给我帮助的坛友们,程序和图纸待我整理以后也一并附上。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-12-10 17:17:34 | 显示全部楼层
本帖最后由 guojizhou 于 2020-12-10 17:22 编辑

原理图和PCB是用立创EDA做的,不知道怎么共享上来请大侠们指点一下。我都是自学的单片机,自己业余时间玩一下,程序有很多不完美的地方,也请高手们指导。


下面是程序:::::

/**
2020年12月4日,还有两个警告因只是启动中用不管他
     上220v可以使用,风枪热惯性大,
        设置 烙铁 风机正常 休眠和字动关机正常时间待调整
2020.12.07        更改了风机速度控制的热风枪pid数值还没有测试

2020.12.08 风机速度控制由PWM控制改为10级控制,
           热风枪和烙铁pid数值还待优化



*/
#include <STC15.h>
#include <intrins.h>
#include <math.h>
//#include        "PCA.h"
//#include <eeprom.h>
//#include "config.h"

/**接口定义**/

sbit C_iron = P1 ^ 0;       //T12控制(C-iron)
sbit C_fan = P1 ^ 1;              //热风枪温度控制
sbit T_iron = P1 ^ 2;              //t12温度控制
sbit T_fan = P1 ^ 3;              //热风枪温度值
sbit T_air = P1 ^ 4;              //环境温度值
sbit V_fan = P1 ^ 5;              //风机控制电压值
sbit V_ref = P1 ^ 6;              //基准电压值
sbit V_dd = P1 ^ 7;              //电源电压

sbit DIO = P3 ^ 2;         // TM1650 数码管驱动的sdo引脚
sbit CLK = P3 ^ 3;         // TM1650 数码管驱动的scl引脚                                          

sbit S_fan  = P3^4;                   //风枪休眠开关
sbit S_iron  = P3^5;       //烙铁休眠开关
sbit select  = P3^6;                //功能选择1开启风枪
sbit R_fan  = P3^7 ;             //风量控制



sbit I_fan = P5 ^ 4;               //热风枪状态
sbit I_iron = P5^ 5;         //烙铁状态



/**共同变量**/

unsigned long VREF = 2488; // 用万用表测量基准电压的真实值,单位mv

unsigned long Air_voltage;
unsigned long system_voltage; // 计算单片机供电电压
unsigned long input_voltage;  // 计算整个板子的输入电压(12~24V)
unsigned long watch_voltage;  //监控电压
unsigned long stop_times=0;                  //停止时间



// PID控制算法
#define KP 1.2f       // 比例系数
#define KI 0.2f       // 积分系数
#define KD 0.1f       // 微分系数
#define MAX_UK 400.0f // 系统允许输出的最大控制量,这里表现为加热数,400个0.5ms加热周期,最长连续加热时间为200ms


int ek = 0, ek_1 = 0, ek_2 = 0; // 记录连续三次的偏差值(设定值-实际测量值)
float uk_1 = 0.0f, uk = 0.0f;   // 记录当前计算的PID调整值和上次计算的PID调整值
long integralSum = 0;           // 位置式PID算法的累计积分项



// 定义一个数码管段码表,0~F,c,消隐,G,u,o,r小数点再加“0x80”
unsigned char CODE[] =
  {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, 0x77, 0X7C, 0X39, 0X5E, 0X79, 0X71, 0x61,  0x58,  0x00,0x3D,0X1C,0X5C,0x50};
//  0,   1,         2,    3,         4,           5,     6,        7,          8,        9,     A,    B,          C,    D,          E,    F, 上c(17),下c(18) 19         20G          u          o           r



//环境温度
unsigned int NTC_R;//定义热敏电阻阻值变量
unsigned char AirTemperature;//定义温度存储变量




bit set = 0;           // 设置键值
bit up = 0;            // 上键值
bit down = 0;          // 下键值
bit write_flag;                   //写EEPROM标志
bit g;
bit sleep_flag=0;           //休眠标志
bit off_flag=0;           //guanj标志

bit k;                                //休眠交换标志


/**t12变量组*****/

unsigned long  t12_voltage;    // 计算t12热电偶电压


unsigned int  t12SetTemperature;   // 当前设定的温度
unsigned int  t12sleepTemperature ;   // 休眠记录当前设定的温度
unsigned char t12SetTemperatureH ;                //         高8位
unsigned char t12SetTemperatureL  ;                 //         低8位


unsigned int  t12ActualTemperature = 0; // 保存T12当前的实际温度
unsigned int  setTempShowTime = 0;      // 记录显示设置温度的时长
unsigned int  need_heat_times = 0;       // 需要加热的时长
unsigned int  heat_times_count = 0;      //当前已经加热的时长

unsigned int  a;      

unsigned int  leijiwencha;      //当前已经加热的时长




/***热风枪变量组***/

unsigned int  FanSetTemperature ;   // 当前设定的温度
unsigned char FanSetTemperatureH ;                //         高8位
unsigned char FanSetTemperatureL ;                 //         低8位


unsigned long  Fan_voltage;                // 热风枪热电偶电压
unsigned int  FanActualTemperature = 0;    // 热风枪当前的实际温度
unsigned int  FansetTempShowTime = 0;      // 记录显示设置温度的时长
unsigned int  Fanneed_heat_times = 0;      // 需要加热的时长
unsigned int  Fanheat_times_count = 0;     //当前已经加热的时长


unsigned int  fanstop_times =0;   //风机延时计时
unsigned int  fan_times_count;          //风机转动时长
unsigned int  FanSpeed = 250;     //风速
unsigned long  V_Fanspeed;        // 热风风速电压







// 初始化各个IO口
void initIO()
{
  // 配置各个端口的输入模式,M1M0:00普通,01推挽,10高阻输入,11开漏
  /*
        以下列出需要配置的端口,其他端口保持默认即可
        t12 = P3^7;             //T12控制  推挽输出模式
        ADC3:系统输入电压检测 P1^3 输入模式
        ADC4:T12热电偶电压检测 P1^4 输入模式
        ADC5:2.5V参考电压输入 P1^5 输入模式
               
                */


  P1M0 |= 0x03; //0000 0011                 //1.0,1.1推挽,1.2,1.3,1.4,1.5,1.6,1.7对应ADC2,3,4,5,6,7。
  P1M1 |= 0xfc; //1111 1100

  P3M0 = 0x80; //1000 0000                 //3.7 推挽对风机
  P3M1 = 0x00; //0000 0000

  P5M0 = 0x30; //0011 0000                //5.4,5.5推挽
  P5M1 = 0x00; //0000 0000


}



/****定时器0初始化****/

void Timer0Init(void)                //1毫秒@11.0592MHz
{
        AUXR |= 0x80;                //定时器时钟1T模式
        TMOD &= 0xF0;                //设置定时器模式
        TL0 = 0xCD;                //设置定时初值
        TH0 = 0xD4;                //设置定时初值
        TF0 = 0;                //清除TF0标志
        TR0 = 1;                //定时器0开始计时
}





/*延时函数,使用STC-ISP自动生成的,比较准确*/
void Delay_ms(unsigned int k) //@12.000MHz
{
  unsigned char i, j;
  for (; k > 0; k--)
  {
    i = 12;
    j = 169;
    do
    {
      while (--j)
        ;
    } while (--i);
  }
}

void Delay_us(unsigned int i)
{
  for (; i > 0; i--)
  {
    _nop_();
    _nop_();
    _nop_();
    _nop_();
  }
}



/*初始化ADC*/
void initADC(void)
{
  /*
        开启相应ADC口的模拟输入功能(相应位置1)
        ADC2:烙铁温度P1.2
                ADC3:风枪温度 P1^3
        ADC4:环境温度 P1^4
        ADC5:风机控制电压 P1^5
               ADC6:2.5V参考电压输入 p1.6
                ADC7:1/11的电源电压输入p1.7
           
            */
  P1ASF = 0xfc; //1111 1100
  ADC_RES = 0;  // 清楚结果寄存器
  ADC_RESL = 0;
  /*
    ADC控制寄存器
    ADC_POWER | SPEED1 | SPEED0 | ADC_FLAG | ADC_START | CHS2 | CHS1 | CHS0
        */
  // 这里初始化的时候,可以先打开电源和设置转换速度
  ADC_CONTR = 0x80; // 1000 0000

  Delay_ms(5);      // 上电之后延时等待一段时间
}




// 直接插入排序
void insertionSort(unsigned int A[], unsigned int n)
{
  unsigned int i, j;
  for (i = 1; i < n; i++)
  {
    for (j = i; j > 0; j--)
    {
      if (A[j] < A[j - 1])
      {
        // 不使用第三变量交换两个数,使用异或运算速度快
        A[j - 1] ^= A[j];
        A[j] ^= A[j - 1];
        A[j - 1] ^= A[j];
      }
    }
  }
}

#define ADC_FLAG 0x10  // ADC转换完成标志
#define ADC_START 0x08 // ADC开始置位


// 获取某个ADC通道的转换值
// 为了提高结果的准确性,每次测量,测5次,并且去掉一个最高值,一个最低值,最后取中间3个的均值返回
unsigned int getADCResult(unsigned int channel)
{
  unsigned int res[5], i, result = 0;
  for (i = 0; i < 5; i++)
  {

        //ADC控制寄存器 ADC_POWER | SPEED1 | SPEED0 | ADC_FLAG | ADC_START | CHS2 | CHS1 | CHS0

    ADC_CONTR = (0x80 | channel | ADC_START); // 选择需要读取的通道,并开启转换
    Delay_us(1);
    while (!(ADC_CONTR & ADC_FLAG))
      ;                                            //等待ADC转换完成
    res = ((ADC_RES << 2) | (ADC_RESL & 0x03)); // 计算转换出来的原始结果
    ADC_RES = 0x00;
    ADC_RESL = 0x00; // 清零结果寄存器
  }
  // 对结果进行排序
  insertionSort(res, 5);
  // 去掉一个最高值,去掉一个最低值,剩余三个求平均值
  result = (res[1] + res[2] + res[3]) / 3;
  return result;
}



/***** 电源电压监控*********/
  void        watchVoltage(void)
{
   unsigned int res;

        //ADC控制寄存器 ADC_POWER | SPEED1 | SPEED0 | ADC_FLAG | ADC_START | CHS2 | CHS1 | CHS0

    ADC_CONTR = (0x80 | 7 | ADC_START); // 选择需要读取的通道,并开启转换
    Delay_us(1);
    while (!(ADC_CONTR & ADC_FLAG))
      ;                                            //等待ADC转换完成
    res = ((ADC_RES << 2) | (ADC_RESL & 0x03)); // 计算转换出来的原始结果
    ADC_RES = 0x00;
    ADC_RESL = 0x00; // 清零结果寄存器

  watch_voltage=(res/2)*120;//简单计算电源电压,并乘分压比,获得实际的输入电压 p1.7单位mV
  }




/***** 风机调节电压*********/
  void        FenVoltage(void)
{
   unsigned int res;

        //ADC控制寄存器 ADC_POWER | SPEED1 | SPEED0 | ADC_FLAG | ADC_START | CHS2 | CHS1 | CHS0

    ADC_CONTR = (0x80 | 5 | ADC_START); // 选择需要读取的通道,并开启转换
    Delay_us(1);
    while (!(ADC_CONTR & ADC_FLAG))
      ;                                            //等待ADC转换完成
    res = ((ADC_RES << 2) | (ADC_RESL & 0x03)); // 计算转换出来的原始结果
    ADC_RES = 0x00;
    ADC_RESL = 0x00; // 清零结果寄存器

  V_Fanspeed=(res/2)*120;//简单计算将V_Fanspeed控制在0-9以内
  }





/*以下是计算各种电压的函数,返回结果的单位都是mv*/
// 计算公式(mv) output_voltage = (VREF万用表测的TL431基准电压值(mv) * 待测通道的ADC值 / TL431基准通道ADC值p1.6)
// 计算获取T12的电压



// 计算获取输入电源电压Vdd
void getInputVoltage(void)
{
input_voltage = (VREF * getADCResult(7) / getADCResult(6) * 11); // 计算下分压电阻点的电压,并乘分压比,获得实际的输入电压 p1.7

system_voltage = (VREF * 1024 / getADCResult(6)); //计算单片机的电源电压,单位mV;

}

// 获取计算环境温度AirTemperature 电压换算成温度
void getAirTemperature(void)
{


    //计算法
   float Rt=0;
   float Rp=10000;
   float T2=273.15f+25;
   float Bx=3950;
   float Ka=273.15f;
   float Air_voltage=0;
   Air_voltage= (VREF * getADCResult(4) / getADCResult(6)); //,单位mV p1.4
   Rt=Air_voltage*10010/(VREF-Air_voltage);                           //10k实测10.01k
   AirTemperature=1/(1/T2+log(Rt/Rp)/Bx)-Ka+0.5f;

        
}


/* 计算热风枪热电偶温度 */
void getFanTemperature(void)
{
  float x = 0.0f;

//  Delay_us(10);    // 等待一段时间,等电容放完电后再测量温度比较准确
   Fan_voltage = (VREF * getADCResult(3) / getADCResult(6)); //计算获取热风枪热电偶的电压,单位mV
  // getFanVoltage(); // 更新热电偶电压
                   //T实际温度 = (ADC电压(mV)-失调电压(mV))/运放增益*热电偶分度值(℃/mV)+室温(℃)
                 //FanActualTemperature = 1.0f*Fan_voltage/ 470.0f*54.0f + 23.0f;


        FanActualTemperature = (1.0f*Fan_voltage-26)/ 580.0f*54.0f + AirTemperature;                //参考T12


   }




/* 计算T12热电偶温度 */
void getT12Temperature(void)
{
  float x = 0.0f;
  C_iron = 0;         //测温的时候,关闭电烙铁
//  Delay_us(10);    // 等待一段时间,等电容放完电后再测量温度比较准确

  t12_voltage = (VREF * getADCResult(2) / getADCResult(6)); //计算t12电压,单位mV

    //T12实际温度 = (ADC电压(mV)-失调电压(mV))/运放增益*热电偶分度值(℃/mV)+室温(℃)
    //t12ActualTemperature = 1.0f*getT12Voltage() / 470.0f*54.0f + 23.0f;
   t12ActualTemperature =( 1.0f*t12_voltage-26)/ 580.0f*54.0f + AirTemperature;          //实测温度修订运放增益



  }













/********************************以下是TM1650数码管显示相关的函数****************************************************/

void Start1650(void)
{ //开始信号
  CLK = 1;
  DIO = 1;
  Delay_us(5);
  DIO = 0;
  Delay_us(5);
  DIO = 0;
}

void Ask1650(void)
{ //ACK信号
  unsigned char timeout = 1;
  CLK = 1;
  Delay_us(5);
  CLK = 0;
  while ((DIO) && (timeout <= 100))
  {
    timeout++;
  }
  Delay_us(5);
  CLK = 0;
}

void Stop1650(void)
{ //停止信号
  CLK = 1;
  DIO = 0;
  Delay_us(5);
  DIO = 1;
  Delay_us(5);
}

void WrByte1650(unsigned char oneByte)
{ //写一个字节,高位在前,低位在后
  unsigned char i;
  CLK = 0;
  Delay_us(1);
  for (i = 0; i < 8; i++)
  {
    oneByte = oneByte << 1;
    DIO = CY;
    CLK = 0;
    Delay_us(5);
    CLK = 1;
    Delay_us(5);
    CLK = 0;
  }
}

//unsigned char Scan_Key(void)

void Scan_Key(void)


{ // 按键扫描
  unsigned char i;
  unsigned char rekey;
  Start1650();
  WrByte1650(0x49); //读按键命令
  Ask1650();
  //DIO = 1;
  for (i = 0; i < 8; i++)
  {
    CLK = 1;
    rekey = rekey << 1;
    if (DIO)
    {
      rekey++;
    }
    Delay_us(5);
    CLK = 0;
  }
  Ask1650();
  Stop1650();

        if(rekey==0x57)set=1; else set=0;                 //判断set键按下
          if(rekey==0x47)up=1;  else up=0;                 //判断up键按下
        if(rekey==0x4f)down=1; else down=0;                 //判断down键按下



// return (rekey);
}


void Set1650(unsigned char add, unsigned char dat)
{ //数码管显示
  //写显存必须从高地址开始写
  Start1650();
  WrByte1650(add); //第一个显存地址
  Ask1650();
  WrByte1650(dat);
  Ask1650();
  Stop1650();
}

// 初始化1650,传入亮度参数,范围0~7
void init1650(unsigned char light)
{
  Set1650(0x48, ((light << 4) | 0x41));//亮度5,8段模式
}

// 数码管显示函数
void display(signed int num,unsigned char pos)
{

  // 计算这个数字对应的千百十个位的数字
  unsigned int tmpnum, qian, bai, shi, ge;
  if (num < 0)
    num = -num;
  tmpnum = num;
  qian = tmpnum / 1000;
  tmpnum %= 1000;
  bai = tmpnum / 100;
  tmpnum %= 100;
  shi = tmpnum / 10;
  ge = tmpnum % 10;

  if(pos==0)ge=17;          //pos=0显示℃

  if(pos==5){ge=18,shi=18,bai=18,qian=18;} //关闭显示

  if(pos==6){ge=18,shi=21,bai=20,qian=19;} //显示Guo

  if(pos==7){ge=22,shi=22,bai=14,qian=18;} //显示Err

  if(pos==8){ge=20;}      //00.0u位小数点显示u

  if(pos==9){ge=20;} //0.00u位小数点显示u


  //pos值对应位置小数点,




  if(pos==4)Set1650(0x68, CODE[qian]+0x80);else Set1650(0x68, CODE[qian]);
  if(pos==3)Set1650(0x6A, CODE[bai]+0x80);else  Set1650(0x6A, CODE[bai]);
  if(pos==2)Set1650(0x6C, CODE[shi]+0x80);else Set1650(0x6C, CODE[shi]);
  if(pos==1)Set1650(0x6E, CODE[ge]+0x80);else Set1650(0x6E, CODE[ge]);



}



/************控制有关函数******************/

/*热风枪加热控制*/
void ControlFanTemperature(void)


{Fanheat_times_count++;                            //当前已经加热的时长计数
  if(Fanneed_heat_times >198) Fanneed_heat_times = 0;       // 需要加热的时长最多加热198ms

if((Fanheat_times_count<=Fanneed_heat_times )&&(!S_fan==0))//如果当前计数小于等于加热数并且手柄不在做模式,就加热
   C_fan=1;
else
   C_fan=0;

if(FanActualTemperature==400)//如果热风温度为400,说明有问题
  C_fan=0;//停止加热



if(Fanheat_times_count==150)//原最多加热到198ms
   C_fan=0;//停止加热

if(Fanheat_times_count==200)//t12停止加热后2ms再检测温度(给电容留出放电时间,防止检测的温度偏高)
  {

   getFanTemperature();//检测电压,计算温度


   display(FanActualTemperature*10,0);//200ms显示一次


   Fanheat_times_count=0;//重新开始加热周期计数



   a=FanSetTemperature+1;//////////////////////////以下为加热算法(请自行理解,不作注释)//////////////////////
   if(FanActualTemperature>a)
    {
     leijiwencha=0;
     if(FanActualTemperature-a<=3)
      Fanneed_heat_times =(FanActualTemperature-a)*10/4+a/1000;
     else
      Fanneed_heat_times =0;
    }
   if(FanActualTemperature<=a)
    {
     leijiwencha=a-t12ActualTemperature;
     if(FanActualTemperature==a)
      leijiwencha=0;
     if(a-FanActualTemperature>=30)
      Fanneed_heat_times =50;                                                         //原来198
     else if(a-FanActualTemperature>=20)
      Fanneed_heat_times =40;                                                         //原来160
     else if(a-FanActualTemperature>=15)
      Fanneed_heat_times =30;                                                         //原来130
     else if(a-FanActualTemperature==10)
      Fanneed_heat_times =10+leijiwencha;                                 //原来90+
     else if(a-FanActualTemperature>=5)
      Fanneed_heat_times =5;                                                          //原来40
     else
//    Fanneed_heat_times =(a-FanActualTemperature)*10/2+FanSetTemperature/500+leijiwencha*10;

             Fanneed_heat_times =(a-FanActualTemperature)*10/2+FanSetTemperature/500+leijiwencha*5;

    }
   }
         
         }
        

  /***风量控制调节P3.7,***/

  void SetFanSpeed(void)

  {

  FenVoltage();

  fan_times_count++;                            //当前运转时长

  if(fan_times_count>=V_Fanspeed)R_fan= 1; else R_fan=0;      // 需要运转时长

  if(fan_times_count ==10)fan_times_count =0;                            //风速分10级


   if(S_fan)fanstop_times=0;

  if(fanstop_times>=1800)R_fan=0;             //热风枪放回手柄5秒停风,拿起恢复



           

  }






/******烙铁控制************/


void controlt12(void)



{heat_times_count++;                            //当前已经加热的时长计数
  if(need_heat_times >198) need_heat_times = 0;       // 需要加热的时长最多加热198ms

if((heat_times_count<=need_heat_times )&&(off_flag==0))//如果当前计数小于等于加热数并且不是关机模式,就加热
  C_iron=1;
else
  C_iron=0;

if(t12ActualTemperature==450)//如果t12温度为450,说明没有插入烙铁头或参数严重错误
C_iron=0;//停止加热



if(heat_times_count==198)//最多加热到198ms
  C_iron=0;//停止加热

if(heat_times_count==200)//t12停止加热后2ms再检测温度(给电容留出放电时间,防止检测的温度偏高)
  {

   getT12Temperature();//检测电压,计算温度


   if(t12ActualTemperature<420)display(t12ActualTemperature*10,0);else display(0,7);         //  超过420°报err


   heat_times_count=0;//重新开始加热周期计数



   a=t12SetTemperature+1;//////////////////////////以下为加热算法(请自行理解,不作注释)//////////////////////
   if(t12ActualTemperature>a)
    {
     leijiwencha=0;
     if(t12ActualTemperature-a<=3)
      need_heat_times =(t12ActualTemperature-a)*10/4+a/1000;
     else
      need_heat_times =0;
    }
   if(t12ActualTemperature<=a)
    {
     leijiwencha=a-t12ActualTemperature;
     if(t12ActualTemperature==a)
      leijiwencha=0;
     if(a-t12ActualTemperature>=30)
      need_heat_times =198;
     else if(a-t12ActualTemperature>=20)
      need_heat_times =160;
     else if(a-t12ActualTemperature>=15)
      need_heat_times =130;
     else if(a-t12ActualTemperature==10)
      need_heat_times =90+leijiwencha;
     else if(a-t12ActualTemperature>=5)
      need_heat_times =50;                                                                  // 原值50
     else
      need_heat_times =(a-t12ActualTemperature)*10/2+t12SetTemperature/500+leijiwencha*10;
    }
   }
         
         }
        






/**************************EEPROM关闭IAP*********************************/
void IAPoff(void)//关闭IAP
{
IAP_CONTR = 0;//关闭IAP 功能
IAP_CMD = 0;//清空命令寄存器
IAP_TRIG = 0;//清空命令触发寄存器
IAP_ADDRH = 0;//清空地址高位
IAP_ADDRL = 0;//清空地址低位
_nop_();//延时

}


/**************************字节读函数***************************************/
unsigned char Byte_Read(unsigned int add)
{
IAP_CONTR = 0x81;//打开IAP,设置操作等待时间
IAP_CMD = 0x01;//字节读命令
IAP_ADDRH = add>>8;//设置高8位地址
IAP_ADDRL = add&0x00ff;//设置低8位地址
IAP_TRIG = 0x5a;//发送5ah到触发寄存器
IAP_TRIG = 0xa5;//发送a5h到触发寄存器
_nop_();  
IAPoff();
return (IAP_DATA);//返回读到的数据
}


/*****************************字节编程函数*****************************/
void Byte_Program(unsigned int add, unsigned char dat)
{

IAP_CONTR = 0x81;//打开IAP,设置操作等待时间
IAP_CMD = 0x02;//字节编程命令
IAP_ADDRH = add>>8;//设置高8位地址
IAP_ADDRL = add&0x00ff;//设置低8位地址
IAP_DATA = dat;//要编程的数据先送进IAP_DATA 寄存器
IAP_TRIG = 0x5a;//发送5ah到触发寄存器
IAP_TRIG = 0xa5;//发送a5h到触发寄存器
_nop_();                        //等待ISP/IAP/EEPROM操作完成

IAPoff();

}

/*****************************扇区擦除函数****************************/
void Sector_Erase(unsigned int add)
{
IAP_CONTR = 0x81;//打开IAP,设置操作等待时间
IAP_CMD = 0x03;//扇区擦除命令
IAP_ADDRH = add>>8;//设置高8位地址
IAP_ADDRL = add&0x00ff;//设置低8位地址
IAP_TRIG = 0x5a;//发送5ah到触发寄存器
IAP_TRIG = 0xa5;//发送a5h到触发寄存器
_nop_();
IAPoff();
}



/******************************EEPROM存储函数***************************************/
void eeprom(void)//用于关机时存储温度数据,以便下次开机时恢复温度
{


    t12SetTemperatureH=t12SetTemperature>>8;           //分成高低8位
    t12SetTemperatureL=t12SetTemperature;

           FanSetTemperatureH=FanSetTemperature>>8;
    FanSetTemperatureL=FanSetTemperature;




   Sector_Erase(0x0000);//擦除扇区


   Byte_Program(0x0000,t12SetTemperatureH);//写入温度高八位到EEPROM
   Byte_Program(0x0001,t12SetTemperatureL);//写入温度低八位到EEPROM

   Byte_Program(0x0002,FanSetTemperatureH);//写入温度高八位到EEPROM
   Byte_Program(0x0003,FanSetTemperatureL);//写入温度低八位到EEPROM

   Delay_ms(10);
  }

/**********读取关机数据**************/

  void readeeprom(void)
{
t12SetTemperatureH=Byte_Read(0x0000);//读取上次关机时保存的设定温度的高八位
t12SetTemperatureL=Byte_Read(0x0001);//读取上次关机时保存的设定温度的低八位
t12SetTemperature=t12SetTemperatureH<<8|t12SetTemperatureL;//计算十进制的设定温度


FanSetTemperatureH=Byte_Read(0x0002);//读取上次关机时保存的设定温度的高八位
FanSetTemperatureL=Byte_Read(0x0003);//读取上次关机时保存的设定温度的低八位
FanSetTemperature=FanSetTemperatureH<<8|FanSetTemperatureL;//计算十进制的设定温度

}




/******************************震动休眠函数********************************/
void ironsleep(void)
{



   if(k==0)
  {

  t12sleepTemperature=t12SetTemperature;                // 休眠设定温度保存

  t12SetTemperature=150;

   k=1;}                                                 //设定休眠温度


//if(S_iron)

if((S_iron!=g)||up||down||set||S_fan)   //震动或开关状态改变,说明晃动了手柄
  {           I_iron=1;

         
         if(k==1)
         
         t12SetTemperature=t12sleepTemperature;
        
          stop_times=0;                     //停止休眠计时        
         

        k=0;    }

        
  g=S_iron;//保存当前震动传感器状态(用于和下一次比较,以便确定是否震动了)
}



/*********自动关机*********/
void ironoff (void)
{

bit off_flag=0;


if(k==1) t12SetTemperature=t12sleepTemperature;        //恢复休眠前设置温度并存入


eeprom();


off_flag=1;


while(off_flag)
{
C_iron=0;                                  //全关
C_fan=0;
R_fan=0;

display(0,5);       // 数码管关闭
Scan_Key();                          //扫描按键

I_iron=1;
Delay_ms(50);
I_iron=0;
Delay_ms(500);
I_fan=1;
Delay_ms(50);
I_fan=0;
Delay_ms(500);

if(set){off_flag=0;stop_times=0;break;}


}

  }


/******************************掉电存储函数***************************************/
void shutdownEEPROM(void)//用于关机时存储温度数据,以便下次开机时恢复温度

{ EA=0;ET0=0;

if(k==1)t12SetTemperature=t12sleepTemperature;        //恢复休眠前设置温度并存入

    display(0,5); // 数码管关闭
  I_iron =0;I_fan =0;C_iron=0;C_fan=0;         //显示和关烙铁节约电量


   eeprom();

  }









/**********烙铁设置函数*************/


   void t12Set(void)
  {bit setflag=0;

                    C_iron =0;         //防止设置时失控



     display(t12SetTemperature*10,0);                    //显示设置温度


                    
                    if(up){t12SetTemperature ++;setflag=1;}                            //设置温度+1
        
                    if(down){t12SetTemperature --;setflag=1;}                        //设置温度-1

        

           I_iron =1;                                  //LED闪烁

        Delay_ms(50);

        I_iron =0;        

        Delay_ms(50);






        
        if (t12SetTemperature > 450)
     t12SetTemperature = 450;





        
        if (t12SetTemperature < 200)
      t12SetTemperature = 200;
        

        
        if(setflag==0) Delay_ms(500);


        
         }



/**********热风枪温度设置函数********** ***/
  void FanTempSet(void)
    {

            
   bit setflag=0;

         C_fan =0;         //防止设置时失控


         display(FanSetTemperature*10,0);

        if(up){FanSetTemperature ++;setflag=1;}                           //设置温度增加

        if(down){FanSetTemperature --;setflag=1;}                   //设置温度-1


        I_iron =0;                  
    I_fan =1;                             //LED闪烁

        Delay_ms(50);

        I_fan =0;

        Delay_ms(50);





        
        if (FanSetTemperature > 400)
     FanSetTemperature = 400;


           


    if (FanSetTemperature < 100)
      FanSetTemperature = 100;
        


    if(setflag==0) Delay_ms(500);


   }


    void FactionSet (void)           //状态显示
  {

   I_iron =1;I_fan =1;

   C_iron =0;C_fan =0;


   eeprom();                  //储存设定值


  display(AirTemperature*10,0);           //显示环境温度
  Delay_ms(1000);
  display(input_voltage / 10,3); // 最大输入电压24000mv,00.00 只有4位数码管
  Delay_ms(1000);
  display(system_voltage,4); // 显示单片机电源电压 0.000
  Delay_ms(1000);

I_iron =0;I_fan =1;
  display(V_Fanspeed,1);
  Delay_ms(1000);

  display(t12SetTemperature*10,0);                 //显示烙铁设定温度
   Delay_ms(1000);


  display( FanSetTemperature*10,0);                 //显示烙铁设定温度
   Delay_ms(1000);

  }








  //定时0中断函数,每隔1ms执行一次
void timer0(void) interrupt 1
{

   fanstop_times++;                                        //风机延时计时

   stop_times++;                                        //休眠计时




   if(stop_times>100000){ironsleep();sleep_flag=1;}else  sleep_flag=0;                //实测200s超过s休眠

   if(stop_times>300000)ironoff ();                                                                //超过600秒关机

   if(stop_times>=600000)stop_times=600000;                                        //防止溢出




watchVoltage();

if(watch_voltage<20000){shutdownEEPROM();C_iron=0;}           //如果电源电压降低到20V说明掉电了关机存数



  Scan_Key();


   SetFanSpeed();          //风机延时

   if(set)FactionSet();          //显示状态

   if(up||down)

{


  if(select)                                         //状态        选择 1是热风枪

  FanTempSet();  else t12Set();

   }else {

   if(select)                                         //状态        选择 1是热风枪
  {

  I_iron =0;I_fan =1; C_iron=0;


  ControlFanTemperature();

  }else

{


I_fan =0; C_fan =0;

  if(sleep_flag==1)        I_iron=0; else  I_iron=1; //休眠led关

controlt12();         

}

}

}



void main(void)
{

/**初始化**/

  initIO(); // 初始化IO口

  init1650(1); // 初始化TM1650显示

  initADC();   // 初始化ADC

  write_flag=1;         //上电标志

  t12SetTemperature=250;

  FanSetTemperature=125;

         readeeprom();

           SetFanSpeed();


  C_iron =0;                        //烙铁关
  C_fan =0;                  //热风枪关




    I_iron =1;                   //LED测试
    I_fan =1;
    display(0,6);      //显示GUO
    Delay_ms(1000);






/*显示初始值**/
  getInputVoltage();  //检测系统电压

  watchVoltage();          //检测输入电压

  getAirTemperature();         //检测环境温度



  I_iron =0;I_fan =0;
display(input_voltage / 10,3);      // 最大输入电压24000mv, 00.00只有4位数码管
  Delay_ms(1000);
display(system_voltage,4);         // 显示单片机电源电压 0.000
  Delay_ms(1000);
display(AirTemperature*10,0);           //显示环境温度
  Delay_ms(1000);

   I_iron =0;I_fan =1;
  display(FanSetTemperature*10,0);                //显示热风枪设定温度
   Delay_ms(1000);
  display(V_Fanspeed,1);
    Delay_ms(1000);

  I_iron =1;I_fan =0;
  display(t12SetTemperature*10,0);                 //显示烙铁设定温度
   Delay_ms(1000);


  Timer0Init(); // 初始化定时器0

  EA=1;
  ET0=1;


/*主循环*/
  while(1)

{         

}

}
        


         

                           

回复 支持 2 反对 0

使用道具 举报

发表于 2020-12-10 18:19:56 | 显示全部楼层
guojizhou 发表于 2020-12-10 17:17
原理图和PCB是用立创EDA做的,不知道怎么共享上来请大侠们指点一下。我都是自学的单片机,自己业余时间玩一 ...

看到会开源编程的高手都要膜拜中。
回复 支持 1 反对 0

使用道具 举报

发表于 2020-12-10 20:31:34 | 显示全部楼层
建议换掉风枪,外壳都熔化了,换成852之类的更好,可以上bga风枪嘴,原装两点卡式风枪嘴选择太少。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-12-10 22:36:23 | 显示全部楼层
憨豆先生 发表于 2020-12-10 20:31
建议换掉风枪,外壳都熔化了,换成852之类的更好,可以上bga风枪嘴,原装两点卡式风枪嘴选择太少。 ...

852是什么鬼?搞个照片看看!:lol:
回复 支持 反对

使用道具 举报

发表于 2020-12-11 08:36:11 | 显示全部楼层
谢谢分享,干得漂亮!:praise:
回复 支持 反对

使用道具 举报

发表于 2020-12-11 09:26:13 | 显示全部楼层
不错,这个很实用。立创eda里有选择导出eda源码
回复 支持 反对

使用道具 举报

发表于 2020-12-11 22:10:49 | 显示全部楼层
guojizhou 发表于 2020-12-10 22:36
852是什么鬼?搞个照片看看!

传照片麻烦,你在某宝搜索“赛克852D”就有了
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-12-11 22:19:39 | 显示全部楼层
把原理图和PBC图付上!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-12-11 22:22:56 | 显示全部楼层
憨豆先生 发表于 2020-12-11 22:10
传照片麻烦,你在某宝搜索“赛克852D”就有了

找到了!要7-80元好贵!
回复 支持 反对

使用道具 举报

发表于 2020-12-12 18:33:27 | 显示全部楼层
推荐用245,比T12还要好不少,
回复 支持 反对

使用道具 举报

发表于 2020-12-12 19:46:15 | 显示全部楼层
guojizhou 发表于 2020-12-11 22:22
找到了!要7-80元好贵!

它的风枪嘴可以做bga,而且机器本身可选配风枪夹。当然你不做bga就用不上。对于做bga的人会很有用。
回复 支持 反对

使用道具 举报

发表于 2023-2-15 10:39:21 | 显示全部楼层
楼主,没家元,能不能分享下pdf?
回复 支持 1 反对 0

使用道具 举报

发表于 2023-2-15 19:28:14 来自手机浏览器 | 显示全部楼层
大佬可以分享一下原代码和hex文件吗
回复 支持 1 反对 0

使用道具 举报

发表于 2023-6-20 22:51:45 | 显示全部楼层
本帖最后由 Destiny.. 于 2023-6-22 18:16 编辑

电位器是几K的,绿色线是什么信号线?
回复 支持 反对

使用道具 举报

发表于 2023-10-26 22:41:23 来自手机浏览器 | 显示全部楼层
我的天大工程
回复 支持 反对

使用道具 举报

发表于 昨天 20:28 | 显示全部楼层
风枪电热丝看不出电源怎么接
回复 支持 反对

使用道具 举报

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

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2024-4-25 20:21 , Processed in 0.218400 second(s), 12 queries , Redis On.

Powered by Discuz!

© 2006-2023 smzj.net

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