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

【提分必看!】蓝桥杯单片机提分技巧(国一经验分享)

目录

  • 前言
  • PCA可编程计数器阵列
    • PCA_Timer.c
    • PCA_Timer.h
  • 按键状态检测
  • 两种计时按键
  • PWM输出逻辑
  • 外部中断(以外中断0为例)
  • 数码管闪烁

前言

本人在(2024年)第十五届蓝桥杯竞赛单片机赛道中取得了全国一等奖的成绩。本文我将会和读者们分享蓝桥杯单片机竞赛可能会用到的提分技巧,帮读者们叩开国一的大门!
官方资料获取(已整合):
蓝桥杯单片机资源包(含指导手册和考点大纲)
优质教程推荐:
蚂蚁工厂科技蓝桥杯单片机教程
小蜜蜂蓝桥杯单片机基础技能与进阶强化教程
其他相关文章:
【国一超全代码分享!】蓝桥杯单片机各模块代码整合

PCA可编程计数器阵列

IAP15F2K61S2单片机只有定时器0、定时器1和定时器2三个定时器,有时我们会遇到定时器资源不够用的情况:NE555频率测量占用了定时器0,超声波测距占用了定时器1,定时器2用作了串口波特率发生器。这时我们会发现没有定时器进行周期计数为我们的业务逻辑提供(周期)中断服务。为了解决这个问题,我们要启动单片机中的PCA模块。

这里简单介绍一下PCA:
PCA(可编程计数器阵列Programmable Counter Array)有5个16位的捕获/比较模块与之相连,由高字节(PCA0H)和低字节(PCA0L)组成。
在这里我们只需要知道:PCA可以充当16位重装载的“定时器”使用

PCA_Timer.c

// PCA初始化
void PCA_TimerInit(void)
{
	// 这些只能背!
	CMOD |= 0x01;//初始化为系统时钟12分频 允许CCON中的CF中断
	CCON &= 0x00;// CF=0;CR=0;

	CL=0x18;
	CH=0xFC;  // 这里的值根据需要的定时时间手动设置
	CR=1;// 开启计数
}

//中断回调函数
void PCA_isr() interrupt 7
{
	if(CF)
	{
		CF=0;// 需要手动(软件)清零溢出标志位
		CL=0x18;// 需要手动重装载,定时器是自动重装载
		CH=0xFC;// 需要手动重装载,定时器是自动重装载
		
		// 下面添加自己的代码
	}
}

PCA_Timer.h

#include "STC15F2K60S2.H"

void PCA_TimerInit(void);

按照以上操作,我们就可以把PCA当做定时器来用,这样就可以很大程度上解决编程过程中“定时器不够用”的问题。

按键状态检测

按键的底层代码参考:【国一超全代码分享!】蓝桥杯单片机各模块代码整合

// 声明四种状态
unsigned char Key_Value;  // 按键当前状态,0为低电平,1为高电平
unsigned char Key_Down;  // 下降沿
unsigned char Key_Up;  // 上升沿
unsigned char Key_Old;  // 按键的上一状态,0为低电平,1为高电平

//
Key_Value = Read_KBD();  // 读取按键当前状态(这里KBD对应矩阵键盘)
Key_Down = Key_Value&(Key_Old^Key_Value);
Key_Up = ~Key_Value&(Key_Old^Key_Value);
Key_Old = Key_Value;

两种计时按键

近两年赛题都会涉及到按键长短按的考点,下面提供一个写法给大家。

// 注意tick和flag,最好都创建独立的,避免冲突
// 按下按键超过时间,LED直接亮
// Key_Value:检测按键保持高电平或低电平
// Key_Up:检测按键上升沿(即按下到松开的那一瞬间)
if(Key_Value==4 && led1_flag==0)
{
	if(led1_tick++>2000)
	{
		led1_tick=0;
		led1_flag=1;
		ucLed^=0xF0;
	}
}
else
{
	if(led1_flag==0)  led1_tick=0;
	else if(led1_flag==1 && Key_Up==4)  led1_flag=0;
}

// 按下按键超过时间,松开了按键,LED才亮
if(Key_Value==5 && led2_flag==0)
{
	if(led2_tick++>2000)
	{
		led2_tick=0;
		led2_flag=1;
	}
}
else
{
	if(led2_flag==0)  led2_tick=0;
	else if(led2_flag==1 && Key_Up==5)  
	{
		led2_flag=0;
		ucLed^=0xF0;
	}
}

PWM输出逻辑

十三届国赛真题(如果没有记错的话)出了一次PWM输出的考点,要求某个引脚输出频率为1kHz,占空比为20%的PWM信号。之后大家在做到这道题的时候会发现,输出PWM信号并不难,但是输出PWM的代码一旦没写好,就很容易影响到其他模块(比如影响到温度读取或者时钟显示等)。以下是我的处理方法,通过这种处理能正常输出PWM信号,也可以不影响其他模块的正常使用。

if(pwm_flag==1)
{
	pp2_flag=0;
	if(pwm_tick<8)
	{
		if(pp1_flag==0)
		{
			pp1_flag=1;
			P0|=0x20;
			P2=P2&0x1F|0xA0;
			P2=P2&0x1F;
		}
	}
	else
	{
		if(pp1_flag==1)
		{
			pp1_flag=0;
			P0|=0x00;
			P2=P2&0x1F|0xA0;
			P2=P2&0x1F;
		}

	}
	if(++pwm_tick==10)  pwm_tick=0;
}
else if(pwm_flag==0)
{
	pp1_flag=0;
	if(pwm_tick<2)
	{
		if(pp2_flag==0)
		{
			pp2_flag=1;
			P0|=0x20;
			P2=P2&0x1F|0xA0;
			P2=P2&0x1F;
		}
	}
	else
	{
		if(pp2_flag==1)
		{
			pp2_flag=0;
			P0|=0x00;
			P2=P2&0x1F|0xA0;
			P2=P2&0x1F;
		}
	}
	if(++pwm_tick==10)  pwm_tick=0;
}

外部中断(以外中断0为例)

// 外部中断(这两句要写在main中)
IT0 = 0;                    //设置INT0的中断类型 (1:仅下降沿 0:上升沿和下降沿)
EX0 = 1;                    //使能INT0中断

//-----------------------------------------
//中断服务程序
void exint0() interrupt 0       //INT0中断入口 INT0对应的应该是按键S5
{
	// 下面写要执行的任务
    ucLed ^= 0xff;
}

数码管闪烁

sprintf(seg_string,"P1    %2d"(unsigned int)dist);
if(shan_tick<2)  // 200ms亮灭闪烁
{
	seg_string[6]=' ';
	seg_string[7]=' ';
}
if(++shan_tick==4)  shan_tick=0;

http://www.kler.cn/news/283589.html

相关文章:

  • phpstorm远程连接阿里云项目
  • 第 8 章 数据的家——MySQL的数据目录
  • 如何使用查询路由构建更先进的 RAG
  • 绕过后端校验的策略
  • 关于el-table的show-summary,合计栏不显示以及保留两位小数问题
  • Quarkus 后端开发记录
  • matlab 采样的非周期性矩形
  • 在野漏洞的应急响应流程
  • 【drools】kie:官方仓库clone 遇到问题解决
  • 利用API接口实现商品信息自动化更新的高效策略
  • centos基础设置
  • 【面试经验】字节商业产品日常实习面经
  • MySQL给用户授权
  • k8S Deployment
  • 计算机毕业设计选题推荐-汽车租赁系统-Java/Python项目实战
  • 整理了几十家高频面试题,让你避坑软件测试公司面试的套路,收藏收藏刷起来...
  • 「OC」CAlayer——巧用动画实现一个丝滑的折叠cell
  • 云端集中管控边缘服务:利用 EMQX ECP 在 K8s 上快速部署 NeuronEX
  • 删除微信重复文件的简易工具
  • unreal engine5中character角色和怪物交互时发生穿模
  • Kubernetes存储Volume
  • 借题《黑神话悟空》,聊聊UE5 游戏开发中基本的 C++ 概念
  • 日常刷题(24)
  • 【为项目做准备】Linux操作系统day1
  • STM32G474采用“多个单通道ADC转换”读取3个ADC引脚的电压
  • 报错:E: 无法修正错误,因为您要求某些软件包保持现状,就是它们破坏了软件包间的依赖关系。
  • [java][基础]ArrayList基本使用
  • NLP(三):词向量
  • 如何利用ChatGPT高效学习英语:从零基础到流利表达
  • 优化 spring boot 的启动速度