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                    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.hqwc.cn/news/675219.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

04-22 周日 阿里云-瑶光上部署FastBuild过程(配置TLS、自定义辅助命令)

04-22 周日 阿里云-瑶光上部署FastBuild过程 时间版本修改人描述2024年4月22日14:18:59V0.1宋全恒新建文档2024年4月23日20:41:26V1.0宋全恒完成了基本流程的添加 简介 前提 准备两台服务,一台部署Docker,一台部署FastBuild的镜像容器服务所述的Docke…

stm32f103zet6_DAC_2_输出电压

实现效果 DAC输出的电压 同过电压表测量电压 1.DAC配置的步骤 初始化DAC时钟。配置DAC的GPIO端口。设置DAC的工作模式(例如,是否使用触发功能,是否启用DAC中断等)。启动DAC。 2常用的函数 函数 HAL_DAC_Start() - 开启指定…

软件系统概要设计说明书(实际项目案例整理模板套用)

系统概要设计说明书 1.整体架构 2.功能架构 3.技术架构 4.运行环境设计 5.设计目标 6.接口设计 7.性能设计 8.运行设计 9.出错设计 全文档获取进主页 软件资料清单列表部分文档(全套可获取): 工作安排任务书,可行性分析报告&…

阿里巴巴alibaba国际站API接口:商品详情和关键词搜索商品列表

阿里巴巴国际站(Alibaba.com)提供了API接口供开发者使用,以实现与平台的数据交互。然而,由于API的详细内容和调用方式可能会随着时间和平台更新而发生变化,以下是一个概述和一般性的指导,关于如何使用阿里巴…

如何让CANoe或Wireshark自动解析应用层协议

当我们使用CANoe软件或Wireshark工具抓取以太网总线上的报文时,网卡首先会把以太网总线上的模拟信号解析成以太网帧数据。数据链路层根据二层头部中的Type字段值确定上层的协议。 如果以太网使用的是TCP/IP协议栈,那么Type值要么是0x0800(IPv4),要么是0x0806(ARP),要么是0x…

USP技术提升大语言模型的零样本学习能力

大语言模型(LLMs)在零样本和少样本学习能力上取得了显著进展,这通常通过上下文学习(in-context learning, ICL)和提示(prompting)来实现。然而,零样本性能通常较弱,因为缺…

AndroidStudio的Iguana版的使用

1.AndroidStudio介绍 Android Studio 是用于开发 Android 应用的官方集成开发环境 (IDE)。Android Studio 基于 IntelliJ IDEA 强大的代码编辑器和开发者工具,还提供更多可提高 Android 应用构建效率的功能,例如: 基于 Gradle 的灵活构建系统…

YOLOv5 V7.0 - rknn模型的验证 输出精度(P)、召回率(R)、mAP50、mAP50-95

1.简介 RKNN官方没有提供YOLOv5模型的验证工具,而YOLOv5自带的验证工具只能验证pytorch、ONNX等常见格式的模型性能,无法运行rknn格式。考虑到YOLOv5模型转换为rknn会有一定的精度损失,但是需要具体数值才能进行评估,所以需要一个…

荷香堪筑梦,鸳鸯和月寻。(变相BFS搜索)

本题链接:登录—专业IT笔试面试备考平台_牛客网 题目: 样例: 输入 3 4 2 .... ***. ..a. 输出 yes 思路: 根据题意,这里 1 s 可以移动多次,我们将每次可以移动避开雪的的位置存储起来,判断当…

线程池

文章目录 普通线程池自定义线程池 普通线程池 //创建线程池,不指定上限 ExecutorService pool1 Executors.newCachedThreadPool(); //创建线程池,指定上限 ExecutorService pool1 Executors.newFixedThreadPool(5); --------------------------------…

【Linux】文件内容相关的命令,补充:管道符

1、查看文件内容 (1-1)查看文件内容:cat,tac,head,tail 查看文件内容cat 文件名查看文件内容并显示行号cat -n 文件名倒着查看文件内容(从最后一行开始)tac 文件名查看文件前10行…

Day1| Java基础 | 1 面向对象特性

Day1 | Java基础 | 1 面向对象特性 基础补充版Java中的开闭原则面向对象继承实现继承this和super关键字修饰符Object类和转型子父类初始化顺序 多态一个简单应用在构造方法中调用多态方法多态与向下转型 问题回答版面向对象面向对象的三大特性是什么?多态特性你是怎…