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;
}
相关推荐
轻口味1 小时前
命名空间与模块化概述
开发语言·前端·javascript
森旺电子2 小时前
51单片机仿真摇号抽奖机源程序 12864液晶显示
单片机·嵌入式硬件·51单片机
晓纪同学2 小时前
QT-简单视觉框架代码
开发语言·qt
威桑2 小时前
Qt SizePolicy详解:minimum 与 minimumExpanding 的区别
开发语言·qt·扩张策略
飞飞-躺着更舒服2 小时前
【QT】实现电子飞行显示器(简易版)
开发语言·qt
明月看潮生2 小时前
青少年编程与数学 02-004 Go语言Web编程 16课题、并发编程
开发语言·青少年编程·并发编程·编程与数学·goweb
明月看潮生2 小时前
青少年编程与数学 02-004 Go语言Web编程 17课题、静态文件
开发语言·青少年编程·编程与数学·goweb
Java Fans2 小时前
C# 中串口读取问题及解决方案
开发语言·c#
盛派网络小助手2 小时前
微信 SDK 更新 Sample,NCF 文档和模板更新,更多更新日志,欢迎解锁
开发语言·人工智能·后端·架构·c#
Chinese Red Guest3 小时前
python
开发语言·python·pygame