关于蓝桥杯嵌入式的部分代码规范及解决问题的算法

news/2024/9/23 13:24:08 标签: 代码规范, 蓝桥杯嵌入式

写在正文之前

在书写代码的时候需要注意代码的规范,不规范的代码运行起来容易出现更多的问题。

同时,在解决一些问题的时候,需要设计一套完整的算法才能完美地解决问题。

不论是代码的规范还是解决问题的算法,都不是一蹴而就的,靠的是平常一点一滴的积累,在这里我希望大家多进行积累这件事,也许在不远的将来可以给你带来很多收获!

ps:虽然本文代码全部都是基于蓝桥杯嵌入式平台给出的,但是其中的真意都是相通的

正文部分

代码规范

信号处理代码

当需要设置占空比和自动重装载值的时候,我们不能时时刻刻都去改变,这是一种对资源的浪费,所以应该设置校验位

这里有一段处理信号的代码,当然这里的代码也存在问题

接下来我会说明这段代码存在的问题并给出处理之后的代码

存在问题的代码
void SIG_Proc(void)                             

{

uint16_t frq_tmp = 0, pwm_tmp = 0; 

if((frq != frq_tmp) || (pwm_tmp != pwm)){

frq_tmp = frq;

pwm_tmp = pwm;

 

LL_TIM_SetAutoReload(TIM3, 1000000/frq - 1);

LL_TIM_OC_SetCompareCH2(TIM3, (1000000/frq + 1)*pwm/100);

}

VR37 = ADC2_Read()*3.3/4095;

}

 

关于这段代码,存在两个问题

问题一

在调用这个函数的时候临时创建两个变量,这个地方写的不好,应该定义一个全局变量

由于生存期和作用域的关系,每次调用这个函数都会把变量重新定义置零

所以其实根本就没有达到它想实现的只有频率和占空比改变的时候才重新设置

问题二

函数库问题,这里用的是LL库,而你使用的是HAL库

所以需要对函数进行修改改成HAL库代码

修改后的代码

将上述的问题解决之后,这里的代码就是一段比较理想的信号处理代码了

uint frq_temp=0;

uint duty_temp=0;

void Sig_Proc(void)

{

if(frq_temp!=frq||duty_temp!=duty)

{

frq_temp=frq;

duty_temp=duty;

 

__HAL_TIM_SET_AUTORELOAD(&htim17,1000000/frq-1);

__HAL_TIM_SetCompare(&htim17,TIM_CHANNEL_1,(1000000/frq+1)*duty/100);

HAL_TIM_GenerateEvent(&htim17,TIM_EventSource_Update);

}

 

}

串口接收处理代码

当接收一个字符才为正确情况时

直接用switch语句能大量节省代码语句,只需要switch出符合的字符,其他的直接一个default执行接收错误的操作

需要注意的是,switch case能传进来的参数的类型是有要求的,注意一下

还是用if条件语句吧

关于串口接收的代码

if(rx_pointer!=0)

  {

      uchar temp=rx_pointer;

      HAL_Delay(1);

      if(rx_pointer==temp)

      {

          usart_Proc();

          rx_pointer=0;

          memset(rx_data,0,sizeof(rx_data));

      }

  }

注意在这里面写的usart_Proc函数需要再写一个memset清除接收数组里面的数据,尽管每次的接收都会给存储信息的数组重新赋值,但是如果上次接收的数据比这次接收的数据要多,那接收到的信息就会存在错误

PWM频率和占空比设置代码

__HAL_TIM_SET_AUTORELOAD(&htim17,1000000/frq-1);
__HAL_TIM_SetCompare(&htim17,TIM_CHANNEL_1,(1000000/frq+1)*duty/100);
HAL_TIM_GenerateEvent(&htim17,TIM_EventSource_Update);

这样写出来的代码的占空比和频率完全正确,要记住这个公式
以后设置频率占空比就都用这个来改变了
但是这段代码放在信号处理代码里面的
 

处理问题的算法

年月转换成日

这看上去是一个很容易实现的功能,也许很多人在最初学习C语言的时候就已经写过了相关的算法内容

解决问题的难点

这个问题的难点在于当时间跨度足够长的时候,增加了很多额外的判断

每隔4年有一个闰年,每个闰年多一天 
但是每隔100年有一个世纪年,它不是闰年(除非能被400整除)
每隔400年有一个特殊的世纪年,它又是闰年

解决的办法

解决的办法其实很简单,就是将所有的时间都转换成天数再进行计算,之所以这样做,是因为闰年和平年存在差异,每个月份之间也存在差异,而日是不存在差异的

将年转换成日
uint32_t days_in_year = car_yea1 * 365 + (car_yea1 / 4) - (car_yea1 / 100) + (car_yea1 / 400);
说明

这个公式是用于将年份转换为天数的近似公式,它考虑了闰年和平年的情况。

每个平年有365天,所以首先将年份乘以365。

每隔4年有一个闰年,因此 (car_yea1 / 4) 表示car_yea1年中的闰年数,每个闰年多一天,所以将其加到总天数中)

但是每隔100年有一个世纪年,它不是闰年(除非能被400整除),因此 (car_yea1 / 100) 表示car_yea1年中的世纪年数,需要将这些世纪减去,以避免重复计算

每隔400年有一个特殊的世纪年,它又是闰年,所以 (car_yea1 / 400) 表示car_yea1年中的特殊世纪数,需要将其加到总天数中。

将月转换成日

使用一个二维数组来存储每个月份在平年和闰年中的天数,然后根据年份是否为闰年来选择相应的天数,以下是示例代码

uint8_t days_in_month[2][13] = {
    // 平年每个月的天数
    {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
    // 闰年每个月的天数
    {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};

// 判断是否为闰年
bool is_leap_year(uint16_t year) {
    return ((year % 4 == 0 &
& year % 100 != 0) || (year % 400 == 0));
}

// 计算某年某月的天数
uint8_t days_in_month_for_year(uint16_t year, uint8_t month) {
    return days_in_month[is_leap_year(year)][month];
}

想要计算出到某个月为止的天数,写一个循环就可以了

结尾

当你看了这里的代码之后,也许你会觉得这就是一个很简单很平常的东西,但就是这样一个看起来很简单的东西,如果平时缺少积累,是绝对想不到的,最后的结果就是你写出一段屎山


http://www.niftyadmin.cn/n/5671999.html

相关文章

二叉树(链式存储)

文章目录 一、树的基础概念二、二叉树2.1 概念 性质2.2 二叉树的存储2.2 二叉树的基本操作手动创建一棵二叉树遍历:前、中、后、层序获取树中节点的个数获取叶子节点的个数获取第K层节点的个数获取二叉树的高度检测值为value的元素是否存在判断一棵树是不是完全二叉…

AI视频生成模型

AI视频生成领域的模型种类繁多,主要分为以下几种常见的模型架构,它们各自擅长不同的任务场景:(今天先挖个坑,后续再来填坑) GAN(Generative Adversarial Networks) 这个之前有介绍过…

计算机毕业设计 教师科研信息管理系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍:✌从事软件开发10年之余,专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ 🍅文末获取源码联系🍅 👇🏻 精…

计算机毕业设计 校园失物招领网站的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍:✌从事软件开发10年之余,专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ 🍅文末获取源码联系🍅 👇🏻 精…

使用思科搭建企业网规划训练,让网络全部互通,使用规则提高工作效率。

1. 企业背景: 某企业分为销售部、行政部、人力资源部、财务部、业务部、接待中心等主要六个部门;配置网管中心,允许网络管理员登录企业交换机和路由器对企业网络进行管理;配置服务器集群,设置FTP、DNS、WEB服务器&am…

定点化学习(一)

学习笔记,方便复习,刷到请划走,避免误导。 我有一个小数3.76,我要用8bit位宽来定点化,是不是就是3.76乘以256,但是得到的数值是962.56,这个0.56是不是可以用四舍五入来舍去。 ChatGPT 说&#…

基于JAVA开发的超市管理系统

1.1社会背景 随着现代科学技术的迅猛发展,计算机技术已经渗透到哥哥领域,成为各行业必不可少的工具,特别是Internet技术的推广和信息高速公路的建立,使IT产业在市场竞争中越发显示出其独特的优势,步入信息化时代&…

C++三大特性——继承性(超万字详解)

目录 前言 一、封装 1. 封装(Encapsulation) 二、继承 1. 构造函数的调用顺序 原理: 2. 析构函数的调用顺序 原理: 3、派生类的隐藏 1. 成员函数隐藏 2. 成员变量隐藏 3. 基类函数的重载隐藏 三、多重继承问题 1. 构…