蓝桥杯单片机第七届省赛模拟风扇系统(足够简单)

看的小蜜蜂老师的视频,自己头一次写。

#include <reg52.h>
#include <onewire.h>

sfr P4 = 0xc0;

sbit R3 = P3^2;
sbit R4 = P3^3;

sbit C2 = P4^2;
sbit C1 = P4^4;

sbit out = P3^4;

unsigned char code SMG_duanma[13] = {0xc0,0xf9,0xa4,
	0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xc6,0xff}; 
// 0 1 2 3 4 5 6 7 8 9 - c 全灭

unsigned char mod = 1;   //工作模式存储变量
unsigned char t_mod = 0;   //计时模式存储变量
unsigned char c_mod = 0;   //温度显示模式控制字
unsigned char t_work = 0;   //倒计时时间
unsigned char t_pwm;  //pwm计时变量
unsigned int temp = 0; //温度存储字
	
void Display_led();

void SelectHC573(unsigned char channel)  //573选通
{
	switch(channel)
	{
		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;
		case 0:
			P2 = P2 & 0x1f;
		break;	
	}
}

void ScanKeys()  //键盘扫描函数
{
  C1 = 0;
  C2 = 1;
	R3 = R4 = 1;
	if(R4 == 0)  //PWM
	{
		void Display_Dynamic();
		while(R4 == 0)
		{
			Display_Dynamic();
		}
		switch(mod)
		{
			case 1:
			mod = 2;
			t_pwm = 3;
			break;
			
			case 2:
			mod = 3;
			t_pwm = 7;
			break;
			
			case 3:
			mod = 1;
			t_pwm = 2;
			break;			
		}	
		Display_led();
	}
	
	if(R3 == 0) //计时
	{
		Display_Dynamic();
		while(R3 == 0)
		{
			Display_Dynamic();
		}
		if(t_mod == 0) t_mod =1 ,t_work = 60;
		else if(t_mod == 1) t_mod = 2 ,t_work = 120;
		else if(t_mod == 2) t_mod = 0 ,t_work = 0;
		Display_led();
	}
	
	C2 = 0;
  C1 = 1;
	R3 = R4 = 1;
	if(R3 == 0)  //机器启闭
	{
		Display_Dynamic();
		while(R3 == 0)
		{
			Display_Dynamic();
		}
		t_work = 0;
		Display_led();
	}
	
	if(R4 == 0)  //温度显示
	{
		Display_Dynamic();
		while(R4 == 0)
		{
			Display_Dynamic();
		}
    if(c_mod == 0) 
		{
			c_mod =1;
		}
		else c_mod = 0;
		Display_led();
	}
}

void Cls_peripheral()  //关闭外设
{
	P0 = 0xff;
	SelectHC573(4);
	SelectHC573(0);
	P0 = 0;
	SelectHC573(5);
	SelectHC573(0);
}

void DisplaySMG_bit(unsigned char pos,unsigned char value)
{
	P0 = 0xff;  //消隐
	SelectHC573(6);
	P0 = 0x01 << pos;
	SelectHC573(0);
	P0 = SMG_duanma[value];
	SelectHC573(7);	
}

void initTimer()   //初始化定时器
{
	TMOD = 0x12;     //T0用PWM计时,T1用作工作计时
	
	TH0 = 0x9b;   //255-100
	TL0 = 0x9b;
	
	TH1 = (65535-50000)/256;
	TL1 = (65535-50000)%256;
	
	ET0 = 1;   //使能中断
	ET1 = 1;
	TF0 = 0;
	TF1 = 0;
	EA = 1;
	TR0 = 0;  //启动
	TR1 = 1;
}

void Delay(unsigned int t)
{
	while(t--)
	{
		Display_Dynamic();
	}
}

void DelaySMG(unsigned char t)
{
	while(t--);
}

void Display_led()   //led显示控制
{
	SelectHC573(4);
	if(mod == 1 & t_work != 0) P0 = 0xfe;
	else if(mod == 2 & t_work != 0) P0 = 0xfd;
	else if(mod == 3 & t_work != 0) P0 = 0xfb;
	else P0 = 0xff;
	SelectHC573(0);
}

void Display_Dynamic()   //数码管动态显示
{
	DisplaySMG_bit(0,10);
	DelaySMG(100);
	DisplaySMG_bit(2,10);
	DelaySMG(100);
	DisplaySMG_bit(3,12);  //熄灭第四位
	DelaySMG(100);
	
	 if(c_mod == 0)  //工作时间显示
	{
		DisplaySMG_bit(1,mod);
	  DelaySMG(100);
		DisplaySMG_bit(7,t_work%10);
	  DelaySMG(100);
		DisplaySMG_bit(6,(t_work/10)%10);
	  DelaySMG(100);
		DisplaySMG_bit(5,t_work/100);
	  DelaySMG(100);
		DisplaySMG_bit(4,0);
	  DelaySMG(100);
	}
	
		if(c_mod == 1)  //温度显示
	{
		DisplaySMG_bit(1,4);  //温度显示模式
	  DelaySMG(100);
		DisplaySMG_bit(4,12);  //熄灭第五位
	  DelaySMG(100);
		DisplaySMG_bit(7,11);  //显示摄氏度
	  DelaySMG(100);
		DisplaySMG_bit(6,temp%10);
	  DelaySMG(100);
		DisplaySMG_bit(5,(temp/10)%10);
	  DelaySMG(100);
	}
}

void Read_DS18B20_temp()  //读取温度
{
	unsigned char LSB,MSB;
	
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0x44);
	
	Delay(1000);
	
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0xbe);

	LSB = Read_DS18B20();
	MSB = Read_DS18B20();
	init_ds18b20();
	
	temp = MSB;
	temp =(temp << 8)| LSB;
	
	temp >>=4;    //数据处理
}

unsigned char count0;
void ServiceTimer0() interrupt 1
{
	count0++; //计数100微秒
	if(count0 == t_pwm)
	{
		out = 0;
	}
	else if(count0 == 10 & t_work !=0) //计数周期 1微秒
	{
		out = 1;
		count0 = 0;
	}
}

unsigned char count1;
void ServiceTimer1() interrupt 3
{
	TH1 = (65535-50000)/256;
	TL1 = (65535-50000)%256;
	
	count1++;
	if(count1 ==20 & t_work != 0)  //计数1秒
	{
		t_work--;		//变化秒数
		count1 = 0;
	}
	if(t_work == 0)
	{
		SelectHC573(4);
		P0 = 0xff;
		SelectHC573(0);
	}
	if(count1 == 20)  //手动重置计数器
	{
		count1 = 0;
	}
}

void main()
{
	Cls_peripheral();
	initTimer();
	while(1)
	{
		ScanKeys();
		Read_DS18B20_temp();
		Display_Dynamic();
	}
}

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
{
	unsigned char i;
	while(t--);
		{
		for(i=0;i<12;i++);
	}
}

//通过单总线向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 int rd_temperature(void)
{
  unsigned char low, high;

  init_ds18b20();					// 初始化
  Write_DS18B20(0xCC);				// 跳过ROM
  Write_DS18B20(0x44);				// 转换温度
 
  init_ds18b20();
  Write_DS18B20(0xCC);
  Write_DS18B20(0xBE);				// 读暂存器
  low = Read_DS18B20();				// 低字节
  high = Read_DS18B20();			// 高字节

  return (high<<8)+low;
}
*/

onewire.h

#ifndef __ONEWIRE_H
#define __ONEWIRE_H

bit init_ds18b20(void);
void Write_DS18B20(unsigned char dat);
unsigned char Read_DS18B20(void);

#endif

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值