手电大家谈-手电筒爱好者之家

 找回密码
 注册成为会员,享受更多功能。

QQ登录

只需一步,快速开始

只需一步,快速开始

搜索
查看: 3273|回复: 17

[其他DIY] 做微波炉变压器点焊机,程序设计

[复制链接]
  • TA的每日心情
    奋斗
    2024-5-21 00:23
  • 签到天数: 1882 天

    [LV.Master]伴坛终老

    发表于 2020-3-1 15:32 | 显示全部楼层 |阅读模式

    马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

    您需要 登录 才可以下载或查看,没有账号?注册成为会员,享受更多功能。

    x
    本帖最后由 xyz123123 于 2020-3-5 18:48 编辑

    http://www.shoudian.org/forum.php?mod=viewthread&tid=1505742 做微波炉变压器点焊机,先做控制板》
    接下来是程序设计。

    电路板焊好后,首先要闪个灯,以确认基本正常。
    1. while (1)
    2. {
    3.     LED_PIN = ~LED_PIN;
    4.     Delay_ms(500);
    5. }
    复制代码

    延时在很多地方用到,如液晶屏接口时序控制,蜂鸣器,液晶屏文字显示停留时间,焊接时间控制等。因此做成一个子程序。
    Keil C51调用函数时传递参数、LCALL、函数返回的RET,开销是固定的。在C程序中嵌入汇编指令,在计数判断各分支插入适当的NOP指令,保证跳或不跳都耗同样的时间,就能实现准确延时若干个机器周期。

    使用12MHz晶振时,传统51单片机一个机器周期是1μs,比较简洁。延时函数就写成
    1. void Delay_us(int8u t);
    复制代码
    1个字节只能计到255μs,适用于电路时序控制等需要十几~一两百微秒延时的地方。

    8位的51单片机处理16位数要复杂一点,因此另写一个
    1. void Delay_us_2(int16u t);
    复制代码
    参数是2字节整数,可实现几十~65535μs的延时。

    当超过上百毫秒时,就不需精确到微秒程度了,可调用刚才的Delay_us_2()。
    1. void Delay_ms(int16u t)
    2. {
    3.     while (t != 0)
    4.     {
    5.         Delay_us_2(99x);
    6.         t -= 1;
    7.     }
    8. }
    复制代码


    回复 dsu_marcocopyright:copyright

    使用道具 举报

  • TA的每日心情
    奋斗
    2024-5-21 00:23
  • 签到天数: 1882 天

    [LV.Master]伴坛终老

     楼主| 发表于 2020-3-1 15:41 | 显示全部楼层
    本帖最后由 xyz123123 于 2020-3-5 18:49 编辑

    接下来要点亮液晶屏。

    大众款1602字符屏,控制芯片一般是HD44780或相似的。
    虽是大众款,可芯片手册难见一份准确的,连初始化的几条指令流程都讲得不太清晰,各兼容芯片的手册都差不多。日货一向小气,估计自该芯片面世起也是能用就得了,内部逻辑结构、设计意图、应用细节,只有设计此芯片的那几个人自珍了。所以拿它来简单用用即可,没多少好考究的。

    虽然芯片规格称接口速度能到1MHz,但液晶模块里PCB走线细且长,又未适当接电源退耦电容,用示波器观察可见波形边沿形状不好。所以将控制脉冲放慢到2~3μs。

    使用12MHz晶振时,传统51单片机一条指令一两μs,和HD44780配合较合适。现今的单时钟周期51单片机或其它高速单片机主频十几MHz以上,1μs能运行十多条指令,受影响明显。
    虽然HD44780提供BUSY信号可查询,但控制指令总共就清屏、设置模式、设置光标、读写数据、读写地址这几条,执行耗时都是固定的,没必要去读BUSY信号。
    况且读BUSY信号这个操作本身也和其它指令一样速度不高。
    再有,网上见的资料大多没提到,读BUSY信号这个操作还须等上一次指令之后好几十微秒才能进行。呃,除了清屏、归零两条指令耗时1.5ms外,其它指令耗时均才37μs,比读BUSY信号还快咧

    回复

    使用道具 举报

  • TA的每日心情
    开心
    2024-3-9 20:19
  • 签到天数: 32 天

    [LV.5]常住居民I

    发表于 2020-3-1 15:46 来自手机 | 显示全部楼层
    支持大神,编程我玩不来
    回复

    使用道具 举报

  • TA的每日心情
    奋斗
    2024-5-21 00:23
  • 签到天数: 1882 天

    [LV.Master]伴坛终老

     楼主| 发表于 2020-3-1 16:07 | 显示全部楼层
    本帖最后由 xyz123123 于 2020-3-1 23:15 编辑

    HD44780每行的显存是40个字符,1602屏每行只可显示16个字符。
    屏幕滚动的功能似乎没什么用,估计不太会用它去做滚动广告、屏保之类的吧。对显示效果要求不高,一般也不会去搞两屏内容快速切换。
    因此写几个常用的功能就够。
    1. void LcdLocate(int8u row, int8u col);  //指定字符显示位置。
    2. void LcdPrint(int8u c);  //显示一个字符。
    3. void LcdPrintString(int8u row, int8u col, int8u *str);  //依次显示str中的字符,直至'\0'。不考虑超出16列、换行之类的。
    4. void LcdClearRow(int8u row);  //其实就是从行首位置起显示16个空格。
    复制代码

    例如,程序初始的界面:
    1. LcdInit();
    2. LcdPrintString(1, 1, "  Spot Welder");
    3. LcdPrintString(2, 1, "    2020-02");
    复制代码
    液晶屏2.jpg

    回复

    使用道具 举报

  • TA的每日心情
    奋斗
    2024-5-21 00:23
  • 签到天数: 1882 天

    [LV.Master]伴坛终老

     楼主| 发表于 2020-3-1 17:50 | 显示全部楼层
    本帖最后由 xyz123123 于 2020-3-15 21:57 编辑

    接下来是按键。

    设置一个定时中断,每1ms扫描一遍按键,记录每个按键的状态、持续时间。当连续若干次的状态不变时,才认为按键已稳定。
    一般微动开关的按键抖动多在5ms以内。若要过滤50Hz市电线路的干扰,可将判断时间加长到几十毫秒,不过按键的响应也会相应延迟。这个时间值可做进参数设置功能里,让用户自由变更。

    在菜单操作中,按+、-键调节数值时,短按一次增减1步长,若持续按键达一两秒则连续自动调节,例如一秒重复10次。
    大范围的调节,例如“触发延迟10~15000μs,调节步长10μs”,一秒重复10次的话,持续按键要150秒才能调到头,显然太久。一般按着键十几秒估计就令人厌烦了。
    因此须判断当持续按键超过例如3秒后,进一步加速,例如一秒重复100次。

    有些产品按键很少,看似简洁,但用起来要区分短按、长按,功能复用太多,很麻烦。
    这里准备6个按键:设置,取消,减,增,确认,焊接。
    按〖设置〗进入参数设置菜单,〖减〗〖增〗移动光标,〖确认〗进入该项,〖取消〗退回上一级菜单。
    在参数项目中,按〖减〗〖增〗进行调节,持续按着可快速调节,按〖确认〗保存,〖取消〗则放弃更改。

    调试观察,扫描一次6个按键要耗好几百步。传统51单片机接12MHz晶振时,1ms里有六七百μs都用来处理按键了。
    简单控制类的应用通常运算量不多,需要的是响应速度。按上述情况,若不用高优先级中断,就要等几百微秒处理完按键之后再来响应其它事件,而且剩下的处理能力只剩两百多步了。
    例如控制步进电机,一圈200个脉冲,每秒5转,则每1ms要处理一个脉冲,1ms内只剩两百多μs来处理,较吃力。
    换成现今的单周期51,速度翻十几倍,1ms里只用去了几十μs,能充分迅速地响应其它事件。

    现在做这个点焊机控制,没什么需要高速响应的控制,焊接动作那几百毫秒精确计时期间可暂停按键、液晶屏等其它处理,大众款51足以胜任了。

    回复

    使用道具 举报

  • TA的每日心情
    开心
    2018-10-27 16:32
  • 签到天数: 5 天

    [LV.2]偶尔看看I

    发表于 2020-3-1 17:58 来自手机 | 显示全部楼层
    你是高手,厉害
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2023-9-9 00:16
  • 签到天数: 1085 天

    [LV.10]以坛为家III

    发表于 2020-3-1 19:23 | 显示全部楼层
    学习高手编程
    回复

    使用道具 举报

  • TA的每日心情
    奋斗
    2024-5-21 00:23
  • 签到天数: 1882 天

    [LV.Master]伴坛终老

     楼主| 发表于 2020-3-1 20:06 | 显示全部楼层
    本帖最后由 xyz123123 于 2020-3-5 18:50 编辑

    接下来是存储器。

    需要保存的几个参数:
      交流电过零点之后多久触发。
      第一次焊接时间。
      第一次焊接之后等待时间。
      第二次焊接时间。
      第二次焊接之后等待时间。

    交流过零检测电路是个电压比较器,检测到电压低于一定值时动作,在零点左右产生一个约1ms宽的脉冲。
    程序可能是在零点之前捕捉到,则延时几百μs后即零点。或是零点之后才捕捉到,则下个半波零点是9点几ms之后。
    为了保持磁平衡,令变压器每次通电整数个全波,因此零点之后才捕捉到的,下个过零点选在19点几ms之后。
    于是,该参数的设置范围是0~20000μs。
    整机做好后,用示波器观察程序捕捉到的零点时刻,减去接触器机械动作延迟时间,来做设定。小继电器的动作时间大概是数毫秒,大个头的接触器不知如何。
    不用示波器的话,也可观察接触器触点通断时的火花,调节达到火花最小即可。

    据说先短焊第一次,可去除氧化层、预热,紧接着焊第二次,这样的效果好。因此预留了两组焊接、等待的时间参数。
    为了保持磁平衡,焊接时间取20ms的整数倍,范围定20~2000ms吧。
    焊接时间也可短到10ms的倍数,程序里只要记录是在正半周还是负半周的过零点触发的,下次交换即可。估计20ms够短了,先不考虑太复杂的。

    焊接之间的间隔,感觉100~2000ms范围可以了。

    AT24Cxx存储器,便宜,IIC接口不复杂。
    为防芯片上电自动复位失败,程序应对其发指令复位。方法见芯片手册,通常发至多9个SCL时钟就能完成。
    只读写几个字节,不需考虑连续读写、页长度之类的,做两个子程序就好。
    1. void At24cByteWrite(int8u addr, int8u dat);
    2. int8u At24cRandomRead(int8u addr);
    复制代码

    Keil C51将多字节整数按高位字节先行,保存到AT24Cxx时按同样顺序就好。
    例如保存一个2字节整数4779,可在存储器地址0x00存0x12、地址0x01存0xAB。

    回复

    使用道具 举报

  • TA的每日心情
    奋斗
    2024-5-21 00:23
  • 签到天数: 1882 天

    [LV.Master]伴坛终老

     楼主| 发表于 2020-3-1 21:22 | 显示全部楼层
    本帖最后由 xyz123123 于 2020-3-1 21:27 编辑

    硬件部分基本好了。接下来是菜单操作过程。

    按〖设置〗键,进入菜单。
    界面1.jpg

    界面3.jpg

    界面5.jpg

    界面7.jpg

    界面8.jpg

    按〖减〗〖增〗移动光标,〖确认〗进入该项,〖取消〗退回上一级菜单。
    按〖减〗〖增〗进行调节数值,持续按着可快速调节,按〖确认〗保存,〖取消〗则放弃更改。
    界面4.jpg

    界面6.jpg

    退出最初级菜单后,回到等待焊接状态。
    界面9.jpg

    各项参数都是简单整数,调节过程都是相似的,只是提示文字、数值范围不同。将不同的部分定义一个结构体
    1. typedef struct
    2. {
    3.   int8u *Title;
    4.   int8u *Unit;
    5.   int16u Value;
    6.   int16u ValueMin;
    7.   int16u ValueMax;
    8.   int16u ValueAdj;
    9. } INPUT_DIALOG;
    复制代码

    做一个子程序InputDialog()来统一调用,比较简洁。例如设置触发延时:
    1. ……
    2. INPUT_DIALOG dialog;

    3. dialog.Title = "Trig Delay";
    4. dialog.Unit = "us";
    5. dialog.Value = (int16u)At24cRandomRead(ADDR_TRIG_DELAY) << 8;
    6. dialog.Value |= At24cRandomRead(ADDR_TRIG_DELAY + 1);
    7. dialog.ValueMin = 0;
    8. dialog.ValueMax = 20000;
    9. dialog.ValueAdj = 10;

    10. InputDialog(&dialog);
    11. ……
    复制代码
    界面2.jpg

    回复

    使用道具 举报

  • TA的每日心情
    慵懒
    2021-9-3 07:49
  • 签到天数: 941 天

    [LV.10]以坛为家III

    发表于 2020-3-1 21:31 | 显示全部楼层
    换stm32f0系列更好,便宜效率更高
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2024-3-9 20:19
  • 签到天数: 32 天

    [LV.5]常住居民I

    发表于 2020-3-1 22:43 来自手机 | 显示全部楼层
    玩得不是一般的溜!
    回复

    使用道具 举报

  • TA的每日心情
    奋斗
    2024-5-21 00:23
  • 签到天数: 1882 天

    [LV.Master]伴坛终老

     楼主| 发表于 2020-3-5 15:32 | 显示全部楼层
    本帖最后由 xyz123123 于 2020-3-5 18:46 编辑

    主程序部分就简单了,按〖设置〗键就进入参数设置菜单,按〖焊接〗则暂停扫描按键、等待过零信号、驱动继电器。
    1. void main()
    2. {
    3.     LcdPrintString(1, 1, "  Spot Welder");
    4.     LcdPrintString(2, 1, "    2020-02");
    5.     LoadConfig();

    6.     while(1)
    7.     {
    8.         if (KeyIsPressed(KEY_SETUP))
    9.         {
    10.             Menu();
    11.             LoadConfig();
    12.         }
    13.         else if (KeyIsPressed(KEY_WELD))
    14.         {
    15.             //暂停按键扫描

    16.             //等待过零信号

    17.             Delay_us_2(cfg_TrigDelay);

    18.             RELAY = RELAY_ON;
    19.             Delay_ms(cfg_WeldingTime1);

    20.             RELAY = RELAY_OFF;
    21.             Delay_ms(cfg_WaitingTime1);

    22.             RELAY = RELAY_ON;
    23.             Delay_ms(cfg_WeldingTime2);

    24.             RELAY = RELAY_OFF;
    25.             Delay_ms(cfg_WaitingTime2);

    26.             //恢复按键扫描
    27.         }
    28.     }
    29. }
    复制代码

    电路板焊好了,用示波器检测一下。
    示波器观察触发控制.jpg

    过零检测用的是交流9V供电入口接两个二极管,驱动一个三极管。交流过零时三极管截止,集电极接的单片机引脚上便出现一个高电平脉冲。
    过零检测1.gif
    估计是因为小变压器内阻高,仅几十mA的平均电流,整流后的正弦半波顶端已被拉平了。

    放大看看。
    过零检测2.gif

    过零检测3.gif
    过零检测用的三极管集电极接的单片机引脚本来是接键盘用的,有个小电容滤波,所以触发波形的上升沿较缓。现在检测的是下降沿,不要紧。

    再放大一点。
    过零检测4.gif
    可见触发脉冲约800μs,即单片机在过零点之后400μs才检测到。

    将“触发延迟”这项参数就设为10ms-400μs=9600μs,用单片机的一个空余引脚输出一个信号来观察。
    触发延迟960us.gif
    能准确定位到下个过零点。

    将参数设置为“第一焊20ms、等100ms、第二焊40ms”的效果。
    焊20ms,停100ms,焊40ms.gif

    程序搞定
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2024-3-9 20:19
  • 签到天数: 32 天

    [LV.5]常住居民I

    发表于 2020-3-5 16:14 来自手机 | 显示全部楼层
    进来看看,看焊接效果。
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2024-5-3 13:54
  • 签到天数: 24 天

    [LV.4]偶尔看看III

    发表于 2020-3-7 13:06 | 显示全部楼层
    做好等收成品
    回复

    使用道具 举报

  • TA的每日心情
    奋斗
    2024-5-21 00:23
  • 签到天数: 1882 天

    [LV.Master]伴坛终老

     楼主| 发表于 2020-3-16 23:58 | 显示全部楼层
    组装和初步试验,见《http://www.shoudian.org/forum.php?mod=viewthread&tid=1508031 做微波炉变压器点焊机,总装》。

    回复

    使用道具 举报

  • TA的每日心情
    慵懒
    2021-9-3 07:49
  • 签到天数: 941 天

    [LV.10]以坛为家III

    发表于 2020-3-17 00:08 | 显示全部楼层
    本帖最后由 hellohello22 于 2020-3-17 00:09 编辑

    t -= 1;

    写成 t--; 不是更简单吗

    点评

    唔,只对指针使用++和--,那样不易搞错2字节数还是4字节数之类的。 喜欢程序每一行写得简单,人看着易懂,调试也方便。例如像 这种就觉得不好,喜欢 while (1) { c = *p; if (c == '\0') break; ...  详情 回复 发表于 2020-3-17 00:36
    回复

    使用道具 举报

  • TA的每日心情
    奋斗
    2024-5-21 00:23
  • 签到天数: 1882 天

    [LV.Master]伴坛终老

     楼主| 发表于 2020-3-17 00:36 | 显示全部楼层
    本帖最后由 xyz123123 于 2020-3-17 00:39 编辑
    hellohello22 发表于 2020-3-17 00:08
    t -= 1;

    写成 t--; 不是更简单吗

    唔,只对指针使用++和--,那样不易搞错2字节数还是4字节数之类的。算术运算的话都明确地写加减多少。

    喜欢程序每一行写得简单,人看着易懂,调试也方便。例如像
    1. while (*str++) {...}
    复制代码
    这种就觉得不好,喜欢
    1. while (1)
    2. {
    3.     c = *p;
    4.     if (c == '\0') break;
    5.     ...
    6.     p++;
    7. }
    复制代码
    这样的。

    如何优化是编译器的事,不应让人分心。
    如今的编译器感觉蛮给力的,增减1的操作尽量使用对应的机器指令,自不必提。
    见Keil C51编译出的,判断一个2字节整数是否等于0
    1. MOV A,低字节
    2. OR A,高字节
    3. JZ ……
    复制代码

    还有2字节整数减1
    1. MOV A,低字节
    2. DEC 低字节
    3. JNZ (没有从高字节借位)
    4. DEC 高字节(若原来低字节是0,即为向高字节借了位)
    复制代码

    都蛮巧妙的。


    点评

    ++/-- 是自动根据类型处理 , 就算你写-=1 /+=1 也是一样的,毫无差别。 uint32_t *p ; p++ 和p+=1 都是地址变换4b uint32_t val; val++和val+=1 都是数组+1  详情 回复 发表于 2020-3-17 09:13
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2019-11-26 08:47
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2020-3-17 09:13 | 显示全部楼层
    xyz123123 发表于 2020-3-17 00:36
    唔,只对指针使用++和--,那样不易搞错2字节数还是4字节数之类的。算术运算的话都明确地写加减多少。

    喜 ...


    ++/-- 是自动根据类型处理 , 就算你写-=1 /+=1 也是一样的,毫无差别。

    uint32_t *p ;
    p++ 和p+=1 都是地址变换4b

    uint32_t val;
    val++和val+=1 都是数值+1



    回复

    使用道具 举报

    本版积分规则

    小黑屋|手机版|Archiver|论坛自带搜索|下载论坛app|手电大家谈-手电筒爱好者之家 ( 备案序号:鲁ICP备05002565号 )
    以上言论纯属个人观点,与手电大家谈立场无关。
    最佳浏览模式:1920*1080


    GMT+8, 2024-5-22 12:03 , Processed in 0.252004 second(s), 62 queries , Gzip On.

    Powered by Discuz! X3.4

    © 2001-2023 Discuz! Team.

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