当前位置: 首页 > article >正文

【蓝桥杯单片机】第十三届省赛第二场

一、真题

二、模块构建

1.编写初始化函数(init.c) 

void Cls_Peripheral(void);

  1. 关闭led    led对应的锁存器由Y4C控制
  2. 关闭蜂鸣器和继电器

2.编写LED函数(led.c)

void Led_Disp(unsigned char ucLed);

  1. 将ucLed取反的值赋给P0

  2. 开启锁存器

  3. 关闭锁存器

3.编写数码管函数(seg.c)

void Seg_Tran(unsigned char *pucSeg_Buf,unsigned char *pucSeg_Code);

(1)段码转换函数

  • 定义两个变量i,j
  • for循环加Switch语句进行段码转换,在资源数据包查找段码表,并根据题目要求进行段码转换
  • 注意添加空格代表都不显示
  • case记得加' '
  • 判断是否有 .

void Seg_Disp(unsigned char *pucSeg_Code,unsigned char ucSeg_Pos);

(2)数码管显示函数

  • 要对数码管进行消隐
  • 显示的位置
  • 显示的内容

4.独立按键代码编写

unsigned char Key_Read_BTN(void)

  1. 有返回值函数(unsigned char)
  2. if语句判断按键是否按下
  3. 返回按键所对应的数字

 5.超声波代码编写

unsigned char Wave_Recv(void);

  1. 定义Tx和Rx引脚
  2. 将定时器里的TR0设置为0
  3. 定义变量,初始值为10,发射10个周期的波形
  4. 为了规范,将定时器的初值进行再次赋值
  5. 再令TR0=1,让定时器开始计时
  6. 发送10个周期的信号
  7. 每12us,TF0溢出,将Tx进行异或运算,while循环加分号
  8. TF0清零
  9. 关闭定时器,将定时器初值清零,打开定时器进行正计时
  10. while(RX&&!TF0)如果接收到信号,或TF0溢出,则退出循环
  11. 退出循环后关闭定时器
  12. 如果TF0溢出导致退出循环,返回最大值255,否则返回计时时间
  13. 返回的时间单位是us,需要统一单位,*0.017 进而换算成距离单位为厘米

6.定时器代码编写

void Timer0Init(void);
void Timer1Init(void);    

  1. 定时器0作为超声波定时器,将TR0=0
  2.  设置定时器0供超声波代码使用,时间为12us,12T,12MHz
  3. 定时器1作为主定时器,加上ET1=1

7.编写AD/DA代码

unsigned char PCF8591_ADC(void);

void PCF8591_DAC(unsigned char dat);

  1.  定义SCL,SDA
  2. 添加"intrins.h"头文件
  3. 定义变量用于存储采集的电压
  4. 写入流程:开始--发送写入地址--等待应答--发送电位器地址--等待应答
  5. 读取流程:开始--发送读取地址--等待应答--变量接收数据--发送应答--终止
  6. 读取地址为0x91 写入地址为0x90
  7. 电位器地址为0x43 光敏电阻地址为0x41

三、主函数编写 

1.调用初始化,定时器0,定时器1,打开中断总开关,stdio.h

2.编写数码管函数

  1.  每200ms检测一次
  2. if模式(Disp_Mode)判断
  3. 不要忘记调用数码管转换函数(否则数码管会全部点亮)

3. 中断服务函数

  1. 为各个变量进行自加
  2.  数码管的动态显示

4.模式界面编写

  1.  电压数据为unsigned char类型,要转化成浮点数  %4.2f
  2. 参数界面注意上下限的值
  3. 测距界面注意超声波状态是否开启

5.ADC函数编写

  1.  没有规定时间,任意即可
  2. 将采集来的数据赋值给变量
  3. 对采集的数据进行判断,看是否在上下限里,从而对超声波设置不同的状态

6.key函数编写 

  1.  定义两个变量
  2. 时间为20ms
  3. if判断两个变量是否相等,相等返回
  4. 不相等进入Switch语句,判断哪个按键被按下
  5. 最后不要忘记加上Key_Val_Old=Key_Val
  6. s4按下,Disp_Mode+1对3取模,因为是三个界面进行切换,根据题目要求,判断是否到参数界面,到参数界面,默认选择电压上限
  7. s6按下,参数值加0.5,注意要判断是否在参数界面
  8. s7按下,参数值减0.5,注意要判断是否在参数界面
  9. 注意s4按键按下界面切换的顺序和题目给的顺序不一致
  10. 由于要求对参数的调整在s4按下后才生效,所以需要增加两个参数,同时记得更改其他按键参数变量

7.超声波函数编写

  1. 性能指标未规定时间,任意即可
  2. 在将测距结果赋值给变量前,先判断状态,为0直接返回,不进行测距

8.编写DAC函数

  1. 判断超声波状态,未开启输出0
  2. 若开启,判断超声波测距结果,用if else语句来实现相应功能 
  3. 关于呈线性关系的那部分图像,可以用数学方法计算出y=kx+b中的k和b

 9.编写led函数

  1. 性能要求led响应时间小于0.2s
  2. 判断处于那个界面
  3. 点亮置1,熄灭置0
  4. 点亮用|=,熄灭用&=(置1再取反)切换亮灭状态用^=
  5. 切换亮灭状态,把它放到定时器中断里

 四、难点解析

1.按键切换界面的顺序和题目所给顺序不一致

2.调整参数时,参数值不生效,当按键按下时才生效

3.加,减模式的循环,用到了if判断

4.DAC的数据转换——通过数学方法解出来


易错点 

将不同函数的计时变量复制粘贴时忘记更改

五、主函数代码

#include "led.h"
#include "init.h"
#include "seg.h"
#include "key.h"
#include "tim.h"
#include "ultrasonic.h"
#include "iic.h"
#include "stdio.h"
//seg
unsigned char pucSeg_Buf[12],pucSeg_Code[8],ucSeg_Pos=0;
//time
unsigned long ulms=0;
unsigned int uiSeg_Dly=0;
unsigned int uiADC_Dly=0;
unsigned int uiDAC_Dly=0;
unsigned int uiKey_Dly=0;
unsigned int uiLed_Dly=0;
unsigned int uiUltrasonic_Dly=0;
//led
unsigned char ucLed=0x00;
//ADC
unsigned char ucADC=0;
float ADC_Pram_Max=4.5 ,ADC_Pram_Min= 0.5;
float ADC_Pram_Max_temp=4.5 ,ADC_Pram_Min_temp= 0.5;
//key
unsigned char Key_Val=0,Key_Val_Old=0;
//ultrasonic
unsigned char ucDist=0;
unsigned char Ultrasonic_Status=0;
//function
void Seg_Proc(void);
void Led_Proc(void);
void ADC_Proc(void);
void DAC_Proc(void);
void Key_Proc(void);
void Ultrasonic_Proc(void);
//mode
unsigned char Disp_Mode=0;
unsigned char Pram_Mode=0;//0--max  1--minvoid main(void)
{Cls_Peripheral();Timer0Init();Timer1Init();EA=1;while(1){Seg_Proc();ADC_Proc();DAC_Proc();Key_Proc();Led_Proc();Ultrasonic_Proc();}
}
void Seg_Proc(void)
{if(uiSeg_Dly<200)return;uiSeg_Dly=0;if(Disp_Mode==0){sprintf(pucSeg_Buf,"U    %4.2f",ucADC/51.0);}else if(Disp_Mode==2){sprintf(pucSeg_Buf,"P  %3.1f %3.1f",ADC_Pram_Max_temp,ADC_Pram_Min_temp);}else{if(Ultrasonic_Status==0){sprintf(pucSeg_Buf,"L    AAA");}else {sprintf(pucSeg_Buf,"L    %3u",(unsigned int)ucDist);}}Seg_Tran(pucSeg_Buf,pucSeg_Code);
}
void Led_Proc(void)
{if(uiLed_Dly<100)return;uiLed_Dly=0;if(Disp_Mode==0){ucLed|=0x01;ucLed&=~0x06;}else if(Disp_Mode==1){ucLed|=0x02;ucLed&=~0x05;}else{ucLed|=0x04;ucLed&=~0x03;}if(Ultrasonic_Status==1){ucLed^=0x80;}else{ucLed&=~0x80;}Led_Disp(ucLed);
}
void ADC_Proc(void)
{if(uiADC_Dly<200)return;uiADC_Dly=0;ucADC=PCF8591_ADC();if((ucADC/51.0>ADC_Pram_Min)&&(ucADC/51.0<ADC_Pram_Max)){Ultrasonic_Status=1;}else{Ultrasonic_Status=0;}
}
void Key_Proc(void)
{if(uiKey_Dly<20)return;uiKey_Dly=0;Key_Val=Key_Read_BTN();if(Key_Val==Key_Val_Old)return;switch(Key_Val){case 4:Disp_Mode=(Disp_Mode+1)%3;if(Disp_Mode==2){Pram_Mode=0;ADC_Pram_Max_temp=ADC_Pram_Max;ADC_Pram_Min_temp=ADC_Pram_Min;}else if(Disp_Mode==0){ADC_Pram_Max=ADC_Pram_Max_temp;ADC_Pram_Min=ADC_Pram_Min_temp;}break;case 5:if(Disp_Mode==2){Pram_Mode=(Pram_Mode+1)%2;}break;case 6:if(Disp_Mode==2){if(Pram_Mode==0){if(ADC_Pram_Max_temp==5.0){ADC_Pram_Max_temp=0.5;}else{ADC_Pram_Max_temp+=0.5;}}else{if(ADC_Pram_Min_temp==5.0){ADC_Pram_Min_temp=0.5;}else{ADC_Pram_Min_temp+=0.5;}}}break;case 7:if(Disp_Mode==2){if(Pram_Mode==0){if(ADC_Pram_Max_temp==0.5){ADC_Pram_Max_temp=5.0;}else{ADC_Pram_Max_temp-=0.5;}}else{if(ADC_Pram_Min_temp==0.5){ADC_Pram_Min_temp=5.0;}else{ADC_Pram_Min_temp-=0.5;}}}break;}Key_Val_Old=Key_Val;
}	
void Ultrasonic_Proc(void)
{if(uiUltrasonic_Dly<500)return;uiUltrasonic_Dly=0;if(Ultrasonic_Status==0)return;ucDist=Wave_Recv();
}
void DAC_Proc(void)
{if(uiDAC_Dly<200)return;uiDAC_Dly=0;if(Ultrasonic_Status==0){PCF8591_DAC(0);}else {if(ucDist<=20){PCF8591_DAC(51);}else if(ucDist>=80){PCF8591_DAC(255);}else{PCF8591_DAC(3.4*ucDist-17);}}
}
void Time_1(void) interrupt 3 
{ulms++;uiSeg_Dly++;uiADC_Dly++;uiDAC_Dly++;uiKey_Dly++;uiLed_Dly++;uiUltrasonic_Dly++;if (ulms%2==0){ucSeg_Pos=(ucSeg_Pos+1)%8;Seg_Disp(pucSeg_Code,ucSeg_Pos);}}

相关文章:

【蓝桥杯单片机】第十三届省赛第二场

一、真题 二、模块构建 1.编写初始化函数(init.c) void Cls_Peripheral(void); 关闭led led对应的锁存器由Y4C控制关闭蜂鸣器和继电器 2.编写LED函数&#xff08;led.c&#xff09; void Led_Disp(unsigned char ucLed); 将ucLed取反的值赋给P0 开启锁存器 关闭锁存…...

【安装及调试旧版Chrome + 多版本环境测试全攻略】

&#x1f468;&#x1f4bb; 安装及调试旧版Chrome 多版本环境测试全攻略 &#x1f310; &#xff08;新手友好版 | 覆盖安装/运行/调试全流程&#xff09; &#x1f570;️ 【背景篇】为什么我们需要旧版浏览器测试&#xff1f; &#x1f30d; &#x1f310; 浏览器世界的“…...

从零开始玩转TensorFlow:小明的机器学习故事 5

图像识别的挑战 1 故事引入&#xff1a;小明的“图像识别”大赛 小明从学校里听说了一个有趣的比赛&#xff1a;“美食图像识别”。参赛者需要训练计算机&#xff0c;看一张食物照片&#xff08;例如披萨、苹果、汉堡等&#xff09;&#xff0c;就能猜出这是什么食物。听起来…...

sql的索引与性能优化相关

之前面试的时候&#xff0c;由于在简历上提到优化sql代码&#xff0c;老是会被问到sql索引和性能优化问题&#xff0c;用这个帖子学习记录一下。 1.为什么要用索引 ------------------------------------------------------------------------------------------------------…...

Snapshot Compressed Imaging:打破传统成像的新视界

在我们的日常生活中,拍照、拍视频已经成为记录生活的常规操作。无论是用手机捕捉美丽的风景,还是用相机拍摄珍贵的瞬间,传统的成像方式似乎已经满足了我们大部分的需求。但你是否想过,在某些特殊的场景下,传统成像技术可能会遇到一些难题,而一种名为 Snapshot Compressed…...

git 命令 设置别名

在 Git 中&#xff0c;你可以通过配置别名来简化常用的命令。这样&#xff0c;你可以使用更短或更易记的命令来完成相同的操作。要设置 Git 命令的别名&#xff0c;你可以使用 git config 命令。 全局设置 如果你想为所有 Git 仓库设置别名&#xff0c;可以使用 --global 选项…...

在Spark中如何配置Executor内存以优化性能

在Spark中&#xff0c;配置Executor内存以优化性能是一个关键步骤。以下是一些具体的配置方法和建议&#xff1a; 一、Executor内存配置参数 在Spark中&#xff0c;Executor的内存配置主要通过以下几个参数进行&#xff1a; --executor-memory 或 spark.executor.memory&…...

Go语言--语法基础2--下载安装

2、下载安装 1、下载源码包&#xff1a; go1.18.4.linux-amd64.tar.gz。 官方地址&#xff1a;https://golang.google.cn/dl/ 云盘地址&#xff1a;链接&#xff1a; https://pan.baidu.com/s/1N2jrRHaPibvmmNFep3VYag 提 取码&#xff1a; zkc3 2、将下载的源码包解压…...

碰撞检测 | 图解凸多边形分离轴定理(附ROS C++可视化)

目录 0 专栏介绍1 凸多边形碰撞检测2 多边形判凸算法3 分离轴定理(SAT)4 算法仿真与可视化4.1 核心算法4.2 仿真实验 0 专栏介绍 &#x1f525;课设、毕设、创新竞赛必备&#xff01;&#x1f525;本专栏涉及更高阶的运动规划算法轨迹优化实战&#xff0c;包括&#xff1a;曲线…...

计算机网络真题练习(高软29)

系列文章目录 计算机网络阶段练习 文章目录 系列文章目录前言一、真题练习总结 前言 计算机网络的阶段练习题&#xff0c;带解析答案。 一、真题练习 总结 就是高软笔记&#xff0c;大佬请略过&#xff01;...

DPVS-1:编译安装DPVS (ubuntu22.04)

操作系统 rootubuntu22:~# lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 22.04.3 LTS Release: 22.04 Codename: jammy rootubuntu22:~# 前置软件准备 apt install git apt install meson apt install gcc ap…...

将 SELinux 永久设置为 Permissive

要将 SELinux 永久设置为 Permissive 模式&#xff0c;可以按照以下步骤操作&#xff1a; 1. 检查当前 SELinux 状态 首先&#xff0c;确认当前 SELinux 的状态&#xff1a; sestatus输出示例&#xff1a; SELinux status: enabled SELinuxfs mount: …...

EasyRTC:全平台支持与自研算法驱动的智能音视频通讯解决方案

在智能硬件的浪潮中&#xff0c;设备之间的互联互通已成为提升用户体验的核心需求。无论是智能家居、智能办公&#xff0c;还是工业物联网&#xff0c;高效的音视频通讯和交互能力是实现智能化的关键。然而&#xff0c;传统音视频解决方案往往面临平台兼容性差、交互体验不佳以…...

Elasticsearch 自动补全搜索 - autocomplete

作者&#xff1a;来自 Elastic Amit Khandelwal 探索处理自动完成的不同方法&#xff0c;从基础到高级&#xff0c;包括输入时搜索、查询时间、完成建议器和索引时间。 在本文中&#xff0c;我们将介绍如何避免严重的性能错误、Elasticsearch 默认解决方案为何不适用以及重要的…...

快速入门Springboot+vue——MybatisPlus多表查询及分页查询

学习自哔哩哔哩上的“刘老师教编程”&#xff0c;具体学习的网站为&#xff1a;7.MybatisPlus多表查询及分页查询_哔哩哔哩_bilibili&#xff0c;以下是看课后做的笔记&#xff0c;仅供参考。 多表查询 多表查询[Mybatis中的]&#xff1a;实现复杂关系映射&#xff0c;可以使…...

工程师 - VSCode的AI编码插件介绍: MarsCode

豆包 MarsCode MarsCode AI: Coding Assistant Code and Innovate Faster with AI 豆包 MarsCode - 编程助手 安装完成并使能后&#xff0c;会在下方状态栏上显示MarsCode AI。 安装完并重启VSCode后&#xff0c;要使用这个插件&#xff0c;需要注册一下账号。然后授权VSCod…...

VOS3000线路对接、路由配置与路由分析操作教程

一、VOS3000简介 VOS3000是一款常用的VoIP运营平台&#xff0c;支持多种线路对接和路由配置&#xff0c;适合新手快速上手。本教程将带你了解如何对接线路、配置路由以及进行路由分析。 二、线路对接 准备工作 获取线路信息&#xff1a;从供应商处获取线路的IP地址、端口、用…...

学习Linux准备2

使用win10系统带的wsl配置ubuntu系统&#xff0c;通过wsl功能我们可以更简单更轻松的获得Linux系统环境。 首先开启Windows自带的wsl功能 打开控制面板&#xff0c;选中启用或关闭Windows功能 这里我们点击进入 将上图红√点击上&#xff0c;点击确定&#xff0c;然后重新启动…...

Java IO 和 NIO 的基本概念和 API

一、 Java IO (Blocking IO) 基本概念&#xff1a; Java IO 是 Java 平台提供的用于进行输入和输出操作的 API。Java IO 基于 流 (Stream) 的模型&#xff0c;数据像水流一样从一个地方流向另一个地方。Java IO 主要是 阻塞式 I/O (Blocking I/O)&#xff0c;即线程在执行 I/O …...

【数据结构】快指针和慢指针

一、 给你单链表的头结点 head ,请你找出并返回链表的中间结点。如果有两个中间结点,则返回第二个中间结点。 要求&#xff1a;只遍历一遍链表 可以使用快慢指针&#xff1a;fast 一次走两步&#xff0c;slow 一次走一步。当 fast NULL&#xff08;偶数个结点&#xff09;或…...

四、综合案例(Unity2D)

一、2D渲染 1、2D相机基本设置 上面是透视&#xff0c;下面是正交 2、图片资源 在Unity中&#xff0c;常规图片导入之后&#xff0c;一般不在Unity中直接使用&#xff0c;而是转为精灵图Sprite 将图片更改为即可使用Unity内置的图片切割功能 无论精灵图片是单个的还是多个的…...

全面汇总windows进程通信(三)

在Windows操作系统下,实现进程间通信(IPC, Inter-Process Communication)有几种常见的方法,包括使用管道(Pipe)、共享内存(Shared Memory)、消息队列(Message Queue)、命名管道(Named Pipe)、套接字(Socket)等。本文介绍如下几种: RPC(远程过程调用,Remote Pr…...

Caffeine:高性能的Java本地缓存库

文章目录 引言什么是Caffeine&#xff1f;Caffeine的主要特点Caffeine的使用方法Caffeine与Google Guava Cache的对比Caffeine与Ehcache的对比总结 引言 在现代软件开发中&#xff0c;缓存是提高应用性能的重要手段之一。通过缓存&#xff0c;可以减少对数据库或其他外部系统的…...

Codes 开源免费研发项目管理平台 2025年第一个大版本3.0.0 版本发布及创新的轻IPD实现

Codes 简介 Codes 是国内首款重新定义 SaaS 模式的开源项目管理平台&#xff0c;支持云端认证、本地部署、全部功能开放&#xff0c;并且对 30 人以下团队免费。它通过创新的方式简化研发协同工作&#xff0c;使敏捷开发更易于实施。并提供低成本的敏捷开发解决方案&#xff0…...

flowable 全生命周期涉及到的api及mysql表

要了解Flowable从流程创建到审批过程中涉及的API和MySQL表。之前对工作流引擎有一些基础了解&#xff0c;但具体到Flowable的细节可能不太熟悉。需要先回忆一下Flowable的基本概念&#xff0c;比如流程定义、流程实例、任务、执行实例等&#xff0c;然后逐步思考每个步骤会用到…...

Golang | 每日一练 (3)

&#x1f4a2;欢迎来到张胤尘的技术站 &#x1f4a5;技术如江河&#xff0c;汇聚众志成。代码似星辰&#xff0c;照亮行征程。开源精神长&#xff0c;传承永不忘。携手共前行&#xff0c;未来更辉煌&#x1f4a5; 文章目录 Golang | 每日一练 (3)题目参考答案map 实现原理hmapb…...

【java】类声明的两种形式

在 Java 中&#xff0c;类的声明有两种形式&#xff1a; public class Test class Test 它们的区别主要在于访问权限和文件名的要求。下面我会详细解释这两种形式的区别。 1. public class Test 访问权限&#xff1a; public 表示这个类是公共的&#xff0c;可以被其他包&am…...

VSCode 中设置 Git 忽略仅因时间戳修改导致的文件变更【使用deepseek生成的一篇文章】

在 VSCode 中设置 Git 忽略仅因时间戳修改导致的文件变更&#xff0c;可通过以下步骤实现&#xff1a; 确认是否为纯时间戳修改 首先确认文件的修改是否仅涉及时间戳&#xff0c;使用终端运行&#xff1a; git diff -- <file>若输出为空但 Git 仍提示修改&#xff0c;可…...

Docker入门及基本概念

让我们从最基础的概念开始逐步理解。假设你已经准备好了docker 环境。 第一步&#xff0c;让我们先通过实际操作来看看当前系统中的镜像(images)和容器(containers)状态&#xff1a; docker images # 查看所有镜像 docker ps -a # 查看所有容器&#xff08;包括未运行…...

java八股文-消息队列

一、MQ基础篇 1. 什么是消息队列&#xff1f; 消息队列&#xff08;MQ&#xff09;是分布式系统中实现异步通信的中间件&#xff0c;解耦生产者和消费者。 2. 使用场景有哪些&#xff1f; 异步处理&#xff08;如注册后发送邮件&#xff09;系统解耦&#xff08;不同服务通过…...