蓝桥杯单片机第七届省赛题详细讲解(模拟风扇控制系统)

看之前强烈建议先自己做一遍!!!

演示视频

题目讲解

首先还是从整个赛题的程序框图开始看起,如图。
在这里插入图片描述
做题之前要做的是把系统框图里面的各个模块先提前调试好!!!(DS18B20,数码管显示,独立按键)
记得接下来每一步都要进行调试。
调试完成后进一步看题目:

在这里插入图片描述
有工作模式,和数码管显示,工作模式先不看,首先看数码管显示。

uchar SMG_mode=0,temp; //数码管模式定义 温度定义
uchar work_mode=1; //工作模式
uint surplus_time=50;//剩余时间定义
void main(void)
{
    
    
	init(); //初始开发板
	while(1)
	{
    
    
		temp=rd_temperature();
	  if(SMG_mode==0)
		{
    
    
			SMG[0]=SMG[2]=21;SMG[1]=work_mode;
			SMG[3]=20;SMG[4]=surplus_time/1000;
			SMG[5]=surplus_time%1000/100;
			SMG[6]=surplus_time%100/10;
			SMG[7]=surplus_time%10;
		}
		SMG_output();
		Dkey_scan();
	}
}

然后接着往下看按键设置。
在这里插入图片描述
首先设置S4,S5两个按键。

case 0x0b: //S5
	surplus_time+=60;
	break;
case 0x07: //S4
	if(work_mode==1)work_mode=2;
else if(work_mode==2)work_mode=3;
else if(work_mode==3)work_mode=1;
	break;

在这里插入图片描述
然后设置S6,S7两个按键。

case 0x0e://S7
	if(SMG_mode==0)SMG_mode=1;
else SMG_mode=0;
	break;
case 0x0d://S6
	surplus_time=0;
	break;

然后在主程序设置对应的数码管显示。

else if(SMG_mode==1)
{
    
    
	SMG[0]=SMG[2]=21;SMG[1]=4;
	SMG[3]=20;SMG[4]=20;
	SMG[5]=temp/10;
	SMG[6]=temp%10;
	SMG[7]=22;			
}

做好这些之后,开始设计PWM波的模式还有,定时时间。我们用定时器0计时和产生PWM波。1KHZ为1ms,所以我们设置定时器时间为100us

uint t=0; //定义定时器计数
uint tt=0; //定义时间计时
//定时器0中断服务函数
void time0() interrupt 1
{
    
    
	t++;
	tt++;
	if(t==10)t=0;
	if(surplus_time!=0)
	{
    
    
		switch(work_mode)
		{
    
    
			case 1:
			if(t<=1) P34=1; //20% 2/10
			else {
    
    P34=0;}break;
			case 2:
			if(t<=2) P34=1; //30% 3/10
			else {
    
    P34=0;}break;
			case 3:
			if(t<=6) P34=1; //70% 7/10
			else {
    
    P34=0;}break;
		}
	} 
	if(tt>=10000){
    
    tt=0;
	if(surplus_time)surplus_time--;} //1s=10000*100us//1s=10000*100us
}

在这里插入图片描述
设置LED指示灯的状态。

switch(work_mode)
{
    
    
	case 1:P2=0X80;P0=0XFE;break; //L1点亮
	case 2:P2=0X80;P0=0XFD;break; //L2点亮
	case 3:P2=0X80;P0=0XFB;break; //L3点亮
}

完整程序

main.c

#include <stc15f2k60s2.h>
#include "intrins.h"
#include "onewire.h"

#define uchar unsigned char
#define uint unsigned int

void SMG_output(void);
void init(void);
void Delay1ms(void);
void delay5ms(void);
void Dkey_scan(void);
void Timer0Init(void);

uchar tab[]={
    
    0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,\
0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0xff,0xbf,0xc6}; //- c
uchar SMG[8]={
    
    20,20,20,20,20,20,20,20};//初始显示10,全息数码管

uchar SMG_mode=0,temp; //数码管模式定义 温度定义
uchar work_mode=1; //工作模式
uint surplus_time=0;//剩余时间定义
uint t=0; //定义定时器计数
uint tt=0; //定义时间计时
void main(void)
{
    
    
	init(); //初始开发板
	Timer0Init();
	while(1)
	{
    
    
		temp=rd_temperature();
	  if(SMG_mode==0)
		{
    
    
			SMG[0]=SMG[2]=21;SMG[1]=work_mode;
			SMG[3]=20;SMG[4]=surplus_time/1000;
			SMG[5]=surplus_time%1000/100;
			SMG[6]=surplus_time%100/10;
			SMG[7]=surplus_time%10;
		}
		else if(SMG_mode==1)
		{
    
    
			SMG[0]=SMG[2]=21;SMG[1]=4;
			SMG[3]=20;SMG[4]=20;
			SMG[5]=temp/10;
			SMG[6]=temp%10;
			SMG[7]=22;			
		}
		switch(work_mode)
		{
    
    
			case 1:P2=0X80;P0=0XFE;break; //L1点亮
			case 2:P2=0X80;P0=0XFD;break; //L2点亮
			case 3:P2=0X80;P0=0XFB;break; //L3点亮
		}
		SMG_output();
		Dkey_scan();
	}
}

void Dkey_scan(void)
{
    
    
	static uchar keybyte=0;
	static uchar key;
	if(((P3&0X0F)!=0X0F)&&(keybyte==0))
	{
    
    
		delay5ms();
		if((P3&0X0F)!=0X0F)
		{
    
    
			keybyte=1;key=P3&0x0f;
		}
	}
	if((keybyte==1)&&((P3&0X0F)==0X0F))
	{
    
    
		if((P3&0X0F)==0X0F)
		{
    
    
			switch(key)
			{
    
    
				case 0x0e://S7
					if(SMG_mode==0)SMG_mode=1;
				else SMG_mode=0;
					break;
				case 0x0d://S6
					surplus_time=0;
					break;
				case 0x0b: //S5
					surplus_time+=60;
					break;
				case 0x07: //S4
					if(work_mode==1)work_mode=2;
				else if(work_mode==2)work_mode=3;
				else if(work_mode==3)work_mode=1;
					break;
			}
			keybyte=0;
		}
	}
}

//定时器0中断服务函数
void time0() interrupt 1
{
    
    
	t++;
	tt++;
	if(t==10)t=0;
	if(surplus_time!=0)
	{
    
    
		switch(work_mode)
		{
    
     //P2=0X80;P0=0XFD
			case 1:
			if(t<=1) {
    
    P34=1;} //20% 2/10
			else {
    
    P34=0;}break;
			case 2:
			if(t<=2) {
    
    P34=1;} //30% 3/10
			else {
    
    P34=0;}break;
			case 3:
			if(t<=6) {
    
    P34=1;} //70% 7/10
			else {
    
    P34=0;}break;
		}
	} 
	if(tt>=10000){
    
    tt=0;
	if(surplus_time)surplus_time--;} //1s=10000*100us
}

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

void SMG_output(void)
{
    
    
	uchar i;
	for(i=0;i<8;i++)
	{
    
    
	P2=(P2&0X1F)|0Xc0;
	P0=(1<<i);
	P2=(P2&0X1F)|0Xe0;
	P0=tab[SMG[i]];
	Delay1ms();
	}
	P2=(P2&0X1F)|0Xc0;
	P0=0Xff;
	P2=(P2&0X1F)|0Xe0;
	P0=0Xff;	
}

void init(void)
{
    
    
	P2=(P2&0X1F)|0XA0;
	P0=0X00;
	P2=(P2&0X1F)|0X80;
	P0=0Xff;
	P2=(P2&0X1F)|0Xc0;
	P0=0Xff;
	P2=(P2&0X1F)|0Xe0;
	P0=0Xff;	
}

void Delay1ms(void)		//@11.0592MHz
{
    
    
	unsigned char i, j;

	_nop_();
	_nop_();
	_nop_();
	i = 11;
	j = 190;
	do
	{
    
    
		while (--j);
	} while (--i);
}

void delay5ms(void)		//@11.0592MHz
{
    
    
	unsigned char i, j;

	i = 54;
	j = 199;
	do
	{
    
    
		while (--j);
	} while (--i);
}

onewire.h

#ifndef __ONEWIRE_H
#define __ONEWIRE_H

#include <stc15f2k60s2.h>

sbit DQ = P1^4;  

unsigned char rd_temperature(void);  //; ;
void Delay_OneWire(unsigned int t);
unsigned char Read_DS18B20(void);
bit init_ds18b20(void);
void Write_DS18B20(unsigned char dat);

#endif

onewire.c

#include "onewire.h"

unsigned char rd_temperature(void)
{
    
    
	unsigned char de,gao;
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0x44);
	
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0xbe);	
	
	de=Read_DS18B20();
	gao=Read_DS18B20();
	
	return((de >>4)|(gao<<4));
}

//
void Delay_OneWire(unsigned int t)  
{
    
    
	t=t*8;
	while(t--);
}

//
void Write_DS18B20(unsigned char dat)
{
    
    
	unsigned char i;
	for(i=0;i<8;i++)
	{
    
    
		DQ = 0;
		DQ = dat&0x01;
		Delay_OneWire(5);
		DQ = 1;
		dat >>= 1;
	}
	Delay_OneWire(5);
}

//
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(5);
	}
	return dat;
}

//
bit init_ds18b20(void)
{
    
    
  	bit initflag = 0;
  	
  	DQ = 1;
  	Delay_OneWire(12);
  	DQ = 0;
  	Delay_OneWire(80);
  	DQ = 1;
  	Delay_OneWire(10); 
    initflag = DQ;     
  	Delay_OneWire(5);
  
  	return initflag;
}

工程文件

工程文件

猜你喜欢

转载自blog.csdn.net/darlingqx/article/details/127569158