目录
一、自己写代码遇到的问题:
1、每个模式下,S5设置到2分钟的时候,按下S6暂停后(工作时间清零0min),再按S5(应 该显示为1min),但是按第一下任然显示0min,按第二下才会显示1min。
分析:
改错:(time_flat 也要清零!!!)
二、参考代码:
时间循环模式:0min——>1min——>2min——>0min...
①每个模式时间设置都存在相同的问题——>说明time_s / time_flat 部分可能存在问题:
②分析:S5按第一次:time_flat == 0——>time_flat = 60
S5按第二次:time_flat == 60——>time_flat = 120 (time_s = time_flat = 120--)
此时按下S6(工作时间清零):stop == 0——>stop = 1
time_s = 0; (此时time_flat = 120)
S5按第三次(设置时间,应该为1min = 60s):(此时time_flat == 120)——>time_flat = 0!
所以此时任然显示0!!!!!
#include "reg52.h"
#include "onewire.h"
unsigned char code SMG_duanma[19] = {
// 0 1 2 3 4 5 6 7
0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
// 8 9 A10 B11 C12 D13 E14 F15
0x80,0x90,0x88,0x80,0xc6,0xc0,0x86,0x8e,
// -16 .17
0xbf,0x7f,0xff}; //共阳数码管
unsigned char yi, er, san, si, wu, liu, qi, ba;
sbit S7 = P3^0;
sbit S6 = P3^1;
sbit S5 = P3^2;
sbit S4 = P3^3;
sbit P34 = P3^4;//PWM输出
unsigned int temp;//温度用int!!!
unsigned char work = 1; //工作模式 1:睡眠风 / 2:自然风 / 3:常风 / 4:温度显示
unsigned char time_s = 0; //(秒)定时时间:0min - 1min(60s) - 2min(120s)
unsigned char time_flat = 0; //定时时间状态变量(注意清零!!!!)
unsigned char set = 0; //定时按键 1:设置定时时间
unsigned char wendu = 0;//进入温度显示界面
unsigned char stop = 0;//停止按键
unsigned int count = 0;//时间计数
unsigned char n = 0;//PWM计数
unsigned char PWM_duty = 0;//PWM占空比
void InitHC138(unsigned char n)
{
switch(n)
{
case 4:
P2 = (P2 & 0x1f) | 0x80;
break;
case 5:
P2 = (P2 & 0x1f) | 0xa0;
break;
case 6:
P2 = (P2 & 0x1f) | 0xc0;
break;
case 7:
P2 = (P2 & 0x1f) | 0xe0;
break;
}
}
void Delayms(unsigned int ms)
{
unsigned int i, j;
for (i = ms; i > 0; i--)
for (j = 845; j > 0; j--);
}
/*======================初始化系统============================================
关闭蜂鸣器与继电器、LED
===========================================================================*/
void InitSystem()
{
InitHC138(4);
P0 = 0xff;
InitHC138(5);
P0 = 0x00;
}
/*=======================数码管显示===========================================
===========================================================================*/
void SMG_Bit(unsigned pos, unsigned char dat)
{
InitHC138(7);
P0 = 0xff;
InitHC138(6);
P0 = 0x01 << pos;
InitHC138(7);
P0 = dat;
}
void SMG_All(unsigned char dat)
{
InitHC138(6);
P0 = 0xff;
InitHC138(7);
P0 = dat;
}
void ShowSMG()
{
SMG_Bit(0, SMG_duanma[yi]);
Delayms(1);
SMG_Bit(1, SMG_duanma[er]);
Delayms(1);
SMG_Bit(2, SMG_duanma[san]);
Delayms(1);
SMG_Bit(3, SMG_duanma[si]);
Delayms(1);
SMG_Bit(4, SMG_duanma[wu]);
Delayms(1);
SMG_Bit(5, SMG_duanma[liu]);
Delayms(1);
SMG_Bit(6, SMG_duanma[qi]);
Delayms(1);
SMG_Bit(7, SMG_duanma[ba]);
Delayms(1);
SMG_All(0xff);//最后一个数码管太亮
}
/*=======================按键================================================
1:睡眠风:占空比20%,L1点亮
2:自然风:30%,L2点亮
3:常风:70%,L3点亮
输出频率1KHz = 1ms = 10 00us = 10*100us(分成10份)
S4:工作模式切换按键,循环切换3种工作模式
S5:定时按键,每次按下时间重置,重新开始倒计时
时间增加1min (0min(停止PWM输出,LED熄灭) - 1min - 2min)
S6:停止按键(LED熄灭),按下立即清零剩余工作时间,PWM停止输出,直到S5重新设置定时时间
S7:室温按键,显示当前室温
再次按下,返回工作模式和剩余时间显示界面,往复。
(室温测量、显示不影响设备正在执行的PWM输出、停止、切换、计时)
===========================================================================*/
void ScanKeys()
{
if (S7 == 0)//室温按键,显示当前室温,再次按下,返回工作模式和剩余时间显示界面,往复。
{
Delayms(10);
if (S7 == 0)
{
if (wendu == 0)
{
wendu = 1;
}
else if (wendu == 1)
{
wendu = 0;
}
}
while(!S7)
{
ShowSMG();
}
}
if (S6 == 0)//停止按键(LED熄灭),按下立即清零剩余工作时间,PWM停止输出,直到S5重新设置定时时间
{
Delayms(10);
if (S6 == 0)
{
if (stop == 0)
{
stop = 1;
}
}
while(!S6)
{
ShowSMG();
}
}
if (S5 == 0)//定时按键,每次按下时间增加1min。时间重置,重新开始倒计时
{
Delayms(10);
if (S5 == 0)
{
if (time_flat == 0)
{
time_flat = 60;//1分钟
}
else if (time_flat == 60)
{
time_flat = 120;//2分钟
}
else if (time_flat == 120)
{
time_flat = 0;//0分钟
}
time_s = time_flat;
if (time_s == 0)
{
TR0 = 0;//关闭定时器,PWM停止输出
InitHC138(4); P0 = 0xff;//LED熄灭
}
else
{
TR0 = 1;//打开定时器
}
}
while(!S5)
{
ShowSMG();
}
}
if (S4 == 0)//工作模式切换按键,循环切换3种工作模式(1:睡眠风 / 2:自然风 / 3:常风)
{
Delayms(10);
if (S4 == 0)
{
if (work == 1)//睡眠风
{
work = 2;
}
else if (work == 2)//自然风
{
work = 3;
}
else if (work == 3)//常风
{
work = 1;
}
}
while(!S4)
{
ShowSMG();
}
}
}
/*=======================DS18B20================================================
bit init_ds18b20(void);
unsigned char Read_DS18B20(void);
void Write_DS18B20(unsigned char dat);
===========================================================================*/
void ds18b20_read_temp()
{
unsigned char gao, di;
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0x44);
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0xbe);
//delay(200);
di = Read_DS18B20();
gao = Read_DS18B20();
init_ds18b20();
temp = gao;
temp = temp << 8;
temp = temp | di;
temp = temp >> 4;
}
/*=======================定时器0==================================================
1KHz = 1ms = 1000us 分成10份,每份100us
1s = 1000ms = 10000*100us
================================================================================*/
void Init_Timer0()//100us产生一次中断
{
TMOD = 0x01;
TH0 = (65535 - 100)/256;
TL0 = (65535 - 100)%256;
//TR0 = 1;
ET0 = 1;
EA = 1;
}
void Service_Timer0() interrupt 1
{
TH0 = (65535 - 100)/256;
TL0 = (65535 - 100)%256;//手动重装
count++;
n++;
if (count == 10000)//1s
{
count = 0;
time_s--;
if (time_s == 0)
{
TR0 = 0;//关闭定时器,PWM停止输出
InitHC138(4); P0 = 0xff;//LED熄灭
}
}
if (time_s > 0)//时间<=0 PWM不输出
{
if (n <= PWM_duty)//分成10份
{
P34 = 1;//输出低电平
}
else if (n < 10)
{
P34 = 0;//(PWM_duty < n < 10)输出高电平
}
else if (n == 10)
{
P34 = 0;
n = 0;//计数清零,继续下一次循环
}
}
}
//***********************主函数*************************************************
void main()
{
InitSystem();
Init_Timer0();
yi = 16; er = 1; san = 16; si = 18;
wu = 0; liu = 0; qi = 0; ba = 0;
while(1)
{
ShowSMG();
ScanKeys();
ds18b20_read_temp();
//(不影响PWM输出、停止、模式切换、计时)
if ((work == 1) && (time_s != 0) && (stop == 0))//L1点亮1110 20%
{
InitHC138(4); P0 = 0xfe;
PWM_duty = 2;
}
else if ((work == 2) && (time_s != 0) && (stop == 0))//L2点亮1101 30%
{
InitHC138(4); P0 = 0xfd;
PWM_duty = 3;
}
else if ((work == 3) && (time_s != 0) && (stop == 0))//L3点亮1011 70%
{
InitHC138(4); P0 = 0xfb;
PWM_duty = 7;
}
if (wendu == 0)//(不影响PWM输出、停止、模式切换、计时)不能把模式切换放这里面
{
yi = 16; er = work; san = 16; si = 18;
wu = 0; liu = time_s/100; qi = (time_s/10)%10; ba = time_s%10;
}
else if (wendu == 1)//进入温度显示界面(不影响PWM输出、停止、模式切换、计时)
{
InitHC138(4); P0 = 0xff;//LED熄灭
yi = 16; er = 4; san = 16; si = 18; wu = 18;
liu = temp/10; qi = temp%10; ba = 12;
}
if (stop == 1)//停止键
{
stop = 0;//释放状态
time_flat = 0;//也要清零!设置2分钟,按S6后(时间清零0min),再按S5(应该为1min),但是按第一下任然显示0min,按第二下才会显示1min。
time_s = 0;
TR0 = 0;//关闭定时器,PWM停止输出
InitHC138(4); P0 = 0xff;//LED熄灭
}
}
}