蓝桥杯第七届模拟风扇

一、初始化系统
首先将系统初始化,关闭蜂鸣器继电器

#include "STC15.h"

#define uchar unsigned char
#define uint unsigned int


void InitHC138(uchar n)
{
	switch(n)
	{
		case 4:P2 = (P2 & 0x1f) | 0x80;break;//LED
		case 5:P2 = (P2 & 0x1f) | 0xa0;break;//蜂鸣器、继电器
		case 6:P2 = (P2 & 0x1f) | 0xc0;break;//位选
		case 7:P2 = (P2 & 0x1f) | 0xe0;break;//段选

	}
}

void InitSystem()
{
	InitHC138(5);
	P0 = 0x00;//关闭蜂鸣器、继电器
	InitHC138(4);
	P0 = 0xff;//关灯
}

头文件

#ifndef _INITSYSTEM_H
#define _INITSYSTEM_H

#include "STC15.h"


#define uchar unsigned char
#define uint unsigned int


extern void InitHC138(uchar n);
extern void InitSystem();

#endif

二、配置中断
配置中断的时候会有许多参数,这些参数在后面也会用到,最好要自己记住,不能混。

配置寄存器的时候要这样:

TMOD = (TMOD & 0x0f) | 0x10;

不能直接或等于
同时要记得配置AUXR,蓝桥杯板子的寄存器

#include "STC15.h"
#include "InitSystem.h"
#include "onewire.h"

//sfr AUXR = 0x8e;
uchar count = 0;
uchar T_s = 120;//数码管显示的秒数
uchar PWM_duty = 0;//脉宽调试的参数
uchar num = 0;

sbit S = P3^4;

void InitTimer1()
{
	TMOD = (TMOD & 0x0f) | 0x10;
	TH1 = (65535-50000)/256;
	TL1 = (65535-50000)%256;

	AUXR = 0xC0;
	TF1 = 0;
	EA = 1;
	ET1 = 1;
	TR1 = 1;
}								   

void Timer1()interrupt 3
{
	TH1 = (65535-50000)/256;
	TL1 = (65535-50000)%256;
	count++;


	if(count == 20)
	{
		T_s--;
	}
	if(T_s == 0)
	{
		EA = 0;
		InitHC138(4);
		P0 = 0x00;
	}
}

void InitTimer0() //控制风速
{
	TMOD = (TMOD & 0xf0) | 0x01;
	TH0 = (65535-100)/256;
	TL0 = (65535-100)%256;
	
//	AUXR |= 0x80;
	TF0 = 0;
	ET0 = 1;
	EA = 1;
	TR0 = 1;	 
}

void Timer0()interrupt 1
{
	TH0 = (65535-100)/256;
	TL0 = (65535-100)%256;
	
	num++;
	if(num == PWM_duty)
	{
		S = 0;
	}
	if(num == 100)
	{
		S = 1;
		num = 0;
	}	
} 

头文件

#ifndef _INTERRUPT_H
#define _INTERRUPT_H

#include "STC15.h"
#include "InitSystem.h"
#include "onewire.h"

extern uchar count;
extern uchar T_s;
extern uchar PWM_duty;
extern uchar num;

sbit S = P3^4;

extern void InitTimer1();
//extern void Timer1()interrupt 3;
extern void InitTimer0();
//extern void Timer0()interrupt 1;

#endif

中断服务函数写一遍就行了(第一次这样写)
三、按键扫描
按键扫描会用到上一步中断中的参数,一定不要用错
按键扫描重要还是按照功能写,我觉得吧,按键里面还是不要有中断里的寄存器了,因为按键改bug改了好久,教程里把中断中的寄存器写在按键里了,参考别人的代码,没有写在里面。先这么写,以后继续看。

#include "STC15.h"
#include "InitSystem.h"
#include "onewire.h"
#include "Interrupt.h"
#include "SMG.h"

uchar K = 1;//风扇功能号
uchar Flag_K = 0;
uchar Flag_time = 0;//时间标志位


sbit S4 = P3^3;//风扇风速控制
sbit S5 = P3^2;//控制定时时长
sbit S6 = P3^1;//停止按键,按下按键时间清零,风扇不转
sbit S7 = P3^0;//室温按键


void ScanKey()
{
	if(S4 == 0)
	{
		delay(10);
 		while(!S4)
		{
			display_SMG();
			switch(K)
			{
				case 1:
					S = 1;
					PWM_duty = 20;
					K = 2;
					break;


				case 2:
					PWM_duty = 50;
					K = 3;
					break;


				case 3:
					PWM_duty = 70;
					K = 1;
					break;

			}
			while(S4 == 0)
			{
				display_SMG();
			}
		}
	}

	if(S5 == 0)
	{
		delay(10);
		while(!S5)
		{
			display_SMG();
			switch(Flag_time)
			{
				case 0:T_s = 60;Flag_time = 1;break;
				case 1:T_s = 120;Flag_time = 2;break;
				case 2:T_s = 0;Flag_time = 0;break;
			}
			while(S5 == 0)
			{
				display_SMG();
			}
		}
	}

	if(S6 == 0)
	{
		delay(10);
		while(!S6)
		{
			display_SMG();
			count = 0;
			Flag_time = 0;
			T_s = 0;
			EA = 0;
			while(S6 == 0)
			{
				display_SMG();
			}
		}
	}

	if(S7 == 0)
	{
		delay(10);
		while(!S7)
		{
			display_SMG();
			//K = 4;
			if(Flag_K == 0)
			{
				Flag_K = 1;
				Read_Temperature();
				display_SMG();
			}
			else
			{
				Flag_K = 0;
			}
			while(S7 == 0)
			{
				 display_SMG();
			}
		}
	}
}

头文件

#define _KEY_H

#include "STC15.h"
#include "InitSystem.h"
#include "onewire.h"
#include "Interrupt.h"
#include "SMG.h"

extern uchar K;
extern uchar Flag_K;

extern void ScanKey();

#endif

这里面还用了DS18B20,要用onewire收发数据,蓝桥杯的赛点资源包里面已经有相关代码了

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

sbit DQ = P1^4;  //单总线接口
unsigned int T_dat;
//单总线延时函数
void Delay_OneWire(unsigned int t)  //STC89C52RC
{
	t = t*7;
	while(t--);
}

void delay(unsigned int time)
{
	while(time--);
}

//通过单总线向DS18B20写一个字节
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);
}

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

//DS18B20设备初始化
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;
}

void Read_Temperature()
{
	unsigned int LSB,MSB;
	Init_DS18B20();
	Write_DS18B20(0xCC);//跳过ROM指令
	Write_DS18B20(0x44);//开始温度转换
	delay(1000);
	Init_DS18B20();
	Write_DS18B20(0xCC);//跳过ROM指令
	Write_DS18B20(0xbe);//写入读取高速暂存器
	LSB = Read_DS18B20();
	MSB = Read_DS18B20();
	Init_DS18B20();

	T_dat = 0x0000;
	T_dat = MSB;
	T_dat = T_dat << 8;
	T_dat = T_dat | LSB;
	T_dat = T_dat >> 4;
}

但还是需要修改,延时函数需要修改

void Delay_OneWire(unsigned int t)  //STC89C52RC
{
	t = t*7;//修改部分
	while(t--);
}

另外除了官方给的代码,还有加几个函数,这个题我就加了一个读温度数据并转换十进制,精确到个位

void Read_Temperature()
{
	unsigned int LSB,MSB;
	Init_DS18B20();
	Write_DS18B20(0xCC);//跳过ROM指令
	Write_DS18B20(0x44);//开始温度转换
	delay(1000);
	Init_DS18B20();
	Write_DS18B20(0xCC);//跳过ROM指令
	Write_DS18B20(0xbe);//写入读取高速暂存器
	LSB = Read_DS18B20();
	MSB = Read_DS18B20();
	Init_DS18B20();

	T_dat = 0x0000;
	T_dat = MSB;
	T_dat = T_dat << 8;
	T_dat = T_dat | LSB;
	T_dat = T_dat >> 4;
}

微处理器读取单个DS18B20的温度数据,可参考以下步骤:
【1】DS18B20复位。
【2】写入字节0xCC,跳过ROM指令。
【3】写入字节0x44,开始温度转换。
【4】延时700~900ms。
【5】DS18B20复位。
【6】写入字节0xCC,跳过ROM指令。
【7】写入字节0xBE,读取高速暂存器。
【8】读取暂存器的第0字节,即温度数据的LSB。
【9】读取暂存器的第1字节,即温度数据的MSB。
【10】 DS18B20复位。,表示读取数据结束。
【11】将LSB和MSB整合成为一个16位数据。
【12】判断读取结果的符号,进行正负温度的数据处理。

onewire的头文件

#ifndef __ONEWIRE_H
#define __ONEWIRE_H

unsigned char rd_temperature(void);  //; ;
#include   "STC15.h"


extern unsigned int T_dat;
sbit  DQ = P1^4;
extern void Delay_OneWire(unsigned int t);
extern void delay(unsigned int time);
extern void Write_DS18B20(unsigned char dat);
extern unsigned char Read_DS18B20(void);
extern bit Init_DS18B20(void);
extern void Read_Temperature(); 
#endif

四、数码管
数码管感觉不是太难,但是还是有问题,数码管显示不太亮,,,

#include "STC15.h"
#include "InitSystem.h"
#include "onewire.h"
#include "Key.h"

#define uchar unsigned char
#define uint unsigned int

unsigned char code SMG_duan[18] = {0xc0,0xf9,0xa4,
	0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x80,0xc6,
	0xc0,0x86,0x8e,0xbf,0x7f};

void display(uchar wei,uchar duan)
{
	InitHC138(7);
	P0 = 0xff;
	InitHC138(6);//位选
	P0 = 0x01 << wei;
	InitHC138(7);//段选
	P0 = duan;
}

void display_all(uchar vaule)
{
	InitHC138(7);
	P0 = vaule;
	InitHC138(6);
	P0 = 0xff;
}

void display_SMG()
{
	if(Flag_K == 0)
	{
		display(0,SMG_duan[16]);
		delay(100);
		display(1,SMG_duan[K]);
		delay(100);
		display(2,SMG_duan[16]);
		delay(100);

		display(7,SMG_duan[T_s%10]);
		delay(100);
		display(6,SMG_duan[(T_s/10)%10]);
		delay(100);
		display(5,SMG_duan[T_s/100]);
		delay(100);
		display(4,SMG_duan[0]);
		delay(100);

		display_all(0xff);
	}
	else
	{
		display(0,SMG_duan[16]);
		delay(100);
		display(1,SMG_duan[4]);
		delay(100);
		display(2,SMG_duan[16]);
		delay(100);

		display(7,SMG_duan[12]);
		delay(100);
		display(6,SMG_duan[T_dat%10]);
		delay(100);
		display(5,SMG_duan[T_dat/10]);
		delay(100);
		display_all(0xff);
	}

}

头文件

#ifndef _SMG_H
#define _SMG_H

#include "STC15.h"
#include "InitSystem.h"
#include "onewire.h"

//extern unsigned char code SMG_duan[18] = {0xc0,0xf9,0xa4,
//	0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x80,0xc6,
//	0xc0,0x86,0x8e,0xbf,0x7f};


extern void display(uchar wei,uchar duan);
extern void display_all(uchar vaule);
extern void display_SMG();

#endif

五,主函数
最后统筹规划一下

#include "STC15.h"
#include "InitSystem.h"
#include "onewire.h"
#include "Key.h"
#include "SMG.h"
#include "Interrupt.h"


void LEDScan()
{
	if(K == 1)
	{
		InitHC138(4);
		P0 = 0xfe;
	}
	else if(K == 2)
	{
		InitHC138(4);
		P0 = 0xfd;
	}
	else if(K == 3)
	{
		InitHC138(4);
		P0 = 0xfb;
	}
}
void main()
{
	InitSystem();
	while(1)
	{
		if(T_s>0)
		{
			InitTimer1();
			InitTimer0();
		}
		Read_Temperature();
		LEDScan();
		display_SMG();
		ScanKey();
	}
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值