蓝桥杯第13届第2场单片机比赛

第十三届蓝桥杯单片机第二场

文章目录

  • 第十三届蓝桥杯单片机第二场
  • 前言
  • 一、赛题分析
  • 二、程序调试步骤
  • 三、部分源程序
  • 主函数部分
  • DAC处理函数
  • 数码管处理函数
  • ADC处理函数
  • 超声波处理函数
  • LED处理函数
  • 总结

  • 前言

    赛题感受:

  • 本届赛题应该是这些年以来,第一次省赛考超声波。首先拿到赛题以后很惊讶,这大概是由于准备不足所导致的。在准备省赛过程中,几乎没有看超声波,由于准备不足,拿到赛题是一头雾水。所以大家也不要以为以前省赛题未考的部分,省赛就不会出。只要是在学习的外设部分,任何外设都有可能出现。大家绝对不能放松警惕,不要因为准备不充分,导致自己跟国赛失之交臂。
  • 比赛过程中,由于源代码的bug过多,就没有在处理源代码。重新写了第十三届蓝桥杯单片机第二场赛题,在重新写过一遍代码后,感觉是真的完了,只能看看运气了。

  • ``

    一、赛题分析

  • 1.本届赛题添加了超声波,由于超声波加入,可能让题难度加大。但逻辑并不是很难。总得来说,逻辑方面的难度基本与往届相同。如果因为超声波问题,做本届赛题会比较棘手。
  • 2.参数退出界面生效问题,按键在进入界面3关闭rb2的功能,保证参数设置状态下,测距功能不受影响。在参数退出界面生效。
  • 二、程序调试步骤

    由于程序是重写的,重写的程序调试步骤如下:

  • 1.对每个界面进行进行分别调试,测试好每一个界面显示
  • 2.加入按键,进行按键调试
  • 3.加入AD/DA模块
  • 4.加入LED显示模块
  • 三、部分源程序

    主函数部分

    /**
    	****************************************************************
    	* @file main.c
    	* @author Happy_Bean
    	* @version v2.0
    	* @date 2022-05-17
    	* @brief  蓝桥杯单片机第十三届省赛(第二场)
    	****************************************************************
    	* @attention 
    	*
    	* Diff1. 参数设置界面下退出生效
    	* Diff2. 超声波测距显示
    */
    
    ···
    
    void main(void)
    {
    	ALL_Init();  // 关闭外设初始化
    	while(1)
    	{
    		Key4_Proc();  // 按键扫描函数
    		
    		ADC_Proc();  // ADC处理函数
    		SEG_Proc();  // 数码管处理函数
    		Soinc_Proc();  // 超声波处理函数
    		LED_Proc();  // LED处理函数
    		DAC_Proc();  // DAC处理函数
    		
    		LED_Disp(uc_LED);  // LED显示函数
    		
    	}
    }
    
    void Timer1_ISR(void) interrupt 3
    {
    	static unsigned int flag_1s;
    	
    	// 按键刷新频率
    	if(++uc_Key_flag == 5)
    		uc_Key_flag = 0;
    	
    	// 数码管刷新频率
    	if(++uc_SEG_flag == 1)
    	{
    			uc_SEG_flag = 0;
    	}
    		SEG_Disp(puc_SEG_Code,uc_SEG_Position);   //数码管显示
    	if(++uc_SEG_Position == 8) uc_SEG_Position = 0;
    	
    	// 超声波刷新频率
    	if(++ui_Sonic_flag == 300)
    		ui_Sonic_flag = 0;
    	
    	if(++flag_1s == 100)  // 计时0.1s
    	{
    		flag_1s = 0;
    		LED_L8_flag ^= 1;
    	}
    }
    

    DAC处理函数

    ···
    
    /**
    	* @brief DAC处理函数
    	* @param 无
    	* @retval 无
    */
    void DAC_Proc()
    {
    	static unsigned char output_dianya;
    	
    	if(Ranging_Show_flag == 0)
    	{
    		if(uc_Dist < 20)
    			output_dianya = 1;
    		else if((uc_Dist <= 80)&&(uc_Dist >= 20))
    			output_dianya = 5;
    		else if(uc_Dist > 80)
    			output_dianya = (1/15)*(uc_Dist - 20)+1;  // 这里算出来的数不一定是整数,需要进行强制类型转换
    	}
    	else if(Ranging_Show_flag == 1)
    	{
    		output_dianya = 0;
    	}
    	
    	PCF8591_DAC((unsigned char)output_dianya*51);
    }
    
    ···
    

    数码管处理函数

    ···
    
    /**
    	* @brief 数码管处理函数
    	* @param 无
    	* @retval 无
    */
    void SEG_Proc()
    {
    	if(uc_SEG_flag) return;  // 刷新频率
    	uc_SEG_flag = 1;
    	
    	Vrb2 = PCF8591_ADC(0x03);  // 使用滑动变阻器进行AD转换
    	Vrb2 = Vrb2*1.96;  // 电压扩大1.96倍
    	dianya_show = Vrb2;
    	
    	if(uc_SEG_MODE == 1)  // 电压显示界面
    	{
    		set_para_flag = 0;
    		
    		dianya_show = (float)dianya_show/100;  // 缩小100倍电压,并强制类型转换为float
    	  sprintf(puc_SEG_Buf,"U    %3.2f",(float)dianya_show);
    	}
    	else if(uc_SEG_MODE == 2)  // 测距界面
    	{
    		distance = uc_Dist;  // 读取实时检测的距离
    		
    		if(Ranging_Show_flag == 0)   // 连续测量标志位为0,进入连续测量界面
    		{
    			if(distance > 99)  // 测量距离大于三位数,数码管显示3位
    			{
    				sprintf(puc_SEG_Buf,"L    %03u",(unsigned int)distance);
    			}
    			else if(distance <= 99)  // 测量距离小于三位数,数码管显示两位
    			{
    				sprintf(puc_SEG_Buf,"L     %02u",(unsigned int)distance);
    			}
    		}
    		else if(Ranging_Show_flag == 1)  // 连续测量标志位为1,退出连续测量界面
    		{
    			sprintf(puc_SEG_Buf,"L    AAA");
    		}
    	}
    	else if(uc_SEG_MODE == 3)  // 参数调整上下限界面
    	{
    		dianya_max = max; dianya_min = min;
    		
    		sprintf(puc_SEG_Buf,"P  %02.1f %02.1f",(float)dianya_max,(float)dianya_min);
    	}
    	
    	
    		SEG_Tran(puc_SEG_Buf,puc_SEG_Code);  // 数码管段码转换
    }
    
    ···
    

    ADC处理函数

    ···
    
    /**
    	* @brief ADC处理函数
    	* @param 无
    	* @retval 无
    */
    void ADC_Proc(void)  // ADC处理函数
    {
    	if(set_para_flag == 0)  // 有效参数界面下,Rb2控制超声波是否进入连续测量
    	{
    		// Vrb2中电压扩大了1.96倍,将数据控制在0 - 4.99  总体电压扩大100倍
    		if((Vrb2 >= min*100)&&(Vrb2 <= max*100))  // 模数转化电压在设定范围内,进入连续测距界面
    			Ranging_Show_flag = 0;  // 在规定范围内,将连续测距标志位置零
    		else  // 不满足设定的电压,退出连续测距界面
    			Ranging_Show_flag = 1;  // 数据不在我们规定的范围内,将连续测距标志位置1,即退出连续测距界面
    	}
    }
    
    ···
    

    超声波处理函数

    /**
    	* @brief 超声波处理函数
    	* @param 无
    	* @retval 无
    */
    void Soinc_Proc(void)
    {
    	if(ui_Sonic_flag) return;  // 刷新频率
    		ui_Sonic_flag = 1;
    	
    		uc_Dist = Sonic();  //测距
    }
    

    LED处理函数

    /**
    	* @brief LED处理函数
    	* @param 无
    	* @retval 无
    */
    void LED_Proc()
    {
    	if((Ranging_Show_flag == 0)&&(LED_L8_flag == 1))
    	{
    		LED_ON(L8);
    	}
    	else
    	{
    		LED_OFF(L8);
    	}
    	
    	if(uc_SEG_MODE == 1)
    	{
    		LED_ON(L1); LED_OFF(L2); LED_OFF(L3);
    	}
    	else if(uc_SEG_MODE == 2)
    	{
    		LED_ON(L2); LED_OFF(L1); LED_OFF(L3);
    	}
    	else if(uc_SEG_MODE == 3)
    	{
    		LED_ON(L3); LED_OFF(L2); LED_OFF(L1);
    	}
    }
    

    总结

    对于本届赛题,省赛考了超声波,这对于后面省赛试题提供了外设考察的多样性。对于每一个模块的驱动,包括串口都不能放下。熟练掌握每一个模块的使用。
    以上就是今天要讲的内容,下面为源代码:
    源代码阿里云链接
    提取码:rd74
    gitlab链接
    蓝桥杯单片机13届第二场源代码链接1
    github链接
    蓝桥杯单片机13届第二场源代码链接2
    有兴趣的朋友可以看一看

    希望这篇文章对你有所帮助。

    本人码龄1年,文章有诸多不妥之处,欢迎大家指正。另附上几位小编推荐的文章,感兴趣的朋友可以看一看。

    嵌入式组:第十三届第二场蓝桥杯嵌入式主观题讲解
    第十三届——蓝桥杯嵌入式第二场
    2022年蓝桥杯嵌入式第二场程序题
    单片机组:蓝桥杯十三届第二场程序设计

    物联沃分享整理
    物联沃-IOTWORD物联网 » 蓝桥杯第13届第2场单片机比赛

    发表评论