这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 活动中心 » 板卡试用 » 【换取逻辑分析仪】+使用C++方式开发单片机程序

共1条 1/1 1 跳转至

【换取逻辑分析仪】+使用C++方式开发单片机程序

专家
2024-10-26 12:53:50   被打赏 35 分(兑奖)     打赏

我自己在Web开发方面长期使用Java语言(和C++一样,Java本身是面向对象的语言),因而习惯于面向对象的开发方式。而在单片机的开发中,一直都是使用面向过程的C语言开发。但使用Arduino开发单片机程序时,可以看到,在Arduino开发中使用C++这种面向对象的方式开发是司空见惯的事情,因此就想着能否在Keil的开发下使用面向对象的方式呢?

作为例子,准备在使用雅特力的AF32F405开发板上,在LED_Toggle例程的基础上,尝试改造为C++方式。选择LED_Toggle例程为基础,是因为这个处理最简单,改造上也相对容易。在改造之前,先做一下说明。当我们把GPIO作为一个驱动LED的对象使用时,不可避免地要使用到系统提供的库函数,或者操作单片机内部的寄存器,这些处理都是以C的方式提供的。但如果我们打开相关的头文件时,比如AF32F405开发板本身的at32f402_405_board.c文件使用at32f402_405_board.h文件:


#ifndef __AT32F402_405_BOARD_H

#define __AT32F402_405_BOARD_H


#ifdef __cplusplus

extern "C" {

#endif


#include "stdio.h"

#include "at32f402_405.h"

...


#ifdef __cplusplus

}

#endif


#endif


在文件中可以看到

#ifdef __cplusplus

extern "C" {

#endif

#ifdef __cplusplus

}

#endif


这是预处理代码。有了这个预处理代码,就表示提供的源文件是支持C和C++混合编程。也就是说,你可以放心地在你的程序中加入C++代码,并使用系统函数,而不用担心编译出错。雅特力提供的所有源文件是都支持C和C++混合编程的,因此我们就不用这方面花功夫了。

除了预处理,我们还需要改变工程的一些编译选项,以方便混合编译。点击魔术棒,

在Target选项Tab中修改编译选项Version 5 为 6

在C/C++所在的Tab中修改选项:

图片3.png

就这两项就行,其它的什么都不用改,使用原来例程默认的选项。

接下来我们在工程中加入main.cpp文件,在main.cpp中加入以下代码:

#include "at32f402_405_board.h"
#include "at32f402_405_clock.h"
class LED_Class{
    private:
    gpio_type *port;
    uint16_t pins;
    crm_periph_clock_type periphClock;
    public:
    LED_Class(gpio_type *port, uint16_t pins, crm_periph_clock_type clock){
        LED_Class::port = port;
        LED_Class::pins = pins;
        LED_Class::periphClock = clock;
    }
    void Init(void){
        gpio_init_type gpio_init_struct;
        /* enable the led clock */
        crm_periph_clock_enable(periphClock, TRUE);
        /* set default parameter */
        gpio_default_para_init(&gpio_init_struct);
        /* configure the led gpio */
        gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
        gpio_init_struct.gpio_out_type  = GPIO_OUTPUT_PUSH_PULL;
        gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT;
        gpio_init_struct.gpio_pins = pins;
        gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
        gpio_init(port, &gpio_init_struct);   
    }
    void Open(void){
        port->clr = pins;
    }
    void Close(void){
        port->scr = pins;
    }
    
    void Toggle(void){
        port->togr = pins;
    }
    
};
int main(void) {
    system_clock_config();
    at32_board_init();
    uart_print_init(115200);
    
    printf("Start main ...\r\n");
    
    
    LED_Class LED1(GPIOF, GPIO_PINS_4, CRM_GPIOF_PERIPH_CLOCK);
    LED1.Init();
    while(1)   {
        LED1.Toggle();
        delay_ms(500);
    }
}


可以看到在代码中,引入了一个LED_Class类,是一个专门用于驱动GPIO为LED用的类。在构造函数中,指明所在GPIO口和使用的引脚,以及所在的时钟总线。在LED_Class中提供了Init初始化函数和Open、Close、Toggle函数。其中的处理使用了底层函数,或者直接操纵寄存器。在main函数中在必要的处理之后,声明一个LED_Class对象LED1,并在while循环中周期亮灭LED(开发板上的红色LED)

在编译之前还有一件事儿要做,那就是把原来的main.c中的main函数改名,随便改成什么名字都行,就是不能再用main了,我改成了main_old,然后对工程进行编译、下载,就可以看到改造后的成果了。

图片4.png

demo.gif

使用面向对象方式开发程序,是有很多优点的,比如逻辑结构清晰,便于理解等,但在实际开发中,尤其是面对资源比较少的单片机,还是不推荐使用C++编程的。原因在于使用C++编程占用的资源,比C大。作为尝试,使用面向对象的方式开发,学习的意义,大于实际应用。至于以后,随着单片机本身提供的资源足够大,用面向对象的方式开发单片机应用,还有很值得期待的。

AT32F402_405_Firmware_Library_V2.0.7.zip


共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]