本帖最后由 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文件待補充,下面是兩張焊了一部分的照片。
01.jpg (3.72 MB, 下載次數: 150)
下載附件
2020-5-21 08:51 上傳
02.jpg (3.36 MB, 下載次數: 164)
下載附件
2020-5-21 08:52 上傳
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();
- }
- }
復制代碼
|