二、点亮LED(GPIO控制)

文件状态:
[ ] 草稿
[ ] 正在修改
[ √ ] 正式发布
文件标识:
当前版本: V1.1
作 者: Skymixos
完成日期: 2022年10月02日

版 本 历 史

版本/状态 作者 参与者 起止日期 备注
V1.0 Skymixos 2022年1月4日 创建文件
V1.1 Skymixos 2022年1月22日 修改文件格式,细化实验过程,完成定稿
V1.2 Skymixos 2022年02月22日 修改编码实现部分的思维导图
V1.3 Skymixos 2022年02月23日 修改文档结构

每日一句:千里之行,始于足下

1. 目的

  • 熟悉嵌入式开发的基本流程
  • 基本了解I.MX6ULL SoC
  • 熟悉I.MX6ULL的GPIO使用方法

2. 目标

  • 掌握ARM裸机程序开发流程(编写,编译,下载,调试)
  • 通过GPIO控制LED的亮灭

3. 嵌入式软件的执行流程

嵌入式设备开机上电后执行流程与PC对比:

设备上电后首先执行Bootloader(比如:BIOS,U-boot),Bootloader加载操作系统(比如:Windows,Linux,uCos等)到内存中执行。而应用程序往往在操作系统起来后被加载执行。目前写的裸机程序(点亮LED)在上述流程图中属于操作系统部分

Bootloader往往支持从FLASH,SD卡,USB,网卡等介质将Kernel加载到DDR中运行,为了调试方便

我们的目标程序(microx.bin)将由U-boot加载到DDR中执行(可以省去底层的初始化以及频繁的FLASH擦写)。

U-boot支持网络下载功能,我们只需要在服务器上开启tffp服务,就可以轻松的将程序下载到开发板上执行。

4. I.MX6ULL GPIO操作的理论基础

4.1 硬件连接

4.1.1 正点原子I.MX6U-MINI LED部分原理图

4.1.2 100ASK_IMX6ULL Pro LED部分原理图

4.1.3 100ASK_IMX6ULL Pro vs I.MX6U-MINI

开发板 控制LED的GPIO GPIO组 控制状态
I.MX6U-MINI GPIO1_IO03 GPIO1 * gpio输出低电平,点亮LED
* gpio输出高电平,熄灭LED
100ASK_IMX6ULL Pro GPIO5_IO03 GPIO5 * gpio输出低电平,点亮LED
* gpio输出高电平,熄灭LED

4.2 GPIO理论基础

LED控制需要的理论基础知识涉及:复用引脚,时钟,GPIO操作。

详细分析见:i.MX6U/LL SoC

5. 软件设计

从aliyun服务器上克隆原始的项目工程并切换到dev_1.0分支:

$ git clone git@code.aliyun.com:luopinjing/microx.git
$ git checkout dev_1.0

5.1 目录结构

目录/文件名 用途/含义 备注
3rd_party 存放一些第三方的开源库 目前该目录只存放了一个内容为空的SConscript文件
bsp 存放板级支持代码(这些代码一般参考官方实现) 目前该目录只存放了一个内容为空的SConscript文件
driver 存放microx系统的设备驱动代码 目前该目录只存放了一个内容为空的SConscript文件
fs 存放microx系统文件系统相关代码 目前该目录只存放了一个内容为空的SConscript文件
include 集中存放头文件
init 存放初始化代码 目前该目录只存放了一个内容为空的SConscript文件
kernel 存放microx系统内核核心代码 目前该目录只存放了一个内容为空的SConscript文件
lib 存放microx系统使用库 目前该目录只存放了一个内容为空的SConscript文件
prebuilt 存放编译工具,kconfig工具等 * gcc-linaro-6.2.1-2016.11-x86_64_arm-linux-gnueabihf.tbz2
* Kconfiglib-master.zip
script 存放编译脚本及配置 * build_log.sh:shell脚本,实现log打印功能
* config.py:编译参数配置,被SConstruct使用
* gen_autoconf_header.py:python脚本,实现将.config转换为autoconf.h的功能
* imx6ull_defconfig:默认的编译配置
* Kconfiglib-master:开源工具,实现图形化配置功能
* build.sh:顶层build.sh的实现,控制整个项目的编译
* gen_autoconf.py:python脚本,实现将.config转换为autoconf.py的功能
* Kconfig
* microx.lds:链接脚本
shell 存放microx系统mini shell代码 目前该目录只存放了一个内容为空的SConscript文件
build.sh 链接文件 指向script下的build.sh
SConstruct 顶层构建文件 类似顶层Makefile功能
README 项目说明及使用介绍
.git 项目版本管理仓库
.gitignore 用于记录无需版本管理的内容 文件用来忽略被指定的文件或文件夹的改动,被记录在.gitignore文件里的文件或文件夹,是无法被git跟踪到的,即被忽略的文件是不会被放入到远程仓库里的

5.2 软件构件系统

5.2.1 Shell脚本

编译系统中含有两个Linux shell脚本文件:build.shbuild_log.sh

  • build_log.sh:实现编译菜单及脚本的日志打印功能
  • build.sh:控制整个项目的编译(包括:编译环境配置,编译,清除等)

Linux shell脚本编程的基础知识见:Linux Shell

5.2.1.1 build_log.sh

#!/bin/bash################################ Log Related ################################
LOG_PRO_OFF="\033[0m"    # close all property
LOG_PRO_FONT_BLACK="\033[1;30m"
LOG_PRO_FONT_RED="\033[1;31m"
LOG_PRO_FONT_GREEN="\033[1;32m"
LOG_PRO_FONT_YELLOW="\033[1;33m"
LOG_PRO_FONT_BLUE="\033[1;34m"
LOG_PRO_FONT_PURPLE="\033[1;35m"
LOG_PRO_FONT_DARKGREEN="\033[1;36m"
LOG_PRO_FONT_WHITE="\033[1;37m"#
# log <log_level> [log]
# example:
# log INFO "hello, this is a test"
#
function log()
{if [ $# -lt 2 ]thenbuild_help;elseloglvel=$1case $loglvel inver)echo -e $LOG_PRO_FONT_GREEN"$2"$LOG_PRO_OFF;;dbg)echo -e $LOG_PRO_FONT_BLUE"$2"$LOG_PRO_OFF;;info)echo -e $LOG_PRO_FONT_DARKGREEN"$2"$LOG_PRO_OFF;;warn)echo -e $LOG_PRO_FONT_PURPLE"$2"$LOG_PRO_OFF;;err)echo -e $LOG_PRO_FONT_RED"$2"$LOG_PRO_OFF;;*)echo -e $LOG_PRO_FONT_WHITE"$2"$LOG_PRO_OFF;;esacfi
}function build_help()
{log info "------------------- microX OS Build Menu ----------------------------"log info "usage: script/build.sh [option]"log info "-s:   setup build enviorment"log info "-m:   menuconfig"log info "-b:   build OS(microX), show less log."log info "-bv:  build OS(microX), show more log."log info "-c:   clean OS(microX)"log info "----------------------------------------------------------------------"
}

5.2.1.2 build.sh

#!/bin/bashexport ENV_BUILD_TOP=`pwd`
export ENV_BUILD_TARGET=microxexport ENV_BUILD_TEXTBASE=0x8000
export ENV_BUILD_TFTPBOOT=/home/book/tftpboot
export ENV_BUILD_CROSS_TOOL=gcc-linaro-6.2.1-2016.11-x86_64_arm-linux-gnueabihf
export ENV_BUILD_TYPE=debugexport ENV_BUILD_OUT=$ENV_BUILD_TOP/out
export ENV_BUILD_SCRIPT_DIR=$ENV_BUILD_TOP/script
export ENV_BUILD_KCONFIGLIB_DIR=$ENV_BUILD_TOP/script/Kconfiglib-master
export ENV_BUILD_3RDPARTY=$ENV_BUILD_TOP/3rd_party
export ENV_BUILD_PYTHON=python3
export ENV_BUILD_CONFIG=$ENV_BUILD_TOP/.configexport ENV_BUILD_LDS=${ENV_BUILD_SCRIPT_DIR}/${ENV_BUILD_TARGET}.lds
export ENV_BUILD_TARGET_ELF=${ENV_BUILD_OUT}/${ENV_BUILD_TARGET}.elf
ENV_BUILD_TARGET_BIN=${ENV_BUILD_OUT}/${ENV_BUILD_TARGET}.bin. $ENV_BUILD_SCRIPT_DIR/build_log.shfunction gen_autoconf_py()
{log dbg "generate autoconf python script"$ENV_BUILD_PYTHON $ENV_BUILD_SCRIPT_DIR/gen_autoconf.py > $ENV_BUILD_OUT/autogen.py$ENV_BUILD_PYTHON $ENV_BUILD_SCRIPT_DIR/gen_autoconf_header.py > $ENV_BUILD_OUT/autogen.h
}function menuconfig()
{if [ ! -f ${ENV_BUILD_TOP}/.config ]; thencp $ENV_BUILD_SCRIPT_DIR/imx6ull_defconfig  ${ENV_BUILD_TOP}/.configfi$ENV_BUILD_PYTHON $ENV_BUILD_KCONFIGLIB_DIR/menuconfig.py $ENV_BUILD_SCRIPT_DIR/Kconfiggen_autoconf_py
}do_build_system()
{if test $1 == "build"; thenlog info "[ Build ] ---- microX ----"if [ ! -d  ${ENV_BUILD_TOP}/prebuilt/${ENV_BUILD_CROSS_TOOL} ]; thenlog err "should exec: ./build.sh -s first"elseexport ENV_BUILD_VERBOSE=1scons -Q -j8fielif test $1 == "build_detail"; thenlog info "[ Build ] ---- microX detail ----"if [ ! -d  ${ENV_BUILD_TOP}/prebuilt/${ENV_BUILD_CROSS_TOOL} ]; thenlog err "should exec: ./build.sh -s first"elseexport ENV_BUILD_VERBOSE=0scons -Q -j8fielif test $1 == "setup"; thenlog info "[ Setup ] ---- Enviorment ----"if [ ! -d ${ENV_BUILD_OUT} ]; thenmkdir -p ${ENV_BUILD_OUT}fiif [ ! -d ${ENV_BUILD_TOP}/prebuilt/Kconfiglib-master ]; thenunzip -o ${ENV_BUILD_TOP}/prebuilt/Kconfiglib-master.zip -d $ENV_BUILD_SCRIPT_DIRfiif [ -f ${ENV_BUILD_TOP}/prebuilt/${ENV_BUILD_CROSS_TOOL}.tbz2 ]; thentar jxf ${ENV_BUILD_TOP}/prebuilt/${ENV_BUILD_CROSS_TOOL}.tbz2 -C $ENV_BUILD_TOP/prebuilt/elselog warn "${ENV_BUILD_TOP}/prebuilt/${ENV_BUILD_CROSS_TOOL}.tbz2 not exist, please check!!!"fielif test $1 == "clean"; thenlog info "[ Clean ] ---- microX ----"if [ -f ${ENV_BUILD_TOP}/config.pyc ]; thenrm ${ENV_BUILD_TOP}/config.pyc -ffiif [ -f ${ENV_BUILD_TOP}/script/config.pyc ]; thenecho "${ENV_BUILD_TOP}/script/config.pyc exist"rm ${ENV_BUILD_TOP}/script/config.pyc -felseecho "${ENV_BUILD_TOP}/script/config.pyc not exist"fiscons -celselog warn "do_build_system: unsupport action"fi
}do_export_env()
{# 交叉编译工具链里的工具: CC,AS, CXX, STRIP, OBJCOPY, OBJDUMPENV_BUILD_TOOCHAIN_PREFIX=${ENV_BUILD_TOP}/prebuilt/${ENV_BUILD_CROSS_TOOL}/bin/arm-linux-gnueabihf-export CC=${ENV_BUILD_TOOCHAIN_PREFIX}gccexport AS=${ENV_BUILD_TOOCHAIN_PREFIX}gccexport AR=${ENV_BUILD_TOOCHAIN_PREFIX}arexport CXX=${ENV_BUILD_TOOCHAIN_PREFIX}g++export LD=${ENV_BUILD_TOOCHAIN_PREFIX}ldexport STRIP=${ENV_BUILD_TOOCHAIN_PREFIX}stripexport OBJCOPY=${ENV_BUILD_TOOCHAIN_PREFIX}objcopyexport OBJDUMP=${ENV_BUILD_TOOCHAIN_PREFIX}objdump
}if [ -f $ENV_BUILD_OUT/.config ]; then. $ENV_BUILD_OUT/.config
fi if [ $# -lt 1 ]; thenbuild_help;
elsedo_export_env;build_action=$1case $build_action in -s) # setup enviormentdo_build_system setup;;;-m) # menuconfig menuconfig;;-b) # build systemdo_build_system build;;;-bv) # build detaildo_build_system build_detail;;;-c) # clean systemdo_build_system clean;;;*)help;;;esac
fi

5.3 核心代码实现

5.3.1 head.S

.text   // .text申明以下为代码段
.global  _start // 定义一个全局符号 _start, 链接脚本microx.lds中会使用该符号
_start:                 ldr sp, =0x80200000    // 设置栈bl clean_bss    // 清除BSS段bl start_kernel // 跳转到 C函数入口: start_kernel执行,该函数在 main.c中实现halt:b  halt     // 如果执行到此处, 将在这里无限循环clean_bss:/* 清除BSS段, __bss_start/__bss_end符号在链接脚本microx.lds中定义 */ldr r1, =__bss_startldr r2, =__bss_endmov r3, #0
clean:str r3, [r1]add r1, r1, #4cmp r1, r2bne cleanmov pc, lr

主要功能:

  • 设置栈
  • 初始化BSS段
  • 跳转到start_kernel处执行

5.3.2 led.h/led.c

led.h:

/*************************************************************************************************
** Copyright © microX OS 2020 - 2030. All rights reserved.
**
** 文件名 : led.h
** 作者 : skymixos.Luo
** 版本 : V1.0
** 描述 : LED驱动头文件
**
**
** 修改记录:
**  日期                 版本                修改人                      备注
** ---------------------------------------------------------------------------------------------
** 2022年10月16日         V1.0               skymixos.Luo                创建文件并添加注释
**
***************************************************************************************************/
#ifndef _MX_HW_LED_H_
#define _MX_HW_LED_H_#include "sys/types.h"typedef enum {LED_DEVICE_ID1,LED_DEVICE_IDMAX
} LED_DEVICE_ID;typedef enum {LED_CTRL_CMD_ON,LED_CTRL_CMD_OFF,
} LED_CTRL_CMD;typedef struct led_device {void* base;         // GPIO控制器基地址mx_bool_t is_init;  // 是否完成设备初始化// 设备初始化,反初始化,控制void (*pfn_init)(struct led_device* hndl);void (*pfn_deinit)(struct led_device* hndl);void (*pfn_ctl)(struct led_device* hndl, LED_DEVICE_ID id, LED_CTRL_CMD cmd);
} led_device_t, *led_device_hndl;led_device_hndl get_led_instance(void);#endif // !_MX_HW_LED_H_

led.c:

/*************************************************************************************************
** Copyright © microX OS 2020 - 2030. All rights reserved.
**
** 文件名 : led.c
** 作者 : skymixos.Luo
** 版本 : V1.0
** 描述 : LED驱动实现
**
**
** 修改记录:
**  日期                 版本                修改人                      备注
** ---------------------------------------------------------------------------------------------
** 2022年9月10日         V1.0               skymixos.Luo                创建文件并添加注释
**
***************************************************************************************************/
#include "sys/io.h"
#include "drv/led.h"
#include "autogen.h"
#include "bsp/imx6ull_soc.h"static led_device_t g_led_device = {0};MX_UNUSED static const mx_int8_t* get_led_id_string(LED_DEVICE_ID id)
{switch (id) {CONVNUMTOSTR(LED_DEVICE_ID1);CONVNUMTOSTR(LED_DEVICE_IDMAX);default: return "unknown led id";}
}MX_UNUSED static const char* get_led_cmd_string(LED_CTRL_CMD cmd)
{switch (cmd) {CONVNUMTOSTR(LED_CTRL_CMD_ON);CONVNUMTOSTR(LED_CTRL_CMD_OFF);default: return "unknown led cmd";}
}/** 对于 100ASK_IMX6ULL Pro开发板: GPIO5_3* 对于 ATK-DL6Y2CM 开发板: GPIO1_4*/
static void led_init(struct led_device* hndl)
{mx_uint32_t reg_val = 0;/* 1.使能GPIO部分的时钟* set CCM to enable GPIO1/5* GPIO5 bit[31:30] = 0b11* GPIO1 bit[27:26] = 0b11*/reg_val = readl(SOC_CCM_BASE + CCM_CCGR1);
#ifdef CONFIG_PLATFORM_ATKDL6Y2CM_IMX6ULLreg_val |= (3 << 26);
#elsereg_val |= (3 << 30);
#endifwritel(reg_val, SOC_CCM_BASE + CCM_CCGR1);/** 2.复用引脚配置* 100ASK_IMX6ULL Pro: IOMUXC_SNVS_SW_MUX_CTL_PAD_SNVS_TAMPER3  229_0014h* ATK-DL6Y2CM: IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO04    20E_006Ch*/
#ifdef CONFIG_PLATFORM_ATKDL6Y2CM_IMX6ULLreg_val = readl(SOC_IOMUXC_BASE + 0x6c);reg_val &= ~(0xf);reg_val |= 5;writel(reg_val, SOC_IOMUXC_BASE + 0x6c);
#elsereg_val = readl(SOC_IOMUXC_SNVS_BASE + 0x14);reg_val &= ~(0xf);reg_val |= 5;writel(reg_val, SOC_IOMUXC_SNVS_BASE + 0x14);
#endif/** 3.将GPIO配置为输出,默认输出高电平,熄灭LED*/reg_val = readl(hndl->base + GPIO_GDIR);reg_val |= (1 << 3);writel(reg_val, hndl->base + GPIO_GDIR);// 将GPIO输出高电平,熄灭LEDreg_val = readl(hndl->base + GPIO_DR);reg_val |= (1 << 3);writel(reg_val, hndl->base + GPIO_DR);
}static void led_deinit(struct led_device* hndl)
{// nothing
}static void led_ctl(struct led_device* hndl, LED_DEVICE_ID id, LED_CTRL_CMD cmd)
{mx_uint32_t led_bit = 0;mx_uint32_t led_val = readl(hndl->base + GPIO_DR);if (id == LED_DEVICE_ID1) {led_bit = 3;} else {return;}if (cmd == LED_CTRL_CMD_ON) {led_val &= ~(1 << led_bit);} else if (cmd == LED_CTRL_CMD_OFF) {led_val |= (1 << led_bit);} else {return;}writel(led_val, hndl->base + GPIO_GR_OFFSET);
}led_device_hndl get_led_instance(void)
{if (g_led_device.is_init == false) {#ifdef CONFIG_PLATFORM_100ASK_IMX6ULLg_led_device.base         = (void*)SOC_GPIO5_BASE;
#elseg_led_device.base         = (void*)SOC_GPIO1_BASE;
#endifg_led_device.pfn_init     = led_init;g_led_device.pfn_deinit   = led_deinit;g_led_device.pfn_ctl      = led_ctl;g_led_device.pfn_init(&g_led_device);g_led_device.is_init = true;}return &g_led_device;
}

主要功能:

  • 实现LED的控制(点亮,熄灭)

5.3.3 main.c

#include "led.h"static void delay(volatile mx_uint32_t d)
{while (d--);
}mx_int32_t start_kernel(void)
{led_device_hndl led = get_led_instance();while (1) {led->pfn_ctl(led, LED_DEVICE_ID1, LED_CTRL_CMD_OFF);delay(10000000);led->pfn_ctl(led, LED_DEVICE_ID1, LED_CTRL_CMD_ON);delay(10000000);}return 0;
}

主要功能:

  • 调用led驱动的控制接口,循环的点亮熄灭LED

5.5 编译测试

5.5.1 云服务器的代码仓库中下载测试代码(code.ayliyun.com)

5.5.1.1 配置git并将SSH公钥添加到aliyun服务器

  • git配置用户名和email
$ git config --global user.name "your_name"
$ git config --global user.email "your_email"

注:将"your_name"和"your_email"替换成自己的用户名和邮箱

比如:

$ git config --global user.name “microx”

$ git config --global user.email “microx@163.com”

  • 生成公钥:
$ ssh-keygen -t rsa -C "your_email"

执行该命令并一路回车之后,会在用户的根目录生成:id_rsa.pub文件,如:

  • 将id_rsa.pub的内容添加到aliyun服务器

  • 下载代码:git clone git@code.aliyun.com:luopinjing/microx.git

下载完成后,切换到dev_1.0分支并:git checkout dev_1.0

检出代码:git checkout v0.0.1

5.5.2 配置(根据自己的开发板选择对应配置)

  • 执行 ./build.sh 会出现编译菜单:

  • 首次下载代码,需先执行:./build.sh -s 来设置编译环境

  • 执行 ./build.sh -m 来选择自己所使用的开发板

菜单使用:回车键(进入子菜单);上下方向键(选择菜单项);左右方向键(用于进入和返回);Esc键(退出菜单);字母Y:保存设置;字母N:不保存设置

5.5.3 编译

  • 执行 ./build.sh -b 命令完成目标程序编译,并将编译产生的microx.bin拷贝到 /home/book/tftpboot/目录下。

  • 执行 ./build.sh -bv 命令会显示详细的编译信息

编译产生的结果存放在 out 目录下:

  • autogen.h:使用配置./build.sh -m 生成的配置最终会转换成autogen.h,里面包含定义的一系列宏,代码中使用这些宏达到条件编译的目的。
  • autogen.py:使用配置./build.sh -m 生成的配置最终会转换成autogen.py,该文件被编译系统使用,达到选择需要编译哪些文件的目标。
  • microx.elf:编译产生的elf文件。
  • microx.bin:最终烧写到目标板上运行的文件,是由microx.elf转换生成的。
  • microx.dis:反汇编文件,用于调试(当程序崩溃时)

5.5.4 下载程序运行测试

5.5.4.1 开发板和Windows的网络连接配置

开发板和Windows开发主机有两种网络连接方式

  • 方式一:开发板和Windows开发主机连接到同一个路由器上(前提是你得有一个路由器)
  • 方式二:开发板和Windosw开发主机通过一根网线直连(如果你的电脑没有网口,可以购买一个USB转网口的转接器)

  • 采用方式一时,路由器会给Windows动态分配IP地址,需要手动给开发板设置一个与Windows在同一网段的地址。
  • 采用方式二时,需要给Windows对应的网卡设置一个与开发板同一网段的IP地址(开发板默认的IP地址为192.168.1.X)。

5.5.4.2 Windows下开启tftp服务

使用tftp服务的时候需要关闭Windows的防火墙,否则开发板不能ping通Windows!!!

  • 开发板设置tftp服务器的ip为Windows的ip:setenv serverip xx.xx.xx.xx

注:这个ip地址以自己机器的ip地址为准

  • 保持参数配置:saveenv

5.5.4.2 下载程序运行

开发板上电后,按下“回车”键进入u-boot的下载模式。通过tftp下载microx.bin到内存地址0x80008000处执行。

6. 小结

3.1 使用到汇编指令及伪指令

  • MOV指令
  • B指令
  • LDR指令
  • LDR伪指令

3.2 C语言知识点

  • 基本的数据类型
  • 结构体: struct
  • 枚举类型:enum
  • 指针,函数指针
  • typedef的使用
  • 位操作:按位与(&),按位或(|),按位取反(~)
  • 关键字:static,volatile

7. 参考资料

  • 链接脚本
  • ARMv7汇编:
  • IMX6ULL SOC:i.MX6U/LL SoC
  • 构建工具SCons:SCons

https://blog.csdn.net/hes_c/article/details/71600471

https://www.cnblogs.com/deepworm/p/10452908.html

二、点亮LED(GPIO控制)相关推荐

  1. zigbee学习之路(二)点亮LED

    一.前言 今天,我来教大家如何点亮led,这也是学习开发板最基础的步骤了. 二.原理分析 cc2530芯片跟虽然是51的内核,但是它跟51单片机还是有区别的,51单片机不需要对IO口进行配置,而cc2 ...

  2. 驱动led --GPIO控制

    GPIO引脚操作方法概述 硬件知识_LED原理图 不同主芯片控制GPIO引脚的方法概述 具体单板控制GPIO引脚的方法详解 具体单板LED程序的编写与实验 汇编与机器码 编程知识_进制 编程知识_字节 ...

  3. STM8S自学笔记-003 GPIO输出:点亮LED灯 and 跑马灯特效

    STM8S自学笔记-003 GPIO输出:点亮LED灯 and 跑马灯特效 点亮LED GPIO初始化函数:GPIO_Init() GPIO电平操作库函数:GPIO_WriteHigh().GPIO_ ...

  4. 51单片机手把手教学(二)—— 点亮 LED 灯(GPIO 操作)

    本文章 来自原创专栏<51单片机手把手教学>,讲解如何使用 Keil uVision 构建 51单片机 程序,发布文章并 会持续为已发布文章添加新内容! 每篇文章都经过了精打细磨! ↓↓↓ ...

  5. Java 通过GPIO控制LED灯的亮灭(一)

    Java 通过GPIO控制LED灯的亮灭(Firefly-RK3399)(一) Note: 为Android 开发,开发工具AndroidStudio 什么是 GPIO ,(General-purpo ...

  6. Linux系统编程二:字符设备控制之点亮LED灯、控制蜂鸣器

    目录 一.概述 二.文件IO 2.1 open和close 2.2 write和read 2.3 ioctrl 三.点亮LED 3.1 程序流程 3.2 代码实现 3.3 编译验证 四.控制蜂鸣器 五 ...

  7. 配置STM32寄存器控制GPIO点亮LED

    STM32点亮LED 寄存器方式 IO简介 1.每个IO可以自由编程,但是IO口寄存器必须按照32位字被访问. 2.每个IO端口都有7个寄存器来控制. CRL [0-7]端口配置寄存器  32位 CR ...

  8. 61-20210407华为海思Hi3516DV300的linux系统下控制GPIO口(标准linux模式点亮LED灯)

    61-20210407华为海思Hi3516DV300的linux系统下控制GPIO口(标准linux模式点亮LED灯) 2021/4/7 15:13 https://xueqiu.com/797071 ...

  9. 巧用1个GPIO控制2个LED显示4种状态

    很多电子产品有状态指示灯,比如电视机: 待机状态亮红灯 开机状态亮绿灯 实现起来很简单,微控制器MCU的两个GPIO分别控制就行: 不过资源总是紧张的,有时候会碰到GPIO不够用的情况. 如果只用1个 ...

最新文章

  1. python tornado入门_Tornado入门
  2. SSM实现个人博客系统
  3. 导出txt文件宏_利用solidwords二次开发导出三维曲面方阵点坐标方法
  4. python for-python循环
  5. 纯CSS3实现轮播图
  6. Nginx教程系列五:Nginx+Keepalived搭建高可用主从架构
  7. Extjs4 radiogroup打开时的被选中值设置为变量
  8. java 微信api框架_Java架构学习(五十二)使用框架开发微信微信框架介绍整合微信开发框架WxJava使用微信返回消息模板接口使用WxJava框架发送模板消息http协议参数转义知识...
  9. Jupyter简易上手的安装与使用教程
  10. 自下而上、从右往左层次遍历
  11. 读者专属福利: Git面试宝典分享
  12. matlab 多速率,多速率信号处理系统设计与实现.PDF
  13. Linux管道函数使用
  14. linux nginx php7,linux nginx配置php7
  15. java获取网络图片_做个看图片的App玩玩_第一篇
  16. kettle的行转列主键用法详解(正规化 宽表到窄表的过程)
  17. 如何判断视频数据是H264编码
  18. 手把手交给大家怎样破解压缩包密码的方法
  19. 关于socket阻塞与非阻塞情况下的recv、seng、read、write返回值问题
  20. 构建自己的Linux 之三 初步完善(提供网络功能等)

热门文章

  1. ubuntu16怎么升级到ubuntu18
  2. 如何做好IT战略规划与IT咨询!
  3. 微机原理——8086中断类型以及中断向量表、中断响应、中断返回
  4. 黑马程序员C++学习-01
  5. Go语言核心知识点和原理详解
  6. java 删除指定文件夹内所有文件
  7. [随笔]python之print函数总结
  8. cocos2d-js 游戏源码
  9. symfony 分表 查询 调用
  10. MATLAB求解运输问题