蓝桥杯单片机第十五届模拟赛II

一、基本要求


使用大赛组委会提供的四梯/国信长天单片机竞赛实训平台,完成本试题的程序设计与调试。程序编写、调试完成后,选手需通过考试系统提交以准考证号命名的hex文件。不符合以上文件提交要求的作品将被评为零分或者被酌情扣分。

硬件设置:

将IAP15F2K61S2单片机内部振荡器频率设定为12MHz

键盘工作模式跳线J5配置为KBD矩阵按键模式。

扩展方式跳线J13配置为IO模式。

请注意:选手需严格按照以上要求配置竞赛板,编写和调试程序,不符合以上配置要求的作品将被评为零分或者被酌情扣分。

二、硬件框图


图1 系统硬件框图

三、功能描述


3.1 基本功能描述

1)通过获取DS18B20温度传感器的温度数据,完成温度测量功能;

2)通过PCF8591 AD/DA芯片完成环境光测量和DAC输出功能;

3)通过LED指示灯完成试题要求的状态指示功能;

4)通过数码管、按键完成试题要求的数据显示和界面切换功能。

3.2 显示功能

1、模式界面

模式界面如图2所示,显示内容包括模式编号,测量的参数数据。

模式1为温度控制模式,显示内容包括编号‘1’和测量的温度参数。

温度参数单位为℃,保留小数点后1位,固定使用3位数码管显示。

图2.1 温度控制模式

模式2为光照度控制模式,显示内容包括编号‘2’和测量的光照度参数。

光照度参数单位为Lux,保留整数,固定使用3位数码管显示,不足3位时,高位(左侧)数码管熄灭。

图2.3 光照度控制模式

2、输出界面

输出界面如图3所示,由标识符(U)和输出的DAC数据组成。

输出的DAC数据单位为V,保留小数点后1位,固定使用2位数码管显示。

图3 输出界面

3、显示要求

按照题目要求的界面格式和切换方式进行设计。

数码管显示无重影、闪烁、过暗、亮度不均匀等严重影响显示效果的缺陷。

3.3 按键功能

1、功能说明

1)S4:定义为“模式切换”,在模式界面下,按下S4按键,切换2种控制模式,切换顺序如下图所示。

图4 模式切换顺序

2)S5:定义为“界面切换”,按下S5按键,切换模式界面和输出界面,切换顺序如图所示。

图5 模式切换顺序

2、按键要求

按键应做好消抖处理,避免出现一次按键动作导致功能多次触发。

按键动作不影响数码管显示等其他功能。

按键S4仅在“模式界面”有效。

3.4 输出功能

模式1,DAC输出与测量的温度参数有关,温度参数与DAC输出关系如图6.1所示。

图6.1 温度参数与DAC输出关系

模式2,DAC输出与测量的光照度参数有关,光照度参数与DAC输出关系如图6.2所示。

图6.2 光照度参数与DAC输出关系

3.5 LED指示灯功能


1)温度控制模式下,指示灯L1点亮,否则指示灯L1熄灭。

2)光照度控制模式下,指示灯L2点亮,否则指示灯L2熄灭。

其余指示灯均处于熄灭状态。

3.6 初始状态


请严格按照以下要求设计作品的上电初始状态。

处于模式界面,温度控制模式。

提示,模式2的关照强度即adc采样的值,0~255对应光照强度

参考代码,满分答案

#include <STC15F2K60S2.H>
#include "onewire.h"
#include "iic.h"
#include "intrins.h"
sbit h1 = P3^2;
sbit h2 = P3^3;
sbit s1 = P4^4;
sbit s2 = P4^2;

unsigned char code SMG_NoDot[18]={0xc0,0xf9,
    0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,
    0x88,0x80,0xc6,0xc0,0x86,0x8e,0xbf,0x7f}; 
unsigned char code SMG_Dot[10] =  {0x40,0x79,
	0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
unsigned char stat_led = 0xff;
unsigned int out_volt = 0;
unsigned int adc_lux = 0;
float temp_value = 0;
float adc_volt = 0;
unsigned int adc_smg = 0;
unsigned int temp_smg = 0;
float lux_data = 0;
unsigned char UI = 0; //0-模式界面 1-输出界面
unsigned char mode = 0; //0-模式一 1-模式二
void Delay20ms()		//@12.000MHz
{
	unsigned char i, j, k;

	_nop_();
	_nop_();
	i = 1;
	j = 234;
	k = 113;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}


void Init_temp()
{
	unsigned char LSB,MSB = 0;
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0x44);
	do{
		init_ds18b20();
		Write_DS18B20(0xcc);
		Write_DS18B20(0xbe);
		LSB = Read_DS18B20();
		MSB = Read_DS18B20();
		MSB = (MSB << 4) | (LSB >> 4);
	}while(MSB == 85);
}

void read_temp()
{
	unsigned char LSB,MSB = 0;
	unsigned int temp = 0;
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0x44);
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0xbe);
	LSB = Read_DS18B20();
	MSB = Read_DS18B20();
	temp = MSB << 8;
	temp = temp | LSB;
	if((temp & 0xf800) == 0x0000)
	{
		temp_value = temp * 0.0625;
	}
	temp_smg = temp_value * 10;
}
void read_adcvalue()
{
	unsigned char adc_value = 0;
	I2CStart();
	I2CSendByte(0x90);
	I2CWaitAck();
	I2CSendByte(0x41);
	I2CWaitAck();
	I2CStop();
	
	I2CStart();
	I2CSendByte(0x91);
	I2CWaitAck();
	adc_lux = I2CReceiveByte();
	I2CSendAck(1);
	I2CStop();
}

void set_dacvalue(unsigned char dac_value)
{
	I2CStart();
	I2CSendByte(0x90);
	I2CWaitAck();
	I2CSendByte(0x41);
	I2CWaitAck();
	I2CSendByte(dac_value);
	I2CWaitAck();
	I2CStop();
}
void SelectHC573(unsigned char channel,unsigned char dat)
{
	P2 = (P2 & 0x1f) | 0x00;
	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 DisplaySMG_Bit(unsigned char pos,unsigned char value)
{
	SelectHC573(6,0x01 << pos);
	SelectHC573(7,value);
	Delay_SMG(500);
	SelectHC573(6,0x01 << pos);
	SelectHC573(7,0xff);
}

void DisplaySMG_All(unsigned char value)
{
	SelectHC573(6,0xff);
	SelectHC573(7,value);
}

void DisplaySMG_Info()
{
	if(UI == 0)
	{
		switch(mode)
		{
			case 0:
				DisplaySMG_Bit(0,SMG_NoDot[1]);
				DisplaySMG_Bit(5,SMG_NoDot[temp_smg / 100]);
				DisplaySMG_Bit(6,SMG_Dot[temp_smg / 10 % 10]);
				DisplaySMG_Bit(7,SMG_NoDot[temp_smg % 10]);
			break;
			case 1:
				DisplaySMG_Bit(0,SMG_NoDot[2]);
				if(adc_lux > 99)
				{
					DisplaySMG_Bit(5,SMG_NoDot[adc_lux / 100]);
					DisplaySMG_Bit(6,SMG_NoDot[adc_lux / 10 % 10]);
					DisplaySMG_Bit(7,SMG_NoDot[adc_lux % 10]);
				}
				else
				{
					DisplaySMG_Bit(6,SMG_NoDot[adc_lux / 10]);
					DisplaySMG_Bit(7,SMG_NoDot[adc_lux % 10]);
				}
				
			break;
		}
	}
	else
	{
		DisplaySMG_Bit(0,0xc1);
		DisplaySMG_Bit(6,SMG_Dot[out_volt / 10]);
		DisplaySMG_Bit(7,SMG_NoDot[out_volt % 10]);
	}
}

void scan_key()
{
	s1 = 0;
	s2 = h1 = h2 = 1;
	if(h1 == 0) //s5
	{
		Delay20ms();
		if(h1 == 0)
		{
			if(UI == 0)
			{
				UI = 1;
			}
			else
			{
				UI = 0;
			}
			while(h1 == 0)
			{
				DisplaySMG_Info();
			}
		}
	}
	else if(h2 == 0) //s4
	{
		Delay20ms();
		if(h2 == 0)
		{
			if(UI == 0)
			{
				if(mode == 0)
				{
					mode = 1;
				}
				else
				{
					mode = 0;
				}
			}
			while(h2 == 0)
			{
				DisplaySMG_Info();
			}
		}
	}
	
}
void out_UI_deal()
{
	float out_value = 0;
	unsigned char set_value = 0;
	if(mode == 0)
	{
		if(temp_value <= 10.0)
		{
			out_value = 1.0;
		}
		else if(temp_value < 40.0)
		{
			out_value = 0.133* temp_value - 0.333;
		}
		else 
		{
			out_value = 5.0;
		}
		out_volt = out_value * 10;
		set_value = out_value / 0.0196;
		set_dacvalue(set_value);
	}
	else if(mode == 1)
	{
		if(adc_lux <= 10)
		{
			out_value = 1.0;
		}
		else if(adc_lux < 240)
		{
			out_value = ((float)4/230)*adc_lux + ((float)19/23);
		}
		else
		{
			out_value = 5.0;
		}
		out_volt = out_value * 10;
		set_value = out_value / 0.0196;
		set_dacvalue(set_value);
	}
}
void led_control()
{
	if(mode == 0)
	{
		stat_led = 0xfe;
		SelectHC573(4,stat_led);
	}
	else if(mode == 1)
	{
		stat_led = 0xfd;
		SelectHC573(4,stat_led);
	}
}
void Init_System()
{
	SelectHC573(4,0xff);
	SelectHC573(5,0x00);
	Init_temp();
	DisplaySMG_All(0xff);
}
void main()
{
	Init_System();
	while(1)
	{
		read_temp();
		read_adcvalue();
		scan_key();
		out_UI_deal();
		DisplaySMG_Info();
		led_control();
	}
}

  • 34
    点赞
  • 71
    收藏
    觉得还不错? 一键收藏
  • 29
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值