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

一、真题

二、模块构建

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--min

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/976074.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Android Coil3缩略图、默认占位图placeholder、error加载错误显示,Kotlin(3)

Android Coil3缩略图、默认占位图placeholder、error加载错误显示&#xff0c;Kotlin&#xff08;3&#xff09; Android Coil3缩略图、默认占位图placeholder、error加载错误显示&#xff0c;Kotlin&#xff08;1&#xff09;-CSDN博客文章浏览阅读667次&#xff0c;点赞18次&…

MariaDB 历史版本下载地址 —— 筑梦之路

MariaDB 官方yum源里面只有目前在维护的版本&#xff0c;而有时候对于老项目来说还是需要老版本的rpm包&#xff0c;国内很多镜像站都是同步的官方仓库&#xff0c;因此下载老版本也不好找&#xff0c;这里主要记录下从哪里可以下载到历史版本的MariaDB rpm包。 1. 官方归档网…

RoCBert:具有多模态对比预训练的健壮中文BERT

摘要 大规模预训练语言模型在自然语言处理&#xff08;NLP&#xff09;任务上取得了最新的最优结果&#xff08;SOTA&#xff09;。然而&#xff0c;这些模型容易受到对抗攻击的影响&#xff0c;尤其是对于表意文字语言&#xff08;如中文&#xff09;。 在本研究中&#xff0…

20250212:https通信

1:防止DNS劫持:使用 https 进行通信。 因为是SDK授权开发,需要尽量压缩so库文件和三方依赖。所以第一想法是使用 head only 的 cpp-httplib 进行开发。 cpp-httplib 需要 SSL 版本是 3.0及以上。但本地已经在开发使用的是1.0.2a版本,不满足需求。 方案1:升级OpenSSL 将Op…

数据驱动未来!天合光能与永洪科技携手开启数字化新篇章

在信息化时代的今天&#xff0c;企业间的竞争早就超越了传统产品与服务的范畴&#xff0c;新的核心竞争力即——数据处理能力和信息技术的应用。作为数据技术领域的领军者&#xff0c;永洪科技凭借其深厚的技术积累和丰富的行业经验&#xff0c;成功助力天合光能实现数字化升级…

Android之图片保存相册及分享图片

文章目录 前言一、效果图二、实现步骤1.引入依赖库2.二维码生成3.布局转图片保存或者分享 总结 前言 其实现在很多分享都是我们自定义的&#xff0c;更多的是在界面加了很多东西&#xff0c;然后把整个界面转成图片保存相册和分享&#xff0c;而且现在分享都不需要第三方&…

政安晨的AI大模型训练实践 十一 - 基于千问的Qwen2.5-VL-3B-Instruct 多模态模型进行微调参数认知 2

政安晨的个人主页&#xff1a;政安晨 欢迎 &#x1f44d;点赞✍评论⭐收藏 希望政安晨的博客能够对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff01; 微调一个大模型要准备的背景知识还是很多的。 本节我们介绍训练阶段的一些主要参数。 这是训…

心理咨询小程序的未来发展

还在眼巴巴看着心理咨询行业的巨大蛋糕却无从下口&#xff1f;今天就来聊聊心理咨询小程序的无限潜力 据统计&#xff0c;全球超 10 亿人受精神心理问题困扰&#xff0c;国内心理健康问题也日益突出&#xff0c;心理咨询需求猛增。可传统心理咨询预约难&#xff0c;费用高&…

反欺诈平台|基于Springboot+vue的反欺诈平台(源码+数据库+文档)​

目录 基于Springbootvue的反欺诈平台系统 一、前言 二、系统设计 三、系统功能设计 5.1用户信息管理 5.2 反诈视频管理 5.3视频收藏管理 5.1案例分析管理 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 博主介…

P8772 [蓝桥杯 2022 省 A] 求和--简单题的陷阱——(不开long long见祖宗!!!

P8772 [蓝桥杯 2022 省 A] 求和 题目分析代码 题目 分析 cnmmd 没什么好分析的&#xff0c;n≤210^5&#xff0c;tmd 我拿着a[100010]算半天 简单题的陷阱- - 代码 #include <iostream> #include <vector> #include <string> #include <algorithm> #i…

如何让传统制造企业从0到1实现数字化突破?

随着全球制造业不断向智能化、数字化转型&#xff0c;传统制造企业面临着前所未有的机遇与挑战。数字化转型不仅是技术的革新&#xff0c;更是管理、文化、业务流程等全方位的变革。从零开始&#xff0c;如何带领一家传统制造企业走向数字化突破&#xff0c;是许多企业领导者面…

TMDS视频编解码算法

因为使用的是DDR进行传输&#xff0c;即双倍频率采样&#xff0c;故时钟只用是并行数据数据的5倍&#xff0c;而不是10倍。 TMDS算法流程&#xff1a; 视频编码TMDS算法流程实现&#xff1a; timescale 1 ps / 1ps //DVI编码通常用于视频传输&#xff0c;将并行数据转换为适合…

SpringBoot源码解析(十一):准备应用上下文

SpringBoot源码系列文章 SpringBoot源码解析(一)&#xff1a;SpringApplication构造方法 SpringBoot源码解析(二)&#xff1a;引导上下文DefaultBootstrapContext SpringBoot源码解析(三)&#xff1a;启动开始阶段 SpringBoot源码解析(四)&#xff1a;解析应用参数args Sp…

跟李沐学AI:InstructGPT论文精读(SFT、RLHF)

原论文&#xff1a;[2203.02155] Training language models to follow instructions with human feedback 原视频&#xff1a;InstructGPT 论文精读【论文精读48】_哔哩哔哩_bilibili 简介 1. RLHF 的基本概念 RLHF 是一种结合强化学习和人类反馈的训练方法&#xff0c;旨在…

基于YOLO11深度学习的运动鞋品牌检测与识别系统【python源码+Pyqt5界面+数据集+训练代码】

《------往期经典推荐------》 一、AI应用软件开发实战专栏【链接】 项目名称项目名称1.【人脸识别与管理系统开发】2.【车牌识别与自动收费管理系统开发】3.【手势识别系统开发】4.【人脸面部活体检测系统开发】5.【图片风格快速迁移软件开发】6.【人脸表表情识别系统】7.【…

条款24:若所有参数皆需类型转换,请为此采用 non-member 函数

1.针对隐式转换的情况&#xff0c;可能会出现误用的情况 示例代码 #include <iostream>class Rational { public:Rational(float iNum1 1, float iNum2 2) { fNum iNum1 / iNum2; }~Rational() {}//自定义逻辑const Rational operator * (const Rational& rhs) …

无人机实战系列(番外一)本地图像+Apple ML Depth Pro

这篇文章作为系列文章 “无人机实战系列” 的一篇番外文章&#xff0c;主要测试了下 Apple 推出的一个基于机器学习的单目图像转深度的工具 ml-depth-pro&#xff0c;这个也是我在找这方面工具时意外发现的一个仓库&#xff0c;后期仍然会以 Depth Anything V2 为主线进行记录。…

MySQL数据库连接池泄露导致MySQL Server超时关闭连接

前言 最近做项目&#xff0c;发现老项目出现xxx&#xff0c;这个错误其实很简单&#xff0c;出现在MySQL数据库Server端对长时间没有使用的client连接执行清楚处理&#xff0c;因为是druid数据库&#xff0c;且在github也出现这样的issue&#xff1a;The last packet successf…

人工智能基础知识笔记一:核函数

1、简介 核函数有严格的数学要求&#xff0c;凡满足Mercer定理【参考本文第9章节】的都可以作为核函数。Mercer 定理确保高维:间任意两个向量的内积一定可以被低维空间中两个向量的某种计算表示(多数时候是内积的某换)。本节通过一个例子讲解核函数的使用。 2、核函数定义 设…

本地部署DeepSeek-R1(Ollama+Docker+OpenWebUI知识库)

安装Ollama 打开 Ollama官网 https://ollama.com/下载安装 Ollama服务默认只允许本机访问&#xff0c;修改允许其它主机访问 OLLAMA_HOST0.0.0.0 ollama serve也可以添加系统环境变量 都知道模型体积很大&#xff0c;顺便也通过环境变量修改模型存放位置&#xff0c;我这…