zl程序教程

您现在的位置是:首页 >  其他

当前栏目

蓝桥杯嵌入式第二课--LCD的移植与文件放置问题

文件嵌入式 -- 蓝桥 移植 LCD 问题 放置
2023-09-14 09:16:16 时间

前言

这节课是对前一课的延申,重点在于我们自己编写的代码要如何放置,以及如何将例程文件中的LCD移植到我们自己的工程当中。

创建一个User文件夹

一、工程文件夹概览

打开一个工程,其实里面很简单,就是三个文件夹以及两个莫名其妙的文件。不卖关子,简单来说就是:

  • MDK-ARM文件夹里存放与IDE有关的文件,点开后里面有一个绿色的工程文件,点击之后能够打开工程,以及一个同名文件夹,里面装着我们代码经过编译后的可执行文件,例如.hex 与.axf文件。

  • Core文件夹里面装着我们需要提交的.c和.h文件,一个Src和一个Inc分别存放.c和.h文件。考试时我们把整个Core文件夹给提交上去。

  • Drivers文件夹存放外设驱动,内容几乎不需要我们关注,因此不做介绍。

二、在Core-->Src中创建User文件夹

我们选择在Core的Src子文件夹中创建一个user文件夹用来放置我们自己编写以及移植的.c和.h文件,其实放在哪儿都无所谓,这只是一个规范性的问题罢了。

例如我们随意创建两个文件,用来放置自己写的代码。

移植LCD代码

一、找到目标代码

根据我们上面的经验,LCD有关的代码放置在例程的Core文件夹的Src和Inc当中,一共三个文件,分别是:

  1. lcd.c //驱动源码

  1. lcd.h //驱动头文件

  1. fonts.h //字体文件

二、复制到User中

belike:

让自定义代码成功编译

一、添加工程文件

二、设置头文件路径

在魔术棒的C/C++栏目下,如下图所示,将user文件夹的地址添加到路径当中。这一步的目的是为了帮助编译器找到自定义的头文件路径。(实际上编译器很傻的)

至此文件的添加就到此结束了,试着编译一遍看看能不能成功通过。

自定义的代码要怎么写

这是一个看似简单实则深奥的问题。大部分的初学者们都习惯在main.c中编写自己的函数,但是这样造成的后果就是面对复杂问题时,容易把事情搞的一团糟,试想阅读布满各种函数实现的main.c文件是怎么样的折磨。因此,这一部分要教大家怎么编写自定义的.c和.h文件,这样,我们在main.c中只要写一句简单的#include 就可以使用自定义的函数,而不需要面对繁杂的函数实现。

模块化的编程风格

一个项目往往由多个模块组成,例如按键模块,LED模块,LCD模块等等。我们习惯将一个模块的相关功能实现放在一个.c文件当中,对数据实例或对象定义,以及函数算法具体实现。另一个为头文件*.h,对模块中的数据结构函数原型进行描述,其中.c和.h文件的命名对应相同

*.h文件的编写

下面是按键模块的一个例子:

#ifndef _KEY_H_
#define _KEY_H_
#include "main.h"

uint8_t keyscan(void);

#endif

从中提取出模板即是:

#ifndef _XXX_H_
#define _XXX_H_
#include "main.h"
数据结构1;
数据结构2;
.
.
函数1;
函数2;
.
.
#endif

简单来说,记住这个模板就行了,更进一步理解请自行百度搜索。值得注意的是:

  • 由于函数实现可能要使用一些HAL库文件,因此.h文件当中应该#include “main.h”

  • .h文件要被对应的.c文件#include

  • .h文件还要被main.c文件#include

*.c文件的编写

对应的按键例子:

#include "key.h"

uint8_t keyscan(void)
{
    if(~HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0)|~HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1)|~HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2)|~HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0))
    {
        HAL_Delay(1000);
        if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0)==0)
        {
            return 1;
        }
        if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1)==0)
        {
            return 2;
        }
        if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2)==0)
        {
            return 3;
        }
        if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)==0)
        {
            return 4;
        }
    }

        return 0;
}

模板是:

#include "xxx.h"

函数实现1
函数实现2
.
.

main.c的使用

#include "xxx.h"
main(){
函数1;
函数2;
}

关于变量

按照变量定义的位置,分为全局变量和局部变量。

  • 全局变量定义在函数之外,可以被多个函数访问。

  • 局部变量定义在函数内部,只可以在函数内部使用。

因此,容易出现的问题是,如果一个文件内定义的全局变量要被另一个文件使用时,需要使用extern声明。

核心理解

  • #include“xxx.h”的作用相当于把这句代码替换成 xxx.h中的内容。

  • 一个文件不能被#include两次,因此需要#ifndef语句避免重定义。

总结

掌握自定义文件的技巧后,基础算是打完了,不懂的地方要及时百度搞懂,接下来便可以进行编程的训练了!