本帖最后由 zuse1021 于 2020-5-21 21:09 编辑
之前做过一个微波炉变压器版的点焊机,总感觉能力不够,在看到隔壁论坛的开源的超级电容点焊机后,打算仿一个。
原版本两个超级电容用均衡版充电,MOS利用升压电路。感觉比较麻烦,于是打算两个恒流模块加上两个独立的220转5V的电源,做成平衡充给电容充电。然后MOS的升压也直接用成品的升压模块,更方便。
手头正好有一些STC的8A8K64S4A12的直插40针的单片机,就利用起来了。既然用了这个单片机,顺便就加上了测电容电压的功能。
下面介绍一下PCB:
考虑到5块包邮的嘉立创,PCB的长度被设定为10cm,右上方是0.36寸四位共阳数码管,三极管是四个9012,四个按键,其它元件在PCB上都标注了。
BOOST MODULE是升压模块,初步打算用这个模块:
输出控制在16v~18v左右,PCB也是按这个模块的尺寸来画的。然而买回来一个却无法升压,大概是坏了,因为只买了1个,所以也不知道这个模块是不是能用上,另一家买的另一种升压模块倒是可以升压,但尺寸不对应哈哈。
四个按键用于控制脉冲长度、脉冲间隔和脉冲次数的设定,同时可以利用EEPROM储存,断电保存上一次的设置,还用于显示电容电压。
下面介绍按键的作用:
key1--进入菜单1--脉冲长度调节--显示脉冲长度
key1-- +1
key2-- -1
key3-- 恢复预设值
key4-- back to main
key2--进入菜单2--脉冲间隔调节--显示脉冲间隔
key1-- +1
key2-- -1
key3-- 恢复预设值
key4-- back to main
key3--进入菜单3--脉冲次数调节--显示脉冲次数
key1-- +1
key2-- -1
key3-- 恢复预设值
key4-- back to main
key4--进入菜单4--电容电压显示--显示总电压
key1-- 显示第一节电容电压
key2-- 显示第二节电容电压
key3-- 保持当前配置于EEPROM
key4-- back to main
MOS板初步打算16个irf3713并联,也可以某宝入一个成品的点焊MOS板。
实际上,只测试了电路和程序没问题,还没有实际装起来。程序和PCB文件待补充,下面是两张焊了一部分的照片。
3L补充了PCB和程序,有兴趣的可以下载大致分了两个部分,一部分是main.c,是主程序,另一部分是ADCread.c,用于测电压。下面把main.c贴上。
- #include <STC8.H>
- #include <stdio.h>
- #include <Intrins.h>
- #include <adcread.h>
- #define WT_12M 0x83
- typedef unsigned int u16; //对数据类型进行声明定义
- typedef unsigned char u8; //对数据类型进行声明定义
- sbit key1=P0^0; //P0.0端口定义为时间减
- sbit key2=P0^1; //P0.1端口定义为时间加
- sbit key3=P0^2; //P0.2端口定义为按下显示第一节电容电压
- sbit key4=P0^3; //P0.3端口定义为按下显示第二节电容电压
- sbit out=P4^1; //P4.1端口定义为驱动脉冲输出
- sbit tst=P5^5; //P5.5端口定义为检测点焊笔准备焊接的输入端
- sbit DIG1=P2^0; //P2.0端口定义为DIG1
- sbit DIG2=P2^1; //P2.1端口定义为DIG2
- sbit DIG3=P2^2; //P2.2端口定义为DIG3
- sbit DIG4=P2^3; //P2.3端口定义为DIG4
- u16 pulse; //输出脉冲长度,×0.1毫秒
- u16 interval; //脉冲间隔,×0.1毫秒
- u8 num; //脉冲次数
- u16 v1; //第一电容电压
- u16 v2; //第二电容电压
- u16 vcc; //总电压
- u8 Page_Sgin; //页面选择
- u8 zz;
- //数码管真值表//
- u8 code LED_CODE[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //显示0~9,
- u8 code LED_S[2]={0x9f,0xaf}; //显示上折角,下折角
- //延时100us//
- void Delay(long t) //STC8Axx基于STC-Y6指令集@12.000MHz,from:STC-ISP;
- {
- u8 ia, ja;
- long ka;
- for(ka=t;ka>0;ka--)
- {
- _nop_();
- ia = 2;
- ja = 140;
- do
- {
- while (--ja);
- } while (--ia);
- }
- }
- //检测点焊笔准备//
- bit stst(void)
- {
- static unsigned int l = 0; //定义静态变量,用来记录延时用.
- if(tst == 0) //如果检测到按键引脚有低电平,记数变量开始累加.
- {
- if(l <7000) //控制延时计数返0,因为当按键不松开时,i一直在累加
- l++; //CPU每检测到一次按键引脚为低电平0,i就累加1次.
- }
- else //如果按键没有按下或者按下后有高电平(抖动)i清0
- l = 0;
- if(l == 6999) //如果变量i的值累加到6999,说明点焊笔已经做好准备,可以焊接了.
- return 1; //返回1,说明已检测到按键有效值.
- else
- return 0; //返回0,说明没有检测到有效值.
- }
- void IapIdle()
- {
- IAP_CONTR = 0; //关闭IAP功能
- IAP_CMD = 0; //清除命令寄存器
- IAP_TRIG = 0; //清除触发寄存器
- IAP_ADDRH = 0x80; //将地址设置到非IAP区域
- IAP_ADDRL = 0;
- }
- char IapRead(int addr) //EEPROM读一字节
- {
- char dat;
- IAP_CONTR = WT_12M; //使能IAP
- IAP_CMD = 1; //设置IAP读命令
- IAP_ADDRL = addr; //设置IAP低地址
- IAP_ADDRH = addr >> 8; //设置IAP高地址
- IAP_TRIG = 0x5a; //写触发命令(0x5a)
- IAP_TRIG = 0xa5; //写触发命令(0xa5)
- _nop_();
- dat = IAP_DATA; //读IAP数据
- IapIdle(); //关闭IAP功能
- return dat;
- }
- void IapProgram(int addr, char dat) //EEPROM写一字节
- {
- IAP_CONTR = WT_12M; //使能IAP
- IAP_CMD = 2; //设置IAP写命令
- IAP_ADDRL = addr; //设置IAP低地址
- IAP_ADDRH = addr >> 8; //设置IAP高地址
- IAP_DATA = dat; //写IAP数据
- IAP_TRIG = 0x5a; //写触发命令(0x5a)
- IAP_TRIG = 0xa5; //写触发命令(0xa5)
- _nop_();
- IapIdle(); //关闭IAP功能
- }
- void IapErase(int addr) //EEPROM擦除一扇区=512字节
- {
- IAP_CONTR = WT_12M; //使能IAP
- IAP_CMD = 3; //设置IAP擦除命令
- IAP_ADDRL = addr; //设置IAP低地址
- IAP_ADDRH = addr >> 8; //设置IAP高地址
- IAP_TRIG = 0x5a; //写触发命令(0x5a)
- IAP_TRIG = 0xa5; //写触发命令(0xa5)
- _nop_(); //
- IapIdle(); //关闭IAP功能
- }
- /********************************
- 数码管动态显示程序
- ********************************/
- void display(u8 wei)
- {
- u8 ke;
- u8 dd=0;
- switch(wei)
- {
- case 1://显示脉冲长度
- for(dd=0;dd<3;dd++)
- {
- if(dd == 0) //显示个位
- {
- P2=0xf7;//个位段码开
- P3=LED_CODE[pulse%10];
- for(ke = 0;ke <100;ke++); //延时一段时间
- P2=0xff;//段码关
- P3=0xff;//位码消隐
- }
- if(dd == 1&& pulse/10%10!=0) //显示十位
- {
- P2=0xfb;//十位段码开
- P3=LED_CODE[pulse/10%10];
- for(ke = 0;ke <100;ke++); //延时一段时间
- P2=0xff;//段码关
- P3=0xff;//位码消隐
- }
- if(dd == 2 && pulse/100%10!=0) //显示百位
- {
- P2=0xfd;//百位段码开
- P3=LED_CODE[pulse/100%10];
- for(ke = 0;ke <100;ke++); //延时一段时间
- P2=0xff;//段码关
- P3=0xff;//位码消隐
- }
- }
- break;
- case 2: //显示脉冲间隔
- for(dd=0;dd<3;dd++)
- {
- if(dd == 0) //显示个位
- {
- P2=0xf7;//个位段码开
- P3=LED_CODE[interval%10];
- for(ke = 0;ke <100;ke++); //延时一段时间
- P2=0xff;//段码关
- P3=0xff;//位码消隐
- }
- if(dd == 1&& interval/10%10!=0) //显示十位
- {
- P2=0xfb;//十位段码开
- P3=LED_CODE[interval/10%10];
- for(ke = 0;ke <100;ke++); //延时一段时间
- P2=0xff;//段码关
- P3=0xff;//位码消隐
- }
- if(dd == 2 && interval/100%10!=0) //显示百位
- {
- P2=0xfd;//百位段码开
- P3=LED_CODE[interval/100%10];
- for(ke = 0;ke <100;ke++); //延时一段时间
- P2=0xff;//段码关
- P3=0xff;//位码消隐
- }
- }
- break;
- case 3: //显示脉冲次数
- for(dd=0;dd<2;dd++)
- {
- if(dd == 0) //显示个位
- {
- P2=0xf7;//个位段码开
- P3=LED_CODE[num%10];
- for(ke = 0;ke <100;ke++); //延时一段时间
- P2=0xff;//段码关
- P3=0xff;//位码消隐
- }
- if(dd == 1&& num/10!=0) //显示十位
- {
- P2=0xfb;//十位段码开
- P3=LED_CODE[num/10%10];
- for(ke = 0;ke <100;ke++); //延时一段时间
- P2=0xff;//段码关
- P3=0xff;//位码消隐
- }
- }
- break;
- case 4: //显示总电压
- for(dd=0;dd<4;dd++)
- {
- if(dd == 0) //显示个位
- {
- P2=0xf7;//个位段码开
- P3=LED_CODE[vcc%10];
- for(ke = 0;ke <100;ke++); //延时一段时间
- P2=0xff;//段码关
- P3=0xff;//位码消隐
- }
- if(dd == 1) //显示十位
- {
- P2=0xfb;//十位段码开
- P3=LED_CODE[vcc/10%10];
- for(ke = 0;ke <100;ke++); //延时一段时间
- P2=0xff;//段码关
- P3=0xff;//位码消隐
- }
- if(dd == 2) //显示百位
- {
- P2=0xfd;//百位段码开
- P3=LED_CODE[vcc/100%10];
- for(ke = 0;ke <100;ke++); //延时一段时间
- P2=0xff;//段码关
- P3=0xff;//位码消隐
- }
- if(dd == 3) //显示千位
- {
- P2=0xfe;//千位段码开
- P3=LED_CODE[vcc/1000]&0x7f;
- for(ke = 0;ke <100;ke++); //延时一段时间
- P2=0xff;//段码关
- P3=0xff;//位码消隐
- }
- }
- break;
- case 5: //显示第一节电容电压
- for(dd=0;dd<4;dd++)
- {
- if(dd == 0) //显示个位
- {
- P2=0xf7;//个位段码开
- P3=LED_CODE[v1/10%10]; //个位显示电压小数点后第二位
- for(ke = 0;ke <100;ke++); //延时一段时间
- P2=0xff;//段码关
- P3=0xff;//位码消隐
- }
- if(dd == 1) //显示十位
- {
- P2=0xfb;//十位段码开
- P3=LED_CODE[v1/100%10]; //十位显示电压小数点后第一位
- for(ke = 0;ke <100;ke++); //延时一段时间
- P2=0xff;//段码关
- P3=0xff;//位码消隐
- }
- if(dd == 2) //显示百位
- {
- P2=0xfd;//百位段码开
- P3=LED_CODE[v1/1000]&0x7f; //百位显示电压小数点前一位+小数点
- for(ke = 0;ke <100;ke++); //延时一段时间
- P2=0xff;//段码关
- P3=0xff;//位码消隐
- }
- if(dd == 3) //显示千位
- {
- P2=0xfe;//千位段码开
- P3=LED_S[0]; //千位显示第一节电容符号
- for(ke = 0;ke <100;ke++); //延时一段时间
- P2=0xff;//段码关
- P3=0xff;//位码消隐
- }
- }
- break;
- case 6: //显示第二节电容电压
- for(dd=0;dd<4;dd++)
- {
- if(dd == 0) //显示个位
- {
- P2=0xf7;//个位段码开
- P3=LED_CODE[v2/10%10]; //个位显示电压小数点后第二位
- for(ke = 0;ke <100;ke++); //延时一段时间
- P2=0xff;//段码关
- P3=0xff;//位码消隐
- }
- if(dd == 1) //显示十位
- {
- P2=0xfb;//十位段码开
- P3=LED_CODE[v2/100%10]; //十位显示电压小数点后第一位
- for(ke = 0;ke <100;ke++); //延时一段时间
- P2=0xff;//段码关
- P3=0xff;//位码消隐
- }
- if(dd == 2) //显示百位
- {
- P2=0xfd;//百位段码开
- P3=LED_CODE[v2/1000]&0x7f; //百位显示电压小数点前一位+小数点
- for(ke = 0;ke <100;ke++); //延时一段时间
- P2=0xff;//段码关
- P3=0xff;//位码消隐
- }
- if(dd == 3) //显示千位
- {
- P2=0xfe;//千位段码开
- P3=LED_S[1]; //千位显示第二节电容符号
- for(ke = 0;ke <100;ke++); //延时一段时间
- P2=0xff;//段码关
- P3=0xff;//位码消隐
- }
- }
- break;
- case 7://显示主菜单
- for(dd=0;dd<4;dd++)
- {
- if(dd == 0) //显示个位
- {
- P2=0xf7;//个位段码开
- P3=LED_S[0];
- for(ke = 0;ke <100;ke++); //延时一段时间
- P2=0xff;//段码关
- P3=0xff;//位码消隐
- }
- if(dd == 1) //显示十位
- {
- P2=0xfb;//十位段码开
- P3=LED_S[1];
- for(ke = 0;ke <100;ke++); //延时一段时间
- P2=0xff;//段码关
- P3=0xff;//位码消隐
- }
- if(dd == 2) //显示百位
- {
- P2=0xfd;//百位段码开
- P3=LED_S[0];
- for(ke = 0;ke <100;ke++); //延时一段时间
- P2=0xff;//段码关
- P3=0xff;//位码消隐
- }
- if(dd == 3) //显示千位
- {
- P2=0xfe;//千位段码开
- P3=LED_S[1];
- for(ke = 0;ke <100;ke++); //延时一段时间
- P2=0xff;//段码关
- P3=0xff;//位码消隐
- }
- }
- default:
- break;
- }
- }
- //按键处理函数
- //返回按键值1~4
- //mode:0,不支持连续按;1,支持连续按;
- //0,没有任何按键按下
- u8 KEY_Scan(u8 mode)
- {
- static u8 key_up=1;//按键标志
- if(mode) key_up=1; //支持连按
- //检测按键是否按下
- if(key_up&&(key1==0||key2==0||key3==0||key4==0))
- {
- Delay(100);//去抖动
- if(key_up&&(key1==0||key2==0||key3==0||key4==0))
- {
- key_up=0;
- if (key1 == 0) return 1;
- else if(key2 == 0) return 2;
- else if(key3 == 0) return 3;
- else if(key4 == 0) return 4;
-
- }
- }
- //检测按键是否松开
- else if(key1==1 && key2==1 && key3==1 && key4==1) key_up=1;
- return 0;//无按键按下
- }
- void Main_Menu()
- {
- u8 i;
- u8 m5=stst();
- if(m5 == 1)
- {
- for(i=0;i<num;i++) //加入 for循环,表明for循环大括号中的程序循环执行num次
- {
- out=0; //将P4.1口赋值 0,对外输出低电平
- Delay(pulse); //调用延时程序;更改延时数字可以更改延时长度;用于改变输出脉冲时间pulse×100us
- out=1; //将P4.1口赋值 1,对外输出高电平
- Delay(interval);//等待间隔时间
- }
- }
- display(7); //显示主菜单CC
- switch(KEY_Scan(0))
- {
- case 1: //key1按下
- Page_Sgin=1; //页面选择置1,进入菜单1--脉冲长度调节
- break;
- case 2: //key2按下
- Page_Sgin=2; //页面选择置2,进入菜单2--脉冲间隔调节
- break;
- case 3: //key3按下
- Page_Sgin=3; //页面选择置3,进入菜单3--脉冲次数调节
- break;
- case 4: //key4按下
- Page_Sgin=4; //页面选择置4,进入菜单4--电容电压显示
- break;
- default:
- break;
- }
- }
- void Menu_1() //菜单1--脉冲长度调节
- {
- switch(KEY_Scan(0))
- {
- case 1: //key1按下
- if(pulse < 999)
- pulse++; //脉冲长度+1
- break;
- case 2: //key2按下
- if(pulse > 1)
- pulse--; //脉冲长度-1
- break;
- case 3: //key3按下
- pulse=20; //脉冲长度恢复预置,2ms
- break;
- case 4: //key4按下
- Page_Sgin=0; //back to 主菜单
- break;
- default :
- break;
- }
- display(1); //显示菜单1-显示脉冲长度
- }
- void Menu_2() //菜单2--脉冲间隔调节
- {
- switch(KEY_Scan(0))
- {
- case 1: //key1按下
- if(interval < 999)
- interval++; //脉冲长度+1
- break;
- case 2: //key2按下
- if(interval > 1)
- interval--; //脉冲长度-1
- break;
- case 3: //key3按下
- interval=3; //脉冲长度恢复预置,300us
- break;
- case 4: //key4按下
- Page_Sgin=0; //back to 主菜单
- break;
- default :
- break;
- }
- display(2); //显示菜单2-显示间隔长度
- }
- void Menu_3() //菜单3--脉冲次数调节
- {
- switch(KEY_Scan(0))
- {
- case 1: //key1按下
- if(num < 99)
- num++; //脉冲次数+1
- break;
- case 2: //key2按下
- if(num > 1)
- num--; //脉冲次数-1
- break;
- case 3: //key3按下
- num=3; //脉冲次数恢复预置,3次
- break;
- case 4: //key4按下
- Page_Sgin=0; //back to 主菜单
- break;
- default :
- break;
- }
- display(3); //显示菜单3-显示脉冲次数
- }
- void Menu_4() //菜单4--电容电压显示
- {
- u16 ib,jb; //定义延迟用临时变量
- v1=GetResult (7); //获取第一节电池电压
- v2=vcc-v1; //计算得到第二节电池电压
-
- switch(KEY_Scan(0))
- {
- case 1: //key1按下
- for (ib = 5000; ib > 0; ib--) //外层循环1000次
- {
- for (jb = 124; jb > 0; jb--) ; //内层循环124次,延时一定长度用于显示第一节电容电压
- {
- display(5); //显示第一节电容电压
- }
- }
- break;
- case 2: //key2按下
- for (ib = 5000; ib > 0; ib--) //外层循环1000次
- {
- for (jb = 124; jb > 0; jb--) ; //内层循环124次,延时一定长度用于显示第二节电容电压
- {
- display(6); //显示第二节电容电压
- }
- }
- break;
- case 3: //key3按下,保持当前配置于EEPROM
- IapErase(0x0400); //擦除EEPROM
- IapProgram(0x0400, pulse>> 8); //写入pulse高8位
- IapProgram(0x0401, pulse & 0xff); //写入pulse低8位
- IapProgram(0x0402, interval>> 8); //写入interval高8位
- IapProgram(0x0403, interval & 0xff); //写入interval低8位
- IapProgram(0x0404, num); //写入num
- break;
- case 4: //key4按下
- Page_Sgin=0; //back to 主菜单
- break;
- default :
- break;
- }
- display(4); //显示总电压=VCC
- }
- void lnterface() //人机界面
- {
- switch(Page_Sgin)
- {
- case 0:
- Main_Menu(); break;
- case 1:
- Menu_1(); break;
- case 2:
- Menu_2(); break;
- case 3:
- Menu_3(); break;
- case 4:
- Menu_4(); break;
- default : break;
- }
- }
- void main() //主函数//
- {
- pulse = IapRead(0x0400); //pulse读EEPROM
- pulse <<= 8; //pulse恢复高位
- pulse |= IapRead(0x0401); //pulse或上低位
- interval = IapRead(0x0402); //interval读EEPROM
- interval <<= 8; //interval恢复高位
- interval |= IapRead(0x0403); //interval或上低位
- num=IapRead(0x0404); //num=读EEPROM
- out=1; //初始化输出端口
- tst= 1; //初始化焊笔检测端口
- Page_Sgin=0; //初始化页面选择
- vcc=GetVCC(); //获取总电压
- while(1)
- {
- lnterface();
- }
- }
复制代码
|