- /*****************STC15W408AS单片机旋转编码器版白光T12控制器代码(by金向维)***********************/
- #include "STC15W408AS.h"//单片机头文件,24MHz时钟频率
- #include "INTRINS.h"//头文件
- unsigned char code duanma[12]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40,0x73};//共阴数码管段码数据(0,1,2,3,4,5,6,7,8,9),倒数第二个是显示负号-的数据,倒数第一个是显示字母P的数据
- 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};//根据NTC电阻随温度变化进而引起电压变化得出的数据,用来查表计算室温(进而对热电偶冷端补偿)
- unsigned char code moren[8]={150,100,43,10,3,5,30,0};//白光控制器的默认参数
- unsigned char canshu[7]={100,43,10,3,5,30,0};//部分参数,依次为:失调电压,热电偶数据,温度步进,休眠时间,关机时间,温度修正,唤醒方式
- sbit dot=P2^7;//数码管的小数点接P2.7
- sbit t12=P2^0;//T12通过P2.0控制
- sbit bw=P3^4;//数码管百位位选为P3.4
- sbit sw=P3^5;//数码管十位位选为P3.5
- sbit gw=P3^6;//数码管个位位选为P3.6
- sbit tihuan=P3^7;//数码管的a段本应该用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;//震动开关接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用来保存编码器上一次的状态,g用来保存震动开关上一次的状态
- bit huancunkaiguan=0;//用于改变设定温度后延时显示设定温度(而不是立刻显示t12温度)
- bit xiumiankaiguan=0;//定义休眠开关
- bit xiumianjishukaiguan=0;//定义休眠计数开关
- bit ganggangkaiji=1;//定义刚刚开机(用于确保刚开机未震动手柄能进入休眠状态,因为每次休眠计时是通过震动传感器状态改变触发的,而刚开机手柄没有震动所以要特殊处理)
- bit guanjikaiguan=0;//定义关机开关
- bit guanjijishukaiguan;//定义关机计数开关
- bit huifumoren=0;//是否恢复默认参数
- bit shezhimoshi=0;//设置模式还是正常工作模式
- bit shezhixianshijishukaiguan;//用于设置模式延时显示P01,P02等菜单项
- bit jinzhicaozuo=1;//用于设置模式下某时刻禁止编码器操作
- bit xianship;//用于设置模式下显示菜单P01,P02等的字母P
- bit wendujiaqiang;//温度加强开关
- bit wendujiaqiangjishukaiguan;//温度加强计数开关
- bit moshijishukaiguan;//编码器按下时间计数开关,用来判断长按还是短按
- signed char wenduxiuzheng;
- signed int huancun;//显示函数直接显示huancun,要显示一个数据将必须这个数据赋值给缓存(由于数码管只有三位,为了在显示三位数同时保持四位数的精度,所以实际显示的是数据除以10,支持显示负数.但是在参数设置模式下显示的是实际值,不除以10)
- signed int shiwen;//10倍实际室温,即实际室温乘以10(为了精确)(允许的室温范围为-11度至50度)
- signed int t12wendu;//T12烙铁头的实际温度(非热电偶的温差)(同样为10倍温度)
- signed int shedingwendu;//设定温度(范围200~450度)
- signed int wencha;//T12两个周期间的温差
- unsigned char zhouqijishu;//加热周期200ms计数
- unsigned char jinduzhi;//设置模式中设置到了P几(P00,P01,P02等等)
- unsigned char moshixuanze;//有效值0,1,2;短按编码器置2,长按置3
- unsigned int jiareshu;//每200ms加热周期内需要加热的次数(一次等于1ms,相当于加热占空比)
- unsigned int huancunjishu;//用于改变设定温度后保持显示设定温度一段时间再显示t12温度(而不是立刻显示t12温度)
- unsigned int baocunwendu;//用于进入休眠时保存退出休眠时恢复原来的设定温度
- unsigned int zengyi;//运算放大器增益
- unsigned int shezhixianshijishu;//设置模式中用于延时显示菜单项
- unsigned int moshijishu;//编码器按下时间计数,用来判断长按还是短按
- unsigned int shijian;
- unsigned long cankaodianya0,t12dianya,ntcdianya,dianyuandianya;//用于参考电压(ADC后的直接数据,未转换为mV),计算电源电压,热电偶经放大器放大后的电压和NTC电阻确定的室温电压(单位均为mV)
- unsigned long xiumianjishu;//等待多长时间进入休眠状态(单位ms)
- unsigned long guanjijishu;//等待多长时间进入关机状态(单位ms)
- unsigned long wendujiaqiangjishu;//多长时间退出温度加强模式(单位ms)
- /********************************EEPROM公共函数(1)************************************************/
- void gonggonghanshu(void)//所有的公共函数都是因为多次使用到了,而把它们整理起来再调用可以减小编译后的文件大小(迫不得已的做法,因为单片机的FLASH太小了,否则装不下程序)
- {
- IAP_TRIG = 0x5a;//发送5ah到触发寄存器
- IAP_TRIG = 0xa5;//发送a5h到触发寄存器
- _nop_();//延时
- IAP_CONTR = 0;//关闭IAP 功能
- IAP_CMD = 0;//清空命令寄存器
- IAP_TRIG = 0;//清空命令触发寄存器
- IAP_ADDRH = 0;//清空地址高位
- IAP_ADDRL = 0;//清空地址低位
- }
- /********************************字节读函数****************************************************/
- unsigned char Byte_Read(unsigned int add)
- {
- IAP_DATA = 0x00;//清空数据
- IAP_CONTR = 0x81;//打开IAP,设置操作等待时间
- IAP_CMD = 0x01;//字节读命令
- IAP_ADDRH = add>>8;//设置高8位地址
- IAP_ADDRL = add&0x00ff;//设置低8位地址
- gonggonghanshu();
- 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 寄存器
- gonggonghanshu();
- }
- /********************************扇区擦除函数************************************************/
- void Sector_Erase(unsigned int add)
- {
- IAP_CONTR = 0x81;//打开IAP,设置操作等待时间
- IAP_CMD = 0x03;//扇区擦除命令
- IAP_ADDRH = add>>8;//设置高8位地址
- IAP_ADDRL = add&0x00ff;//设置低8位地址
- gonggonghanshu();
- }
- /********************************1ms延时函数*************************************************/
- void delay_ms (unsigned int a)//24MHz时钟时的1毫秒延时函数
- {
- unsigned int b;
- while(a--)
- {
- for(b=0;b<1200;b++);
- }
- }
- /********************************10us延时函数************************************************/
- void delay_10us (unsigned int a)//24MHz时钟时的10微秒延时函数
- {
- unsigned int b;
- while(a--)
- {
- for(b=0;b<12;b++);
- }
- }
- /********************************数码管延时关断函数******************************************/
- void guanduan (void)//用于关断数码管的位选
- {
- delay_ms(1);//延时
- bw=1;//关断百位
- sw=1;//关断十位
- gw=1;//关断个位
- }
- /********************************公共函数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;
- }
- /********************************显示函数****************************************************/
- void display(signed int a)//显示函数(显示实际数据除以10(参数设置模式除外),支持显示负数,负数显示方式为百位显示负号"-"十位和个位显示数据)
- {
- unsigned char baiwei,shiwei,gewei,d;//定义百位,十位,个位,每次显示帧数
- unsigned char f;//用于小数点闪烁
- signed int c;//用于处理数字a
- if(a<0)//如果a是负数
- c=-a;//取a的相反数
- else//否则
- c=a;//就直接取a
- if(guanjikaiguan==1&&shezhimoshi==0)//如果是关机状态
- c=0;//就显示000
- if(shezhimoshi==0)//如果是正常模式就显示数据的十分之一,如果是设置模式直接显示数据
- c=c/10;
- baiwei=c/100;//计算百位
- c=c%100;
- shiwei=c/10;//计算十位
- c=c%10;
- gewei=c;//计算个位
- for(d=0;d<20;d++)//显示部分,每次显示20个循环(20帧)
- {
- if(a<0)//如果a是负数,则百位显示负号
- gonggonghanshu10(duanma[10]);
- else if(shezhimoshi==1&&xianship==1)//在设置模式显示菜单项时,百位显示字母P
- gonggonghanshu10(duanma[11]);
- else//否则直接显示百位
- gonggonghanshu10(duanma[baiwei]);//显示百位
- if(shijian>6000&&f>1)//如果是温度加强模式,十位小数点闪烁
- dot=1;
- bw=0;//打开百位
- guanduan();//延时关断百位
- gonggonghanshu10(duanma[shiwei]);//显示十位
- if(wendujiaqiang==1&&f>1)//如果是温度加强模式,十位小数点闪烁
- dot=1;
- sw=0;//打开十位
- guanduan();//延时关断十位
- gonggonghanshu10(duanma[gewei]);//显示个位
- if((xiumiankaiguan==1&&guanjikaiguan==0)&&f>1)//如果是休眠状态,个位小数点闪烁
- dot=1;
- gw=0;//打开个位
- guanduan();//延时关断个位
- if(d==19)//用于确定小数点何时点亮(从而实现闪烁)
- f++;
- if(f==4)
- f=0;
- }
- }
- /********************************ADC公共函数**************************************************/
- void gonggonghanshu2(void)//此函数测量单片机电源电压
- {
- ADC_CONTR=0x88;//ADC_POWER, SPEED1, SPEED0, ADC_FLAG---ADC_START, CHS2, CHS1, CHS0
- delay_10us(5);//延时等待转换结束
- ADC_RESL=ADC_RESL&0x03;//取转换结果低八位中的低二位
- cankaodianya0=(ADC_RES*4+ADC_RESL);//把结果转换成十进制数据(10位ADC,最大值1024)
- dianyuandianya=2549760/cankaodianya0;//计算电源电压,单位mV
- }
- /********************************ADC测电压函数************************************************/
- void adc (void)//ADC函数,用于测量和计算各种电压
- {
- signed char a;//查NTC表用
- signed int b;//两次温度求平均值用
- gonggonghanshu2();//公共函数2(此函数功能是测量电源电压,单位mV)
- ADC_CONTR=0x89;//ADC_POWER, SPEED1, SPEED0, ADC_FLAG---ADC_START, CHS2, CHS1, CHS0 转换采用最低速度速,低速更精确(测量t12电压务必使用最低速度AD转换,实测高速误差大)
- 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;//得出室温(实际室温乘以10)
- t12wendu=(t12dianya-canshu[0])*canshu[1]*10/zengyi+shiwen-wenduxiuzheng*10;//计算t12的实际温度
- if((t12wendu-b)>-2000&&(t12wendu-b)<2000)//如果两次温度相差不超过200度
- t12wendu=(t12wendu+b)/2;//就两次温度求平均值
- if(t12wendu<shiwen)//如果t12温度小于室温
- t12wendu=shiwen;//就取室温
- b=t12wendu;//记录上一次温度
- if(t12wendu>5000)//如果得出的温度超过500度,说明没有插入烙铁头或参数错误(因为烙铁头的温度不可能超过500度)
- t12wendu=5000;//显示500作为错误指示(注意显示函数显示的是1/10,所以要显示500,需要赋值5000)
- if(huancunkaiguan==1)//如果缓存开关开,说明刚刚改变了设定温度
- huancun=shedingwendu;//于是显示设定温度(而不是t12温度)
- else
- huancun=t12wendu;//否则直接显示t12温度
- }
- /********************************定时器0初始化函数*******************************************/
- void timer0init (void)//定时器0初始化程序,24MHz频率下,每1ms中断一次
- {
- TMOD=0x00;//定时模式,16位自动重装
- TH0=0xf8; //计时1ms
- TL0=0x2f;
- ET0=1;//开启定时器0中断
- TR0=1;//启动定时器0
- }
- /********************************定时器1初始化函数*******************************************/
- void timer1init (void)//定时器0初始化程序,24MHz频率下,每1ms中断一次
- {
- TMOD=0x00;//定时模式,16位自动重装
- TH1=0xf8; //计时1ms
- TL1=0x2f;
- ET1=1;//开启定时器1中断
- TR1=1;//启动定时器1
- }
- /********************************恢复默认值函数********************************************/
- void morenzhi(void)//恢复控制器的默认参数
- {
- unsigned char a;
- Sector_Erase(0x0000);//擦除扇区
- for(a=0;a<9;a++)//一项一项的查表并存储参数
- Byte_Program(a,moren[a]);
- }
- /********************************公共函数4(退出温度加强)************************************/
- void gonggonghanshu4(void)
- {
- wendujiaqiangjishukaiguan=0;//温度加强计数关闭
- wendujiaqiangjishu=0;//清零温度加强计数
- wendujiaqiang=0;//退出温度加强
- }
- /********************************公共函数3(编码器)******************************************/
- void gonggonghanshu3(void)
- {
- ganggangkaiji=0;//已经开机
- if(xiumiankaiguan==1)//如果原来在休眠状态
- {
- xiumiankaiguan=0;//停止休眠
- shedingwendu=baocunwendu;//恢复休眠前的设定温度
- }
- xiumianjishukaiguan=1;//允许新的一次休眠计时
- xiumianjishu=0;//从0开始计时
- guanjijishukaiguan=0;//停止关机计数
- guanjikaiguan=0;//退出关机状态
- gonggonghanshu4();//退出温度加强
- }
- /********************************公共函数6(记录编码器状态)**********************************/
- void gonggonghanshu6(void)
- {
- e=encodera;//记录编码器a脚此次状态
- f=encoderb;//记录编码器b脚此次状态
- h=bianmaanniu;//记录编码按钮此次状态
- }
- /********************************公共函数8(进入休眠)****************************************/
- void gonggonghanshu8(void)
- {
- ganggangkaiji=0;//已经开机
- baocunwendu=shedingwendu;//记录当前设定温度
- shedingwendu=2000;//设定休眠温度
- xiumiankaiguan=1;//进入休眠状态
- xiumianjishukaiguan=0;//停止休眠计数
- xiumianjishu=0;//清零休眠计数
- guanjijishukaiguan=1;//允许关机计数
- }
- /********************************公共函数9(确定按下模式)************************************/
- void gonggonghanshu9(void)
- {
- if(h==1&&bianmaanniu==0)//如果按下了编码器
- moshijishukaiguan=1;//允许按下时间计数
- if(moshijishukaiguan==1)//如果允许按下时间计数
- moshijishu++;//就开始计数
- if(moshijishukaiguan==1&&bianmaanniu==1)//如果在计数过程中编码器松开
- {
- moshijishukaiguan=0;//停止按下时间计数
- if(moshijishu>1500)//
- moshixuanze=3;
- else if(moshijishu>300)//如果按下时间大于0.3秒
- moshixuanze=2;//就是长按
- else//否则
- moshixuanze=1;//就是短按;
- moshijishu=0;//清零计数
- }
- }
- /********************************编码器函数(正常加热模式调用)********************************/
- void bianmaqi(void)
- {
- if(e==1&&f==1&&encodera==1&&encoderb==0)//和前一次状态比较确定为右旋
- {
- shedingwendu=shedingwendu+canshu[2]*10;//步进
- if(shedingwendu>4500)//最高允许450度
- shedingwendu=4500;
- huancun=shedingwendu;//显示改变后的设定温度
- huancunkaiguan=1;//打开缓存开关(用于延时显示设定温度1.5秒)
- huancunjishu=0;//重新开始缓存计数
- gonggonghanshu3();
- }
- if(e==1&&f==1&&encodera==0&&encoderb==1)//和前一次状态比较确定为左旋
- {
- shedingwendu=shedingwendu-canshu[2]*10;//步进
- if(shedingwendu<2000)//最低允许200度
- shedingwendu=2000;
- huancun=shedingwendu;//显示改变后的设定温度
- huancunkaiguan=1;//打开缓存开关(用于延时显示设定温度1.5秒)
- huancunjishu=0;//重新开始缓存计数
- gonggonghanshu3();
- }
- gonggonghanshu9();//确定按下模式
- if(moshixuanze==2)//如果是长按
- {
- gonggonghanshu8();//就进入休眠状态
- moshixuanze=0;//清零按下模式
- }
- if(moshixuanze==3)
- {
- jinduzhi=0;//进度值设为0
- shezhimoshi=1;//进入参数设置模式
- ET0=0;//关闭定时器0中断
- TR0=0;//关闭定时器0
- IE=0x82;//打开定时器1中断,关闭定时器0中断
- timer1init();//初始化定时器1
- ganggangkaiji=1;//认为是刚刚开机
- moshixuanze=0;//清零模式选择
- }
- if(xiumiankaiguan==0)//如果不是休眠状态
- {
- if(moshixuanze==1)//如果是短按
- {
- wendujiaqiang=~wendujiaqiang;//改变温度加强状态
- moshixuanze=0;
- }
- if(wendujiaqiang==1)//如果温度加强打开
- wendujiaqiangjishukaiguan=1;//开始温度加强计时
- }
- else//如果是休眠状态
- {
- if(moshixuanze==1)//如果是短按
- {
- gonggonghanshu3();//退出温度加强模式
- moshixuanze=0;//清零按下模式
- }
- }
- gonggonghanshu6();//记录编码器状态
- }
- /********************************读取设置数据函数******************************************/
- void duqushezhishuju(void)//读取控制器的参数
- {
- unsigned char a;
- zengyi=Byte_Read(0x0000);//读取增益原始参数
- zengyi=zengyi+100;//换算到正确的区间
- for(a=0;a<7;a++)//读取其他的参数值
- {
- canshu[a]=Byte_Read(a+1);
- }
- wenduxiuzheng=canshu[5]-30;
- }
- /********************************保存数据函数**********************************************/
- void baocunshuju(void)//保存控制器数据到EEPROM
- {
- unsigned char a;
- Sector_Erase(0x0000);//擦除扇区
- Byte_Program(0x0000,(zengyi-100));//保存增益参数
- for(a=0;a<7;a++)//保存其他参数
- {
- Byte_Program(a+1,canshu[a]);
- }
- }
- /********************************公共函数7(刷新菜单显示)*************************************/
- void gonggonghanshu7(void)
- {
- huancun=canshu[jinduzhi-2];
- if(jinduzhi==0)
- huancun=huifumoren;
- if(jinduzhi==1)
- huancun=zengyi;
- if(jinduzhi==7)
- huancun=wenduxiuzheng;
- }
- /********************************公共函数11(退出设置模式,进入加热模式)**************************/
- void gonggonghanshu11(void)
- {
- shijian=0;
- moshixuanze=0;
- baocunshuju();//保存数据到EEPROM
- xianship=0;//所以百位不再显示字母P
- shezhimoshi=0;//退出设置模式
- ET1=0;//关闭定时器1
- TR1=0;
- IE=0x88;//关闭定时器1中断,开启定时器0中断
- timer0init();//初始化定时器0,进入正常工作模式!!!!!!!!!!!
- ganggangkaiji=1;//认为是刚刚开机
- xiumianjishukaiguan=1;//允许新的一次休眠计时
- xiumianjishu=0;//从0开始计时
- }
- /********************************编码器函数2(参数设置模式调用)******************************/
- void bianmaqi2(void)
- {
- gonggonghanshu9();//确定按下模式
- if(e==1&&f==1&&encodera==1&&encoderb==0&&jinzhicaozuo==0)//和前一次状态比较确定为右旋
- {
- 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)//和前一次状态比较确定为左旋
- {
- 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)//如果超过设定时间
- gonggonghanshu11();//自动退出参数设置模式,进入加热模式
- if(h==0&&bianmaanniu==1&&jinzhicaozuo==0)//如果按下编码按钮,并且此时允许操作编码器
- {
- if(jinduzhi==0&&huifumoren==1)//如果在P00菜单选择了恢复默认值
- {
- morenzhi();//就恢复默认值
- duqushezhishuju();//并重新读取数据到RAM
- }
- jinduzhi++;//菜单数加一(即下一项菜单)
- xianship=1;//百位显示字母P
- huancun=jinduzhi;//显示新的菜单项(指P几菜单)
- jinzhicaozuo=1;//由于菜单项要延迟显示1.5秒才显示菜单对应的参数,所以显示菜单项的时候禁止操作编码器改变参数
- shezhixianshijishukaiguan=1;//允许开始新的延迟计数(1.5秒)
- shezhixianshijishu=0;//从0开始计数
- baocunshuju();//保存数据到EEPROM
- if(jinduzhi==9||moshixuanze==3)//菜单项最大为P08,如果到了P09说明所有的菜单都设置完了
- gonggonghanshu11();//退出参数设置模式,进入加热模式
- }
- gonggonghanshu6();//记录编码器状态
- if(bianmaanniu==0)
- shijian=0;
- }
- /********************************掉电存储函数*********************************************/
- void diaodiancunchu(void)//用于关机时存储温度数据,以便下次开机时恢复温度
- {
- gonggonghanshu2();//检测电源电压
- if(dianyuandianya<4850)//如果电源电压降低到4.85V说明掉电了
- {
- P2=0x00;//关闭数码管位选和t12(即停止显示,停止加热),节约电量
- P3=0x70;//关闭替换脚,关闭位选脚,节约电量
- if(xiumiankaiguan==1)//如果是休眠状态
- shedingwendu=baocunwendu;//就恢复休眠前的温度
- Sector_Erase(0x0200);//擦除扇区
- Byte_Program(0x0200,(shedingwendu/10-200));//写入温度到EEPROM
- delay_ms(40);//等待写入完毕
- t12=1;//设定温度已经保存,于是加热t12以尽快耗尽电容电量,加速关机
- delay_ms(1000);//最多加热1S
- }
- }
- /********************************震动休眠函数**********************************************/
- void zhendongxiumian(void)
- {
- if(zhendongkaiguan!=g)//震动开关状态改变,说明晃动了手柄
- {
- ganggangkaiji=0;//已经开机
- xiumianjishu=0;//清零休眠计数
- xiumianjishukaiguan=1;//开始新的休眠计数
- if((xiumiankaiguan==1&&guanjikaiguan==0)||(xiumiankaiguan==1&&guanjikaiguan==1&&canshu[6]==0))//
- {
- xiumiankaiguan=0;//停止休眠
- shedingwendu=baocunwendu;//恢复原来的温度
- xiumianjishukaiguan=1;//允许新一次休眠计数
- xiumianjishu=0;//从0开始计数
- guanjijishukaiguan=0;//停止关机计数
- guanjikaiguan=0;//退出关机状态(如果原来是关机状态的话)
- }
- }
- g=zhendongkaiguan;//保存当前震动传感器状态(用于和下一次比较,以便确定是否震动了)
- }
- /********************************定时器0中断函数********************************************/
- void timer0(void) interrupt 1//定时0中断函数,用于检测旋转编码器,掉电存储等操作(仅用于正常工作模式)
- {
- unsigned int a,b;
- unsigned char buchang;
- diaodiancunchu();//调用掉电存储函数
- bianmaqi();//调用编码器函数
- zhendongxiumian();//调用震动休眠函数
- if(huancunkaiguan==1)//延时显示计数
- huancunjishu++;
- if(xiumianjishukaiguan==1||ganggangkaiji==1)//休眠计数
- {
- if(wendujiaqiang==0)//如果不是温度加强模式
- xiumianjishu++;//就计数
- else//否则
- xiumianjishu=1;//不计数
- }
- if(guanjijishukaiguan==1||canshu[4]==0)//关机计数
- guanjijishu++;
- if(wendujiaqiangjishukaiguan==1)//温度加强计数
- wendujiaqiangjishu++;
- if(wendujiaqiangjishu==60000)//如果到达设定的温度加强时间(60s)
- gonggonghanshu4();//退出温度加强模式
- if(xiumianjishu==canshu[3]*60000)//如果达到设定时间就休眠
- gonggonghanshu8();//进入休眠模式
-
- if(guanjijishu==canshu[4]*60000)//如果关机计数达到了设定的时间
- {
- guanjikaiguan=1;//进入关机状态
- guanjijishukaiguan=0;//停止关机计数
- guanjijishu=0;//清零关机计数
- }
- zhouqijishu++;//加热周期计数
- if(jiareshu>196)//最多加热196ms
- jiareshu=196;
- if((zhouqijishu<=jiareshu)&&(guanjikaiguan==0))//如果当前计数小于等于加热数并且不是关机模式
- t12=1;//就加热
- else//否则
- t12=0;//不加热
- if(t12wendu==5000)//如果t12温度为500,说明没有插入烙铁头或参数严重错误
- t12=0;//停止加热
- if(huancunjishu==1500)//设定温度延时显示1.5秒
- {
- huancunkaiguan=0;//如果达到了1.5秒,关闭缓存开关
- huancunjishu=0;//停止缓存计数
- huancun=t12wendu;//由显示设定温度改为显示t12温度
- }
- if(zhouqijishu==200)//t12停止加热后2ms再检测温度(给电容留出放电时间,防止检测的温度偏高)
- {
- adc();//检测电压,计算温度
- zhouqijishu=0;//重新开始加热周期计数
- 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中断函数*******************************************/
- void timer1(void) interrupt 3//定时器1中断仅用于参数设置模式
- {
- shijian++;
- t12=0;
- bianmaqi2();//调用编码器2函数
- if(ganggangkaiji==1)//如果刚刚开机
- {
- xianship=1;//百位显示字母P
- huancun=jinduzhi;//显示菜单P00(因为此时进度值为0)
- ganggangkaiji=0;//已经开机
- shezhixianshijishukaiguan=1;//允许设置显示计数
- }
- if(shezhixianshijishukaiguan==1)//如果允许设置显示计数,就开始计数
- shezhixianshijishu++;
- if(shezhixianshijishu==1500)//如果计数到规定的1.5s
- {
- xianship=0;//停止显示百位的字母P
- shezhixianshijishukaiguan=0;//停止设置显示计数
- shezhixianshijishu=0;//清零计数
- jinzhicaozuo=0;//此时禁止操作编码器
- huancun=canshu[jinduzhi-2];
- if(jinduzhi==0)//显示当前菜单项对应的参数(P00的参数)
- huancun=huifumoren;
- if(jinduzhi==1)//同上,不再赘述
- huancun=zengyi;
- if(jinduzhi==7)
- huancun=wenduxiuzheng;
- jinzhicaozuo=0;//禁止编码器操作
- }
- }
- /********************************主函数*****************************************************/
- void main (void)//主函数
- {
- P1M0=0x00;//P1除P1.0,P1.1,P1.2为输入模式外均为正常模式
- P1M1=0x07;
- P1ASF=0x07;//设置P1相应ADC转换的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);//读取上次关机时保存的设定温度
- shedingwendu=(shedingwendu+200)*10;
- if(shedingwendu>4500||shedingwendu<2000)//如果读取的设定温度超出范围
- shedingwendu=3000;//就设为300度
- duqushezhishuju();//读取控制器的设置参数
- if(bianmaanniu==0)//如果开机时编码按钮是低电平(即按下了按钮)
- {
- shezhimoshi=1;//进入参数设置模式
- IE=0x82;//打开定时器1中断,关闭定时器0中断
- timer1init();//初始化定时器1
- }
- else//如果开机时没有按下编码器按钮
- {
- shezhimoshi=0;//进入正常加热模式
- IE=0x88;//打开定时器0中断,关闭定时器1中断
- timer0init();//初始化定时器0
- }
- while(1)
- {
- display(huancun);//数码管显示数据
- }
- }
复制代码 以上为金大师STC15F204EA T12数码管焊台固件,本人小白。只知道改引脚P5.5,后来发现STC15W408AS没有定时器1,导致刷了程序导致T12无法正常工作,请教大佬们怎么把定时器1改成定时器2。
|