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

embedded/2024/12/22 9:32:38/

点亮一个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                    GPIOCLED_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;   //引脚速度为100MhzGPIO_InitStructure.GPIO_Pin      =  LED_PIN_0;           //初始化LED0GPIO_Init(LED_PORT_0, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin      =  LED_PIN_1;           //初始化LED1GPIO_Init(LED_PORT_1, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin      =  LED_PIN_2;           //初始化LED2GPIO_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;#endifled->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;
}


http://www.ppmy.cn/embedded/37327.html

相关文章

STM32单片机ADC功能详解

文章目录 1. ADC概述 2. ADC结构图 3. 引脚定义 4. 转换模式 5. 数据对齐 6. 转换时间 7. 硬件电路 8. STM32使用ADC单/多通道检测数据 1. ADC概述 功能:ADC是一个将模拟信号(如电压)转换为数字信号的设备。在微控制器中&#xff0c…

小说阅读网站的设计与实现(论文+源码)_kaic

小说阅读网站的设计与实现 摘 要 伴随着网络技术的不断创新及电子商务的飞速发展,网上阅读的方式日益发挥出其不可替代的优越性,不同的阅读网站也随之蓬勃发展,网上阅读形式以独特的优势,发展蓄势蓬勃。在线阅读作为一种全新的阅…

软考中级-软件设计师(十)网络与信息安全基础知识

一、网络概述 1.1计算机网络的概念 计算机网络的发展:具有通信功能的单机系统->具有通信功能的多机系统->以共享资源为目的的计算机网络->以局域网及因特网为支撑环境的分布式计算机系统 计算机网络的功能:数据通信、资源共享、负载均衡、高…

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

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

python 使用 MQTT

目录结构 1、py代码 offRelay12-yixing.py # _*_ coding: utf-8 _*_ # 须用到第三方库:paho-mqtt # 安装命令 python3 -m pip install paho-mqttimport time import json import paho.mqtt.client as mqtt# 函数:关闭所有房间的12路继电器模块上指定的…

matlab中syms用法

syms x; f sin(x); f是syms类型: 这个代码将创建一个名为 x 的符号变量。现在,可以使用 x 进行代数运算,比如求导、积分、解方程等。 用法: 1.求导: syms x f x^2 2*x 1; df diff(f, x);2阶求导: df…

N7552A是德科技N7552A电子校准件

181/2461/8938产品概述: 更小巧轻便的 2 端口模块,支持 3.5 mm 或 N 型 50 Ω 连接器,能够将校准时间缩短一半 特点 频率范围:直流至 9 GHz 使用 N 型或 3.5 mm 连接器 更小巧轻便的 2 端口电子校准件(ECal&#xff…

[Linux] GDB使用指南----包含CentOS7下安装以及使用

什么是GDB? GDB 是由 GUN 软件系统社区提供的调试工具,同 GCC 配套组成了一套完整的开发环境,GDB 是 Linux 和许多 类Unix系统的标准开发环境。可以用来调试C、C、Go、java、 objective-c、PHP等语言。 GDB的作用 程序启动时,可…