蓝桥杯之单片机学习(二十六)——模拟风扇控制系统(附题目和完整代码)

一、题目要求

在这里插入图片描述

二、代码操作

2.1 main.c

#include <STC15F2K60S2.h>
#include "onewire.h"

#define uchar unsigned char
#define uint unsigned int
	
uchar code SMG_duanma[19] = 
	{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,
	 0x88,0x80,0xc6,0xc0,0x86,0x8e,
	 0xbf,0x7f,0XFF};//分别是0-9(对应下标),A-F,“-”,“.”,“灭”

//分别是“0.-9.”
uchar code SMG_Dot_AC[10] = 
	 {0X40,0X79,0X24,0X30,0X19,0X12,0X02,0X78,0X00,0X10};
uchar yi,er,san,si,wu,liu,qi,ba;
//工作模式记录
uchar MODE = 1;
//时间记录
uchar Time = 0;
//时间模式检查
uchar Mode_Time = 0;
//停止标识位(为0时停止)
uchar Check_Time_Sign = 1;
//定时PWM标志位
uchar tt = 0;
//室温模式检查
uchar Mode_Temp_Display = 0;
//记秒标志位
uint miao = 0;

//系统初始化
void Initsys();
//配置HC138
void SelectHC138(uchar channel);
//在pos位码上,显示value段码
void DisplaySMG_Bit(uchar pos, uchar value);
//数码管8位码显示
void SMG_Display();
//数码管的延时
void Delay_one_ms_SMG();
//独立按键(BTN)
void Alone_Key();
//按键消抖延时
void Delay_five_ms_Key();
void Timer0Init(void);		//100微秒@11.0592MHz
	 


void main()
{
	yi = er = san = si = wu = liu = qi = ba = 18;
	Initsys();
	Timer0Init();		//100微秒@11.0592MHz
	while(1)
	{
		yi = 16; er = MODE; san = 16;si = 18;
		wu = Time / 1000; liu = Time % 1000 / 100; qi = Time % 100 / 10 ; ba = Time % 10;
		Alone_Key();
		SMG_Display();
		if(Time == 0 || Check_Time_Sign == 0)
		{
			SelectHC138(4);
			P0 = 0XFF;
		}
		if(Mode_Temp_Display == 1)
		{
			uchar temp;
			while(1)
			{
				uchar flag = 0;
				temp = Temper();
				yi = 16; er = 4; san = 16;si = 18;
				wu = 18; liu = temp / 10; qi = temp % 10; ba = 12;
				SMG_Display();
				if(P30 == 0)
				{
					Delay_five_ms_Key();
					if(P30 == 0)
					{
						flag = 1;
					}
					while(!P30);
				}
				if(flag == 1){Mode_Temp_Display = 0;break;}
			}
		}
	}
}


//按键消抖延时
void Delay_five_ms_Key()
{
	uint i,j;
	for(i = 0; i < 5; i++)
		for(j = 845; j > 0; j--);
}

//独立按键(BTN)
void Alone_Key()
{
	//S7按键
	if(P30 == 0)
	{
		Delay_five_ms_Key();
		if(P30 == 0)
		{
			if(Mode_Temp_Display == 0)Mode_Temp_Display = 1;
			else if(Mode_Temp_Display == 1)Mode_Temp_Display = 0;
		}
		while(!P30);
	}
	//S6按键
	else if(P31 == 0)
	{
		Delay_five_ms_Key();
		if(P31 == 0)
		{
			SelectHC138(4);
			if(Check_Time_Sign == 1){Check_Time_Sign = 0;Time = 0;P0 = 0XFF;}
			else if(Check_Time_Sign == 0)Check_Time_Sign = 1;
		}
		while(!P31);
	}
	//S5按键
	else if(P32 == 0)
	{
		Delay_five_ms_Key();
		if(P32 == 0)
		{
			if(Mode_Time == 0){Mode_Time = 1;Time = 60;}
			else if(Mode_Time == 1){Mode_Time = 2;Time = 120;}
			else if(Mode_Time == 2){Mode_Time = 0;Time = 0;}
		}
		while(!P32);
	}
	//S4按键
	else if(P33 == 0)
	{
		Delay_five_ms_Key();
		if(P33 == 0)
		{
			SelectHC138(4);
			if(MODE == 1){MODE = 2;P0 = 0XFD;}
			else if(MODE == 2){MODE = 3;P0 = 0XFB;}
			else if(MODE == 3){MODE = 1;P0 = 0XFE;}
		}
		while(!P33);
	}
}

//配置HC138
void SelectHC138(uchar channel)
{
	switch(channel)
	{
		case 4:    //LED
			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;
		case 0:    //锁住所有寄存器
			P2 = (P2 & 0X1F) | 0X00;
		break;
	}
}

//系统初始化
void Initsys()
{
	SelectHC138(5);
	P0 = 0X00;//关闭蜂鸣器和继电器
	SelectHC138(4);
	P0 = 0XFF;//关闭LED
	
	SelectHC138(6);
	P0 = 0XFF; //选择所有数码管
	SelectHC138(7);
	P0 = 0XFF; //关闭所有数码管
}

//在pos位码上,显示value段码
void DisplaySMG_Bit(uchar pos, uchar value)
{
	SelectHC138(6);
	P0 = 0X01 << pos;
	SelectHC138(7);
	P0 = value;
}

//数码管8位码显示
void SMG_Display()
{
	DisplaySMG_Bit(0, SMG_duanma[yi]);
	Delay_one_ms_SMG();
	DisplaySMG_Bit(1, SMG_duanma[er]);
	Delay_one_ms_SMG();
	DisplaySMG_Bit(2, SMG_duanma[san]);
	Delay_one_ms_SMG();
	DisplaySMG_Bit(3, SMG_duanma[si]);
	Delay_one_ms_SMG();
	
	DisplaySMG_Bit(4, SMG_duanma[wu]);
	Delay_one_ms_SMG();
	DisplaySMG_Bit(5, SMG_duanma[liu]);
	Delay_one_ms_SMG();
	DisplaySMG_Bit(6, SMG_duanma[qi]);
	Delay_one_ms_SMG();
	DisplaySMG_Bit(7, SMG_duanma[ba]);
	Delay_one_ms_SMG();
}

//数码管的延时
void Delay_one_ms_SMG()
{
	uint j;
	for(j = 845; j > 0; j--);
}

void Timer0Init(void)		//100微秒@11.0592MHz
{
	AUXR |= 0x80;		//定时器时钟1T模式
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0xAE;		//设置定时初值
	TH0 = 0xFB;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	
	ET0 = 1;
	EA = 1;
}

//PWM和倒计时
void Timer0Server() interrupt 1
{
	tt++;
	miao++;
	if(tt == 11)tt = 1;
	if(Time > 0 && Check_Time_Sign == 1)
	{
		if(MODE == 1)
		{
			if(tt < 3)P34 = 1;
			else P34 = 0;
		}
		else if(MODE == 2)
		{
			if(tt < 4 )P34 = 1;
			else P34 = 0;
		}
		else if(MODE == 3)
		{
			if(tt < 8)P34 = 1;
			else P34 = 0;
		}
	}
	if(miao == 10000)
	{
		miao = 0;
		if(Time > 0)Time--;
	}
}


2.2 onewire.c

/*
  程序说明: 单总线驱动程序
  软件环境: Keil uVision 4.10 
  硬件环境: CT107单片机综合实训平台(外部晶振12MHz) STC89C52RC单片机
  日    期: 2011-8-9
*/
#include "reg52.h"

sbit DQ = P1^4;  //单总线接口

//单总线延时函数
void Delay_OneWire(unsigned int t)  //STC89C52RC
{
	while(t--);
}

//通过单总线向DS18B20写一个字节
void Write_DS18B20(unsigned char dat)
{
	unsigned char i;
	for(i=0;i<8;i++)
	{
		DQ = 0;
		DQ = dat&0x01;
		Delay_OneWire(50);
		DQ = 1;
		dat >>= 1;
	}
	Delay_OneWire(50);
}

//从DS18B20读取一个字节
unsigned char Read_DS18B20(void)
{
	unsigned char i;
	unsigned char dat;
  
	for(i=0;i<8;i++)
	{
		DQ = 0;
		dat >>= 1;
		DQ = 1;
		if(DQ)
		{
			dat |= 0x80;
		}	    
		Delay_OneWire(50);
	}
	return dat;
}

//DS18B20设备初始化
bit init_ds18b20(void)
{
  	bit initflag = 0;
  	
  	DQ = 1;
  	Delay_OneWire(120);
  	DQ = 0;
  	Delay_OneWire(800);
  	DQ = 1;
  	Delay_OneWire(100); 
    initflag = DQ;     
  	Delay_OneWire(50);
  
  	return initflag;
}

unsigned char Temper()
{

	unsigned char di8,gao8,temp;
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0x44);
	Delay_OneWire(200);
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0xbe);
	
	di8=Read_DS18B20();
	gao8=Read_DS18B20();
	
	temp=gao8<<4; 
	temp=temp|(di8>>4);
	return temp;

}

三、PWM示波器测试

3.1 PWM20%输出波形

在这里插入图片描述

3.2 PWM30%输出波形

在这里插入图片描述

3.3 PWM70%输出波形

在这里插入图片描述

附、一些感悟

C语言中如何定义多个变量
查了网上,可以这样

int a,b,c;
a=b=c=5;
在这里插入图片描述

这样abc都是5了

posted @ 2022-05-10 08:37  周末不下雨  阅读(155)  评论(0编辑  收藏  举报