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

文章详细描述了一个单片机竞赛项目的要求,涉及使用IAP15F2K61S2单片机实现超声波测距、模拟功能、界面显示、按键控制和参数调整,同时给出了硬件配置、功能描述、代码示例和评分标准。
摘要由CSDN通过智能技术生成

一、基本要求


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

硬件设置:

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

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

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

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

二、硬件框图


图1 系统硬件框图

三、功能描述


3.1 基本功能描述

1、通过超声波传感器完成距离测量功能;

2、通过 PCF8591完成试题要求的模拟功能;

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

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

3.2 显示功能

1、测距界面

测距界面如图2所示,显示内容包括标识符(A)和距离值组成。距离值固定使用3位数码管显示,数码管显示不足3位时,高位(左侧)数码管熄灭。

距离值单位为:cm。

图2 测距界面

2、参数界面

参数界面如图3所示,由标识符(P)、模式值(按键模式:1;旋钮模式:2),参数下限、间隔符和参数上限组成。固定使用2位数码管显示参数下限/上限。

参数上限、参数下限单位为:cm。

图3 参数界面

3、记录界面

记录界面如图4所示,由标识符(E)和报警次数组成。

图4.1 记录界面(报警次数0-9)

图4.2 记录界面(报警次数>9)

测量的距离值由“参数下限≤测量的距离值≤参数上限”变为“测量的距离值>参数上限”或“测量的距离值<参数下限”时,报警次数加1;

注意:持续处于测量的距离值>参数上限或测量的距离值<参数下限时,报警次数不改变,

4、显示要求

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

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

3.3 按键功能

1、功能说明

(1)S4:定义为“切换”,按下S4按键,切换“测距界面”、“参数界面”和“记录界面”。

图5 界面切换顺序

(2)S5:

在“参数界面”下,定义为“模式”,按下按键S5,切换参数调整模式。切换顺序如图6所示。

图6 模式切换

在“记录界面下”,定义为“清零”,按下按键S5,清零当前的报警次数。

(3)S9:在“参数界面”下

“按键模式”下,定义为“上限调整”,按下按键S9,参数上限加10。参数上限调整顺序:

50 60 70 80 90 50 …

“旋钮模式”下,定义为“上限”,按下按键S9,可使用旋钮调整当前参数上限。调整顺序详见3.4(1)。

(4)S8:在“参数界面”下,

“按键模式”下,定义为“下限调整”,按下按键S8,参数下限加10。参数下限调整顺序:

0 10 20 30 40 0 10 …

“旋钮模式”下,定义为“下限”,按下按键S8,可使用旋钮调整当前参数上限。调整顺序详见3.4(2)。

(5)按键要求

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

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

③ 当前界面或模式下无功能的按键按下,不触发其它界面的功能。

④ 参数上限调整范围“50-90”;

⑤ 参数下限调整范围“0-50”。

3.4 旋钮模式

使用PCF8591的ADC功能采集RB2的模拟信号,模拟旋钮功能调整参数上限或参数下限:

(1)“上限”调整过程如图7所示:

图7 “上限”调整过程

(2)“下限”调整过程如图8所示:

图8 “下限”调整过程

3.5 LED指示灯功能

(1)测距界面下,指示灯 L1 点亮,否则指示灯 L1 熄灭。

(2)参数界面下,指示灯 L2 点亮,否则指示灯 L2 熄灭。

(3)记录界面下,指示灯 L3 点亮,否则指示灯 L3 熄灭。

(4)参数下限≤测量的距离值≤参数上限,指示灯L8点亮,否则L8以0.1s为间隔切换亮灭状态。

(5)除L1、L2、L3和L8指示灯外,其余指示灯均处于熄灭状态。

3.6 初始状态

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

1、处于测距界面

2、按键模式

3、参数上限60;参数下限10。

代码仅供参考,功能演示正常

满分答案

#include <STC15F2K60S2.H>
#include "intrins.h"
#include "iic.h"
void SelectHC573(unsigned char channel,unsigned char dat);
unsigned int Wave_data();
void read_adcvolt();
void alarm_system();
sbit TX = P1^0;
sbit RX = P1^1;
sbit h1 = P3^2;
sbit h2 = P3^3;
sbit s1 = P4^4;
sbit s2 = P4^2;
unsigned int num_200ms = 0;
unsigned char stat_warn = 0;
unsigned char num_01s = 0;
unsigned char stat_L8 = 0;
unsigned char stat_led = 0xff;
unsigned char stat_up = 0;
unsigned char stat_down = 0;
float adc_volt = 0;
unsigned char key_up = 60;
unsigned char key_down = 10;
unsigned char count_warn = 0;
unsigned int distance = 0;
unsigned char key_mode = 0; //0-按键模式 1-旋钮模式
unsigned char mode = 0;//0-测距界面 1-参数界面 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};
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 Delay12us()		//@12.000MHz
{
	unsigned char i;

	_nop_();
	_nop_();
	i = 33;
	while (--i);
}
void Init_timer0()
{
	TMOD = TMOD & 0xf0;
	TMOD = TMOD | 0x01;
	TH0 = (65535 - 10000) / 256;
	TL0 = (65535 - 10000) % 256;
	TR0 = 1;
	EA = 1;
	ET0 = 1;
}

void Sevice_timer0() interrupt 1
{
	TH0 = (65535 - 10000) / 256;
	TL0 = (65535 - 10000) % 256;
	if(stat_L8 == 2)
	{
		num_01s++;
		if(num_01s == 10)
		{
			num_01s = 0;
			if((stat_led | 0x7f) == 0xff)
			{
				stat_led = stat_led & 0x7f;
				SelectHC573(4,stat_led);
			}
			else
			{
				stat_led = stat_led | 0x80;
				SelectHC573(4,stat_led);
			}
		}
	}
	num_200ms++;
	if(num_200ms == 20)
	{
		num_200ms = 0;
		distance = Wave_data();
		read_adcvolt();
		alarm_system();
	}
}
void Init_Wave()
{
	unsigned char i;
	for(i = 0;i < 8;i++)
	{
		TX = 1;
		Delay12us();
		TX = 0;
		Delay12us();
	}
}
unsigned int Wave_data()
{
	unsigned int timer;
	TMOD = TMOD & 0x0f;
	TMOD = TMOD | 0x10;
	TH1 = TL1 = 0;
	Init_Wave();
	TR1 = 1;
	while((RX == 1) && (TF1 == 0));
	TR1 = 0;
	if(TF1 == 0)
	{
		timer = TH1 << 8 | TL1;
		return(timer * 0.017);
	}
	else
	{
		TF1 = 0;
		return 0;
	}
}

void read_adcvolt()
{
	unsigned char adc_value;
	I2CStart();
	I2CSendByte(0x90);
	I2CWaitAck();
	I2CSendByte(0x03);
	I2CWaitAck();
	I2CStop();
	
	I2CStart();
	I2CSendByte(0x91);
	I2CWaitAck();
	adc_value = I2CReceiveByte();
	I2CSendAck(1);
	I2CStop();
	
	adc_volt = adc_value * (5.0 / 255);
}
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 DelaySMG(unsigned int t)
{
	while(t--);
}
void DisplaySMG_Bit(unsigned char pos,unsigned char value)
{
	SelectHC573(6,0x01 << pos);
	SelectHC573(7,value);
	DelaySMG(500);
	SelectHC573(6,0x01 << pos);
	SelectHC573(7,0xff);
}	
void DisplaySMG_All(unsigned char value)
{
	SelectHC573(6,0xff);
	SelectHC573(7,value);
}
void DisplaySMG_Info()
{
	switch(mode)
	{
		case 0:
			DisplaySMG_Bit(0,0x88);
			if(distance > 99)
			{
				DisplaySMG_Bit(5,SMG_NoDot[distance / 100]);
			}
			DisplaySMG_Bit(6,SMG_NoDot[distance / 10 % 10]);
			DisplaySMG_Bit(7,SMG_NoDot[distance % 10]);
		break;
		case 1:
			DisplaySMG_Bit(0,0x8c);
			DisplaySMG_Bit(1,SMG_NoDot[key_mode + 1]);
			DisplaySMG_Bit(3,SMG_NoDot[key_down / 10]);
			DisplaySMG_Bit(4,SMG_NoDot[key_down % 10]);
			DisplaySMG_Bit(5,SMG_NoDot[16]);
			DisplaySMG_Bit(6,SMG_NoDot[key_up / 10]);
			DisplaySMG_Bit(7,SMG_NoDot[key_up % 10]);
		break;
		case 2:
			DisplaySMG_Bit(0,0x86);
			if(count_warn > 9)
			{
				DisplaySMG_Bit(7,SMG_NoDot[16]);
			}
			else
			{
				DisplaySMG_Bit(7,SMG_NoDot[count_warn]);
			}
		break;
	}
	
}
void scan_key()
{
	s1 = 0;
	s2 = h1 = h2 = 1;
	if(h1 == 0) //s5
	{
		Delay20ms();
		if(h1 == 0)
		{
			if(mode == 1)
			{
				if(key_mode == 0)
				{
					key_mode = 1;
				}
				else if(key_mode == 1)
				{
					key_mode = 0;
				}
			}
			else if(mode == 2)
			{
				count_warn = 0;
			}
			while(h1 == 0)
			{
				DisplaySMG_Info();
			}
		}
	}
	else if(h2 == 0) //s4
	{
		Delay20ms();
		if(h2 == 0)
		{
			if(mode == 0)
			{
				mode = 1;
			}
			else if(mode == 1)
			{
				mode = 2;
			}
			else
			{
				mode = 0;
			}
			while(h2 == 0)
			{
				DisplaySMG_Info();
			}
		}
	}
	
	s2 = 0;
	s1 = h1 = h2 = 1;
	if(h1 == 0) //s9
	{
		Delay20ms();
		if(h1 == 0)
		{
			if(mode == 1)
			{
				stat_down = 0;
				if(key_mode == 0)
				{
					stat_up = 0;
					if(key_up == 90)
					{
						key_up = 50;
					}
					else
					{
						key_up = key_up + 10;
					}
				}
				if(key_mode == 1)
				{
					stat_up = 1;
				}
			}
			while(h1 == 0)
			{
				DisplaySMG_Info();
			}
		}
	}
	else if(h2 == 0) //s8
	{
		Delay20ms();
		if(h2 == 0)
		{
			if(mode == 1)
			{
				stat_up = 0;
				if(key_mode == 0)
				{
					stat_down = 0;
					if(key_down == 40)
					{
						key_down = 0;
					}
					else
					{
						key_down = key_down + 10;
					}
				}
				if(key_mode == 1)
				{
					stat_down = 1;
				}
			}
			while(h2 == 0)
			{
				DisplaySMG_Info();
			}
		}
	}
}
void xuanniu_mode()
{
	if((mode == 1) && (stat_up == 1))
	{
		if(adc_volt <= 1.0)
		{
			key_up = 50;
		}
		else if(adc_volt <= 2.0)
		{
			key_up = 60;
		}
		else if(adc_volt <= 3.0)
		{
			key_up = 70;
		}
		else if(adc_volt <= 4.0)
		{
			key_up = 80;
		}
		else if(adc_volt <= 5.0)
		{
			key_up = 90;
		}
	}
	else if((mode == 1) && (stat_down == 1))
	{
		if(adc_volt < 1.0)
		{
			key_down = 0;
		}
		else if(adc_volt < 2.0)
		{
			key_down = 10;
		}
		else if(adc_volt < 3.0)
		{
			key_down = 20;
		}
		else if(adc_volt < 4.0)
		{
			key_down = 30;
		}
		else if(adc_volt < 5.0)
		{
			key_down = 40;
		}
	}
}
void alarm_system()
{
	if(stat_warn == 0)
	{
		if((distance > key_up) || (distance < key_down))
		{
			count_warn++;
			stat_warn = 1;
			stat_L8 = 2;
		}
	}
	if((key_down <= distance) && (distance <= key_up))
	{
		stat_warn = 0;
		stat_L8 = 1;
	}
}
void led_System()
{
	if(mode == 0)
	{
		stat_led = stat_led | 0x04;
		stat_led = stat_led & 0xfe;
		SelectHC573(4,stat_led);
	}
	else if(mode == 1)
	{
		stat_led = stat_led | 0x01;
		stat_led = stat_led & 0xfd;
		SelectHC573(4,stat_led);
	}
	else if(mode == 2)
	{
		stat_led = stat_led | 0x02;
		stat_led = stat_led & 0xfb;
		SelectHC573(4,stat_led);
	}
	if(stat_L8 == 1)
	{
		stat_led = stat_led & 0x7f;
		SelectHC573(4,stat_led);
	}
}
void Init_System()
{
	Init_timer0();
	DisplaySMG_All(0xff);
	SelectHC573(4,0xff);
	SelectHC573(5,0x00);
}
void main()
{
	Init_System();
	while(1)
	{
		scan_key();
		xuanniu_mode();
		DisplaySMG_Info();
		led_System();
	}
}

  • 20
    点赞
  • 69
    收藏
    觉得还不错? 一键收藏
  • 14
    评论
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值