【蓝桥杯单片机第十届国赛真题】

【蓝桥杯单片机第十届国赛真题】

文章目录

  • 【蓝桥杯单片机第十届国赛真题】
  • 前言
  • 一、真题
  • 二、源码


前言

【蓝桥杯单片机第十届国赛真题】_第1张图片

有幸进入国赛,为自己大学最后一个比赛画上完满的句号^@^

下面为蓝桥杯单片机第十届国赛程序部分,功能差不多都实现了,可能存在小bug,望大佬指正,有需完整工程的小伙伴可自行下载。
在该工程中,长按的功能会先导致短按界面的切换,还未解决,题目无特殊说明,不能导致界面的切换应该也算ok。

在这里插入图片描述

工程链接

链接: https://pan.baidu.com/s/1gqBQ2bb7g20u45Nmqf7A6w?pwd=x8ty 提取码: x8ty 复制这段内容后打开百度网盘手机App,操作更方便哦 
--来自百度网盘超级会员v5的分享

一、真题

【蓝桥杯单片机第十届国赛真题】_第2张图片

【蓝桥杯单片机第十届国赛真题】_第3张图片
【蓝桥杯单片机第十届国赛真题】_第4张图片
【蓝桥杯单片机第十届国赛真题】_第5张图片
【蓝桥杯单片机第十届国赛真题】_第6张图片
【蓝桥杯单片机第十届国赛真题】_第7张图片

【蓝桥杯单片机第十届国赛真题】_第8张图片
【蓝桥杯单片机第十届国赛真题】_第9张图片

【蓝桥杯单片机第十届国赛真题】_第10张图片

二、源码

在main.c中主要分为5部分功能,smg_task数码管显示任务、data_task数据处理任务、logical_task逻辑处理任务、key_task按键任务以及中断任务。
/*============================第十届国赛================================
@Author:小殷同学
@Date:2023.6.6
=======================================================================*/
#include "public.h"
#include "iic.h"
#include "onewire.h"
/*==========================下面为宏和变量定义=========================*/

//数码管段码(0~9、shut-off、"-")
code uchar smg_data[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf,0xc6,0xc7,
						0xc0,0x8c};

//初始化,使所有数码管熄灭(必须是9个元素)
xdata uchar smg_bit[11] = {10,10,10,10,10,10,10,10,10};
uchar L[5];                                                                    //led控制                                                                  
uchar str[12];                                                                 //串口接收缓存
bit usart_flag = 0;                                                            //接收完成标志
uchar count_index = 0;                                                         //数组下标索引
uchar data_interface = 1,mode = 1,param_interface = 1;                         //界面相关
uchar number = 0;                                                              //参数编号
bit   param_set_flag = 0;                                                      //参数设置标志
xdata uint temperature = 0,dis = 0,count = 0;                                  //温度 距离  计数
xdata uint set_t = 30,set_dis = 35,old_set_t = 30,old_set_dis = 35;            //温度阈值和距离
//下面为数据刷新周期变量
uchar t_feq = 0;
uchar dis_feq = 0;
uchar key_feq = 0;
uchar led_feq = 0;
bit adc_flag = 1;                        //adc启动标志位
/*===========================下面为函数相关声明=========================*/
void Init_System(void);               //系统初始化
void smg_task(void);                  //数码管显示任务
void data_task(void);                 //数据刷新任务
void logical_task(void);              //逻辑处理任务
void key_task(void);                  //按键任务
/*============================下面为函数相关实现========================*/
void smg_task(void)
{
	if(mode == 1)
	{
		if(data_interface == 1)
		{
			smg_bit[1] = 12;//C 0110 0011 0xc6
			smg_bit[2] = 10;
			smg_bit[3] = 10;
			smg_bit[4] = 10;
			smg_bit[5] = temperature/1000;
			smg_bit[6] = temperature/100%10;
			smg_bit[7] = temperature/10%10;
			smg_bit[8] = temperature%10;
		}
		else if(data_interface == 2)
		{
			smg_bit[1] = 13;//L 1110 0011 0xc7
			smg_bit[2] = 10;
			smg_bit[3] = 10;
			smg_bit[4] = 10;
			smg_bit[5] = 10;
			smg_bit[6] = 10;
			smg_bit[7] = dis/10;
			smg_bit[8] = dis%10;
		}
		else if(data_interface == 3)
		{
			smg_bit[1] = 14; //O 0000 0011 0xc0
			smg_bit[2] = 10;
			smg_bit[3] = 10;
			smg_bit[4] = (count > 9999)?(count/10000):(10);
			smg_bit[5] = (count > 999)?(count/1000%10):(10);
			smg_bit[6] = (count > 99)?(count/100%10):(10);
			smg_bit[7] = (count > 9)?(count/10%10):(10);
			smg_bit[8] = count%10;
		}
	}
	else if(mode == 2)
	{
		if(param_interface == 1)
		{
			smg_bit[1] = 15;//P 0011 0001 0x8c
			smg_bit[2] = 10;
			smg_bit[3] = 10;
			smg_bit[4] = number%10;
			smg_bit[5] = 10;
			smg_bit[6] = 10;
			smg_bit[7] = set_t/10;
			smg_bit[8] = set_t%10;
		}
		else if(param_interface == 2)
		{
			smg_bit[1] = 15;//P 0011 0001 0x8c
			smg_bit[2] = 10;
			smg_bit[3] = 10;
			smg_bit[4] = number%10;
			smg_bit[5] = 10;
			smg_bit[6] = 10;
			smg_bit[7] = set_dis/10;
			smg_bit[8] = set_dis%10;
		}
	}
}


void data_task(void)
{
	if(T2H < 0xd9)
	{
		if(t_feq > 150)
		{
			t_feq = 1;
			temperature = Read_Temp() * 100;
		}
		if(dis_feq > 120)
		{
			dis_feq = 1;
			dis = Get_Dis();
		}
	}
	if(usart_flag)
	{
		
		if(str[0] == 'S' && str[1] == 'T' && count_index == 2)
		{
			printf("$%d,%.2f\r\n",dis,temperature/100.0);
		}
		else if(str[0] == 'P' && str[1] == 'A' && str[2] == 'R' && str[3] == 'A' && count_index == 4)
		{
			printf("\#%d,%d\r\n",set_dis,set_t);
		}
		else
		{
			printf("ERROR\r\n");
		}
		usart_flag = 0;
		count_index = 0;
	}
}


void logical_task(void)
{
	//参数编号
	number = (param_interface == 1)?(4):(5);
	if(led_feq > 120)
	{
		led_feq = 1;
		//LED控制
		L[1] = (temperature > set_t * 100)?(1):(0);
		L[2] = (dis < set_dis)?(1):(0);
		L[3] = (adc_flag == 1)?(1):(0);
	}

	//DAC输出
	if(adc_flag == 1)
	{
		if(dis <= set_dis)
		{
			//5v -255 
			Write_DAC(2*51);
		}
		else
		{
			Write_DAC(4*51);
		}
	}
	else
	{
		Write_DAC(0.4*51);
	}
}


void key_task(void)
{
	uchar key_value = 0;
	if(key_feq > 20)
	{
		key_feq = 1;
		key_value = read_key();
	}
	switch(key_value)
	{
		
	//参数和数据界面切换
		case 13:
			if(mode == 1)
			{
				mode = 2;
				//数据界面进入参数界面默认为温度参数
				param_interface = 1;
			}
			else if(mode == 2)
			{
				mode = 1;
				//参数界面进入数据界面默认为温度数据
				data_interface = 1; 
				if(old_set_dis != set_dis || old_set_t != set_t) //当设置参数有变化时才发送改变
				{
					old_set_dis = set_dis;
				    old_set_t = set_t;
					count++;
					Write_AT24C02(1,count >> 8);
					Delay5ms();
					Write_AT24C02(2,count & 0xff);  
					Delay5ms();
				}
				
			}	
		break;
	//数据界面切换
		case 12:
				if(mode == 1)
				{
					if(++data_interface > 3)
					{
						data_interface = 1;
					}
				}
				else if(mode == 2)
				{
					if(++param_interface > 2)
					{
						param_interface = 1;
					}
				}
		break;
	//在参数界面下减
		case 16:
			if(mode == 2)
			{
				//温度参数
				if(param_interface == 1)
				{
					if(set_t > 0)
					{
						set_t -= 2;
					}
				}
				else if(param_interface == 2)
				{
					if(set_dis > 0)
					{
						set_dis -= 5;
					}
				}
			}
		break;
	//参数界面下 加
		case 17:
			if(mode == 2)
			{
				if(param_interface == 1)
				{
					if(set_t < 99)
					{
						set_t += 2;
					}
					else
					{
						set_t = 99;
					}
				}
				else if(param_interface == 2)
				{
					if(set_dis < 99)
					{
						set_dis += 5;
					}
					else 
					{
						set_dis = 99;
					}
				}
			}
		break;
		//长按s12
		case 112:
			count = 0;
			break;
		//长按s13 切换adc输出功能
		case 113:
			adc_flag = ~adc_flag;
				
			break;
	}
}

void Init_System(void)
{
	Control_IO(0x80,0xff);
	Control_IO(0xa0,0x00);
	Control_IO(0xc0,0x00);
	while(t_feq++ < 150)
	{
		temperature = Read_Temp()*100;
	}
	UartInit();
	Timer2Init();
	if(Read_AT24C02(0) == 0xff)   //不是第一次上电
	{
		count = (Read_AT24C02(1)<<8|Read_AT24C02(2));  //上电读取EEPROM
	}
	else
	{
		Write_AT24C02(0,0xff);  
		Delay5ms();
		Write_AT24C02(1,count >> 8);  
		Delay5ms();
		Write_AT24C02(2,count & 0xff);   
		Delay5ms();
	}
	
}

void main(void)
{
	Init_System();
	while(1)
	{
		data_task();
		logical_task();
		smg_task();
		key_task();
	}
}



/*=============================下面为中断相关处理======================*/
void Timer2_Server() interrupt 12
{
	static uchar dsp_smg = 1;
	Control_IO(0x80,~(L[1] <<0 | L[2] << 1 | L[3] <<2));
	Control_IO(0xc0,0x00);
	if(data_interface == 1 && dsp_smg == 6 && mode == 1)
	{
		Control_IO(0xe0,smg_data[smg_bit[dsp_smg]] & 0x7f);
	}
	else
	{
		Control_IO(0xe0,smg_data[smg_bit[dsp_smg]]);
	}
	Control_IO(0xc0,1 << (dsp_smg - 1));
	if(++dsp_smg > 8)
	{
		dsp_smg = 1;
	}
	t_feq++;
	dis_feq++;
	key_feq++;
	led_feq++;
}


void Usart_Server() interrupt 4
{
	uchar dat = 0;
	if(RI)
	{
		RI = 0;
		dat = SBUF;
		if(dat == 0 || dat == '\r' || dat == '\n')
		{
			usart_flag = 1;
			str[count_index] = '0';
		}
		else
		{
			str[count_index++] = dat;
		}
	}
}

你可能感兴趣的:(蓝桥杯国赛,单片机,蓝桥杯,嵌入式硬件)