第12届蓝桥杯单片机省赛代码展示

本文介绍了一个使用DAC进行电压输出并结合DS18B20温度传感器的代码示例,涉及I2C通信、SMG模块以及按键控制的温度设置和显示功能。
摘要由CSDN通过智能技术生成

本届代码相比于后两届,考了DAC电压输出模块。

DAC电压输出虽然不难,但依旧非常重要,需要考虑单位转化的问题。

其余难度不是很大。

代码如下,欢迎大家交流和指正错误。

#include "reg52.h"
#include "iic.h"
#include "onewire.h"

sfr P4 = 0xC0;

sbit C0 = P4^4;
sbit C1 = P4^2;
sbit R0 = P3^2;
sbit R1 = P3^3;

unsigned int Temp;
unsigned int Set_Temp = 25;

unsigned char rd1;
unsigned int Volt;

unsigned char S4_mode = 1;
unsigned char S5_mode = 1;

unsigned char led_state = 0xFF;

bit S4;
bit S5;
bit S8;
bit S9;

unsigned char SMG_duanma[]={
	0xc0,//0
	0xf9,//1
	0xa4,//2
	0xb0,//3
	0x99,//4
	0x92,//5
	0x82,//6
	0xf8,//7
	0x80,//8
	0x90,//9
	0x88,//A
	0x83,//B
	0xc6,//C
	0xa1,//D
	0x86,//E
	0x8e,//F
	0xbf,//
	0x7f//
};

unsigned char SMG_duanma_Dot[]={
	0x40,//0
	0x79,//1
	0x24,//2
	0x30,//3
	0x19,//4
	0x12,//5
	0x02,//6
	0x78,//7
	0x00,//8
	0x10,//9
};

void Select_HC573(unsigned char channel ,dat)
{
	P0 = dat;
	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) | 0x00;
			break;
	}
	P2 = (P2 & 0x1F) | 0x00;
}

void Delay_SMG(unsigned int t)
{
	while(t--);
}

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

void SMG_Bit(unsigned char pos ,value)
{
	Select_HC573(6,0xFF);
	Select_HC573(7,0xFF);
	
	Select_HC573(6,0x01 << pos);
	Select_HC573(7,value);
}

void Temp_Update()
{
	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();
	
	Temp = MSB;
	Temp = Temp << 8;
	Temp |= LSB;
	
	Temp = Temp >> 4;//舍去小数
	Temp *= 100;
	Temp += (LSB & 0x0F) * 6.25; //原本分辨率为0.0625,乘100倍
}

void Volt_Out(unsigned dat)      //很重要,DAC电压输出
{
	I2CStart();
	I2CSendByte(0x90);
	I2CWaitAck();
	I2CSendByte(0x43);
	I2CWaitAck();
	I2CSendByte(dat);
	I2CWaitAck();
	I2CStop();
}

void DisPlay_Temp()
{
	SMG_Bit(7,SMG_duanma[Temp % 10 / 1]);
	Delay_SMG(500);
	SMG_Bit(6,SMG_duanma[Temp % 100 / 10]);
	Delay_SMG(500);
	SMG_Bit(5,SMG_duanma_Dot[Temp % 1000 / 100]);
	Delay_SMG(500);
	SMG_Bit(4,SMG_duanma[Temp % 10000 / 1000]);
	Delay_SMG(500);
	
	SMG_Bit(0,0xc6); //C
	Delay_SMG(500);
}

void DisPlay_Set_Temp()
{
	SMG_Bit(7,SMG_duanma[Set_Temp % 10]);
	Delay_SMG(500);
	SMG_Bit(6,SMG_duanma[Set_Temp / 10]);
	Delay_SMG(500);
	
	SMG_Bit(0,0x8C); //P
	Delay_SMG(500);
}

void DisPlay_Volt()
{
	SMG_Bit(7,SMG_duanma[Volt % 10 / 1]);
	Delay_SMG(500);
	SMG_Bit(6,SMG_duanma[Volt % 100 / 10]);
	Delay_SMG(500);
	SMG_Bit(5,SMG_duanma_Dot[Volt % 1000 / 100]);
	Delay_SMG(500);
	
	
	SMG_Bit(0,0x88); //A
	Delay_SMG(500);
}

void DisPlay_SMG()
{
	if(S4_mode == 1)
	{
		DisPlay_Temp();
	}
	else if(S4_mode == 2)
	{
		DisPlay_Set_Temp();
	}
	else if(S4_mode == 3)
	{
		DisPlay_Volt();
	}
}

void Scan_Key()
{
	C0 = 0;
	C1 = 1;
	R0 = R1 = 1;
	if(R0 == 0) // s5
	{
		Delay(50);
		if(R0 == 0 )
		{
			Delay(50);
			if(R0 == 0 && S5 == 0)
			{
				S5 = 1;
				if(S5_mode == 1)
				{
					S5_mode = 2;
				}
				else if(S5_mode == 2)
				{
					S5_mode = 1;
				}
			}
		}
	}
	else
	{
		S5 = 0;
	}
	
	if(R1 == 0) // s4
	{
		Delay(50);
		if(R1 == 0 && S4 == 0)
		{
			S4 = 1;
			if(S4_mode == 1)
			{
				S4_mode = 2;
			}
			else if(S4_mode == 2)
			{
				S4_mode = 3;
			}
			else if(S4_mode == 3)
			{
				S4_mode = 1;
			}
		}
	}
	else
	{
		S4 = 0;
	}
	
	C0 = 1;
	C1 = 0;
	R0 = R1 = 1;
	if(R0 == 0) // s9
	{
		Delay(50);
		if(R0 == 0 && S9 == 0)
		{
			S9 = 1;
			if(S4_mode == 2)
			{
				Set_Temp += 1;
			}
		}
	}
	else
	{
		S9 = 0;
	}
	
	if(R1 == 0) // s8
	{
		Delay(50);
		if(R1 == 0 && S8 == 0)
		{
			S8 = 1;
			if(S4_mode == 2)
			{
				Set_Temp -= 1;
			}
		}
	}
	else
	{
		S8 = 0;
	}
}

void Volt_update()
{
	if(S5_mode == 1)
	{
		if(Temp > Set_Temp * 100)
		{
			Volt_Out(0);
			Volt = 0;
		}
		else
		{
			Volt_Out(255);
			Volt = 500;
		}
	}
	
	else if(S5_mode == 2)
	{
		if(Temp > 4000) //>40℃
		{
			Volt_Out(204);
			Volt = 400;
		}
		else if(Temp > 2000)
		{
			Volt_Out(51 + ((float)(Temp - 2000) * 153.0 / 2000.0));
			Volt = (int)((51 + ((float)(Temp - 2000) * 153.0 / 2000.0)) / 255 * 5 *100);
		}
		else
		{
			Volt_Out(51);
			Volt = 100;
		}
	}
}

void DisPlay_Led()
{
	if(S5_mode == 1)
	{
		led_state &= 0xFE;
	}
	else
	{
		led_state |= ~0xFE;
	}
	
	if(S4_mode == 1)
	{
		led_state &= 0xFD;
	}
	else
	{
		led_state |= ~0xFD;;
	}
	
	if(S4_mode == 2)
	{
		led_state &= 0xFB;
	}
	else
	{
		led_state |= ~0xFB;
	}
	
	if(S4_mode == 3)
	{
		led_state &= 0xF7;
	}
	else
	{
		led_state |= ~0xF7;
	}
	
	Select_HC573(4,led_state);
}

void Sys()
{
	Select_HC573(6,0xFF);
	Select_HC573(7,0x0FF);
	Select_HC573(5,0x00);
	Select_HC573(4,0xFF);
}


void main()
{
	Sys();
	while(1)
	{
		Temp_Update();
		Scan_Key();
		Volt_update();
		DisPlay_Led();
		DisPlay_SMG();
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值