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

该文分享了第七届蓝桥杯单片机国赛的程序代码,包括数码管显示、数据处理、逻辑处理、按键任务和中断任务等功能模块,涉及DS1302时钟芯片、IIC通信和ADC电压测量。程序实现了时间显示、电压上下限设置、频率周期查询等操作,并提供了工程链接供下载。

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


前言

在这里插入图片描述

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

下面为蓝桥杯单片机第七届国赛程序部分,功能差不多都实现了,可能存在小bug,望大佬指正,总体来说这届难度并不是很大,有需完整工程的小伙伴可自行下载。

在这里插入图片描述

工程链接

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

一、真题

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二、源码

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

uchar  smg_bit[9] = {10,10,10,10,10,10,10,10,10};          
//数码管段码 0-9 shut-off -
uchar smg_data[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xff,0xbf};
uchar interface_index = 1;                                          //界面索引
uchar hour = 23,min = 59,sec = 55;                                    //时、分、秒
uchar set_bit = 0,s4_flag = 0,s4_flag2 = 0,s4_flag3 = 0,s4_flag4 = 0,set_bit_volt = 0;                                        //设置时分秒位标志 和S4按下
bit set_bit_flash = 0;                                                //时分秒闪烁标志
uchar number = 0;                                                     //编号
uint volt = 0;                                                        //adc 电压
uint max_volt = 2000,min_volt = 1000;                                    //电压上限和下限值
uchar event = 0,e_hour = 0,e_min = 0,e_sec = 0;                       //事件类型和查询时间
uint feq = 0,t = 0;                                                   //频率和周期
uchar key_feq = 0;                                                    //按键刷新频率
uchar adc_feq = 0;                                                    //adc刷新
/*===================================================下面为函数声明+===============================================*/
void smg_task(void);                                                     //数码管显示任务
void data_task(void);                                                    //数据处理任务
void logical_task(void);                                                 //逻辑处理任务
void key_task(void);                                                     //按键任务
void Save_Data(void);                                                    //AT24C02数据保存
/*=====================================================下面为函数实现==============================================*/
void smg_task(void)
{
	//显示时间
	if(interface_index == 1 && s4_flag == 0)
	{
		smg_bit[1] = hour/10;
		smg_bit[2] = hour%10;
		smg_bit[3] = 11;
		smg_bit[4] = min/10;
		smg_bit[5] = min%10;
		smg_bit[6] = 11;
		smg_bit[7] = sec/10;
		smg_bit[8] = sec%10;
	}
	else if(interface_index == 1 && s4_flag == 1)
	{
		if(set_bit == 1)
		{
			if(set_bit_flash)
			{
				smg_bit[1] = hour/10;
				smg_bit[2] = hour%10;
			}
			else
			{
				smg_bit[1] = 10;
				smg_bit[2] = 10;
			}
			smg_bit[3] = 11;
			smg_bit[4] = min/10;
			smg_bit[5] = min%10;
			smg_bit[6] = 11;
			smg_bit[7] = sec/10;
			smg_bit[8] = sec%10;
		}
		else if(set_bit == 2)
		{
			if(set_bit_flash)
			{
				smg_bit[4] = min/10;
				smg_bit[5] = min%10;
			}
			else
			{
				smg_bit[4] = 10;
			    smg_bit[5] = 10;
			}
			smg_bit[1] = hour/10;
			smg_bit[2] = hour%10;
			smg_bit[3] = 11;
			smg_bit[6] = 11;
			smg_bit[7] = sec/10;
			smg_bit[8] = sec%10;
		}
		else if(set_bit == 3)
		{
			if(set_bit_flash)
			{
				smg_bit[7] = sec/10;
				smg_bit[8] = sec%10;
			}
			else
			{
				smg_bit[7] = 10;
				smg_bit[8] = 10;
			}
			smg_bit[1] = hour/10;
			smg_bit[2] = hour%10;
			smg_bit[3] = 11;
			smg_bit[4] = min/10;
			smg_bit[5] = min%10;
			smg_bit[6] = 11;
		}
	}
	
	//显示电压
	else if(interface_index == 2 && s4_flag2 == 0)
	{
		smg_bit[1] = 11;
		smg_bit[2] = number;
		smg_bit[3] = 11;
		smg_bit[4] = 10;
		smg_bit[5] = volt/1000;
		smg_bit[6] = volt/100%10;
		smg_bit[7] = volt/10%10;
		smg_bit[8] = volt%10;
	}
	else if(interface_index == 2 && s4_flag2 == 1)
	{
		if(set_bit_volt == 1)
		{
			//上限
			if(set_bit_flash)
			{
				smg_bit[1] = max_volt/1000;
				smg_bit[2] = max_volt/100%10;
				smg_bit[3] = max_volt/10%10;
				smg_bit[4] = max_volt%10;
		
			}
			else
			{
				smg_bit[1] = 10;
				smg_bit[2] = 10;
				smg_bit[3] = 10;
				smg_bit[4] = 10;
			}
				smg_bit[5] = min_volt/1000;
				smg_bit[6] = min_volt/100%10;
				smg_bit[7] = min_volt/10%10;
				smg_bit[8] = min_volt%10;
		}
		else if(set_bit_volt == 2)
		{
			if(set_bit_flash)
			{
				smg_bit[5] = min_volt/1000;
				smg_bit[6] = min_volt/100%10;
				smg_bit[7] = min_volt/10%10;
				smg_bit[8] = min_volt%10;
			}
			else
			{
				smg_bit[5] = 10;
				smg_bit[6] = 10;
				smg_bit[7] = 10;
				smg_bit[8] = 10;
			}
				smg_bit[1] = max_volt/1000;
				smg_bit[2] = max_volt/100%10;
				smg_bit[3] = max_volt/10%10;
				smg_bit[4] = max_volt%10;
		}
	}
	
	//频率和周期
	else if(interface_index == 3 && s4_flag3 == 0)
	{
		smg_bit[1] = 11;
		smg_bit[2] = number;
		smg_bit[3] = 11;
		smg_bit[4] = feq/10000;
		smg_bit[5] = feq/1000%10;
		smg_bit[6] = feq/100%10;
		smg_bit[7] = feq/10%10;
		smg_bit[8] = feq%10;
	}
	else if(interface_index == 3 && s4_flag3 == 1)
	{
		smg_bit[1] = 11;
		smg_bit[2] = number;
		smg_bit[3] = 11;
		smg_bit[4] = t/10000;
		smg_bit[5] = t/1000%10;
		smg_bit[6] = t/100%10;
		smg_bit[7] = t/10%10;
		smg_bit[8] = t%10;
	}
	//查询显示
	else if(interface_index == 4 && s4_flag4 == 0)
	{
		smg_bit[1] = 10;
		smg_bit[2] = 10;
		smg_bit[3] = 1;
		smg_bit[4] = 10;
		smg_bit[5] = 10;
		smg_bit[6] = 10;
		smg_bit[7] = event/10;
		smg_bit[8] = event%10;
	}
	else if(interface_index == 4 && s4_flag4 == 1)
	{
		smg_bit[1] = e_hour/10;
		smg_bit[2] = e_hour%10;
		smg_bit[3] = 11;
		smg_bit[4] = e_min/10;
		smg_bit[5] = e_min%10;
		smg_bit[6] = 11;
		smg_bit[7] = e_sec/10;
		smg_bit[8] = e_sec%10;
	}
}

void data_task(void)
{
	uchar time[3];
	if(T2H < 0xd9)
	{
		if(s4_flag == 0)  //s4_flag == 1时为时钟配置 时间不进行更新 配置完成后再进行更新
		{
			time[0] = Read_Ds1302_Byte(0x81);
			time[1] = Read_Ds1302_Byte(0x83);
			time[2] = Read_Ds1302_Byte(0x85);
			
			hour = (time[2]/16*10 + time[2]%16);
			min  = (time[1]/16*10 + time[1]%16);
			sec  = (time[0]/16*10 + time[0]%16);
		}
		
		if(adc_feq > 120)
		{
			adc_feq = 1;
			volt = read_adc() * (5.0/255) * 1000;  //v-->mv
		}
		
	}
}

void logical_task(void)
{
	if(volt < min_volt)
	{
		event = 0;
		Write_AT24C02(6,event);
		Delay10ms();
		Write_AT24C02(7,hour);
		Delay10ms();
		Write_AT24C02(8,min);
		Delay10ms();
		Write_AT24C02(9,sec);
		Delay10ms();
	}
	else if(volt > max_volt)
	{
		event = 1;
		Write_AT24C02(6,event);
		Delay10ms();
		Write_AT24C02(7,hour);
		Delay10ms();
		Write_AT24C02(8,min);
		Delay10ms();
		Write_AT24C02(9,sec);
		Delay10ms();
	}
}

void key_task(void)
{
	static bit old_s4_flag = 0,old_s4_flag2 = 0;
	uchar key_value = 0;
	if(key_feq > 20)
	{
		key_feq = 1;
		key_value = read_key();
	}
	switch(key_value)
	{
		case 7:  //时钟
			interface_index = 1;
			if(old_s4_flag)
			{
				s4_flag = 0;   //开始进行时间刷新
				//写入设置的时间
				Init_DS1302(hour,min,sec);
			}
			break;
		case 6:  //电压
			interface_index = 2;
		    number = 1;
			if(old_s4_flag2)
			{
				s4_flag2 = 0;
				Write_AT24C02(2,min_volt >> 8); //高位
				Delay100ms();
				Write_AT24C02(3,min_volt & 0xff);  //低位
				Delay100ms();
				Write_AT24C02(4,max_volt >> 8); //高位
				Delay100ms();
				Write_AT24C02(5,max_volt & 0xff);  //低位
				Delay100ms();
				
			}
			break;
		case 5:   //频率
			interface_index = 3;
		    number = 2;
			break;
		case 4:   //功能
			if(interface_index == 1)   //在时钟界面下
			{
				s4_flag = 1;
				old_s4_flag = s4_flag;
				if(set_bit == 0)
				{
					set_bit = 1;
				}
				else if(set_bit == 1)
				{
					set_bit = 2;
				}
				else if(set_bit == 2)
				{
					set_bit = 3;
				}
				else if(set_bit == 3)
				{
					set_bit = 1;
				}
			}
			//电压设置
			if(interface_index == 2)     //在电压界面下设置上限和下限
			{
				s4_flag2 = 1;
				old_s4_flag2 = s4_flag2;
				if(set_bit_volt == 0)
				{
					set_bit_volt = 1;
				}
				else if(set_bit_volt == 1)
				{
					set_bit_volt = 2;
				}
				else if(set_bit_volt == 2)
				{
					set_bit_volt = 1;
				}
			}
			
			//频率周期切换
			if(interface_index == 3)
			{
				if(s4_flag3 == 0)
				{
					s4_flag3 = 1;
				}
				else if(s4_flag3 == 1)
				{
					s4_flag3 = 0;
				}
			}
			
			//事件查询切换
			if(interface_index == 4)
			{
				if(s4_flag4 == 0)
				{
					s4_flag4 = 1;
				}
				else if(s4_flag4 == 1)
				{
					s4_flag4 = 0;
				}
			}
			break;
		case 11:  //加
			if(s4_flag)
			{
				if(set_bit == 1)
				{
					if(hour < 24)
					{
						hour++;
					}
					else
					{
						hour = 12;
					}
				}
				else if(set_bit == 2)
				{
					if(min < 60)
					{
						min++;
					}
					else
					{
						min = 60;
					}
				}
				else if(set_bit == 3)
				{
					if(sec < 60)
					{
						sec++;
					}
					else
					{
						sec = 60;
					}
				}
			}
			
			if(s4_flag2)
			{
				if(set_bit_volt == 1)
				{
					if(max_volt < 9999)  //四位数码管最大值
					{
						max_volt += 500;
					}
					else
					{
						max_volt = 9999;
					}
		
				}
				else if(set_bit_volt == 2)
				{
					if(min_volt < 9999)
					{
						min_volt += 500;
					}
					else
					{
						min_volt = 9999;
					}
				}
			}
			break;
		case 10:  //减
			if(s4_flag)
			{
				if(set_bit == 1)
				{
					if(hour > 0)
					{
						hour--;
					}
					else
					{
						hour = 0;
					}
				}
				else if(set_bit == 2)
				{
					if(min > 0)
					{
						min--;
					}
					else
					{
						min = 0;
					}
				}
				else if(set_bit == 3)
				{
					if(sec > 0)
					{
						sec--;
					}
					else
					{
						sec = 0;
					}
				}
			}
			if(s4_flag2)
			{
				if(set_bit_volt == 1)
				{
					if(max_volt > 0)
					{
						max_volt -= 500;
					}
					else
					{
						max_volt = 0;
					}
				}
				else if(set_bit_volt == 2)
				{
					if(min_volt > 0)
					{
						min_volt -= 500;
					}
					else
					{
						min_volt = 0;
					}

				}
			}
			break;
		case 9:   //查询
			interface_index = 4;
			break;
		case 8:  //空
			break;
		default:
			break;
	}
}

void Save_Data(void)
{
	if(Read_AT24C02(1) == 0xff)  //不是第一次上电
	{
		min_volt = (Read_AT24C02(2))<<8 | Read_AT24C02(3) ;
		Delay10ms();
		max_volt = (Read_AT24C02(4))<<8 | Read_AT24C02(5) ;
		Delay10ms();
		event = Read_AT24C02(6);       //事件类型
		Delay10ms();
		e_hour = Read_AT24C02(7);  
		Delay10ms();
		e_min = Read_AT24C02(8);
		Delay10ms();
		e_sec = Read_AT24C02(9);
		Delay10ms();
	}
	else
	{
		Write_AT24C02(1,0xff); //第一次上电后写入数据 作为后面的判断
		Delay10ms();
		Write_AT24C02(2,min_volt >> 8);
		Delay10ms();
		Write_AT24C02(3,min_volt & 0xff);
		Delay10ms();
		Write_AT24C02(4,max_volt >> 8);
		Delay10ms();
		Write_AT24C02(5,max_volt & 0xff);
		Delay10ms();
		Write_AT24C02(6,event);
		Delay10ms();
		Write_AT24C02(7,e_hour);
		Delay10ms();
		Write_AT24C02(8,e_hour);
		Delay10ms();
		Write_AT24C02(9,e_sec);
		Delay10ms();
	}
}
void Init_System(void)
{
	Control_IO(0x80,0xff);
	Control_IO(0xa0,0x00);
	Control_IO(0xc0,0x00);
	Init_Timer0();
	Timer2Init();
	Init_DS1302(hour,min,sec);
	Save_Data();
}

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


/*==========================================================下面为中断处理=========================================*/
void Server_Timer2() interrupt 12
{
	static uchar dsp_smg = 1;
	static uint count = 0;
	static uint feq_count = 0;
	if(++feq_count == 500)
	{
		feq_count = 0;
		TR0 = 0;
		feq = ((uint)(TH0 << 8) | TL0) * 2;
		t = (1.0/feq) * 1000000;
		TH0 = TL0 = 0;
		TR0 = 1;
	}
	Control_IO(0xc0,0x00);
	Control_IO(0xe0,smg_data[smg_bit[dsp_smg]]);
	Control_IO(0xc0,1 << (dsp_smg - 1));
	if(++dsp_smg > 8)
	{
		dsp_smg = 1;
	}
	
	if(s4_flag || s4_flag2)
	{
		if(count++ == 1000)
		{
			count = 0;
			set_bit_flash = ~set_bit_flash;
		}
	}
	//下面为数据刷新频率相关变量
	key_feq++;
	adc_feq++;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

华阳电子工作室

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值