C语言实现面向对象—以LED驱动为例

点亮一个LED

常见的LED代码

分层分离思想

面向对象的LED驱动

LED左边高电平。 当LED右边为低电平时,LED有电流通过,LED亮。反之,LED灭

GPIO功能描述:

点亮LED的步骤及代码:

开启GPIO的时钟

配置GPIO为输出模式

GPIO输出低电平

 

设备驱动的分层分离设计

硬件抽象层(HAL):硬件抽象层是位于最底层的层次,负责与特定硬件设备进行通信。它隐藏了底层硬件的细节,为上层提供统一的接口。HAL层通常由操作系统提供或者由芯片厂商提供的驱动程序组成。

设备驱动层:设备驱动层位于硬件抽象层之上,负责管理特定设备的操作和控制。它与硬件抽象层进行交互,并提供更高级别的接口供上层使用。设备驱动层通常由操作系统内核或者第三方开发者提供。

总线控制层:总线控制层负责管理设备之间的通信和协调。在一个系统中可能存在多个设备通过总线连接的情况,总线控制层负责管理这些设备之间的数据传输和信号交换。

操作系统抽象层:操作系统抽象层位于设备驱动层之上,提供了更高级别的接口和服务,使得应用程序可以方便地访问设备。这包括对文件系统的访问、进程管理、内存管理等。

用户空间接口:用户空间接口提供了用户空间程序与设备驱动层之间的通信接口,使得用户程序可以通过系统调用或者特定的库函数来访问设备。

main.c

#define LED_CLOCK_0()                 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE)
#define LED_PIN_0                     GPIO_Pin_5
#define LED_PORT_0                    GPIOE

#define LED_CLOCK_1()                 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE)
#define LED_PIN_1                     GPIO_Pin_6
#define LED_PORT_1                    GPIOE

#define LED_CLOCK_2()                 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE)
#define LED_PIN_2                     GPIO_Pin_13
#define LED_PORT_2                    GPIOC

LED_t LED;


/******************************************************************************
 * @brief     初始化LED
 *
 * @param[in] 无
 *
 * @return    无
 *
 ******************************************************************************/
void LED_Init_Easy(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    LED_CLOCK_0();    //使能GPIO引脚时钟
    LED_CLOCK_1();
    LED_CLOCK_2();

    GPIO_InitStructure.GPIO_Mode     =  GPIO_Mode_OUT;       //配置GPIO为输出模式
    GPIO_InitStructure.GPIO_OType    =  GPIO_OType_PP;       //推挽输出
    GPIO_InitStructure.GPIO_PuPd     =  GPIO_PuPd_UP;        //上拉模式
    GPIO_InitStructure.GPIO_Speed    =  GPIO_Speed_100MHz;   //引脚速度为100Mhz

    GPIO_InitStructure.GPIO_Pin      =  LED_PIN_0;           //初始化LED0
    GPIO_Init(LED_PORT_0, &GPIO_InitStructure);
    
    GPIO_InitStructure.GPIO_Pin      =  LED_PIN_1;           //初始化LED1
    GPIO_Init(LED_PORT_1, &GPIO_InitStructure);
    
    GPIO_InitStructure.GPIO_Pin      =  LED_PIN_2;           //初始化LED2
    GPIO_Init(LED_PORT_2, &GPIO_InitStructure);

    GPIO_SetBits(LED_PORT_0, LED_PIN_0);                     //三个LED全部设置为灭
    GPIO_SetBits(LED_PORT_1, LED_PIN_1);
    GPIO_SetBits(LED_PORT_2, LED_PIN_1);

//    GPIO_InitTypeDef GPIO_InitStructure;
//    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);
//    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
//    
//    GPIO_InitStructure.GPIO_Mode     =  GPIO_Mode_OUT;       //配置GPIO为输出模式
//    GPIO_InitStructure.GPIO_OType    =  GPIO_OType_PP;       //推挽输出
//    GPIO_InitStructure.GPIO_PuPd     =  GPIO_PuPd_UP;        //上拉模式
//    GPIO_InitStructure.GPIO_Speed    =  GPIO_Speed_100MHz;   //引脚速度为100Mhz

//    GPIO_InitStructure.GPIO_Pin      =  GPIO_Pin_5;
//    GPIO_Init(GPIOE, &GPIO_InitStructure);
//    
//    GPIO_InitStructure.GPIO_Pin      =  GPIO_Pin_6;
//    GPIO_Init(GPIOE, &GPIO_InitStructure);
//    
//    GPIO_InitStructure.GPIO_Pin      =  GPIO_Pin_13;
//    GPIO_Init(GPIOC, &GPIO_InitStructure);
}




/******************************************************************************
 * @brief     简单的延时函数
 *
 * @param[in]  time  :  延时时间
 *
 * @return     无
 *
 ******************************************************************************/
void Delay(int time)
{
    for (int i = time; i > 0; i--) {
        for (int j = 0xffff; j > 0; j--) {
            ;
        }
    }
}

//int main(void)
//{
//    LED_Init_Easy();

//    while (1) {

//        //打开所有的LED灯
//        GPIO_ResetBits(LED_PORT_0, LED_PIN_0);
//        GPIO_ResetBits(LED_PORT_1, LED_PIN_1);
//        GPIO_ResetBits(LED_PORT_2, LED_PIN_2);
//        Delay(1000);

//        //关闭所有的LED灯
//        GPIO_SetBits(LED_PORT_0, LED_PIN_0);
//        GPIO_SetBits(LED_PORT_1, LED_PIN_1);
//        GPIO_SetBits(LED_PORT_2, LED_PIN_2);
//        Delay(1000);
//    }
//}


LED_t gLed[3];

int main(void)
{

    LED_Init(&gLed[0], GPIOE, GPIO_Pin_5);
    LED_Init(&gLed[1], GPIOE, GPIO_Pin_6);
    LED_Init(&gLed[2], GPIOC, GPIO_Pin_13);

    while (1) {

        //打开所有的LED灯
        LED_On(&gLed[0]);
        LED_On(&gLed[1]);
        LED_On(&gLed[2]);
        Delay(1000);

        //关闭所有的LED灯
        LED_Off(&gLed[0]);
        LED_Off(&gLed[1]);
        LED_Off(&gLed[2]);
        Delay(1000);
    }
}

 led.c

#include "led.h"



//高电平灭,低电平亮
#define     LED_PIN_ON                          0
#define     LED_PIN_OFF                         1

#if  defined  (STM32F40_41xxx)



#define    __LED_CONFIG_IO_OUTPUT(port, pin)         { GPIO_InitTypeDef                    GPIO_InitStructure; \
                                                       GPIO_InitStructure.GPIO_Mode     =  GPIO_Mode_OUT; \
                                                       GPIO_InitStructure.GPIO_OType    =  GPIO_OType_PP; \
                                                       GPIO_InitStructure.GPIO_PuPd     =  GPIO_PuPd_UP; \
                                                       GPIO_InitStructure.GPIO_Speed    =  GPIO_Speed_100MHz; \
                                                       GPIO_InitStructure.GPIO_Pin      =  pin ; \
                                                       GPIO_Init(port, &GPIO_InitStructure);}

#define    __LED_IO_SET(port, pin, value)            { if (value == LED_PIN_OFF) \
                                                            GPIO_SetBits(port, pin); \
                                                       else \
                                                           GPIO_ResetBits(port, pin); \
                                                     }
#endif




/******************************************************************************
 * @brief     初始化LED
 *
 * @param[in]  led   :  led结构体指针
 * @param[in]  port  :  引脚端口
 * @param[in]  pin   :  引脚
 *
 * @return     0, 表示初始化成功, 其他值表示失败
 *
 ******************************************************************************/
int LED_Init(LED_t *led, LED_GPIO_Port_t port, uint32_t pin) //IO初始化
{
    if (!led)
        return -1;

    //配置引脚,默认输出
#if  defined  (STM32F40_41xxx)

    assert_param(IS_GPIO_ALL_PERIPH(port));

    if (port  == GPIOA)        { RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); }
    else if (port  == GPIOB)   { RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); }
    else if (port  == GPIOC)   { RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); }
    else if (port  == GPIOD)   { RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); }
    else if (port  == GPIOE)   { RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE); }
    else if (port  == GPIOF)   { RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE); }
    else if (port  == GPIOG)   { RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE); }
    else return -1;

#endif

    led->port = port;
    led->pin = pin;
    led->init = true;
    led->status = false;

    __LED_CONFIG_IO_OUTPUT(led->port, led->pin);
    LED_Off(led);

    return 0;
}




/******************************************************************************
 * @brief      打开led
 *
 * @param[in]  led   :  led结构体指针
 *
 * @return     0, 表示正常, 其他值表示失败
 *
 ******************************************************************************/
int LED_On(LED_t *led)
{
    if (!led || !led->init)
        return -1;  //初始化引脚之后

    __LED_IO_SET(led->port, led->pin, LED_PIN_ON);   //低电平亮
    led->status = true;

    return 0;
}




/******************************************************************************
 * @brief      关闭led
 *
 * @param[in]  led   :  led结构体指针
 *
 * @return     0, 表示正常, 其他值表示失败
 *
 ******************************************************************************/
int LED_Off(LED_t *led)
{
    if (!led || !led->init)
        return -1;  //初始化引脚之后
    
    __LED_IO_SET(led->port, led->pin, LED_PIN_OFF);   //高电平灭
    led->status = false;

    return 0;
}




/******************************************************************************
 * @brief      设置led状态
 *
 * @param[in]  led   :  led结构体指针
 * @param[in]  status:  led开关状态
 *
 * @return     0, 表示正常, 其他值表示失败
 *
 ******************************************************************************/
int LED_SetStatus(LED_t *led, bool status)
{
    if (!led || !led->init)
        return -1;  //初始化引脚之后
    
    led->status = status;

    return 0;
}




/******************************************************************************
 * @brief      刷新led状态
 *
 * @param[in]  led   :  led结构体指针
 *
 * @return     0, 表示正常, 其他值表示失败
 *
 ******************************************************************************/
int LED_RefreshStatus(LED_t *led)
{
    if (!led || !led->init)
        return -1;  //初始化引脚之后
    
    if (led->status == true) {
        __LED_IO_SET(led->port, led->pin, LED_PIN_ON);   //低电平亮
    } else {
        __LED_IO_SET(led->port, led->pin, LED_PIN_OFF);   //高电平灭
    }

    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/598855.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

前端数据可视化基础(折线图)

目录 前言: 画布: 折线图 (Line Chart): 前言: 前端中的数据可视化是指将大量数据以图形或图像的形式在前端页面上展示出来,以便用户能够更直观地理解和分析这些数据。数据可视化是一种强大的工具,它利用了人类视觉…

城市二手房数据分析与房价预测

实现功能 数据分析 二手房价格-时间分析 二手房数量-时间分析 二手房分布-区域分析 二手房户型分析 二手房朝向分析 二手房价格-区域分析 二手房热词词云 房价预测 采用合适的算法模型,对模型进行评估。通过输入影响因素输出预测价格。 采用技术与框架 M…

在Unity中实现分页数据显示和分页控制

参考:用两种简单的方式实现unity的分页效果 using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using UnityEngine.Rendering.VirtualTexturing; using UnityEngine.TerrainUtils;public class PageControll…

五一反向旅游,景区“AI+视频监控”将持续助力旅游业发展

一、建设背景 每年五一劳动节出去旅游都是人挤人状态,这导致景区的体验感极差。今年“五一反向旅游”的话题冲上了热搜,好多人选择了五一之后再出去旅游,避开拥挤的人群,这个时候景区的监管力度和感知能力就更要跟上去&#xff0…

Gradio之blocks灵活搭建页面

这里写目录标题 搭建一个UI界面搭建上半部分的框架比例调节以及其他效果搭建下半部分左边部分搭建下半部分右边部分拓展-CSS的应用 使用标签搭建第二个页面示例 补充AccordionGroup() 搭建一个UI界面 搭建上半部分的框架 如下图,我们想要基本还原下图右边的UI界面…

AI去衣技术在动画制作中的应用

随着科技的发展,人工智能(AI)已经在各个领域中发挥了重要作用,其中包括动画制作。在动画制作中,AI去衣技术是一个重要的工具,它可以帮助动画师们更加高效地完成工作。 AI去衣技术是一种基于人工智能的图像…

如何自己快速的制作流程图?6个软件教你快速进行流程图制作

如何自己快速的制作流程图?6个软件教你快速进行流程图制作 自己制作流程图可以是项目管理、流程设计或教学展示中的重要环节。以下是六款常用的流程图制作软件,它们都提供了快速、简单的方式来制作流程图: 迅捷画图:这是一款非…

Azide-PEG-Azide,82055-94-5可以用于制备抗体、蛋白质、多肽等生物分子的标记物

【试剂详情】 英文名称 Azide-PEG-Azide,N3-PEG-N3 中文名称 叠氮-聚乙二醇-叠氮,聚氧乙烯二叠氮化物 CAS号 82055-94-5 外观性状 由分子量决定,粘稠液体或者固体。 分子量 0.4k,0.6k,1k,2k&#…

用友GRP A++Cloud 政府财务云 任意文件读取漏洞复现

0x01 产品简介 用友GRP A++Cloud 政府财务云系统具有多项核心功能,旨在满足各类组织的财务管理需求。首先,它提供了财务核算功能,能够全面管理企业的总账、固定资产、现金、应付应收等模块,实时掌握企业的财务状况,并通过科目管理、凭证处理、报表分析等功能为决策提供有…

启明云端ESP8266+企业微信考勤机项目,多种方式认证能防止代打

智能考勤机需要有识别功能,用户容量,记录容量限制,还有物联网通讯方式,最后衔接到云平台,最后就是根据具体需求来设计。 ①识别方式:现如今市场上的考勤机主要有人脸、指纹、IC卡和ID卡等多种识别方式。不…

虚拟机文件夹共享操作(本地访问)

新建一个文件夹 右击文件夹点击属性 找到共享 点击共享 选择本地用户共享就可以了 本地winr 输入我们图片中的格式(IP前加 “\\” ) 会弹一个窗口,输入虚拟机的入户名和密码就可以共享了(一般默认用户名都是administrator&am…

人工智能-2024期中考试

前言 人工智能期中考试,认真准备了但是没考好,结果中游偏下水平。 第4题没拿分 (遗传算法:知识点在课堂上一笔带过没有细讲,轮盘赌算法在书本上没有提到,考试的时候也没讲清楚,只能靠猜&…

Linux进程——Linux进程与进程优先级

前言:在上一篇了解完一部分常见的进程状态后,我们先来把剩下的进程状态了解一下,再来进入进程优先级的学习! 如果对前面Linux进程不太熟悉可以先阅读: Linux进程 本篇主要内容: 僵尸进程和孤儿进程 Linux进…

绘画作品3d数字云展厅提升大众的艺术鉴赏和欣赏能力

3D虚拟展厅作为未来艺术的展示途径,正逐渐成为文化创意产业蓬勃发展的重要引擎。这一创新形式不仅打破了传统艺术展览的局限性,更以其独特的魅力吸引着全球观众的目光。 3D虚拟艺术品展厅以其独特的魅力,助力提升大众的艺术鉴赏和欣赏能力。观…

python - rst file to html

文章目录 python - rst file to html概述笔记下载安装PyCharm最新的学习版新建虚拟环境为Conda的工程添加docutils库新建python文件,添加转换代码运行自己写的python文件,执行转换转换结果END python - rst file to html 概述 开源工程中有一个.rst文件…

自动驾驶主流芯片及平台架构(一)

零部件成本下降、中低端车竞争加剧,推动ADAS渗透率在中国市场快速提升,自主品牌ADAS装配量大幅提升 零部件成本下降、中低端车竞争加剧,推动ADAS渗透率在中国市场快速提升,自主品牌ADAS装配量大幅提升。5年前在一些高端车型上才有…

(持续更新升级)火爆的ChatGPT源码+高质量AI绘画系统+分销功能+详细图文搭建部署教程

随着人工智能技术的迅猛发展,智能对话和创意艺术不再是遥不可及,而是可以触手可及的现实。 分享一款集ChatGPT源码、高质量AI绘画系统以及强大分销功能于一体的系统源码,对接了大名鼎鼎的ChatGPT接口及Midjourney两个王牌接口,另…

C++ 函数与指针

函数内部数据是地址需要传递给调用函数,返回的当然是指针了!当然,这个返回地址也可以通过函数参数返回! 函数的参数是指针可以输出函数多个结果,返回值本身就是返回数据,什么时候需要返回指针呢&#xff1f…

【北京迅为】《iTOP-3588开发板源码编译手册》-第4章 Android12/Linux设备树简介

RK3588是一款低功耗、高性能的处理器,适用于基于arm的PC和Edge计算设备、个人移动互联网设备等数字多媒体应用,RK3588支持8K视频编解码,内置GPU可以完全兼容OpenGLES 1.1、2.0和3.2。RK3588引入了新一代完全基于硬件的最大4800万像素ISP&…

迅为RK3568开发板资料说明4750+页专属文档专为3568编写

iTOP-3568开发板采用瑞芯微RK3568处理器,内部集成了四核64位Cortex-A55处理器。主频高达2.0Ghz,RK809动态调频。集成了双核心架构GPU,ARM G52 2EE、支持OpenGLES1.1/2.0/3.2、OpenCL2.0、Vulkan1.1、内嵌高性能2D加速硬件。 内置独立NPU,算力…