蓝桥杯单片机---第十届省赛题目解析

2024-03-30 17:20

本文主要是介绍蓝桥杯单片机---第十届省赛题目解析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 比赛题目
  • 一、代码相关定义、声明
    • 1.头文件声明
    • 2.变量声明
  • 二、主要函数
    • 1.main函数
    • 2.按键扫描
    • 3.数码管显示
    • 4.LED显示
    • 5.定时器中断
  • 三、次要函数
    • 1.初始化函数Init
    • 2.按键函数Key
    • 3.LED函数Led
    • 4.数码管函数Seg
    • 5.iic函数中
    • 6.onewire函数中
  • 总结


比赛题目

在这里插入图片描述
这里因为我没有这个题目的pdf版本所以截取的是博主:是七喜呀!这个博主大大的,侵权删!

一、代码相关定义、声明

1.头文件声明

/* 头文件声明区 */
#include <STC15F2K60S2.H>//单片机寄存器专用头文件
#include <Init.h>//初始化底层驱动专用头文件
#include <Led.h>//Led底层驱动专用头文件
#include <Key.h>//按键底层驱动专用头文件
#include <Seg.h>//数码管底层驱动专用头文件
#include "onewire.h"
#include "iic.h"

2.变量声明

/* 变量声明区 */
unsigned char Key_Val,Key_Down,Key_Old,Key_Up;//按键专用变量
unsigned char Key_Slow_Down;//按键减速专用变量
unsigned char Seg_Buf[8] = {10,10,10,10,10,10,10,10};//数码管显示数据存放数组
unsigned char Seg_Point[8] = {0,0,0,0,0,0,0,0};//数码管小数点数据存放数组
unsigned char Seg_Pos;//数码管扫描专用变量
unsigned int Seg_Slow_Down;//数码管减速专用变量
unsigned char ucLed[8] = {0,0,0,0,0,0,0,0};//Led显示数据存放数组
unsigned char Seg_Disp_Mode;//0-频率显示界面 1-电压显示界面
unsigned int Freq;//实施频率
unsigned int Timer_1000Ms;//计时变量
float Volate;//实时电压
bit Output_Mode;//电压输出状态
float Volate_Out;//输出电压
bit Led_Flag = 1;//LED状态
bit Seg_Flag = 1;//数码管状态

二、主要函数

1.main函数

/* Main */
void main()
{System_Init();Timer1_Init();Timer0Init();while (1){Key_Proc();Seg_Proc();Led_Proc();}
}

2.按键扫描


/* 键盘处理函数 */
void Key_Proc()
{if(Key_Slow_Down) return;Key_Slow_Down = 1;//键盘减速程序Key_Val = Key_Read();//实时读取键码值Key_Down = Key_Val & (Key_Old ^ Key_Val);//捕捉按键下降沿Key_Up = ~Key_Val & (Key_Old ^ Key_Val);//捕捉按键上降沿Key_Old = Key_Val;//辅助扫描变量switch(Key_Down){case 4:Seg_Disp_Mode ^= 1;break;case 5:Output_Mode ^= 1;break;case 6:Led_Flag ^= 1;break;case 7:Seg_Flag ^= 1;break;}
}

3.数码管显示

/* 信息处理函数 */
void Seg_Proc()
{unsigned char i = 3;if(Seg_Slow_Down) return;Seg_Slow_Down = 1;//数码管减速程序Volate = Ad_Read(0x43) / 51.0;if(Output_Mode == 0)Volate_Out = 2;else Volate_Out = Volate;switch(Seg_Disp_Mode){case 0:Seg_Buf[0] = 11;Seg_Buf[3] = Freq / 10000 % 10;Seg_Buf[4] = Freq / 1000 % 10;Seg_Buf[5] = Freq / 100 % 10;Seg_Buf[6] = Freq / 10 % 10;Seg_Buf[7] = Freq % 10;Seg_Point[5] = 0;while(Seg_Buf[i] == 0){Seg_Buf[i] = 10;if(++i == 7) break;}break;case 1:Seg_Buf[0] = 12;Seg_Buf[3] = 10;Seg_Buf[4] = 10;Seg_Buf[5] = (unsigned char)Volate;Seg_Buf[6] = (unsigned int)(Volate * 100) / 10 % 10;Seg_Buf[7] = (unsigned int)(Volate * 100) % 10;Seg_Point[5] = 1;break;}
}

4.LED显示

/* 其他显示函数 */
void Led_Proc()
{unsigned char i = 0;Da_Write(Volate_Out * 51);for(i = 0 ; i < 2 ; ++ i)ucLed[i] = (i == Seg_Disp_Mode);ucLed[2] = ((Volate >= 1.5 && Volate < 2.5) || (Volate >= 3.5));ucLed[3] = ((Freq >= 1000 && Freq < 5000) || (Freq >= 10000));ucLed[4] = Output_Mode;
}

5.定时器中断

/* 定时器0中断初始化函数 */
void Timer0Init(void)		//0毫秒@12.000MHz
{AUXR &= 0x7F;		//定时器时钟12T模式TMOD &= 0xF0;		//设置定时器模式TMOD |= 0x05;TL0 = 0x00;		//设置定时初始值TH0 = 0x00;		//设置定时初始值TF0 = 0;		//清除TF0标志TR0 = 1;		//定时器0开始计时
}void Timer1_Init(void)		//1毫秒@12.000MHz
{AUXR &= 0xBF;			//定时器时钟12T模式TMOD &= 0x0F;			//设置定时器模式TL1 = 0x18;				//设置定时初始值TH1 = 0xFC;				//设置定时初始值TF1 = 0;				//清除TF1标志TR1 = 1;				//定时器1开始计时ET1 = 1;EA = 1;
}/* 定时器0中断服务函数 */
void Timer0Server() interrupt 3
{  if(++Key_Slow_Down == 10) Key_Slow_Down = 0;//键盘减速专用if(++Seg_Slow_Down == 500) Seg_Slow_Down = 0;//数码管减速专用if(++Seg_Pos == 8) Seg_Pos = 0;//数码管显示专用if(Seg_Flag == 1)Seg_Disp(Seg_Pos,Seg_Buf[Seg_Pos],Seg_Point[Seg_Pos]);else Seg_Disp(Seg_Pos,10,0);if(Led_Flag == 1)Led_Disp(Seg_Pos,ucLed[Seg_Pos]);else Led_Disp(Seg_Pos,0);if(++Timer_1000Ms == 1000){Timer_1000Ms = 0;Freq = TH0 << 8 | TL0;TH0 = TL0 = 0;}
}

三、次要函数

1.初始化函数Init

在Init.c文件当中

#include <Init.h>void System_Init()
{P0 = 0xff;P2 = P2 & 0x1f | 0x80;P2 &= 0x1f;P0 = 0x00;P2 = P2 & 0x1f | 0xa0;P2 &= 0x1f;
}

在Init.h文件当中

#include <STC15F2K60S2.H>
void System_Init();

2.按键函数Key

在Key.c文件当中

#include <Key.h>
/*
unsigned char Key_Read()
{unsigned char temp = 0;P44 = 0;P42 = 1;P35 = 1;P34 = 1;if(P33 == 0) temp = 4;if(P32 == 0) temp = 5;if(P31 == 0) temp = 6;if(P30 == 0) temp = 7;P44 = 1;P42 = 0;P35 = 1;P34 = 1;if(P33 == 0) temp = 8;if(P32 == 0) temp = 9;if(P31 == 0) temp = 10;if(P30 == 0) temp = 11;P44 = 1;P42 = 1;P35 = 0;P34 = 1;if(P33 == 0) temp = 12;if(P32 == 0) temp = 13;if(P31 == 0) temp = 14;if(P30 == 0) temp = 15;P44 = 1;P42 = 1;P35 = 1;P34 = 0;if(P33 == 0) temp = 16;if(P32 == 0) temp = 17;if(P31 == 0) temp = 18;if(P30 == 0) temp = 19;return temp;
}
*/
unsigned char Key_Read()
{unsigned char temp = 0;if(P33 == 0) temp = 4;if(P32 == 0) temp = 5;if(P31 == 0) temp = 6;if(P30 == 0) temp = 7;return temp;
}

在Key.h文件当中

#include <STC15F2K60S2.H>
unsigned char Key_Read();

3.LED函数Led

#include <Led.h>void Led_Disp(unsigned char addr,enable)
{static unsigned char temp = 0x00;static unsigned char temp_old = 0xff;if(enable)temp |= 0x01 << addr;elsetemp &= ~(0x01 << addr);if(temp != temp_old){P0 = ~temp;P2 = P2 & 0x1f | 0x80;P2 &= 0x1f;temp_old = temp;}
}void Beep(unsigned char flag)
{static unsigned char temp = 0x00;static unsigned char temp_old = 0xff;if(flag)temp |= 0x40;elsetemp &= ~0x40;if(temp != temp_old){P0 = temp;P2 = P2 & 0x1f | 0xa0;P2 &= 0x1f;temp_old = temp;		}
}void Relay(unsigned char flag)
{static unsigned char temp = 0x00;static unsigned char temp_old = 0xff;if(flag)temp |= 0x10;elsetemp &= ~0x10;if(temp != temp_old){P0 = temp;P2 = P2 & 0x1f | 0xa0;P2 &= 0x1f;temp_old = temp;		}	
}

4.数码管函数Seg

#include <Seg.h>unsigned char seg_dula[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xc6,0x8c,0x88};
unsigned char seg_wela[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};void Seg_Disp(unsigned char wela,dula,point)
{P0 = 0xff;P2 = P2 & 0x1f | 0xe0;P2 &= 0x1f;P0 = seg_wela[wela];P2 = P2 & 0x1f | 0xc0;P2 &= 0x1f;P0 = seg_dula[dula];if(point)P0 &= 0x7f;P2 = P2 & 0x1f | 0xe0;P2 &= 0x1f;	
}

5.iic函数中

/*	#   I2C代码片段说明1. 	本文件夹中提供的驱动代码供参赛选手完成程序设计参考。2. 	参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题中对单片机时钟频率的要求,进行代码调试和修改。
*/
#include "iic.h"#define DELAY_TIME	5//
static void I2C_Delay(unsigned char n)
{do{_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();		}while(n--);      	
}//
void I2CStart(void)
{sda = 1;scl = 1;I2C_Delay(DELAY_TIME);sda = 0;I2C_Delay(DELAY_TIME);scl = 0;    
}//
void I2CStop(void)
{sda = 0;scl = 1;I2C_Delay(DELAY_TIME);sda = 1;I2C_Delay(DELAY_TIME);
}//
void I2CSendByte(unsigned char byt)
{unsigned char i;for(i=0; i<8; i++){scl = 0;I2C_Delay(DELAY_TIME);if(byt & 0x80){sda = 1;}else{sda = 0;}I2C_Delay(DELAY_TIME);scl = 1;byt <<= 1;I2C_Delay(DELAY_TIME);}scl = 0;  
}//
unsigned char I2CReceiveByte(void)
{unsigned char da;unsigned char i;for(i=0;i<8;i++){   scl = 1;I2C_Delay(DELAY_TIME);da <<= 1;if(sda) da |= 0x01;scl = 0;I2C_Delay(DELAY_TIME);}return da;    
}//
unsigned char I2CWaitAck(void)
{unsigned char ackbit;scl = 1;I2C_Delay(DELAY_TIME);ackbit = sda; scl = 0;I2C_Delay(DELAY_TIME);return ackbit;
}//
void I2CSendAck(unsigned char ackbit)
{scl = 0;sda = ackbit; I2C_Delay(DELAY_TIME);scl = 1;I2C_Delay(DELAY_TIME);scl = 0; sda = 1;I2C_Delay(DELAY_TIME);
}
//=========================unsigned char Ad_Read(unsigned char addr)
{unsigned char temp;I2CStart();I2CSendByte(0x90);I2CWaitAck();I2CSendByte(addr);I2CWaitAck();I2CStart();I2CSendByte(0x91);I2CWaitAck();temp = I2CReceiveByte();I2CSendAck(1);I2CStop();return temp;
} void Da_Write(unsigned char dat)
{I2CStart();I2CSendByte(0x90);I2CWaitAck();I2CSendByte(0x41);I2CWaitAck();I2CSendByte(dat);I2CWaitAck();I2CStop();
}

6.onewire函数中

/*	# 	单总线代码片段说明1. 	本文件夹中提供的驱动代码供参赛选手完成程序设计参考。2. 	参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题中对单片机时钟频率的要求,进行代码调试和修改。
*/
#include <reg52.h>
sbit DQ = P1^4;
//
void Delay_OneWire(unsigned int t)  
{unsigned char i;while(t--){for(i=0;i<12;i++);}
}//
void Write_DS18B20(unsigned char dat)
{unsigned char i;for(i=0;i<8;i++){DQ = 0;DQ = dat&0x01;Delay_OneWire(5);DQ = 1;dat >>= 1;}Delay_OneWire(5);
}//
unsigned char Read_DS18B20(void)
{unsigned char i;unsigned char dat;for(i=0;i<8;i++){DQ = 0;dat >>= 1;DQ = 1;if(DQ){dat |= 0x80;}	    Delay_OneWire(5);}return dat;
}//
bit init_ds18b20(void)
{bit initflag = 0;DQ = 1;Delay_OneWire(12);DQ = 0;Delay_OneWire(80);DQ = 1;Delay_OneWire(10); initflag = DQ;     Delay_OneWire(5);return initflag;
}//========================float rd_temperature(void)
{unsigned char low,high;//返回温度的高低八位init_ds18b20();//初始化Write_DS18B20(0xcc);//跳过ROMWrite_DS18B20(0x44);//进行温度转换init_ds18b20();//初始化Write_DS18B20(0xcc);//跳过ROMWrite_DS18B20(0xbe);//读取温度low = Read_DS18B20();//读取低位high = Read_DS18B20();//读取高位return ((high << 8) | low ) / 16.0;
}

总结

1.主要学习了AD的读取—AD_Read(0x43)/ 51;
然后输出则是Da_Write(Volate_Out * 51);
2.然后就是NE555的配置方法

//将原本的数据改成这个样子其实就是TMOD |= 0x05要被加入
void Timer0Init(void)		//0毫秒@12.000MHz
{AUXR &= 0x7F;		//定时器时钟12T模式TMOD &= 0xF0;		//设置定时器模式TMOD |= 0x05;TL0 = 0x00;		//设置定时初始值TH0 = 0x00;		//设置定时初始值TF0 = 0;		//清除TF0标志TR0 = 1;		//定时器0开始计时
}
//生成的是12T自动重装载的1毫秒的定时器1的定时器
void Timer1_Init(void)		//1毫秒@12.000MHz
{AUXR &= 0xBF;			//定时器时钟12T模式TMOD &= 0x0F;			//设置定时器模式TL1 = 0x18;				//设置定时初始值TH1 = 0xFC;				//设置定时初始值TF1 = 0;				//清除TF1标志TR1 = 1;				//定时器1开始计时ET1 = 1;EA = 1;
}
void Timer0Server() interrupt 3//这里修改成3
写在定时器三里面
if(++Timer_1000Ms == 1000){Timer_1000Ms = 0;Freq = TH0 << 8 | TL0;TH0 = TL0 = 0;}

这篇关于蓝桥杯单片机---第十届省赛题目解析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/862103

相关文章

网页解析 lxml 库--实战

lxml库使用流程 lxml 是 Python 的第三方解析库,完全使用 Python 语言编写,它对 XPath表达式提供了良好的支 持,因此能够了高效地解析 HTML/XML 文档。本节讲解如何通过 lxml 库解析 HTML 文档。 pip install lxml lxm| 库提供了一个 etree 模块,该模块专门用来解析 HTML/XML 文档,下面来介绍一下 lxml 库

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

基于51单片机的自动转向修复系统的设计与实现

文章目录 前言资料获取设计介绍功能介绍设计清单具体实现截图参考文献设计获取 前言 💗博主介绍:✌全网粉丝10W+,CSDN特邀作者、博客专家、CSDN新星计划导师,一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等单片机设计 主要对象是咱们电子相关专业的大学生,希望您们都共创辉煌!✌💗 👇🏻 精彩专栏 推荐订阅👇🏻 单片机

OWASP十大安全漏洞解析

OWASP(开放式Web应用程序安全项目)发布的“十大安全漏洞”列表是Web应用程序安全领域的权威指南,它总结了Web应用程序中最常见、最危险的安全隐患。以下是对OWASP十大安全漏洞的详细解析: 1. 注入漏洞(Injection) 描述:攻击者通过在应用程序的输入数据中插入恶意代码,从而控制应用程序的行为。常见的注入类型包括SQL注入、OS命令注入、LDAP注入等。 影响:可能导致数据泄

题目1254:N皇后问题

题目1254:N皇后问题 时间限制:1 秒 内存限制:128 兆 特殊判题:否 题目描述: N皇后问题,即在N*N的方格棋盘内放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在同一斜线上。因为皇后可以直走,横走和斜走如下图)。 你的任务是,对于给定的N,求出有多少种合法的放置方法。输出N皇后问题所有不同的摆放情况个数。 输入

题目1380:lucky number

题目1380:lucky number 时间限制:3 秒 内存限制:3 兆 特殊判题:否 提交:2839 解决:300 题目描述: 每个人有自己的lucky number,小A也一样。不过他的lucky number定义不一样。他认为一个序列中某些数出现的次数为n的话,都是他的lucky number。但是,现在这个序列很大,他无法快速找到所有lucky number。既然

从状态管理到性能优化:全面解析 Android Compose

文章目录 引言一、Android Compose基本概念1.1 什么是Android Compose?1.2 Compose的优势1.3 如何在项目中使用Compose 二、Compose中的状态管理2.1 状态管理的重要性2.2 Compose中的状态和数据流2.3 使用State和MutableState处理状态2.4 通过ViewModel进行状态管理 三、Compose中的列表和滚动

Spring 源码解读:自定义实现Bean定义的注册与解析

引言 在Spring框架中,Bean的注册与解析是整个依赖注入流程的核心步骤。通过Bean定义,Spring容器知道如何创建、配置和管理每个Bean实例。本篇文章将通过实现一个简化版的Bean定义注册与解析机制,帮助你理解Spring框架背后的设计逻辑。我们还将对比Spring中的BeanDefinition和BeanDefinitionRegistry,以全面掌握Bean注册和解析的核心原理。

CSP 2023 提高级第一轮 CSP-S 2023初试题 完善程序第二题解析 未完

一、题目阅读 (最大值之和)给定整数序列 a0,⋯,an−1,求该序列所有非空连续子序列的最大值之和。上述参数满足 1≤n≤105 和 1≤ai≤108。 一个序列的非空连续子序列可以用两个下标 ll 和 rr(其中0≤l≤r<n0≤l≤r<n)表示,对应的序列为 al,al+1,⋯,ar​。两个非空连续子序列不同,当且仅当下标不同。 例如,当原序列为 [1,2,1,2] 时,要计算子序列 [

多线程解析报表

假如有这样一个需求,当我们需要解析一个Excel里多个sheet的数据时,可以考虑使用多线程,每个线程解析一个sheet里的数据,等到所有的sheet都解析完之后,程序需要提示解析完成。 Way1 join import java.time.LocalTime;public class Main {public static void main(String[] args) thro