蓝桥杯:第七届—“模拟风扇控制系统”(PWM)

目录

一、自己写代码遇到的问题:

1、每个模式下,S5设置到2分钟的时候,按下S6暂停后(工作时间清零0min),再按S5(应 该显示为1min),但是按第一下任然显示0min,按第二下才会显示1min。

分析:

改错:(time_flat 也要清零!!!)

二、参考代码:

 

一、自己写代码遇到的问题:

1、每个模式下,S5设置到2分钟的时候,按下S6暂停后(工作时间清零0min),再按S5(应 该显示为1min),但是按第一下任然显示0min,按第二下才会显示1min。

时间循环模式:0min——>1min——>2min——>0min...

分析:

①每个模式时间设置都存在相同的问题——>说明time_s / time_flat 部分可能存在问题:watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6KGM5LiN5Zyw5LiK,size_20,color_FFFFFF,t_70,g_se,x_16watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6KGM5LiN5Zyw5LiK,size_20,color_FFFFFF,t_70,g_se,x_16

 

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6KGM5LiN5Zyw5LiK,size_20,color_FFFFFF,t_70,g_se,x_16watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6KGM5LiN5Zyw5LiK,size_15,color_FFFFFF,t_70,g_se,x_16

 ②分析: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!!!!!

改错:(time_flat 也要清零!!!)

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6KGM5LiN5Zyw5LiK,size_14,color_FFFFFF,t_70,g_se,x_16

 

二、参考代码:

#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熄灭
		}
	}
}

 

 

  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

行不地上

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值