首页 > 其他分享 >蓝桥杯第十三届单片机省赛真题(IAP15F2K61S2)

蓝桥杯第十三届单片机省赛真题(IAP15F2K61S2)

时间:2024-04-04 23:01:02浏览次数:24  
标签:真题 pos Nixie 蓝桥 单片机 flag num Time hc

一、题目

二、题目分析

1、难点(笔者个人认为)

(1)s17按键短按和长按的设置不同,界面不同

s17短按在参数界面需要把温度参数-1;

s17长按在时间界面需要显示分,秒界面;

所以笔者这里把两个数码管显示分两个函数

void Nixie_Show()//数码管显示函数
{
	Nixie_pos_num(1,16);
	Nixie_pos_num(3,17);
	if(flag_s12 == 0)//温度显示界面
	{
		Temp = Read_DS18B20_Temp();
		Nixie_pos_num(2,1);
		Nixie_pos_num(4,17);
		Nixie_pos_num(5,17);
		Nixie_pos_num(6,Temp/1000);
		Nixie_Dian_pos_num(7,Temp/100%10);
		Nixie_pos_num(8,Temp/10%10);
	}
	if(flag_s12 == 1)//时间显示界面
	{
		Nixie_pos_num(2,2);
		Nixie_pos_num(4,Time[2]/16);
		Nixie_pos_num(5,Time[2]%16);
		Nixie_pos_num(6,18);
		Nixie_pos_num(7,Time[1]/16);
		Nixie_pos_num(8,Time[1]%16);
	}
	if(flag_s12 == 2)//参数显示界面
	{
		Nixie_pos_num(2,3);
		Nixie_pos_num(4,17);
		Nixie_pos_num(5,17);
		Nixie_pos_num(6,17);
		Nixie_pos_num(7,Temp_C/10);
		Nixie_pos_num(8,Temp_C%10);
	}
}

void Nixie_Time_S17()//在时间显示界面下,长按s17显示界面
{
	if(flag_s12 == 1)
	{
		Read_Ds1302_Time(Time);
		Nixie_pos_num(1,16);
		Nixie_pos_num(2,2);
		Nixie_pos_num(3,17);
		Nixie_pos_num(4,Time[1]/16);
		Nixie_pos_num(5,Time[1]%16);
		Nixie_pos_num(6,18);
		Nixie_pos_num(7,Time[0]/16);
		Nixie_pos_num(8,Time[0]%16);
	}
	
}

分别显示不同的界面,避免界面冲突。当然这里也可以通过switch语句进行界面选择,读者可以自己调整

(2)出现两个不同时间产生不同状态,L1点亮,5秒熄灭,L3要0.1秒交替闪烁

这里直接使用Delay是有问题的,LED灯和数码管显示会频闪。笔者这里用到是定时器

void Timer0Init(void)		//50毫秒@12MHz
{
	TMOD = 0x01;
	TL0 = (65535 - 50000) % 256;		//设置定时初值
	TH0 = (65535 - 50000) / 256;		//设置定时初值
	TR0 = 1;		//定时器0开始计时
	EA = 1;
	ET0 = 1;
}

void Timer0Init_Time() interrupt 1
{
	TL0 = (65535 - 50000) % 256;		//设置定时初值
	TH0 = (65535 - 50000) / 256;		//设置定时初值
	count++;
	if(count % 5 == 0)//计时100ms
	{
		flag_L3 = ~flag_L3;
	}
	if(count == 100)//计时5s
	{
		flag_timer_relay = 0;
		flag_L1 = 0;
		count = 0;
	}
}

让定时器到点发起中断,产生效果

(3)、温度浮点数处理

在上一篇笔记笔者已经提到,有兴趣的读者可以到这里的四、2、第十五届蓝桥杯单片机模拟II(IAP15F2K61S2)-CSDN博客

这里就不过多阐述

三、代码(仅供参考)

1、头文件

#include <STC15F2K60S2.H>
#include <ds1302.H>
#include <onewire.H>

2、变量声明

sbit K1 = P3^5;
sbit K2 = P3^4;
sbit K3 = P3^3;
sbit K4 = P3^2;

sbit L1 = P0^0;
sbit L2 = P0^1;
sbit L3 = P0^2;
//==================数组定义===================
code unsigned char Seg_Table[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xc1,0xff,0xbf};//数码管不带小数点 16:0xc1:U 18:0xbf:-
code unsigned char Seg_Dian_Table[] = {0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0x08,0x03,0x46,0x21,0x06,0x0e};//数码管带小数点
unsigned char Time[3]={0x55,0x59,0x07};//秒,分,时
//==================变量定义===================
unsigned char flag_s12;//按键s12按下三种状态
unsigned char flag_s13;//按键s13按下两种状态
unsigned char flag_relay = 0;//继电器两种状态
unsigned char Temp_C = 23;//温度参数
unsigned char count;//定时器计时参数
unsigned char flag_L3;//L3灯状态
unsigned char flag_L1;//L1灯状态
unsigned char flag_timer_relay;//时间控制模式下继电器状态
unsigned int Temp;//温度变量

3、函数声明

//==================函数声明===================
void Nixie_Show();//数码管显示函数
void Scan_Key();//按键控制函数
void Nixie_Time_S17();//在时间显示界面下,长按s17显示
void Relay();//继电器控制函数
void LED();//LED灯控制函数
//=============================================

四、函数模块

1、其他函数

void delay(unsigned char i)
{
	while(i--);
}

void hc(unsigned char n)//通道选择
{
	switch(n)
	{
		case 0:
			P2 = P2 & 0x1f;
			break;
		case 4:
			P2 = (P2 & 0x1f) | 0x80;//LED
			break;
		case 5:
			P2 = (P2 & 0x1f) | 0xa0;//蜂鸣器,继电器
			break;
		case 6:
			P2 = (P2 & 0x1f) | 0xc0;//数码管位选
			break;
		case 7:
			P2 = (P2 & 0x1f) | 0xe0;//数码管段选
			break;
	}
}

void System_Init()//系统初始化
{
	hc(4);
	P0 = 0xFF;
	hc(5);
	P0 = 0x00;
	hc(0);
}

2、数码管

void Nixie_pos_num(unsigned char pos,num)//数码管(不带小数点)位置,显示数字
{
	hc(6);
	P0 = 0x01 << (pos-1);
	hc(7);
	P0 = Seg_Table[num];
	delay(500);
	P0 = 0xFF;
	hc(0);
}

void Nixie_Dian_pos_num(unsigned char pos,num)//数码管(带小数点)位置,显示数字
{
	hc(6);
	P0 = 0x01 << (pos-1);
	hc(7);
	P0 = Seg_Dian_Table[num];
	delay(500);
	P0 = 0xFF;
	hc(0);
}

void Nixie_Show()//数码管显示函数
{
	Nixie_pos_num(1,16);
	Nixie_pos_num(3,17);
	if(flag_s12 == 0)//温度显示界面
	{
		Temp = Read_DS18B20_Temp();
		Nixie_pos_num(2,1);
		Nixie_pos_num(4,17);
		Nixie_pos_num(5,17);
		Nixie_pos_num(6,Temp/1000);
		Nixie_Dian_pos_num(7,Temp/100%10);
		Nixie_pos_num(8,Temp/10%10);
	}
	if(flag_s12 == 1)//时间显示界面
	{
		Nixie_pos_num(2,2);
		Nixie_pos_num(4,Time[2]/16);
		Nixie_pos_num(5,Time[2]%16);
		Nixie_pos_num(6,18);
		Nixie_pos_num(7,Time[1]/16);
		Nixie_pos_num(8,Time[1]%16);
	}
	if(flag_s12 == 2)//参数显示界面
	{
		Nixie_pos_num(2,3);
		Nixie_pos_num(4,17);
		Nixie_pos_num(5,17);
		Nixie_pos_num(6,17);
		Nixie_pos_num(7,Temp_C/10);
		Nixie_pos_num(8,Temp_C%10);
	}
}

void Nixie_Time_S17()//在时间显示界面下,长按s17显示界面
{
	if(flag_s12 == 1)
	{
		Read_Ds1302_Time(Time);
		Nixie_pos_num(1,16);
		Nixie_pos_num(2,2);
		Nixie_pos_num(3,17);
		Nixie_pos_num(4,Time[1]/16);
		Nixie_pos_num(5,Time[1]%16);
		Nixie_pos_num(6,18);
		Nixie_pos_num(7,Time[0]/16);
		Nixie_pos_num(8,Time[0]%16);
	}
	
}

3、按键

void Scan_Key()//按键控制函数
{
	K2 = K3 = K4 = 1;K1 = 0;
	if(K3 == 0 || K4 == 0)
	{
		delay(100);
		if(K3 == 0)//s12按键按下
		{
			flag_s12 = (flag_s12 + 1) % 3;
			while(K3 == 0)
			{
				Nixie_Show();
			}
		}
		if(K4 == 0)//s13按键按下
		{
			flag_s13 = (flag_s13 + 1) % 2;
			while(K4 == 0)
			{
				Nixie_Show();
				LED();
			}
		}
	}
	if(flag_s12 == 2)//在参数设置界面关于s16,s17控制
	{
		K1 = K3 = K4 = 1;K2 = 0;
		if(K3 == 0 || K4 == 0)
		{
			delay(100);
			if(K3 == 0)//s16按键按下
			{
				Temp_C++;
				if(Temp_C >= 90)
				{
					Temp_C = 90;
				}
				while(K3 == 0)
				{
					Nixie_Show();
				}
			}
			if(K4 == 0)//s17按键按下
			{
				Temp_C--;
				if(Temp_C <= 10)
				{
					Temp_C = 10;
				}
				while(K4 == 0)
				{
					Nixie_Show();
				}
			}
		}
	}
	if(flag_s12 == 1)//在时间显示界面关于s17控制
	{
		K1 = K3 = K4 = 1;K2 = 0;
		if(K4 == 0)
		{
			delay(100);
			if(K4 == 0)
			{
				while(K4 == 0)
				{
					Nixie_Time_S17();
				}
			}
		}
	}
}

4、LED

void LED()//LED灯控制函数
{
	//L1灯控制
	if(Time[0]==0x00&&Time[1]==0x00)
	{
		if(flag_L1 == 0)
		{
			hc(4);
			L1 = 0;
			hc(0);
		}
		else
		{
			hc(4);
			L1 = 1;
			hc(0);
		}
	}
	else
	{
		hc(4);
		L1 = 1;
		hc(0);
	}
	//L2灯控制
	if(flag_s13 == 0)
	{
		hc(4);
		L2 = 0;
		hc(0);
	}
	else
	{
		hc(4);
		L2 = 1;
		hc(0);
	}
	//L3灯控制
	if(flag_relay == 1)//在继电器吸合状态
	{
		if(flag_L3 == 0)
		{
			hc(4);
			L3 = 0;
			hc(0);
		}
		else
		{
			hc(4);
			L3 = 1;
			hc(0);
		}
	}
	else
	{
		hc(4);
		L3 = 1;
		hc(0);
	}
}

5、继电器

void Relay()//继电器控制函数
{
	if(flag_s13 == 0)//温度控制模式
	{
		if(Temp>Temp_C*100)
		{
			hc(5);
			P0 = 0x10;
			hc(0);
			flag_relay = 1;
		}
		else
		{
			hc(5);
			P0 = 0x00;
			hc(0);
			flag_relay = 0;
		}
	}
	if(flag_s13 == 1)//时间控制模式
	{
		if(Time[0]==0x00&&Time[1]==0x00)
		{
			hc(5);
			P0 = 0x10;
			hc(0);
			flag_relay = 1;
			flag_timer_relay = 1;
		}
		else
		{
			hc(5);
			P0 = 0x00;
			hc(0);
			flag_relay = 0;
		}
	}
}

6、main

void main()
{
	System_Init();
	Timer0Init();
	Temp = Read_DS18B20_Temp();
	Write_Ds1302_Time(Time);
	while(1)
	{
		Read_Ds1302_Time(Time);
		Temp = Read_DS18B20_Temp();
		Nixie_Show();
		Scan_Key();
		LED();
		Relay();
	}
}

7、onewrie

unsigned int Read_DS18B20_Temp()
{
	unsigned char LSB,MSB;
	unsigned int Temp;
	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) | LSB;
	Temp = Temp >> 4;
	Temp = Temp * 100;
	Temp =  Temp + (LSB & 0x0f) * 0.0625 * 100;
	return Temp;
}

8、ds1302

code unsigned char Write_Time[3]={0x80,0x82,0x84};
code unsigned char Read_Time[3]={0x81,0x83,0x85};
void Write_Ds1302_Time(unsigned char *time)
{
	unsigned char i;
	Write_Ds1302_Byte(0x8e,0x00);
	for(i = 0;i < 3;i++)
	{
		Write_Ds1302_Byte(Write_Time[i],time[i]);
	}
	Write_Ds1302_Byte(0x8e,0x00);
}

void Read_Ds1302_Time(unsigned char *time)
{
	unsigned char i;
	for(i = 0;i < 3;i++)
	time[i]=Read_Ds1302_Byte(Read_Time[i]);
}

五、演示

六、总结

注意:本代码只是提供读者参考,给读者提供一个方法。

蓝桥杯第十三届单片机省赛的题难度不大,但是要处理的细节比较多,需要细心看题,认真思考。

标签:真题,pos,Nixie,蓝桥,单片机,flag,num,Time,hc
From: https://blog.csdn.net/2201_75616203/article/details/137384295

相关文章

  • 小美的蛋糕切割(美团2024届秋招笔试第一场编程真题)
    题面核心思想前缀和(不过是以一整行或一整列的维度)(滑动窗口应该也可以)需要注意的是可以横着切也可以竖着切代码importjava.util.*;publicclassMain{publicstaticvoidmain(String[]args){finallongMOD=(long)(1e9+7);Scannerscanne......
  • 第十四届蓝桥杯单片机省赛真题
    逻辑部分纯手写简单零基础模板套用即可main.c#include"smg.h"#include"key.h"#include"led.h"#include"iic.h"#include"onewire.h"#include"ds1302.h"#include"timer.h"#include"uart.h"#i......
  • 2022蓝桥杯大赛软件类国赛真题 卡牌
    importjava.util.Scanner;publicclassMain{staticfinalintN=200005;staticlongn,m;staticint[]a=newint[N];staticint[]b=newint[N];publicstaticvoidmain(String[]args){Scannersc=newScanner(System.in......
  • 少儿编程 2024年3月电子学会图形化编程等级考试Scratch一级真题解析(选择题)
    2024年3月scratch编程等级考试一级真题选择题(共25题,每题2分,共50分)1、单击下列哪个按钮,能够让舞台变为“全屏模式”A、B、C、D、答案:C考点分析:考查scratch平台的使用,四个选项分别是:开始程序,停止程序,全屏模式,恢复正常模式,答案C2、下列哪个选项可以将当前背景换成第二......
  • 第十四届蓝桥杯B组c/c++第五题接龙数列
    动态规划  接龙数列我打眼一看感觉得用栈stack,取出首位和末位全都入栈,每次弹出栈顶,获取此时的栈顶并弹出和下一个栈顶比较。整了老半天发现不行,原来是我脑子瓦特了。虽然没有用栈解决这道问题,但是,栈和队列都是非常重要的只是,不了解的同学们可以去学习一下,下面有传送门。......
  • 蓝桥杯算法题:开心
    https://www.lanqiao.cn/problems/3824/learningeg:n=1234,k=2可以简单的列出这些选项:●1+2+34●1+23+4●12+3+4利用DFS和回溯的思想,程序推导如下:将n分成左右两部分,l表示left左侧的值,r表示right右侧的值。先将l加入res,再将r作为新的n......
  • 蓝桥杯填九宫幻方
    通过回溯算法对未输入得数字进行全排列后,依次填入格子,判断是否符合条件。可以更改幻方的大小,来填充任意幻方#include<stdio.h>#include<stdlib.h>#include<stdbool.h>intboard[3][3];//保存输入的幻方intans[3][3][3];//填充后符合条件的幻方inttmp[3][3];//幻方......
  • 2022CSP-J组真题 2.解密
    线上OJ:https://www.luogu.com.cn/problem/P8814核心思想:对本题先进行数学公式推导已知ed=(......
  • 蓝桥杯——翻硬币
    题目小明正在玩一个"翻硬币"的游戏。桌上放着排成一排的若干硬币。我们用*表示正面,用o表示反面(是小写字母,不是零)。比如,可能情形是:**oo***oooo;如果同时翻转左边的两个硬币,则变为:oooo***oooo。现在小明的问题是:如果已知了初始状态和要达到的目标状态每次只能同时翻转......
  • 2024SMU蓝桥训练1补题
    B-航班时间思路:地理知识--时差计算-东加西减。此处去程和返程方向相反,时差相加必然抵消。那么就可以知道实际飞行时间ps:这题有点奇怪,本地跑不过样例,交上去是AC。本地跑过样例,交上去RE,WA。RE好像是因为输入的格式不够严格..D-飞机降落思路:全排列枚举ordfs--dfs类似之前电科......