|
- /*****************STC15W408AS單片機(jī)旋轉(zhuǎn)編碼器版白光T12控制器代碼(by金向維)***********************/
- #include "STC15W408AS.h"//單片機(jī)頭文件,24MHz時鐘頻率
- #include "INTRINS.h"//頭文件
- unsigned char code duanma[12]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40,0x73};//共陰數(shù)碼管段碼數(shù)據(jù)(0,1,2,3,4,5,6,7,8,9),倒數(shù)第二個是顯示負(fù)號-的數(shù)據(jù),倒數(shù)第一個是顯示字母P的數(shù)據(jù)
- unsigned int code wendubiao[62]={924,959,996,1033,1071,1110,1150,1190,1232,1273,1315,1358,1401,1443,1487,1501,1574,1619,1663,1706,1751,1756,1776,1810,1853,1903,1958,2017,2078,2141,2204,2266,2327,2387,2444,2500,2554,2607,2657,2706,2738,2800,2844,2889,2931,2974,3016,3056,3098,3139,3179,3218,3257,3296,3333,3372,3408,3446,3484,3519,3554,3590};//根據(jù)NTC電阻隨溫度變化進(jìn)而引起電壓變化得出的數(shù)據(jù),用來查表計算室溫(進(jìn)而對熱電偶冷端補(bǔ)償)
- unsigned char code moren[8]={150,100,43,10,3,5,30,0};//白光控制器的默認(rèn)參數(shù)
- unsigned char canshu[7]={100,43,10,3,5,30,0};//部分參數(shù),依次為:失調(diào)電壓,熱電偶數(shù)據(jù),溫度步進(jìn),休眠時間,關(guān)機(jī)時間,溫度修正,喚醒方式
- sbit dot=P2^7;//數(shù)碼管的小數(shù)點(diǎn)接P2.7
- sbit t12=P2^0;//T12通過P2.0控制
- sbit bw=P3^4;//數(shù)碼管百位位選為P3.4
- sbit sw=P3^5;//數(shù)碼管十位位選為P3.5
- sbit gw=P3^6;//數(shù)碼管個位位選為P3.6
- sbit tihuan=P3^7;//數(shù)碼管的a段本應(yīng)該用P1.0控制,由于P1.0被用來控制T12,所以要用P3.7替代P1.0
- sbit encoderb=P1^4;//編碼器的b腳接P1.4
- sbit encodera=P3^2;//編碼器的a腳接P3.2
- sbit zhendongkaiguan=P5^5;//震動開關(guān)接P5.5
- sbit bianmaanniu=P3^3;//編碼器的按鍵接P3.3
- sbit a7=P2^7;
- sbit a6=P2^6;
- sbit a5=P2^5;
- sbit a4=P2^4;
- sbit a3=P2^3;
- sbit a2=P2^2;
- sbit a1=P2^1;
- bit e=1,f=1,g,h=1;//e,f,h用來保存編碼器上一次的狀態(tài),g用來保存震動開關(guān)上一次的狀態(tài)
- bit huancunkaiguan=0;//用于改變設(shè)定溫度后延時顯示設(shè)定溫度(而不是立刻顯示t12溫度)
- bit xiumiankaiguan=0;//定義休眠開關(guān)
- bit xiumianjishukaiguan=0;//定義休眠計數(shù)開關(guān)
- bit ganggangkaiji=1;//定義剛剛開機(jī)(用于確保剛開機(jī)未震動手柄能進(jìn)入休眠狀態(tài),因?yàn)槊看涡菝哂嫊r是通過震動傳感器狀態(tài)改變觸發(fā)的,而剛開機(jī)手柄沒有震動所以要特殊處理)
- bit guanjikaiguan=0;//定義關(guān)機(jī)開關(guān)
- bit guanjijishukaiguan;//定義關(guān)機(jī)計數(shù)開關(guān)
- bit huifumoren=0;//是否恢復(fù)默認(rèn)參數(shù)
- bit shezhimoshi=0;//設(shè)置模式還是正常工作模式
- bit shezhixianshijishukaiguan;//用于設(shè)置模式延時顯示P01,P02等菜單項(xiàng)
- bit jinzhicaozuo=1;//用于設(shè)置模式下某時刻禁止編碼器操作
- bit xianship;//用于設(shè)置模式下顯示菜單P01,P02等的字母P
- bit wendujiaqiang;//溫度加強(qiáng)開關(guān)
- bit wendujiaqiangjishukaiguan;//溫度加強(qiáng)計數(shù)開關(guān)
- bit moshijishukaiguan;//編碼器按下時間計數(shù)開關(guān),用來判斷長按還是短按
- signed char wenduxiuzheng;
- signed int huancun;//顯示函數(shù)直接顯示huancun,要顯示一個數(shù)據(jù)將必須這個數(shù)據(jù)賦值給緩存(由于數(shù)碼管只有三位,為了在顯示三位數(shù)同時保持四位數(shù)的精度,所以實(shí)際顯示的是數(shù)據(jù)除以10,支持顯示負(fù)數(shù).但是在參數(shù)設(shè)置模式下顯示的是實(shí)際值,不除以10)
- signed int shiwen;//10倍實(shí)際室溫,即實(shí)際室溫乘以10(為了精確)(允許的室溫范圍為-11度至50度)
- signed int t12wendu;//T12烙鐵頭的實(shí)際溫度(非熱電偶的溫差)(同樣為10倍溫度)
- signed int shedingwendu;//設(shè)定溫度(范圍200~450度)
- signed int wencha;//T12兩個周期間的溫差
- unsigned char zhouqijishu;//加熱周期200ms計數(shù)
- unsigned char jinduzhi;//設(shè)置模式中設(shè)置到了P幾(P00,P01,P02等等)
- unsigned char moshixuanze;//有效值0,1,2;短按編碼器置2,長按置3
- unsigned int jiareshu;//每200ms加熱周期內(nèi)需要加熱的次數(shù)(一次等于1ms,相當(dāng)于加熱占空比)
- unsigned int huancunjishu;//用于改變設(shè)定溫度后保持顯示設(shè)定溫度一段時間再顯示t12溫度(而不是立刻顯示t12溫度)
- unsigned int baocunwendu;//用于進(jìn)入休眠時保存退出休眠時恢復(fù)原來的設(shè)定溫度
- unsigned int zengyi;//運(yùn)算放大器增益
- unsigned int shezhixianshijishu;//設(shè)置模式中用于延時顯示菜單項(xiàng)
- unsigned int moshijishu;//編碼器按下時間計數(shù),用來判斷長按還是短按
- unsigned int shijian;
- unsigned long cankaodianya0,t12dianya,ntcdianya,dianyuandianya;//用于參考電壓(ADC后的直接數(shù)據(jù),未轉(zhuǎn)換為mV),計算電源電壓,熱電偶經(jīng)放大器放大后的電壓和NTC電阻確定的室溫電壓(單位均為mV)
- unsigned long xiumianjishu;//等待多長時間進(jìn)入休眠狀態(tài)(單位ms)
- unsigned long guanjijishu;//等待多長時間進(jìn)入關(guān)機(jī)狀態(tài)(單位ms)
- unsigned long wendujiaqiangjishu;//多長時間退出溫度加強(qiáng)模式(單位ms)
- /********************************EEPROM公共函數(shù)(1)************************************************/
- void gonggonghanshu(void)//所有的公共函數(shù)都是因?yàn)槎啻问褂玫搅?而把它們整理起來再調(diào)用可以減小編譯后的文件大小(迫不得已的做法,因?yàn)閱纹瑱C(jī)的FLASH太小了,否則裝不下程序)
- {
- IAP_TRIG = 0x5a;//發(fā)送5ah到觸發(fā)寄存器
- IAP_TRIG = 0xa5;//發(fā)送a5h到觸發(fā)寄存器
- _nop_();//延時
- IAP_CONTR = 0;//關(guān)閉IAP 功能
- IAP_CMD = 0;//清空命令寄存器
- IAP_TRIG = 0;//清空命令觸發(fā)寄存器
- IAP_ADDRH = 0;//清空地址高位
- IAP_ADDRL = 0;//清空地址低位
- }
- /********************************字節(jié)讀函數(shù)****************************************************/
- unsigned char Byte_Read(unsigned int add)
- {
- IAP_DATA = 0x00;//清空數(shù)據(jù)
- IAP_CONTR = 0x81;//打開IAP,設(shè)置操作等待時間
- IAP_CMD = 0x01;//字節(jié)讀命令
- IAP_ADDRH = add>>8;//設(shè)置高8位地址
- IAP_ADDRL = add&0x00ff;//設(shè)置低8位地址
- gonggonghanshu();
- return (IAP_DATA);//返回讀到的數(shù)據(jù)
- }
- /********************************字節(jié)編程函數(shù)************************************************/
- void Byte_Program(unsigned int add, unsigned char dat)
- {
- IAP_CONTR = 0x81;//打開IAP,設(shè)置操作等待時間
- IAP_CMD = 0x02;//字節(jié)編程命令
- IAP_ADDRH = add>>8;//設(shè)置高8位地址
- IAP_ADDRL = add&0x00ff;//設(shè)置低8位地址
- IAP_DATA = dat;//要編程的數(shù)據(jù)先送進(jìn)IAP_DATA 寄存器
- gonggonghanshu();
- }
- /********************************扇區(qū)擦除函數(shù)************************************************/
- void Sector_Erase(unsigned int add)
- {
- IAP_CONTR = 0x81;//打開IAP,設(shè)置操作等待時間
- IAP_CMD = 0x03;//扇區(qū)擦除命令
- IAP_ADDRH = add>>8;//設(shè)置高8位地址
- IAP_ADDRL = add&0x00ff;//設(shè)置低8位地址
- gonggonghanshu();
- }
- /********************************1ms延時函數(shù)*************************************************/
- void delay_ms (unsigned int a)//24MHz時鐘時的1毫秒延時函數(shù)
- {
- unsigned int b;
- while(a--)
- {
- for(b=0;b<1200;b++);
- }
- }
- /********************************10us延時函數(shù)************************************************/
- void delay_10us (unsigned int a)//24MHz時鐘時的10微秒延時函數(shù)
- {
- unsigned int b;
- while(a--)
- {
- for(b=0;b<12;b++);
- }
- }
- /********************************數(shù)碼管延時關(guān)斷函數(shù)******************************************/
- void guanduan (void)//用于關(guān)斷數(shù)碼管的位選
- {
- delay_ms(1);//延時
- bw=1;//關(guān)斷百位
- sw=1;//關(guān)斷十位
- gw=1;//關(guān)斷個位
- }
- /********************************公共函數(shù)10(顯示)********************************************/
- void gonggonghanshu10(unsigned char a)
- {
- a7=a&0x80;
- a6=a&0x40;
- a5=a&0x20;
- a4=a&0x10;
- a3=a&0x08;
- a2=a&0x04;
- a1=a&0x02;
- tihuan=a&0x01;
- }
- /********************************顯示函數(shù)****************************************************/
- void display(signed int a)//顯示函數(shù)(顯示實(shí)際數(shù)據(jù)除以10(參數(shù)設(shè)置模式除外),支持顯示負(fù)數(shù),負(fù)數(shù)顯示方式為百位顯示負(fù)號"-"十位和個位顯示數(shù)據(jù))
- {
- unsigned char baiwei,shiwei,gewei,d;//定義百位,十位,個位,每次顯示幀數(shù)
- unsigned char f;//用于小數(shù)點(diǎn)閃爍
- signed int c;//用于處理數(shù)字a
- if(a<0)//如果a是負(fù)數(shù)
- c=-a;//取a的相反數(shù)
- else//否則
- c=a;//就直接取a
- if(guanjikaiguan==1&&shezhimoshi==0)//如果是關(guān)機(jī)狀態(tài)
- c=0;//就顯示000
- if(shezhimoshi==0)//如果是正常模式就顯示數(shù)據(jù)的十分之一,如果是設(shè)置模式直接顯示數(shù)據(jù)
- c=c/10;
- baiwei=c/100;//計算百位
- c=c%100;
- shiwei=c/10;//計算十位
- c=c%10;
- gewei=c;//計算個位
- for(d=0;d<20;d++)//顯示部分,每次顯示20個循環(huán)(20幀)
- {
- if(a<0)//如果a是負(fù)數(shù),則百位顯示負(fù)號
- gonggonghanshu10(duanma[10]);
- else if(shezhimoshi==1&&xianship==1)//在設(shè)置模式顯示菜單項(xiàng)時,百位顯示字母P
- gonggonghanshu10(duanma[11]);
- else//否則直接顯示百位
- gonggonghanshu10(duanma[baiwei]);//顯示百位
- if(shijian>6000&&f>1)//如果是溫度加強(qiáng)模式,十位小數(shù)點(diǎn)閃爍
- dot=1;
- bw=0;//打開百位
- guanduan();//延時關(guān)斷百位
- gonggonghanshu10(duanma[shiwei]);//顯示十位
- if(wendujiaqiang==1&&f>1)//如果是溫度加強(qiáng)模式,十位小數(shù)點(diǎn)閃爍
- dot=1;
- sw=0;//打開十位
- guanduan();//延時關(guān)斷十位
- gonggonghanshu10(duanma[gewei]);//顯示個位
- if((xiumiankaiguan==1&&guanjikaiguan==0)&&f>1)//如果是休眠狀態(tài),個位小數(shù)點(diǎn)閃爍
- dot=1;
- gw=0;//打開個位
- guanduan();//延時關(guān)斷個位
- if(d==19)//用于確定小數(shù)點(diǎn)何時點(diǎn)亮(從而實(shí)現(xiàn)閃爍)
- f++;
- if(f==4)
- f=0;
- }
- }
- /********************************ADC公共函數(shù)**************************************************/
- void gonggonghanshu2(void)//此函數(shù)測量單片機(jī)電源電壓
- {
- ADC_CONTR=0x88;//ADC_POWER, SPEED1, SPEED0, ADC_FLAG---ADC_START, CHS2, CHS1, CHS0
- delay_10us(5);//延時等待轉(zhuǎn)換結(jié)束
- ADC_RESL=ADC_RESL&0x03;//取轉(zhuǎn)換結(jié)果低八位中的低二位
- cankaodianya0=(ADC_RES*4+ADC_RESL);//把結(jié)果轉(zhuǎn)換成十進(jìn)制數(shù)據(jù)(10位ADC,最大值1024)
- dianyuandianya=2549760/cankaodianya0;//計算電源電壓,單位mV
- }
- /********************************ADC測電壓函數(shù)************************************************/
- void adc (void)//ADC函數(shù),用于測量和計算各種電壓
- {
- signed char a;//查NTC表用
- signed int b;//兩次溫度求平均值用
- gonggonghanshu2();//公共函數(shù)2(此函數(shù)功能是測量電源電壓,單位mV)
- ADC_CONTR=0x89;//ADC_POWER, SPEED1, SPEED0, ADC_FLAG---ADC_START, CHS2, CHS1, CHS0 轉(zhuǎn)換采用最低速度速,低速更精確(測量t12電壓務(wù)必使用最低速度AD轉(zhuǎn)換,實(shí)測高速誤差大)
- delay_10us(5);
- ADC_RESL=ADC_RESL&0x03;
- t12dianya=(ADC_RES*4+ADC_RESL);
- t12dianya=2490*t12dianya/cankaodianya0;//計算t12電壓,單位mV
-
- ADC_CONTR=0x8a;//ADC_POWER, SPEED1, SPEED0, ADC_FLAG---ADC_START, CHS2, CHS1, CHS0
- delay_10us(5);
- ADC_RESL=ADC_RESL&0x03;
- ntcdianya=(ADC_RES*4+ADC_RESL);
- ntcdianya=2490*ntcdianya/cankaodianya0;//計算ntc電壓,單位mV
- for(a=0;wendubiao[a]<ntcdianya;a++)//查表計算室溫
- {
- if(a>=61)//如果超出表的范圍就取允許的最高溫度(50度)
- break;//并且退出查表
- }
- shiwen=(a-11)*10;//得出室溫(實(shí)際室溫乘以10)
- t12wendu=(t12dianya-canshu[0])*canshu[1]*10/zengyi+shiwen-wenduxiuzheng*10;//計算t12的實(shí)際溫度
- if((t12wendu-b)>-2000&&(t12wendu-b)<2000)//如果兩次溫度相差不超過200度
- t12wendu=(t12wendu+b)/2;//就兩次溫度求平均值
- if(t12wendu<shiwen)//如果t12溫度小于室溫
- t12wendu=shiwen;//就取室溫
- b=t12wendu;//記錄上一次溫度
- if(t12wendu>5000)//如果得出的溫度超過500度,說明沒有插入烙鐵頭或參數(shù)錯誤(因?yàn)槔予F頭的溫度不可能超過500度)
- t12wendu=5000;//顯示500作為錯誤指示(注意顯示函數(shù)顯示的是1/10,所以要顯示500,需要賦值5000)
- if(huancunkaiguan==1)//如果緩存開關(guān)開,說明剛剛改變了設(shè)定溫度
- huancun=shedingwendu;//于是顯示設(shè)定溫度(而不是t12溫度)
- else
- huancun=t12wendu;//否則直接顯示t12溫度
- }
- /********************************定時器0初始化函數(shù)*******************************************/
- void timer0init (void)//定時器0初始化程序,24MHz頻率下,每1ms中斷一次
- {
- TMOD=0x00;//定時模式,16位自動重裝
- TH0=0xf8; //計時1ms
- TL0=0x2f;
- ET0=1;//開啟定時器0中斷
- TR0=1;//啟動定時器0
- }
- /********************************定時器1初始化函數(shù)*******************************************/
- void timer1init (void)//定時器0初始化程序,24MHz頻率下,每1ms中斷一次
- {
- TMOD=0x00;//定時模式,16位自動重裝
- TH1=0xf8; //計時1ms
- TL1=0x2f;
- ET1=1;//開啟定時器1中斷
- TR1=1;//啟動定時器1
- }
- /********************************恢復(fù)默認(rèn)值函數(shù)********************************************/
- void morenzhi(void)//恢復(fù)控制器的默認(rèn)參數(shù)
- {
- unsigned char a;
- Sector_Erase(0x0000);//擦除扇區(qū)
- for(a=0;a<9;a++)//一項(xiàng)一項(xiàng)的查表并存儲參數(shù)
- Byte_Program(a,moren[a]);
- }
- /********************************公共函數(shù)4(退出溫度加強(qiáng))************************************/
- void gonggonghanshu4(void)
- {
- wendujiaqiangjishukaiguan=0;//溫度加強(qiáng)計數(shù)關(guān)閉
- wendujiaqiangjishu=0;//清零溫度加強(qiáng)計數(shù)
- wendujiaqiang=0;//退出溫度加強(qiáng)
- }
- /********************************公共函數(shù)3(編碼器)******************************************/
- void gonggonghanshu3(void)
- {
- ganggangkaiji=0;//已經(jīng)開機(jī)
- if(xiumiankaiguan==1)//如果原來在休眠狀態(tài)
- {
- xiumiankaiguan=0;//停止休眠
- shedingwendu=baocunwendu;//恢復(fù)休眠前的設(shè)定溫度
- }
- xiumianjishukaiguan=1;//允許新的一次休眠計時
- xiumianjishu=0;//從0開始計時
- guanjijishukaiguan=0;//停止關(guān)機(jī)計數(shù)
- guanjikaiguan=0;//退出關(guān)機(jī)狀態(tài)
- gonggonghanshu4();//退出溫度加強(qiáng)
- }
- /********************************公共函數(shù)6(記錄編碼器狀態(tài))**********************************/
- void gonggonghanshu6(void)
- {
- e=encodera;//記錄編碼器a腳此次狀態(tài)
- f=encoderb;//記錄編碼器b腳此次狀態(tài)
- h=bianmaanniu;//記錄編碼按鈕此次狀態(tài)
- }
- /********************************公共函數(shù)8(進(jìn)入休眠)****************************************/
- void gonggonghanshu8(void)
- {
- ganggangkaiji=0;//已經(jīng)開機(jī)
- baocunwendu=shedingwendu;//記錄當(dāng)前設(shè)定溫度
- shedingwendu=2000;//設(shè)定休眠溫度
- xiumiankaiguan=1;//進(jìn)入休眠狀態(tài)
- xiumianjishukaiguan=0;//停止休眠計數(shù)
- xiumianjishu=0;//清零休眠計數(shù)
- guanjijishukaiguan=1;//允許關(guān)機(jī)計數(shù)
- }
- /********************************公共函數(shù)9(確定按下模式)************************************/
- void gonggonghanshu9(void)
- {
- if(h==1&&bianmaanniu==0)//如果按下了編碼器
- moshijishukaiguan=1;//允許按下時間計數(shù)
- if(moshijishukaiguan==1)//如果允許按下時間計數(shù)
- moshijishu++;//就開始計數(shù)
- if(moshijishukaiguan==1&&bianmaanniu==1)//如果在計數(shù)過程中編碼器松開
- {
- moshijishukaiguan=0;//停止按下時間計數(shù)
- if(moshijishu>1500)//
- moshixuanze=3;
- else if(moshijishu>300)//如果按下時間大于0.3秒
- moshixuanze=2;//就是長按
- else//否則
- moshixuanze=1;//就是短按;
- moshijishu=0;//清零計數(shù)
- }
- }
- /********************************編碼器函數(shù)(正常加熱模式調(diào)用)********************************/
- void bianmaqi(void)
- {
- if(e==1&&f==1&&encodera==1&&encoderb==0)//和前一次狀態(tài)比較確定為右旋
- {
- shedingwendu=shedingwendu+canshu[2]*10;//步進(jìn)
- if(shedingwendu>4500)//最高允許450度
- shedingwendu=4500;
- huancun=shedingwendu;//顯示改變后的設(shè)定溫度
- huancunkaiguan=1;//打開緩存開關(guān)(用于延時顯示設(shè)定溫度1.5秒)
- huancunjishu=0;//重新開始緩存計數(shù)
- gonggonghanshu3();
- }
- if(e==1&&f==1&&encodera==0&&encoderb==1)//和前一次狀態(tài)比較確定為左旋
- {
- shedingwendu=shedingwendu-canshu[2]*10;//步進(jìn)
- if(shedingwendu<2000)//最低允許200度
- shedingwendu=2000;
- huancun=shedingwendu;//顯示改變后的設(shè)定溫度
- huancunkaiguan=1;//打開緩存開關(guān)(用于延時顯示設(shè)定溫度1.5秒)
- huancunjishu=0;//重新開始緩存計數(shù)
- gonggonghanshu3();
- }
- gonggonghanshu9();//確定按下模式
- if(moshixuanze==2)//如果是長按
- {
- gonggonghanshu8();//就進(jìn)入休眠狀態(tài)
- moshixuanze=0;//清零按下模式
- }
- if(moshixuanze==3)
- {
- jinduzhi=0;//進(jìn)度值設(shè)為0
- shezhimoshi=1;//進(jìn)入?yún)?shù)設(shè)置模式
- ET0=0;//關(guān)閉定時器0中斷
- TR0=0;//關(guān)閉定時器0
- IE=0x82;//打開定時器1中斷,關(guān)閉定時器0中斷
- timer1init();//初始化定時器1
- ganggangkaiji=1;//認(rèn)為是剛剛開機(jī)
- moshixuanze=0;//清零模式選擇
- }
- if(xiumiankaiguan==0)//如果不是休眠狀態(tài)
- {
- if(moshixuanze==1)//如果是短按
- {
- wendujiaqiang=~wendujiaqiang;//改變溫度加強(qiáng)狀態(tài)
- moshixuanze=0;
- }
- if(wendujiaqiang==1)//如果溫度加強(qiáng)打開
- wendujiaqiangjishukaiguan=1;//開始溫度加強(qiáng)計時
- }
- else//如果是休眠狀態(tài)
- {
- if(moshixuanze==1)//如果是短按
- {
- gonggonghanshu3();//退出溫度加強(qiáng)模式
- moshixuanze=0;//清零按下模式
- }
- }
- gonggonghanshu6();//記錄編碼器狀態(tài)
- }
- /********************************讀取設(shè)置數(shù)據(jù)函數(shù)******************************************/
- void duqushezhishuju(void)//讀取控制器的參數(shù)
- {
- unsigned char a;
- zengyi=Byte_Read(0x0000);//讀取增益原始參數(shù)
- zengyi=zengyi+100;//換算到正確的區(qū)間
- for(a=0;a<7;a++)//讀取其他的參數(shù)值
- {
- canshu[a]=Byte_Read(a+1);
- }
- wenduxiuzheng=canshu[5]-30;
- }
- /********************************保存數(shù)據(jù)函數(shù)**********************************************/
- void baocunshuju(void)//保存控制器數(shù)據(jù)到EEPROM
- {
- unsigned char a;
- Sector_Erase(0x0000);//擦除扇區(qū)
- Byte_Program(0x0000,(zengyi-100));//保存增益參數(shù)
- for(a=0;a<7;a++)//保存其他參數(shù)
- {
- Byte_Program(a+1,canshu[a]);
- }
- }
- /********************************公共函數(shù)7(刷新菜單顯示)*************************************/
- void gonggonghanshu7(void)
- {
- huancun=canshu[jinduzhi-2];
- if(jinduzhi==0)
- huancun=huifumoren;
- if(jinduzhi==1)
- huancun=zengyi;
- if(jinduzhi==7)
- huancun=wenduxiuzheng;
- }
- /********************************公共函數(shù)11(退出設(shè)置模式,進(jìn)入加熱模式)**************************/
- void gonggonghanshu11(void)
- {
- shijian=0;
- moshixuanze=0;
- baocunshuju();//保存數(shù)據(jù)到EEPROM
- xianship=0;//所以百位不再顯示字母P
- shezhimoshi=0;//退出設(shè)置模式
- ET1=0;//關(guān)閉定時器1
- TR1=0;
- IE=0x88;//關(guān)閉定時器1中斷,開啟定時器0中斷
- timer0init();//初始化定時器0,進(jìn)入正常工作模式!!!!!!!!!!!
- ganggangkaiji=1;//認(rèn)為是剛剛開機(jī)
- xiumianjishukaiguan=1;//允許新的一次休眠計時
- xiumianjishu=0;//從0開始計時
- }
- /********************************編碼器函數(shù)2(參數(shù)設(shè)置模式調(diào)用)******************************/
- void bianmaqi2(void)
- {
- gonggonghanshu9();//確定按下模式
- if(e==1&&f==1&&encodera==1&&encoderb==0&&jinzhicaozuo==0)//和前一次狀態(tài)比較確定為右旋
- {
- if(jinduzhi==0)//菜單P00
- huifumoren=1;
- if(jinduzhi==1)//菜單P01
- {
- if(zengyi<350)
- zengyi++;
- }
- if(jinduzhi==2)//菜單P02
- {
- if(canshu[0]<250)
- canshu[0]=canshu[0]+2;
- }
- if(jinduzhi==3)//菜單P03
- {
- if(canshu[1]<50)
- canshu[1]++;
- }
- if(jinduzhi==4)//菜單P04
- {
- if(canshu[2]==0)
- canshu[2]=1;
- else if(canshu[2]==1)
- canshu[2]=2;
- else if(canshu[2]==2)
- canshu[2]=5;
- else if(canshu[2]==5)
- canshu[2]=10;
- }
- if(jinduzhi==5)//菜單P05
- {
- if(canshu[3]<60)
- canshu[3]++;
- }
- if(jinduzhi==6)//菜單P06
- {
- if(canshu[4]<180)
- {
- if(canshu[4]<30)
- canshu[4]++;
- else
- canshu[4]=canshu[4]+10;
- }
- }
- if(jinduzhi==7)//菜單P07
- {
- if(wenduxiuzheng<30)
- {
- wenduxiuzheng++;
- canshu[5]=wenduxiuzheng+30;
- }
- }
- if(jinduzhi==8)//菜單P08
- canshu[6]=1;
- gonggonghanshu7();//刷新菜單顯示
- shijian=0;
- }
- if(e==1&&f==1&&encodera==0&&encoderb==1&&jinzhicaozuo==0)//和前一次狀態(tài)比較確定為左旋
- {
- if(jinduzhi==0)//同上,不再贅述
- huifumoren=0;
- if(jinduzhi==1)
- {
- if(zengyi>200)
- zengyi--;
- }
- if(jinduzhi==2)
- {
- if(canshu[0]>=2)
- canshu[0]=canshu[0]-2;
- }
- if(jinduzhi==3)
- {
- if(canshu[1]>30)
- canshu[1]--;
- }
- if(jinduzhi==4)
- {
- if(canshu[2]==1)
- canshu[2]=0;
- else if(canshu[2]==2)
- canshu[2]=1;
- else if(canshu[2]==5)
- canshu[2]=2;
- else if(canshu[2]==10)
- canshu[2]=5;
- }
- if(jinduzhi==5)
- {
- if(canshu[3]>0)
- canshu[3]--;
- }
- if(jinduzhi==6)
- {
- if(canshu[4]>0)
- {
- if(canshu[4]<31)
- canshu[4]--;
- else
- canshu[4]=canshu[4]-10;
- }
- }
- if(jinduzhi==7)
- {
- if(wenduxiuzheng>-30)
- {
- wenduxiuzheng--;
- canshu[5]=wenduxiuzheng+30;
- }
- }
- if(jinduzhi==8)
- canshu[6]=0;
- gonggonghanshu7();//刷新菜單顯示
- shijian=0;
- }
- if(shijian>8000)//如果超過設(shè)定時間
- gonggonghanshu11();//自動退出參數(shù)設(shè)置模式,進(jìn)入加熱模式
- if(h==0&&bianmaanniu==1&&jinzhicaozuo==0)//如果按下編碼按鈕,并且此時允許操作編碼器
- {
- if(jinduzhi==0&&huifumoren==1)//如果在P00菜單選擇了恢復(fù)默認(rèn)值
- {
- morenzhi();//就恢復(fù)默認(rèn)值
- duqushezhishuju();//并重新讀取數(shù)據(jù)到RAM
- }
- jinduzhi++;//菜單數(shù)加一(即下一項(xiàng)菜單)
- xianship=1;//百位顯示字母P
- huancun=jinduzhi;//顯示新的菜單項(xiàng)(指P幾菜單)
- jinzhicaozuo=1;//由于菜單項(xiàng)要延遲顯示1.5秒才顯示菜單對應(yīng)的參數(shù),所以顯示菜單項(xiàng)的時候禁止操作編碼器改變參數(shù)
- shezhixianshijishukaiguan=1;//允許開始新的延遲計數(shù)(1.5秒)
- shezhixianshijishu=0;//從0開始計數(shù)
- baocunshuju();//保存數(shù)據(jù)到EEPROM
- if(jinduzhi==9||moshixuanze==3)//菜單項(xiàng)最大為P08,如果到了P09說明所有的菜單都設(shè)置完了
- gonggonghanshu11();//退出參數(shù)設(shè)置模式,進(jìn)入加熱模式
- }
- gonggonghanshu6();//記錄編碼器狀態(tài)
- if(bianmaanniu==0)
- shijian=0;
- }
- /********************************掉電存儲函數(shù)*********************************************/
- void diaodiancunchu(void)//用于關(guān)機(jī)時存儲溫度數(shù)據(jù),以便下次開機(jī)時恢復(fù)溫度
- {
- gonggonghanshu2();//檢測電源電壓
- if(dianyuandianya<4850)//如果電源電壓降低到4.85V說明掉電了
- {
- P2=0x00;//關(guān)閉數(shù)碼管位選和t12(即停止顯示,停止加熱),節(jié)約電量
- P3=0x70;//關(guān)閉替換腳,關(guān)閉位選腳,節(jié)約電量
- if(xiumiankaiguan==1)//如果是休眠狀態(tài)
- shedingwendu=baocunwendu;//就恢復(fù)休眠前的溫度
- Sector_Erase(0x0200);//擦除扇區(qū)
- Byte_Program(0x0200,(shedingwendu/10-200));//寫入溫度到EEPROM
- delay_ms(40);//等待寫入完畢
- t12=1;//設(shè)定溫度已經(jīng)保存,于是加熱t(yī)12以盡快耗盡電容電量,加速關(guān)機(jī)
- delay_ms(1000);//最多加熱1S
- }
- }
- /********************************震動休眠函數(shù)**********************************************/
- void zhendongxiumian(void)
- {
- if(zhendongkaiguan!=g)//震動開關(guān)狀態(tài)改變,說明晃動了手柄
- {
- ganggangkaiji=0;//已經(jīng)開機(jī)
- xiumianjishu=0;//清零休眠計數(shù)
- xiumianjishukaiguan=1;//開始新的休眠計數(shù)
- if((xiumiankaiguan==1&&guanjikaiguan==0)||(xiumiankaiguan==1&&guanjikaiguan==1&&canshu[6]==0))//
- {
- xiumiankaiguan=0;//停止休眠
- shedingwendu=baocunwendu;//恢復(fù)原來的溫度
- xiumianjishukaiguan=1;//允許新一次休眠計數(shù)
- xiumianjishu=0;//從0開始計數(shù)
- guanjijishukaiguan=0;//停止關(guān)機(jī)計數(shù)
- guanjikaiguan=0;//退出關(guān)機(jī)狀態(tài)(如果原來是關(guān)機(jī)狀態(tài)的話)
- }
- }
- g=zhendongkaiguan;//保存當(dāng)前震動傳感器狀態(tài)(用于和下一次比較,以便確定是否震動了)
- }
- /********************************定時器0中斷函數(shù)********************************************/
- void timer0(void) interrupt 1//定時0中斷函數(shù),用于檢測旋轉(zhuǎn)編碼器,掉電存儲等操作(僅用于正常工作模式)
- {
- unsigned int a,b;
- unsigned char buchang;
- diaodiancunchu();//調(diào)用掉電存儲函數(shù)
- bianmaqi();//調(diào)用編碼器函數(shù)
- zhendongxiumian();//調(diào)用震動休眠函數(shù)
- if(huancunkaiguan==1)//延時顯示計數(shù)
- huancunjishu++;
- if(xiumianjishukaiguan==1||ganggangkaiji==1)//休眠計數(shù)
- {
- if(wendujiaqiang==0)//如果不是溫度加強(qiáng)模式
- xiumianjishu++;//就計數(shù)
- else//否則
- xiumianjishu=1;//不計數(shù)
- }
- if(guanjijishukaiguan==1||canshu[4]==0)//關(guān)機(jī)計數(shù)
- guanjijishu++;
- if(wendujiaqiangjishukaiguan==1)//溫度加強(qiáng)計數(shù)
- wendujiaqiangjishu++;
- if(wendujiaqiangjishu==60000)//如果到達(dá)設(shè)定的溫度加強(qiáng)時間(60s)
- gonggonghanshu4();//退出溫度加強(qiáng)模式
- if(xiumianjishu==canshu[3]*60000)//如果達(dá)到設(shè)定時間就休眠
- gonggonghanshu8();//進(jìn)入休眠模式
-
- if(guanjijishu==canshu[4]*60000)//如果關(guān)機(jī)計數(shù)達(dá)到了設(shè)定的時間
- {
- guanjikaiguan=1;//進(jìn)入關(guān)機(jī)狀態(tài)
- guanjijishukaiguan=0;//停止關(guān)機(jī)計數(shù)
- guanjijishu=0;//清零關(guān)機(jī)計數(shù)
- }
- zhouqijishu++;//加熱周期計數(shù)
- if(jiareshu>196)//最多加熱196ms
- jiareshu=196;
- if((zhouqijishu<=jiareshu)&&(guanjikaiguan==0))//如果當(dāng)前計數(shù)小于等于加熱數(shù)并且不是關(guān)機(jī)模式
- t12=1;//就加熱
- else//否則
- t12=0;//不加熱
- if(t12wendu==5000)//如果t12溫度為500,說明沒有插入烙鐵頭或參數(shù)嚴(yán)重錯誤
- t12=0;//停止加熱
- if(huancunjishu==1500)//設(shè)定溫度延時顯示1.5秒
- {
- huancunkaiguan=0;//如果達(dá)到了1.5秒,關(guān)閉緩存開關(guān)
- huancunjishu=0;//停止緩存計數(shù)
- huancun=t12wendu;//由顯示設(shè)定溫度改為顯示t12溫度
- }
- if(zhouqijishu==200)//t12停止加熱后2ms再檢測溫度(給電容留出放電時間,防止檢測的溫度偏高)
- {
- adc();//檢測電壓,計算溫度
- zhouqijishu=0;//重新開始加熱周期計數(shù)
- if(wendujiaqiang==1)
- a=shedingwendu+515;
- else
- a=shedingwendu+15;
- if(a>4515)
- a=4515; //////////////////////////以下為加熱算法(請自行理解,不作注釋)//////////////////////
- if(t12wendu>a)
- {
- if(t12wendu-a<=20)
- jiareshu=(t12wendu-a)/4+a/1000;
- else
- jiareshu=0;
- }
- if(t12wendu<=a)
- {
- wencha=a-t12wendu;
- if(wencha>30)
- {
- buchang++;
- if(buchang>150)
- buchang=150;
- }
- else
- buchang=0;
- if(a-t12wendu>=300)
- jiareshu=198;
- else if(a-t12wendu>=200)
- jiareshu=160;
- else if(a-t12wendu>=150)
- jiareshu=130;
- else if(a-t12wendu>=100)
- jiareshu=90+wencha/2+buchang;
- else if(a-t12wendu>=50)
- jiareshu=50+buchang*2;
- else
- jiareshu=shedingwendu/400+wencha*2/3+buchang;
- }
- }
- if((b>t12wendu)&&(t12wendu<shedingwendu-30))
- jiareshu=jiareshu+50;
- b=t12wendu;
- }
- /********************************定時器1中斷函數(shù)*******************************************/
- void timer1(void) interrupt 3//定時器1中斷僅用于參數(shù)設(shè)置模式
- {
- shijian++;
- t12=0;
- bianmaqi2();//調(diào)用編碼器2函數(shù)
- if(ganggangkaiji==1)//如果剛剛開機(jī)
- {
- xianship=1;//百位顯示字母P
- huancun=jinduzhi;//顯示菜單P00(因?yàn)榇藭r進(jìn)度值為0)
- ganggangkaiji=0;//已經(jīng)開機(jī)
- shezhixianshijishukaiguan=1;//允許設(shè)置顯示計數(shù)
- }
- if(shezhixianshijishukaiguan==1)//如果允許設(shè)置顯示計數(shù),就開始計數(shù)
- shezhixianshijishu++;
- if(shezhixianshijishu==1500)//如果計數(shù)到規(guī)定的1.5s
- {
- xianship=0;//停止顯示百位的字母P
- shezhixianshijishukaiguan=0;//停止設(shè)置顯示計數(shù)
- shezhixianshijishu=0;//清零計數(shù)
- jinzhicaozuo=0;//此時禁止操作編碼器
- huancun=canshu[jinduzhi-2];
- if(jinduzhi==0)//顯示當(dāng)前菜單項(xiàng)對應(yīng)的參數(shù)(P00的參數(shù))
- huancun=huifumoren;
- if(jinduzhi==1)//同上,不再贅述
- huancun=zengyi;
- if(jinduzhi==7)
- huancun=wenduxiuzheng;
- jinzhicaozuo=0;//禁止編碼器操作
- }
- }
- /********************************主函數(shù)*****************************************************/
- void main (void)//主函數(shù)
- {
- P1M0=0x00;//P1除P1.0,P1.1,P1.2為輸入模式外均為正常模式
- P1M1=0x07;
- P1ASF=0x07;//設(shè)置P1相應(yīng)ADC轉(zhuǎn)換的I/O口為ADC輸入模式
- P2M0=0xff;//P2都是推挽模式
- P2M1=0x00;
- P3M0=0xf0;//P3.4,P3.5,P3.6,P3.7為推挽模式,P3.2,P3.3為輸入模式,其余正常模式
- P3M1=0x06;
- ADC_CONTR=0xe0;//打開ADC電源
- shedingwendu=Byte_Read(0x0200);//讀取上次關(guān)機(jī)時保存的設(shè)定溫度
- shedingwendu=(shedingwendu+200)*10;
- if(shedingwendu>4500||shedingwendu<2000)//如果讀取的設(shè)定溫度超出范圍
- shedingwendu=3000;//就設(shè)為300度
- duqushezhishuju();//讀取控制器的設(shè)置參數(shù)
- if(bianmaanniu==0)//如果開機(jī)時編碼按鈕是低電平(即按下了按鈕)
- {
- shezhimoshi=1;//進(jìn)入?yún)?shù)設(shè)置模式
- IE=0x82;//打開定時器1中斷,關(guān)閉定時器0中斷
- timer1init();//初始化定時器1
- }
- else//如果開機(jī)時沒有按下編碼器按鈕
- {
- shezhimoshi=0;//進(jìn)入正常加熱模式
- IE=0x88;//打開定時器0中斷,關(guān)閉定時器1中斷
- timer0init();//初始化定時器0
- }
- while(1)
- {
- display(huancun);//數(shù)碼管顯示數(shù)據(jù)
- }
- }
復(fù)制代碼 以上為金大師STC15F204EA T12數(shù)碼管焊臺固件,本人小白。只知道改引腳P5.5,后來發(fā)現(xiàn)STC15W408AS沒有定時器1,導(dǎo)致刷了程序?qū)е耇12無法正常工作,請教大佬們怎么把定時器1改成定時器2。
|
|