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

2024-03-11 09:04

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

文章目录

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

比赛题目

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

一、代码相关定义、声明

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-参数设置 2-DA输出
float Temperature;//实时温度变量
unsigned char Seg_temp_Disp = 25;//显示参数
unsigned char Seg_temp_contorl = 25;//参数控制
float Volat;//AD
bit Out_Put;//AD模式转换变量

二、主要函数

1.main函数

/* Main */
void main()
{rd_temperature();Delay750ms();System_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:if(++Seg_Disp_Mode == 3) Seg_Disp_Mode = 0;if(Seg_Disp_Mode == 1) Seg_temp_Disp = Seg_temp_contorl;if(Seg_Disp_Mode == 2) Seg_temp_contorl = Seg_temp_Disp;break;case 8:if(Seg_Disp_Mode == 1){if(--Seg_temp_Disp == 255) Seg_temp_Disp = 0;}break;case 9:if(Seg_Disp_Mode == 1){if(++Seg_temp_Disp == 100) Seg_temp_Disp = 99;}break;case 5:Out_Put ^= 1;break;}
}

3.数码管显示

/* 信息处理函数 */
void Seg_Proc()
{if(Seg_Slow_Down) return;Seg_Slow_Down = 1;//数码管减速程序//信息获取区域Temperature = rd_temperature();//实时读取温度值Volat = Ad_Read();switch(Seg_Disp_Mode){case 0://温度显示界面Seg_Buf[0] = 11;//CSeg_Buf[4] = (unsigned char)Temperature / 10 % 10;Seg_Buf[5] = (unsigned char)Temperature % 10;Seg_Buf[6] = (unsigned int)(Temperature * 100) / 10 % 10;Seg_Buf[7] = (unsigned int)(Temperature * 100)% 10;Seg_Point[5] = 1;break;case 1:Seg_Buf[0] = 12;//PSeg_Buf[4] = 10;Seg_Buf[5] = 10;Seg_Buf[6] = Seg_temp_Disp / 10 % 10;Seg_Buf[7] = Seg_temp_Disp % 10;Seg_Point[5] = 0;break;case 2:Seg_Buf[0] = 13;//PSeg_Buf[5] = (unsigned char)Volat;Seg_Buf[6] = (unsigned int)(Volat * 100) / 10 % 10;Seg_Buf[7] = (unsigned int)(Volat * 100) % 10;Seg_Point[5] = 1;break;}
}

4.电压模式1、2输出 & LED显示

/* 其他显示函数 */
void Led_Proc()
{unsigned char i = 0;if(Out_Put == 0){if(Temperature < Seg_temp_Disp)Volat = 0;else Volat = 5;}else{if(Temperature < 20)Volat = 1;else if(Temperature > 40)Volat = 4;else Volat = 0.15 * (Temperature - 20) + 1;}Da_Write(Volat * 51);ucLed[0] = !Out_Put;for(i = 0 ; i < 3 ; ++ i)ucLed[i + 1] = (i == Seg_Disp_Mode);
}

5.定时器中断

/* 定时器0中断初始化函数 */
void Timer0Init(void)		//1毫秒@12.000MHz
{AUXR &= 0x7F;		//定时器时钟12T模式TMOD &= 0xF0;		//设置定时器模式TL0 = 0x18;		//设置定时初始值TH0 = 0xFC;		//设置定时初始值TF0 = 0;		//清除TF0标志TR0 = 1;		//定时器0开始计时ET0 = 1;    //定时器中断0打开EA = 1;     //总中断打开
}/* 定时器0中断服务函数 */
void Timer0Server() interrupt 1
{  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;//数码管显示专用Seg_Disp(Seg_Pos,Seg_Buf[Seg_Pos],Seg_Point[Seg_Pos]);Led_Disp(Seg_Pos,ucLed[Seg_Pos]);
}

6.消除85°C显示

void Delay750ms(void)	//@12.000MHz
{unsigned char data i, j, k;i = 35;j = 51;k = 182;do{do{while (--k);} while (--j);} while (--i);
}

三、次要函数

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;
}

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



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

相关文章

C语言中自动与强制转换全解析

《C语言中自动与强制转换全解析》在编写C程序时,类型转换是确保数据正确性和一致性的关键环节,无论是隐式转换还是显式转换,都各有特点和应用场景,本文将详细探讨C语言中的类型转换机制,帮助您更好地理解并在... 目录类型转换的重要性自动类型转换(隐式转换)强制类型转换(显式转换)常见错误与注意事项总结与建议类型

MySQL 缓存机制与架构解析(最新推荐)

《MySQL缓存机制与架构解析(最新推荐)》本文详细介绍了MySQL的缓存机制和整体架构,包括一级缓存(InnoDBBufferPool)和二级缓存(QueryCache),文章还探讨了SQL... 目录一、mysql缓存机制概述二、MySQL整体架构三、SQL查询执行全流程四、MySQL 8.0为何移除查

在Rust中要用Struct和Enum组织数据的原因解析

《在Rust中要用Struct和Enum组织数据的原因解析》在Rust中,Struct和Enum是组织数据的核心工具,Struct用于将相关字段封装为单一实体,便于管理和扩展,Enum用于明确定义所有... 目录为什么在Rust中要用Struct和Enum组织数据?一、使用struct组织数据:将相关字段绑

使用Java实现一个解析CURL脚本小工具

《使用Java实现一个解析CURL脚本小工具》文章介绍了如何使用Java实现一个解析CURL脚本的工具,该工具可以将CURL脚本中的Header解析为KVMap结构,获取URL路径、请求类型,解析UR... 目录使用示例实现原理具体实现CurlParserUtilCurlEntityICurlHandler

深入解析Spring TransactionTemplate 高级用法(示例代码)

《深入解析SpringTransactionTemplate高级用法(示例代码)》TransactionTemplate是Spring框架中一个强大的工具,它允许开发者以编程方式控制事务,通过... 目录1. TransactionTemplate 的核心概念2. 核心接口和类3. TransactionT

数据库使用之union、union all、各种join的用法区别解析

《数据库使用之union、unionall、各种join的用法区别解析》:本文主要介绍SQL中的Union和UnionAll的区别,包括去重与否以及使用时的注意事项,还详细解释了Join关键字,... 目录一、Union 和Union All1、区别:2、注意点:3、具体举例二、Join关键字的区别&php

Spring IOC控制反转的实现解析

《SpringIOC控制反转的实现解析》:本文主要介绍SpringIOC控制反转的实现,IOC是Spring的核心思想之一,它通过将对象的创建、依赖注入和生命周期管理交给容器来实现解耦,使开发者... 目录1. IOC的基本概念1.1 什么是IOC1.2 IOC与DI的关系2. IOC的设计目标3. IOC

java中的HashSet与 == 和 equals的区别示例解析

《java中的HashSet与==和equals的区别示例解析》HashSet是Java中基于哈希表实现的集合类,特点包括:元素唯一、无序和可包含null,本文给大家介绍java中的HashSe... 目录什么是HashSetHashSet 的主要特点是HashSet 的常用方法hasSet存储为啥是无序的

Linux中shell解析脚本的通配符、元字符、转义符说明

《Linux中shell解析脚本的通配符、元字符、转义符说明》:本文主要介绍shell通配符、元字符、转义符以及shell解析脚本的过程,通配符用于路径扩展,元字符用于多命令分割,转义符用于将特殊... 目录一、linux shell通配符(wildcard)二、shell元字符(特殊字符 Meta)三、s

使用Python实现批量访问URL并解析XML响应功能

《使用Python实现批量访问URL并解析XML响应功能》在现代Web开发和数据抓取中,批量访问URL并解析响应内容是一个常见的需求,本文将详细介绍如何使用Python实现批量访问URL并解析XML响... 目录引言1. 背景与需求2. 工具方法实现2.1 单URL访问与解析代码实现代码说明2.2 示例调用