|

楼主 |
发表于 2020-12-10 17:17:34
|
显示全部楼层
本帖最后由 guojizhou 于 2020-12-10 17:22 编辑
原理图和PCB是用立创EDA做的,不知道怎么共享上来请大侠们指点一下。我都是自学的单片机,自己业余时间玩一下,程序有很多不完美的地方,也请高手们指导。
下面是程序:::::
/**
2020年12月4日,还有两个警告因只是启动中用不管他
上220v可以使用,风枪热惯性大,
设置 烙铁 风机正常 休眠和字动关机正常时间待调整
2020.12.07 更改了风机速度控制的热风枪pid数值还没有测试
2020.12.08 风机速度控制由PWM控制改为10级控制,
热风枪和烙铁pid数值还待优化
*/
#include <STC15.h>
#include <intrins.h>
#include <math.h>
//#include "PCA.h"
//#include <eeprom.h>
//#include "config.h"
/**接口定义**/
sbit C_iron = P1 ^ 0; //T12控制(C-iron)
sbit C_fan = P1 ^ 1; //热风枪温度控制
sbit T_iron = P1 ^ 2; //t12温度控制
sbit T_fan = P1 ^ 3; //热风枪温度值
sbit T_air = P1 ^ 4; //环境温度值
sbit V_fan = P1 ^ 5; //风机控制电压值
sbit V_ref = P1 ^ 6; //基准电压值
sbit V_dd = P1 ^ 7; //电源电压
sbit DIO = P3 ^ 2; // TM1650 数码管驱动的sdo引脚
sbit CLK = P3 ^ 3; // TM1650 数码管驱动的scl引脚
sbit S_fan = P3^4; //风枪休眠开关
sbit S_iron = P3^5; //烙铁休眠开关
sbit select = P3^6; //功能选择1开启风枪
sbit R_fan = P3^7 ; //风量控制
sbit I_fan = P5 ^ 4; //热风枪状态
sbit I_iron = P5^ 5; //烙铁状态
/**共同变量**/
unsigned long VREF = 2488; // 用万用表测量基准电压的真实值,单位mv
unsigned long Air_voltage;
unsigned long system_voltage; // 计算单片机供电电压
unsigned long input_voltage; // 计算整个板子的输入电压(12~24V)
unsigned long watch_voltage; //监控电压
unsigned long stop_times=0; //停止时间
// PID控制算法
#define KP 1.2f // 比例系数
#define KI 0.2f // 积分系数
#define KD 0.1f // 微分系数
#define MAX_UK 400.0f // 系统允许输出的最大控制量,这里表现为加热数,400个0.5ms加热周期,最长连续加热时间为200ms
int ek = 0, ek_1 = 0, ek_2 = 0; // 记录连续三次的偏差值(设定值-实际测量值)
float uk_1 = 0.0f, uk = 0.0f; // 记录当前计算的PID调整值和上次计算的PID调整值
long integralSum = 0; // 位置式PID算法的累计积分项
// 定义一个数码管段码表,0~F,c,消隐,G,u,o,r小数点再加“0x80”
unsigned char CODE[] =
{0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, 0x77, 0X7C, 0X39, 0X5E, 0X79, 0X71, 0x61, 0x58, 0x00,0x3D,0X1C,0X5C,0x50};
// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F, 上c(17),下c(18) 19 20G u o r
//环境温度
unsigned int NTC_R;//定义热敏电阻阻值变量
unsigned char AirTemperature;//定义温度存储变量
bit set = 0; // 设置键值
bit up = 0; // 上键值
bit down = 0; // 下键值
bit write_flag; //写EEPROM标志
bit g;
bit sleep_flag=0; //休眠标志
bit off_flag=0; //guanj标志
bit k; //休眠交换标志
/**t12变量组*****/
unsigned long t12_voltage; // 计算t12热电偶电压
unsigned int t12SetTemperature; // 当前设定的温度
unsigned int t12sleepTemperature ; // 休眠记录当前设定的温度
unsigned char t12SetTemperatureH ; // 高8位
unsigned char t12SetTemperatureL ; // 低8位
unsigned int t12ActualTemperature = 0; // 保存T12当前的实际温度
unsigned int setTempShowTime = 0; // 记录显示设置温度的时长
unsigned int need_heat_times = 0; // 需要加热的时长
unsigned int heat_times_count = 0; //当前已经加热的时长
unsigned int a;
unsigned int leijiwencha; //当前已经加热的时长
/***热风枪变量组***/
unsigned int FanSetTemperature ; // 当前设定的温度
unsigned char FanSetTemperatureH ; // 高8位
unsigned char FanSetTemperatureL ; // 低8位
unsigned long Fan_voltage; // 热风枪热电偶电压
unsigned int FanActualTemperature = 0; // 热风枪当前的实际温度
unsigned int FansetTempShowTime = 0; // 记录显示设置温度的时长
unsigned int Fanneed_heat_times = 0; // 需要加热的时长
unsigned int Fanheat_times_count = 0; //当前已经加热的时长
unsigned int fanstop_times =0; //风机延时计时
unsigned int fan_times_count; //风机转动时长
unsigned int FanSpeed = 250; //风速
unsigned long V_Fanspeed; // 热风风速电压
// 初始化各个IO口
void initIO()
{
// 配置各个端口的输入模式,M1M0:00普通,01推挽,10高阻输入,11开漏
/*
以下列出需要配置的端口,其他端口保持默认即可
t12 = P3^7; //T12控制 推挽输出模式
ADC3:系统输入电压检测 P1^3 输入模式
ADC4:T12热电偶电压检测 P1^4 输入模式
ADC5:2.5V参考电压输入 P1^5 输入模式
*/
P1M0 |= 0x03; //0000 0011 //1.0,1.1推挽,1.2,1.3,1.4,1.5,1.6,1.7对应ADC2,3,4,5,6,7。
P1M1 |= 0xfc; //1111 1100
P3M0 = 0x80; //1000 0000 //3.7 推挽对风机
P3M1 = 0x00; //0000 0000
P5M0 = 0x30; //0011 0000 //5.4,5.5推挽
P5M1 = 0x00; //0000 0000
}
/****定时器0初始化****/
void Timer0Init(void) //1毫秒@11.0592MHz
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0xCD; //设置定时初值
TH0 = 0xD4; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
}
/*延时函数,使用STC-ISP自动生成的,比较准确*/
void Delay_ms(unsigned int k) //@12.000MHz
{
unsigned char i, j;
for (; k > 0; k--)
{
i = 12;
j = 169;
do
{
while (--j)
;
} while (--i);
}
}
void Delay_us(unsigned int i)
{
for (; i > 0; i--)
{
_nop_();
_nop_();
_nop_();
_nop_();
}
}
/*初始化ADC*/
void initADC(void)
{
/*
开启相应ADC口的模拟输入功能(相应位置1)
ADC2:烙铁温度P1.2
ADC3:风枪温度 P1^3
ADC4:环境温度 P1^4
ADC5:风机控制电压 P1^5
ADC6:2.5V参考电压输入 p1.6
ADC7:1/11的电源电压输入p1.7
*/
P1ASF = 0xfc; //1111 1100
ADC_RES = 0; // 清楚结果寄存器
ADC_RESL = 0;
/*
ADC控制寄存器
ADC_POWER | SPEED1 | SPEED0 | ADC_FLAG | ADC_START | CHS2 | CHS1 | CHS0
*/
// 这里初始化的时候,可以先打开电源和设置转换速度
ADC_CONTR = 0x80; // 1000 0000
Delay_ms(5); // 上电之后延时等待一段时间
}
// 直接插入排序
void insertionSort(unsigned int A[], unsigned int n)
{
unsigned int i, j;
for (i = 1; i < n; i++)
{
for (j = i; j > 0; j--)
{
if (A[j] < A[j - 1])
{
// 不使用第三变量交换两个数,使用异或运算速度快
A[j - 1] ^= A[j];
A[j] ^= A[j - 1];
A[j - 1] ^= A[j];
}
}
}
}
#define ADC_FLAG 0x10 // ADC转换完成标志
#define ADC_START 0x08 // ADC开始置位
// 获取某个ADC通道的转换值
// 为了提高结果的准确性,每次测量,测5次,并且去掉一个最高值,一个最低值,最后取中间3个的均值返回
unsigned int getADCResult(unsigned int channel)
{
unsigned int res[5], i, result = 0;
for (i = 0; i < 5; i++)
{
//ADC控制寄存器 ADC_POWER | SPEED1 | SPEED0 | ADC_FLAG | ADC_START | CHS2 | CHS1 | CHS0
ADC_CONTR = (0x80 | channel | ADC_START); // 选择需要读取的通道,并开启转换
Delay_us(1);
while (!(ADC_CONTR & ADC_FLAG))
; //等待ADC转换完成
res = ((ADC_RES << 2) | (ADC_RESL & 0x03)); // 计算转换出来的原始结果
ADC_RES = 0x00;
ADC_RESL = 0x00; // 清零结果寄存器
}
// 对结果进行排序
insertionSort(res, 5);
// 去掉一个最高值,去掉一个最低值,剩余三个求平均值
result = (res[1] + res[2] + res[3]) / 3;
return result;
}
/***** 电源电压监控*********/
void watchVoltage(void)
{
unsigned int res;
//ADC控制寄存器 ADC_POWER | SPEED1 | SPEED0 | ADC_FLAG | ADC_START | CHS2 | CHS1 | CHS0
ADC_CONTR = (0x80 | 7 | ADC_START); // 选择需要读取的通道,并开启转换
Delay_us(1);
while (!(ADC_CONTR & ADC_FLAG))
; //等待ADC转换完成
res = ((ADC_RES << 2) | (ADC_RESL & 0x03)); // 计算转换出来的原始结果
ADC_RES = 0x00;
ADC_RESL = 0x00; // 清零结果寄存器
watch_voltage=(res/2)*120;//简单计算电源电压,并乘分压比,获得实际的输入电压 p1.7单位mV
}
/***** 风机调节电压*********/
void FenVoltage(void)
{
unsigned int res;
//ADC控制寄存器 ADC_POWER | SPEED1 | SPEED0 | ADC_FLAG | ADC_START | CHS2 | CHS1 | CHS0
ADC_CONTR = (0x80 | 5 | ADC_START); // 选择需要读取的通道,并开启转换
Delay_us(1);
while (!(ADC_CONTR & ADC_FLAG))
; //等待ADC转换完成
res = ((ADC_RES << 2) | (ADC_RESL & 0x03)); // 计算转换出来的原始结果
ADC_RES = 0x00;
ADC_RESL = 0x00; // 清零结果寄存器
V_Fanspeed=(res/2)*120;//简单计算将V_Fanspeed控制在0-9以内
}
/*以下是计算各种电压的函数,返回结果的单位都是mv*/
// 计算公式(mv) output_voltage = (VREF万用表测的TL431基准电压值(mv) * 待测通道的ADC值 / TL431基准通道ADC值p1.6)
// 计算获取T12的电压
// 计算获取输入电源电压Vdd
void getInputVoltage(void)
{
input_voltage = (VREF * getADCResult(7) / getADCResult(6) * 11); // 计算下分压电阻点的电压,并乘分压比,获得实际的输入电压 p1.7
system_voltage = (VREF * 1024 / getADCResult(6)); //计算单片机的电源电压,单位mV;
}
// 获取计算环境温度AirTemperature 电压换算成温度
void getAirTemperature(void)
{
//计算法
float Rt=0;
float Rp=10000;
float T2=273.15f+25;
float Bx=3950;
float Ka=273.15f;
float Air_voltage=0;
Air_voltage= (VREF * getADCResult(4) / getADCResult(6)); //,单位mV p1.4
Rt=Air_voltage*10010/(VREF-Air_voltage); //10k实测10.01k
AirTemperature=1/(1/T2+log(Rt/Rp)/Bx)-Ka+0.5f;
}
/* 计算热风枪热电偶温度 */
void getFanTemperature(void)
{
float x = 0.0f;
// Delay_us(10); // 等待一段时间,等电容放完电后再测量温度比较准确
Fan_voltage = (VREF * getADCResult(3) / getADCResult(6)); //计算获取热风枪热电偶的电压,单位mV
// getFanVoltage(); // 更新热电偶电压
//T实际温度 = (ADC电压(mV)-失调电压(mV))/运放增益*热电偶分度值(℃/mV)+室温(℃)
//FanActualTemperature = 1.0f*Fan_voltage/ 470.0f*54.0f + 23.0f;
FanActualTemperature = (1.0f*Fan_voltage-26)/ 580.0f*54.0f + AirTemperature; //参考T12
}
/* 计算T12热电偶温度 */
void getT12Temperature(void)
{
float x = 0.0f;
C_iron = 0; //测温的时候,关闭电烙铁
// Delay_us(10); // 等待一段时间,等电容放完电后再测量温度比较准确
t12_voltage = (VREF * getADCResult(2) / getADCResult(6)); //计算t12电压,单位mV
//T12实际温度 = (ADC电压(mV)-失调电压(mV))/运放增益*热电偶分度值(℃/mV)+室温(℃)
//t12ActualTemperature = 1.0f*getT12Voltage() / 470.0f*54.0f + 23.0f;
t12ActualTemperature =( 1.0f*t12_voltage-26)/ 580.0f*54.0f + AirTemperature; //实测温度修订运放增益
}
/********************************以下是TM1650数码管显示相关的函数****************************************************/
void Start1650(void)
{ //开始信号
CLK = 1;
DIO = 1;
Delay_us(5);
DIO = 0;
Delay_us(5);
DIO = 0;
}
void Ask1650(void)
{ //ACK信号
unsigned char timeout = 1;
CLK = 1;
Delay_us(5);
CLK = 0;
while ((DIO) && (timeout <= 100))
{
timeout++;
}
Delay_us(5);
CLK = 0;
}
void Stop1650(void)
{ //停止信号
CLK = 1;
DIO = 0;
Delay_us(5);
DIO = 1;
Delay_us(5);
}
void WrByte1650(unsigned char oneByte)
{ //写一个字节,高位在前,低位在后
unsigned char i;
CLK = 0;
Delay_us(1);
for (i = 0; i < 8; i++)
{
oneByte = oneByte << 1;
DIO = CY;
CLK = 0;
Delay_us(5);
CLK = 1;
Delay_us(5);
CLK = 0;
}
}
//unsigned char Scan_Key(void)
void Scan_Key(void)
{ // 按键扫描
unsigned char i;
unsigned char rekey;
Start1650();
WrByte1650(0x49); //读按键命令
Ask1650();
//DIO = 1;
for (i = 0; i < 8; i++)
{
CLK = 1;
rekey = rekey << 1;
if (DIO)
{
rekey++;
}
Delay_us(5);
CLK = 0;
}
Ask1650();
Stop1650();
if(rekey==0x57)set=1; else set=0; //判断set键按下
if(rekey==0x47)up=1; else up=0; //判断up键按下
if(rekey==0x4f)down=1; else down=0; //判断down键按下
// return (rekey);
}
void Set1650(unsigned char add, unsigned char dat)
{ //数码管显示
//写显存必须从高地址开始写
Start1650();
WrByte1650(add); //第一个显存地址
Ask1650();
WrByte1650(dat);
Ask1650();
Stop1650();
}
// 初始化1650,传入亮度参数,范围0~7
void init1650(unsigned char light)
{
Set1650(0x48, ((light << 4) | 0x41));//亮度5,8段模式
}
// 数码管显示函数
void display(signed int num,unsigned char pos)
{
// 计算这个数字对应的千百十个位的数字
unsigned int tmpnum, qian, bai, shi, ge;
if (num < 0)
num = -num;
tmpnum = num;
qian = tmpnum / 1000;
tmpnum %= 1000;
bai = tmpnum / 100;
tmpnum %= 100;
shi = tmpnum / 10;
ge = tmpnum % 10;
if(pos==0)ge=17; //pos=0显示℃
if(pos==5){ge=18,shi=18,bai=18,qian=18;} //关闭显示
if(pos==6){ge=18,shi=21,bai=20,qian=19;} //显示Guo
if(pos==7){ge=22,shi=22,bai=14,qian=18;} //显示Err
if(pos==8){ge=20;} //00.0u位小数点显示u
if(pos==9){ge=20;} //0.00u位小数点显示u
//pos值对应位置小数点,
if(pos==4)Set1650(0x68, CODE[qian]+0x80);else Set1650(0x68, CODE[qian]);
if(pos==3)Set1650(0x6A, CODE[bai]+0x80);else Set1650(0x6A, CODE[bai]);
if(pos==2)Set1650(0x6C, CODE[shi]+0x80);else Set1650(0x6C, CODE[shi]);
if(pos==1)Set1650(0x6E, CODE[ge]+0x80);else Set1650(0x6E, CODE[ge]);
}
/************控制有关函数******************/
/*热风枪加热控制*/
void ControlFanTemperature(void)
{Fanheat_times_count++; //当前已经加热的时长计数
if(Fanneed_heat_times >198) Fanneed_heat_times = 0; // 需要加热的时长最多加热198ms
if((Fanheat_times_count<=Fanneed_heat_times )&&(!S_fan==0))//如果当前计数小于等于加热数并且手柄不在做模式,就加热
C_fan=1;
else
C_fan=0;
if(FanActualTemperature==400)//如果热风温度为400,说明有问题
C_fan=0;//停止加热
if(Fanheat_times_count==150)//原最多加热到198ms
C_fan=0;//停止加热
if(Fanheat_times_count==200)//t12停止加热后2ms再检测温度(给电容留出放电时间,防止检测的温度偏高)
{
getFanTemperature();//检测电压,计算温度
display(FanActualTemperature*10,0);//200ms显示一次
Fanheat_times_count=0;//重新开始加热周期计数
a=FanSetTemperature+1;//////////////////////////以下为加热算法(请自行理解,不作注释)//////////////////////
if(FanActualTemperature>a)
{
leijiwencha=0;
if(FanActualTemperature-a<=3)
Fanneed_heat_times =(FanActualTemperature-a)*10/4+a/1000;
else
Fanneed_heat_times =0;
}
if(FanActualTemperature<=a)
{
leijiwencha=a-t12ActualTemperature;
if(FanActualTemperature==a)
leijiwencha=0;
if(a-FanActualTemperature>=30)
Fanneed_heat_times =50; //原来198
else if(a-FanActualTemperature>=20)
Fanneed_heat_times =40; //原来160
else if(a-FanActualTemperature>=15)
Fanneed_heat_times =30; //原来130
else if(a-FanActualTemperature==10)
Fanneed_heat_times =10+leijiwencha; //原来90+
else if(a-FanActualTemperature>=5)
Fanneed_heat_times =5; //原来40
else
// Fanneed_heat_times =(a-FanActualTemperature)*10/2+FanSetTemperature/500+leijiwencha*10;
Fanneed_heat_times =(a-FanActualTemperature)*10/2+FanSetTemperature/500+leijiwencha*5;
}
}
}
/***风量控制调节P3.7,***/
void SetFanSpeed(void)
{
FenVoltage();
fan_times_count++; //当前运转时长
if(fan_times_count>=V_Fanspeed)R_fan= 1; else R_fan=0; // 需要运转时长
if(fan_times_count ==10)fan_times_count =0; //风速分10级
if(S_fan)fanstop_times=0;
if(fanstop_times>=1800)R_fan=0; //热风枪放回手柄5秒停风,拿起恢复
}
/******烙铁控制************/
void controlt12(void)
{heat_times_count++; //当前已经加热的时长计数
if(need_heat_times >198) need_heat_times = 0; // 需要加热的时长最多加热198ms
if((heat_times_count<=need_heat_times )&&(off_flag==0))//如果当前计数小于等于加热数并且不是关机模式,就加热
C_iron=1;
else
C_iron=0;
if(t12ActualTemperature==450)//如果t12温度为450,说明没有插入烙铁头或参数严重错误
C_iron=0;//停止加热
if(heat_times_count==198)//最多加热到198ms
C_iron=0;//停止加热
if(heat_times_count==200)//t12停止加热后2ms再检测温度(给电容留出放电时间,防止检测的温度偏高)
{
getT12Temperature();//检测电压,计算温度
if(t12ActualTemperature<420)display(t12ActualTemperature*10,0);else display(0,7); // 超过420°报err
heat_times_count=0;//重新开始加热周期计数
a=t12SetTemperature+1;//////////////////////////以下为加热算法(请自行理解,不作注释)//////////////////////
if(t12ActualTemperature>a)
{
leijiwencha=0;
if(t12ActualTemperature-a<=3)
need_heat_times =(t12ActualTemperature-a)*10/4+a/1000;
else
need_heat_times =0;
}
if(t12ActualTemperature<=a)
{
leijiwencha=a-t12ActualTemperature;
if(t12ActualTemperature==a)
leijiwencha=0;
if(a-t12ActualTemperature>=30)
need_heat_times =198;
else if(a-t12ActualTemperature>=20)
need_heat_times =160;
else if(a-t12ActualTemperature>=15)
need_heat_times =130;
else if(a-t12ActualTemperature==10)
need_heat_times =90+leijiwencha;
else if(a-t12ActualTemperature>=5)
need_heat_times =50; // 原值50
else
need_heat_times =(a-t12ActualTemperature)*10/2+t12SetTemperature/500+leijiwencha*10;
}
}
}
/**************************EEPROM关闭IAP*********************************/
void IAPoff(void)//关闭IAP
{
IAP_CONTR = 0;//关闭IAP 功能
IAP_CMD = 0;//清空命令寄存器
IAP_TRIG = 0;//清空命令触发寄存器
IAP_ADDRH = 0;//清空地址高位
IAP_ADDRL = 0;//清空地址低位
_nop_();//延时
}
/**************************字节读函数***************************************/
unsigned char Byte_Read(unsigned int add)
{
IAP_CONTR = 0x81;//打开IAP,设置操作等待时间
IAP_CMD = 0x01;//字节读命令
IAP_ADDRH = add>>8;//设置高8位地址
IAP_ADDRL = add&0x00ff;//设置低8位地址
IAP_TRIG = 0x5a;//发送5ah到触发寄存器
IAP_TRIG = 0xa5;//发送a5h到触发寄存器
_nop_();
IAPoff();
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 寄存器
IAP_TRIG = 0x5a;//发送5ah到触发寄存器
IAP_TRIG = 0xa5;//发送a5h到触发寄存器
_nop_(); //等待ISP/IAP/EEPROM操作完成
IAPoff();
}
/*****************************扇区擦除函数****************************/
void Sector_Erase(unsigned int add)
{
IAP_CONTR = 0x81;//打开IAP,设置操作等待时间
IAP_CMD = 0x03;//扇区擦除命令
IAP_ADDRH = add>>8;//设置高8位地址
IAP_ADDRL = add&0x00ff;//设置低8位地址
IAP_TRIG = 0x5a;//发送5ah到触发寄存器
IAP_TRIG = 0xa5;//发送a5h到触发寄存器
_nop_();
IAPoff();
}
/******************************EEPROM存储函数***************************************/
void eeprom(void)//用于关机时存储温度数据,以便下次开机时恢复温度
{
t12SetTemperatureH=t12SetTemperature>>8; //分成高低8位
t12SetTemperatureL=t12SetTemperature;
FanSetTemperatureH=FanSetTemperature>>8;
FanSetTemperatureL=FanSetTemperature;
Sector_Erase(0x0000);//擦除扇区
Byte_Program(0x0000,t12SetTemperatureH);//写入温度高八位到EEPROM
Byte_Program(0x0001,t12SetTemperatureL);//写入温度低八位到EEPROM
Byte_Program(0x0002,FanSetTemperatureH);//写入温度高八位到EEPROM
Byte_Program(0x0003,FanSetTemperatureL);//写入温度低八位到EEPROM
Delay_ms(10);
}
/**********读取关机数据**************/
void readeeprom(void)
{
t12SetTemperatureH=Byte_Read(0x0000);//读取上次关机时保存的设定温度的高八位
t12SetTemperatureL=Byte_Read(0x0001);//读取上次关机时保存的设定温度的低八位
t12SetTemperature=t12SetTemperatureH<<8|t12SetTemperatureL;//计算十进制的设定温度
FanSetTemperatureH=Byte_Read(0x0002);//读取上次关机时保存的设定温度的高八位
FanSetTemperatureL=Byte_Read(0x0003);//读取上次关机时保存的设定温度的低八位
FanSetTemperature=FanSetTemperatureH<<8|FanSetTemperatureL;//计算十进制的设定温度
}
/******************************震动休眠函数********************************/
void ironsleep(void)
{
if(k==0)
{
t12sleepTemperature=t12SetTemperature; // 休眠设定温度保存
t12SetTemperature=150;
k=1;} //设定休眠温度
//if(S_iron)
if((S_iron!=g)||up||down||set||S_fan) //震动或开关状态改变,说明晃动了手柄
{ I_iron=1;
if(k==1)
t12SetTemperature=t12sleepTemperature;
stop_times=0; //停止休眠计时
k=0; }
g=S_iron;//保存当前震动传感器状态(用于和下一次比较,以便确定是否震动了)
}
/*********自动关机*********/
void ironoff (void)
{
bit off_flag=0;
if(k==1) t12SetTemperature=t12sleepTemperature; //恢复休眠前设置温度并存入
eeprom();
off_flag=1;
while(off_flag)
{
C_iron=0; //全关
C_fan=0;
R_fan=0;
display(0,5); // 数码管关闭
Scan_Key(); //扫描按键
I_iron=1;
Delay_ms(50);
I_iron=0;
Delay_ms(500);
I_fan=1;
Delay_ms(50);
I_fan=0;
Delay_ms(500);
if(set){off_flag=0;stop_times=0;break;}
}
}
/******************************掉电存储函数***************************************/
void shutdownEEPROM(void)//用于关机时存储温度数据,以便下次开机时恢复温度
{ EA=0;ET0=0;
if(k==1)t12SetTemperature=t12sleepTemperature; //恢复休眠前设置温度并存入
display(0,5); // 数码管关闭
I_iron =0;I_fan =0;C_iron=0;C_fan=0; //显示和关烙铁节约电量
eeprom();
}
/**********烙铁设置函数*************/
void t12Set(void)
{bit setflag=0;
C_iron =0; //防止设置时失控
display(t12SetTemperature*10,0); //显示设置温度
if(up){t12SetTemperature ++;setflag=1;} //设置温度+1
if(down){t12SetTemperature --;setflag=1;} //设置温度-1
I_iron =1; //LED闪烁
Delay_ms(50);
I_iron =0;
Delay_ms(50);
if (t12SetTemperature > 450)
t12SetTemperature = 450;
if (t12SetTemperature < 200)
t12SetTemperature = 200;
if(setflag==0) Delay_ms(500);
}
/**********热风枪温度设置函数********** ***/
void FanTempSet(void)
{
bit setflag=0;
C_fan =0; //防止设置时失控
display(FanSetTemperature*10,0);
if(up){FanSetTemperature ++;setflag=1;} //设置温度增加
if(down){FanSetTemperature --;setflag=1;} //设置温度-1
I_iron =0;
I_fan =1; //LED闪烁
Delay_ms(50);
I_fan =0;
Delay_ms(50);
if (FanSetTemperature > 400)
FanSetTemperature = 400;
if (FanSetTemperature < 100)
FanSetTemperature = 100;
if(setflag==0) Delay_ms(500);
}
void FactionSet (void) //状态显示
{
I_iron =1;I_fan =1;
C_iron =0;C_fan =0;
eeprom(); //储存设定值
display(AirTemperature*10,0); //显示环境温度
Delay_ms(1000);
display(input_voltage / 10,3); // 最大输入电压24000mv,00.00 只有4位数码管
Delay_ms(1000);
display(system_voltage,4); // 显示单片机电源电压 0.000
Delay_ms(1000);
I_iron =0;I_fan =1;
display(V_Fanspeed,1);
Delay_ms(1000);
display(t12SetTemperature*10,0); //显示烙铁设定温度
Delay_ms(1000);
display( FanSetTemperature*10,0); //显示烙铁设定温度
Delay_ms(1000);
}
//定时0中断函数,每隔1ms执行一次
void timer0(void) interrupt 1
{
fanstop_times++; //风机延时计时
stop_times++; //休眠计时
if(stop_times>100000){ironsleep();sleep_flag=1;}else sleep_flag=0; //实测200s超过s休眠
if(stop_times>300000)ironoff (); //超过600秒关机
if(stop_times>=600000)stop_times=600000; //防止溢出
watchVoltage();
if(watch_voltage<20000){shutdownEEPROM();C_iron=0;} //如果电源电压降低到20V说明掉电了关机存数
Scan_Key();
SetFanSpeed(); //风机延时
if(set)FactionSet(); //显示状态
if(up||down)
{
if(select) //状态 选择 1是热风枪
FanTempSet(); else t12Set();
}else {
if(select) //状态 选择 1是热风枪
{
I_iron =0;I_fan =1; C_iron=0;
ControlFanTemperature();
}else
{
I_fan =0; C_fan =0;
if(sleep_flag==1) I_iron=0; else I_iron=1; //休眠led关
controlt12();
}
}
}
void main(void)
{
/**初始化**/
initIO(); // 初始化IO口
init1650(1); // 初始化TM1650显示
initADC(); // 初始化ADC
write_flag=1; //上电标志
t12SetTemperature=250;
FanSetTemperature=125;
readeeprom();
SetFanSpeed();
C_iron =0; //烙铁关
C_fan =0; //热风枪关
I_iron =1; //LED测试
I_fan =1;
display(0,6); //显示GUO
Delay_ms(1000);
/*显示初始值**/
getInputVoltage(); //检测系统电压
watchVoltage(); //检测输入电压
getAirTemperature(); //检测环境温度
I_iron =0;I_fan =0;
display(input_voltage / 10,3); // 最大输入电压24000mv, 00.00只有4位数码管
Delay_ms(1000);
display(system_voltage,4); // 显示单片机电源电压 0.000
Delay_ms(1000);
display(AirTemperature*10,0); //显示环境温度
Delay_ms(1000);
I_iron =0;I_fan =1;
display(FanSetTemperature*10,0); //显示热风枪设定温度
Delay_ms(1000);
display(V_Fanspeed,1);
Delay_ms(1000);
I_iron =1;I_fan =0;
display(t12SetTemperature*10,0); //显示烙铁设定温度
Delay_ms(1000);
Timer0Init(); // 初始化定时器0
EA=1;
ET0=1;
/*主循环*/
while(1)
{
}
}
|
|