📄 我的空调程序.c
字号:
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
#define SYS_OK 0
#define SYS_ERROR 1
#define DIS_SYS_WAIT 0x0
#define DIS_SYS_INPUT 0x10
#define DIS_VOID 0xFF
#define WAIT_cCurrTemp 0
#define WAIT_TIME 1
#define FLASH_SetTemp 0x18 // 0001 1000
#define FLASH_PWM 0x06 // 0000 0110
#define DELAY_CLOSEDIS 5 //没按键,延时5秒关背光
#define DELAY_INPUT 5 //没按键,延时5秒返回显示温度
#define KEYCODE_UP 0x1 //加温度
#define KEYCODE_DOWN 0x2 //减温度
#define KEYCODE_FAN 0x4 //设置风速
#define KEYCODE_ONOFF 0x8 //开关风机
#define KEYCODE_PWM 0xc //设置PWM
#define WAIT_cCurrTemp 0
#define MAX_TEMP 32
#define MIN_TEMP 15
sbit bDQ = P1^0; // DS1820数据线
sbit bLED_light = P1^1; // LED 背光驱动,低有效
sbit bKey1 = P1^2; // 键盘扫描线1,高有效
sbit bKey2 = P1^3; // 键盘扫描线2,高有效
sbit bKey3 = P1^4; // 键盘输入线1,低有效
sbit bKey4 = P1^5; // 键盘输入线2,低有效
sbit bFAN = P0^5; // 开风机PWM, 低有效
sbit bAC_Zero = P3^2; // 过零脉冲输入口
//uchar ucCount1; // 记录过零脉冲宽度
uchar ucCount; // 可控占空比0-95%宽度=10mS-ucCount1
uchar ucPWM; // 输出占空比
uchar bdata ucLED;
sbit bFAN_AUTO = ucLED^3;
sbit bFAN_LOW = ucLED^2;
sbit bFAN_MIN = ucLED^1;
sbit bFAN_HIGH = ucLED^0;
bit bPowerON = 0; // 开机状态=1
uchar ucTimer;
/**************** LED显示相关变量 ********************/
// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, C, 度
const uchar code aucLEDNUMCODE[]={ 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x39,0x63};
const uchar code aucLEDcs[]={0x17,0x1b,0x1d,0x1e,0x0f}; //last one??????????/* LED位选 */
uchar ucScanIndex; /* 数码管位选控制 */
uchar ucLEDData[4]; /* 临时显示缓冲数组 */
uchar ucLEDFlash[5]; /* 显示缓冲数组 */
bit bNeg; /* 负号标志 */
uchar ucFlashType;
bit bFlash;
uchar ucCurrSec;
uchar ucSystemStatus;
uchar ucDelaySec; //切换延时秒数
uchar ucCloseDelaySec; //关背光延时秒数
uchar aucTmpValue[2];
uchar ucFanSpeed;
char cCurrTemp;
char cSetTemp;
/**********************************************************************/
uchar ucLongDelay; //长按键
uchar ucDelayKey;
uint nDelay100uS;
char cKEYCode;
bit bStill;
bit bUpdateDisOK;
//uchar x1;
//uchar x2;
/****************************** 函数声明 ******************************/
void SetFanStatus(void);
void DisposeKey(void);
void ScanLED(void);
uchar SCANKEY(void);
void DisplayTemp(char Temp);
void Key(uchar k);
void DisposeDelay(uchar LType);
void UpdateDis(uchar status);
/**********************************************************************/
bit Init_DS18B20(void)
{
bit sysOK = 0;
bDQ = 0; // 单片机将DQ拉低
nDelay100uS = 6;
while(nDelay100uS); // 精确延时 大于 500us
bDQ = 1; // 拉高总线
nDelay100uS = 4;
while(bDQ && nDelay100uS); // 稍做延时后 如果bDQ=0则初始化成功 bDQ=1则初始化失败
//bDQ=1???????????????????????????????????????????
if(nDelay100uS != 0)
{
nDelay100uS = 4;
while(~bDQ && nDelay100uS);
if(nDelay100uS != 0)
{
sysOK = 1; // 在延时时间内18B20有应答证明初始化成功
}
}
return(sysOK);
}
/**********************************************************************/
char ReadOneChar(void)
{
uchar i;
uchar j;
uchar dat = 0;
for (i=8; i>0; i--)
{
bDQ = 0; // 给脉冲信号
bDQ = 0;
dat >>= 1;
bDQ = 1; // 给脉冲信号
if(bDQ)
{
dat |= 0x80;
}
j = 8; // 延时15~30uS后再读下一位数据
while(j--)
{
}
}
return(dat);
}
/**********************************************************************/
void WriteOneChar(uchar dat)
{
uchar i, j;
for (i = 8; i > 0; i--)
{
bDQ = 0;
bDQ = 0;
bDQ = dat & 0x01;
j = 8; // 保持数据电平15~30uS
while(j--)
{
}
bDQ = 1;
dat >>= 1;
}
}
/**********************************************************************/
char ReadTemperature(void)
{
bit f;
union UniTEMP
{
uint T;
uchar T_byte[2];
}idata uT;
f=Init_DS18B20();
if(f != 0) // 18B20初始化成功?
{
ET0 = 0;
ET1 = 0;
WriteOneChar(0xCC); // 跳过读序号列号的操作
WriteOneChar(0xBE); // 读取温度寄存器等(共可读9个寄存器) 前两个就是温度
uT.T_byte[1] = ReadOneChar();
uT.T_byte[0] = ReadOneChar();
ET0 = 1;
ET1 = 1;
}
else
{
return(99);
}
f = Init_DS18B20();
if(f != 0)
{
ET0 = 0;
ET1 = 0;
WriteOneChar(0xCC); // 跳过读序号列号的操作
WriteOneChar(0x44); // 启动温度转换
nDelay100uS = 1100; // 等待AD转换结束9位AD约100mS
ET0 = 1;
ET1 = 1;
}
else
{
return(99);
}
bNeg = 0;
if((uT.T_byte[0] & 0x80) != 0)// 负数标志位为1?
{
uT.T = ~uT.T+1; // 转换成正数
bNeg = 1; // 负数标志置位
}
uT.T += 8; // 四舍五入
uT.T >>= 4; // 取整
return(uT.T_byte[1]);
}
/********************* 初始化变量 **********************/
void INITVar(void)
{
ucSystemStatus = DIS_SYS_WAIT;//=0 //系统初始状态
ucFlashType = WAIT_cCurrTemp;//=0 //初始闪烁方式
bPowerON = 1;
ucFanSpeed = 4; //风扇自动4/停止0
cSetTemp = 24; //初始设定温度
cCurrTemp = -1; //默认温度=-1
}
//char code DX516[3] _at_ 0x3b; //保留0x3b开始的3个字节
/****************************** 主函数 *********************************/
void main()
{
TMOD = 0x11;
TH0 = -30; // 定时器0
TL0 =39; // 定时中断
TR0 = 1;
ET0 = 1;
TH1 = -3; // 定时器1
TL1 = 0; // 定时中断
TR1 = 1;
ET1 = 1;
EA = 1;
// IP=8;
Init_DS18B20();
if(Init_DS18B20())
{
bLED_light = 0; // 开机DS18B20正常就开背光
ucCloseDelaySec = 3; // 延时3秒关背光
}
WriteOneChar(0xCC); // 跳过读序号列号的操作
WriteOneChar(0x44); // 启动温度转换
nDelay100uS = 1100; // 等待AD转换结束9位AD约100mS
INITVar(); //初始化变量
while(1)
{
if(nDelay100uS == 0) //nDelay100us是和18b20采集温度相关的延时控制
{ //延时时间到,启动温度转换
cCurrTemp = ReadTemperature();
if(ucFlashType != FLASH_PWM)
{
SetFanStatus();
}
}
if(cKEYCode != 0)
{
DisposeKey(); //处理键盘数据
}
UpdateDis(ucSystemStatus); //????????/
if(ucDelaySec == 0)
{
DisposeDelay(ucSystemStatus);//处理延时
}
if(ucCloseDelaySec == 0)
{
bLED_light = 1; //关背光
}
}
}
/***************** 定时器1中断:多任务分时处理 **************************/
void timer1() interrupt 3 //约840uS中断1次,11次约为10mS,即100Hz波的1个周期
{
TH1 = -3; //定时器1重装
//////////////////// 任务1:PWM输出 //////////////////////////////////
if(bAC_Zero == 0)
{
if(ucCount < 100) //可控占空比0-95%宽度=10mS-ucCount1
ucCount += 5; // 定时器1中断记数有效控制宽度
// if(ucCount1)
// {
// x1 = ucCount1;
// ucCount1 = 0;
// }
}
else
{
// ucCount1++; // 定时器1中断记数过零脉冲宽度
// if(ucCount)
// {
// x = ucCount;
ucCount = 0;
// }
}
if(ucCount <= 100 - ucPWM)
{
bFAN = 1;
}
else
{
bFAN = 0;
}
///////////////////// 任务2:显示刷新 ////////////////////////
ScanLED();
///////////////////// 任务3:延时 ////////////////////////////
if(nDelay100uS)
{
nDelay100uS--;
}
}
/***************** 定时器0中断:多任务分时处理 **************************/
void timer0() interrupt 1 // 1/240秒中断1次,240次为1S
{
TL0 = 39;
TH0 = -30;
///////////////////// 任务1:秒处理 /////////////////////
ucTimer++; // 定时器0中断次数记数
if(ucTimer == 240)
{
ucTimer = 0;
ucCurrSec++;
if(ucDelaySec)
{
ucDelaySec--;
}
if(ucCloseDelaySec != 0)
{
ucCloseDelaySec--;
}
}
/////////////////// 任务2:闪烁 ////////////////////////////////
if(ucTimer == 120||ucTimer == 0)// 半秒切换闪烁
{
bFlash = !bFlash;
}
/////////////////// 任务3:按键扫描 ////////////////////////////
if(ucDelayKey == 0) // 若刚才没按键则扫描按键
{
if(SCANKEY() != 0) // 若有按键动作
{
ucDelayKey = 3; // 设置延迟时间消颤约12mS
}
else
{
bStill = 0; // 松键状态标志
}
}
else // 有按键利用DelayKey按键消颤
{
if(--ucDelayKey == 0) // 消颤或延时时间到?
{
bLED_light = 0; // 开背光
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -