这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 企业专区 » Renesas » 瑞萨RA0单片机连载之三基于面向对象的LED灯

共3条 1/1 1 跳转至

瑞萨RA0单片机连载之三基于面向对象的LED灯

助工
2024-05-11 14:28:22     打赏

【前言】

在我试用了好几十种单片机后,发现,每个单片机都需要重复造轮子,感觉非常的累,比如OLED屏,每次都需要去重写他的驱动,这样非常耗时耗精力,在看到《百问网》的面向对象编程中,我学习到了面向编程的思想,感觉非常有必要打造自己的一套风格的代码,同样的功能,只需要修改BSP驱动就可以使用。因此,借此次RA0E1系列的单片机,希望能第一次搭建自己的面向对象的编程。

【创建工程】

此次创建工程,我采用RASC+MDK来开发。

1、打开FSP for RASC,创建基础的工程:

image.png

2、选择生成MDK5的工程,芯片选择对象的型号:

image.png

3、选择非RTOS

image.png

4、选择生成最小系统的工程:

image.png

5、打开原理图,查看开发板给用户可以使用的LED灯,有两个LED是可以提供给我们用户的,分别为P103、P104:

image.png

6、配置这两个IO为输出模式:

image.png

7、配置好后,生成工程,并打用MDK打开工程:

image.png

8、在工程中,我添加applications、devices、include、libs、drivers。这四个文件夹是学习百问网的面向对象的工程文件夹

image.png

其中他的功能如下:

1). 应用程序 位于 applications 目录下,用于存放业务相关的代码,它们可能是多个模块对象的联 调,也可能是数据的处理。比如“根据按键操作 LED”,这就属于应用层的代码。按键和 LED 的操作函数,不属于应用层,而是属于底下的设备层。 这一层需要和底层驱动完全解耦合:这一层的代码移植到其它平台时,无需修改代码。

2). 头文件 位于 include 目录下,主要存放 error.h 和 config.h,前者用于统一错误代码,后者 用于配置整个工程。 

3). 设备层 位于 devices 目录。简单设备的文件直接放在 devices 目录里;对于模块,在 devices 目录下根据模块名字创建一个子目录,用来存放模块的文件。 在 dev_xxx.h 中根据设备的特性定义一些结构体,在 dev_xxx.c 里实现了这些结构体, 并使用链表来管理同类设备。上层代码获取这些结构体后,就可以直接调用结构的函数指针 来操作设备。 

4)驱动层 位于 drivers 目录,存放的平台相关的驱动源代码。 drivers.h:根据 config.h 中的宏开关,包含 drv_xxx.h。 drv_xxx.h:接口,供外部代码调用。 drv_xxx.h:驱动代码,一般用来实现并注册 dev_xxx.h 中声明的结构体,会调用平台 提供的 HAL 库。

【注】以上4点说明引用《百问网》的内容,如有侵权请联系删除。

在devices文件夹中添加一个LED文件夹,创建led.h/c。

image.png

led.h中定义结构体来定义LED的init、on、off方法。

#ifndef __LED_H__
#define __LED_H__

typedef struct LedDev{
    int (*Init)(struct LedDev *ptdev);
    void (*On)(void);
	  void (*Off)(void);
}LedDevice;

struct LedDev *LedGetDevice(void);

#endif

Led.c中实例化LED对象代码如下:

#include "devices.h"
#include "hal_data.h"
#include <libs.h>
#include <errno.h>
#include <stdio.h>
#include "led.h"

static void LedON(void);
static void LedOFF(void);
static int LedDevInit(struct LedDev *ptdev);

static struct LedDev gDevice = {
    .Init = LedDevInit,
    .On = LedON,
		.Off = LedOFF,
};

static IODevice *gLedDevice;

struct LedDev *LedGetDevice(void)
{
    return &gDevice;
}


static int LedDevInit(struct LedDev *ptdev)
{
	if(NULL == ptdev) return -EINVAL;
	gLedDevice = IODeviceFind("LED");
	if(NULL == gLedDevice)
	{
		printf("Failed to find LED!\r\n");
		return -ENXIO;
	}
	if(ESUCCESS != gLedDevice->Init(gLedDevice))
	{
		printf("Failed to init GPIO!\r\n");
		return -EIO;
		
	}
	return ESUCCESS;
	
}

static void LedON(void)
{
	gLedDevice->Write(gLedDevice,1);
}

static void LedOFF(void)
{
	gLedDevice->Write(gLedDevice,0);
}

在app.c中初始化LED并添加测试函数:

void led_blink(void)
{
	UartDevicesRegister();
	IODevicesRegister();
	LedDevice *pDevice = LedGetDevice();
	if(NULL == pDevice)
    {
        printf("Error. There is no LED device!\r\n");
        return;
    }
    pDevice->Init(pDevice);
	printf("start\r\n");
	while(1)
	{
		printf("start\r\n");
		pDevice->On();
		R_BSP_SoftwareDelay(1,BSP_DELAY_UNITS_SECONDS);
		pDevice->Off();
		R_BSP_SoftwareDelay(1,BSP_DELAY_UNITS_SECONDS);
	}
}

至此面向对象的LED就完成了,初始化多个LED只需要需要添加实例化的LED就行了,移植到其他芯片,只需要重新定义一下dev_gpio中的IO就行了。




关键词: 刘工爱评测之瑞萨RA0单片机     瑞萨RA0     单片机         

高工
2024-05-11 16:46:43     打赏
2楼

谢谢分享


助工
2024-09-18 18:00:43     打赏
3楼

谢谢楼主分享。


共3条 1/1 1 跳转至

回复

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