单片机教程

51单片机

CPU发展

  • CPU:带控制和运算。
  • 单片机:其中一种CPU,功能简单,可以理解为就是CPU
  • Soc:应用级,功能复杂。
  • DSP:擅长处理计算。

物联网感知层主控多为单片机。

51单片机内核是免费的。电容触摸IC(内带CPU)、Wifi芯片(ESP8266)、LoRa无线通信IC等专用Soc均有采用51内核。

开发板选择(普中科技):通过开发板学习,需要软硬结合。

制作开发板涉及采购,供应链等,个人制作是不可靠的。

需要的基础:编程基础和电学基础、英语、计算机基础知识、兴趣、时间。

单片机与嵌入式的区别

CPU差异:是否有MMU,即虚拟地址映射。

操作系统差异:实时操作系统,linux操作系统。

应用领域差异:低端和中高端,低性能与中高性能。

单片机是低层次的嵌入式设备;嵌入式是单片机的高级延伸过和必然趋势。

单片机与物联网的区别

物联网三层架构:

  • 感知层:传感器,如光传感器(带单片机),采集数据
  • 传输层:无线网络,如Wifi、LoRa,将采集数据传输到应用层
  • 应用层:云服务器,边缘服务器等,分析计算,将指令返回给感知层执行

实现自下而上,自上而下双路径。

单片机是物联网感知层的核心。

相关概念

  • 电路到集成电路(IC):
  • 电子设备:功率、体积、功能
  • CPU = 运算器 + 控制器
  • CPU = ALU(运算控制单元) + cache + Bus
  • CPU = 汇编指令(学会了汇编就学会了这个CPU) + 寄存器
  • CPU工作原理:通过总线从存储器获取指令到内部,然后译码执行
  • 在软件工程师眼里,操作硬件就是操作寄存器。寄存器是对硬件的抽象。

单片机定义:属于计算机的一种。

组成如下:

  • CPU、内部存储器、IO
  • 可以理解为微型计算机
  • MCU:微控制器
  • 说的都是一个东西。

结构框图如下:

中间部分为CPU模块,其他对应相应的外设模块。

ROM与RAM

  • ROM:read only memory,外存(只读存储器),CPU只能按照块来访问
  • RAM:random access memory,内存(随机访问存储器),可以被CPU按照字节进行访问
  • CPU首先将程序从外存加载到内存,然后从内存中读取指令到寄存器中与执行。
  • 单片机中的ROM(flash)用于存储用户烧录的程序,CPU直接读取ROM中的程序进行执行。
  • RAM分为SRAM和DRAM:单片机中的RAM为SRAM,不需要初始化,可以直接使用,程序运行中产生的数据存储到SRAM中;嵌入式SOC中的RAM为DRAM,需要初始化。
  • 总结:ROM存程序,RAM存数据。

单片机工作原理

单片机主频

外设与内部外设

内部外设:GPIO控制器、串口控制器、中断控制器等。

外部外设:至今没有集成到单片机内部的电路模块。

电路板(PCB板)

PCB板 = 基板(绝缘,玻璃纤维)+印刷电路

单层板、双面板、四层板、六层板等,覆铜之上一般会刷一层绝缘的油墨,避免氧化或与外部导电。

作用:构架和连接,硬件电路的载体。

硬件和软件

硬件比较吃经验。电路板为产品,偏低端。20%

软件偏思维和逻辑。产品为代码,偏高端。80%

需要懂一些硬件,才能编程,以软件为主线,附带学习硬件。

硬件

工作职责:

  • 电路图分析和设计
  • 元件的选择和参数设计
  • PCB设计和样板焊接、调试
  • 生产跟踪和问题解决

软件

工作职责:

初级:辅助测试、写代码、维护

中级:独立工作、对产品负责、调bug

高级:需求分析、框架设计、团队管理

学到基础(知识和能力)、找到工作、学习和锻炼、中级、高级/转方向

  • 数据手册是芯片产品的使用说明书。由芯片厂商写的。
  • 电路原理图
  • PCB
  • BOM:物料清单表

开发工具

万用表

焊接套装

keil软件

单片机分类

51的单片机由Intel公司设计诞生,C8051内核,8位单片机。

热门:宏晶公司的STC51系列单片机。

发展趋势:

主频越来越高、内部外设越来越多、越复杂。

ROM和RAM越来越大。

集成其他模块做成专用SOC。包含通用性和专用型单片机。

  • 51单片机,低性能
  • PIC单片机,有16位和32位,工业领域,RISC架构
  • AVR单片机,不推荐
  • MSP430、STM8等,MSP430是低功耗,STM8是高性能8位单片机。
  • ARM Cortex-M单片机:32位单片机,主流单片机。
  • 低性能选择51、STM8等,高性能采用ARM Cortex-M。

STC单片机系列特点

https://www.stcmcudata.com/

1T单片机(高性能51单片机):12MHz分频为1MHz(6时钟周期、12时钟周期)

ISP/IAP支持,系统在线编程/在线编程。方便程序的烧录和升级,不在需要使用烧录器了,直接在开发板上通过USB口进行程序的烧录。

  • STC89/90系列,替代AT89C51。适合用来学习。12T单片机。
  • STC11、STC12、STC15系列。1T单片机,不适合用来学习。STC15系列是最新的版本(新产品推荐使用)。

51单片机硬件平台

选用51单片机:STM89C52,8K ROM,512字节RAM

普中科技51单片机A2套件。

外围电路

  • 晶振电路
  • 复位电路
  • USB下载电路
  • 电源供电电路

标准C语言与keil C51的C语言

标准C语言独立于其他各种应用的编程语言,用途广泛。

keil C51是标准C语言的一种。

程序开发过程

源码编写

编译生成可执行程序

烧录

仿真器和ISP

仿真器用于替代单片机进行仿真,该设备价格非常贵。后来升级为调试器。

最小系统

能工作的最小开销。

  • 供电电路:电解电容用来稳压,普通电容用来滤波。
  • 晶振电路
  • 复位电路

二进制与IO端口

位(bit,b)与字节(byte,B):一个字节等于8位

单片机的IO物理上表现为单片机的引脚。

51单片机软件开发

单片机编程一般步骤

原理图分析

芯片数据手册阅读

流水灯

  • 原理图分析

分析:单片机P2输出高电平时,LED灭,输出低电平时,LED亮。

  • 代码编写

拷贝模板工程文件,修改组名:

右键管理组进入下图:

 

确认。

修改项目输出属性:

点亮LED的核心代码:

P2=0x00; //将P2端口全写0,即可点亮8个LED。

  • 编写延时函数

利用单片机小精灵软件生成此延时函数:

软件配置如下:

实际使用的是100ms的延时函数。

按键输入

按键:用于用户与CPU交互。

处理方式:轮询(CPU每隔很短时间去查看一次按键是否被按下,效率低下)、中断(效率高)

按键接法:独立按键和矩阵键盘

原理图分析

分析:单片机P3口所接按键引脚读取到低电平时,表明此按键已经被按下,否则则没有被按下。

以检测P3.3所接按键是否被按下,如果被按下,则反转LED灯状态。

  • 代码编写

拷贝模板工程文件,修改组名:方法同流水灯实验。

  • 按键消抖

定时器/计数器

  • 定时器

SOC的一个内部外设。

定时器是CPU的“闹钟”。

定时器是使用计数来实现的。

  • 计数器

可以计算外部脉冲个数。

  • 定时器工作原理(本质对内部脉冲进行计数)

设置时钟源头(内部脉冲源,用于计数的脉冲),定时时间等于脉冲时间*脉冲个数。

设定定时时间(计数个数)。

打开定时器。

设置中断处理函数。

定时器计数到后产生中断,CPU接收到此中断信号后,执行中断处理函数。

  • 软件通过寄存器来控制硬件

单片机学习内容:CPU和各种内部外设。

各种内部外设的编程接口就是寄存器。

熟悉一款单片机其实就是熟悉它的寄存器。

单片机越复杂则对应寄存器越多越复杂。

MSB:Most Significant Bit,二进制数中属于最高有效位。

LSB:Least Significant Bit,在二进制数中意为最低有效位。

相关寄存器:

具体每个寄存器及其相关位的详细介绍请看数据手册。

利用定时器定时实现LED灯闪烁:

代码编写:

拷贝模板工程文件,修改组名:方法同流水灯实验。

分析:定时0.5s,在定时器定时期间CPU还可以去做主任务,定时时间到产生中断,在中断处理函数中改变LED灯状态。

12T模式下,时钟频率为1MHz,时钟周期为1us。最多能定时65535(16位定时器),也就是最多能定位的时间为65535*1us=65535us=65.535ms。

如果需要定时500ms,则定时多次,然后进行累加。

计算TH0和TL0:(51单片机是加法计数器)

确定定时时间为:10ms

12T模式,外部晶振11.0592MHz,则实际周期为1/(11.0592MHz/12),即计数一次消耗的时间。

则计数个数为:10ms/(1/(11.0592MHz/12))=9216,计算过程中使用9215

TL0 =(65535-9615) % 256=0x00;低8位

TH0 =(65535-9615)  / 256 =0xDC;高8位

串口通信

  • 同步异步
  • 单工、半双工、全双工

单工:同一时刻,只能单方发送或者接收

半双工:同一时刻,一方能发送或者接收

全双工:同一时刻,一方既能发送又能接收

一、单工

数据只在一个方向上传输,不能实现双方通信。

栗子:电视、广播。

二、半双工

允许数据在两个方向上传输,但是同一时间数据只能在一个方向上传输,其实际上是切换的单工。

栗子:对讲机。

三、全双工

允许数据在两个方向上同时传输。

栗子:手机通话。

  • 并口和串口
  • 电平信号和差分信号(传输距离远,抗干扰能力强,RS485)
  • 通信关键:编码、传输和解码

串行通信相关概念:

  • 发送方有发送移位寄存器,接收方有发送移位寄存器。
  • 数据在发送方和接收方CPU中处理都是以字节为单位整字节处理的。
  • 数据在通信线上以位为单位逐个bit进行传输。
  • 起始位、结束位、停止位、奇偶校验位、数据位
  • 波特率:1s传输多少个bit位,发送方和接收方波特率必须设置成一样,否则会出现意想不到的问题。
  • 流控:速率协商,处理办法,禁用即可。
  • 现在串口用作主控和其他芯片之间的通讯接口。
  • 51单片机具有一个全双工串口,具有独立的接收和发送缓冲器。
  • 相关寄存器:

 通过轮训方式发送,中断形式接收数据。

注意:对于串口的四种工作模式,只需要使用工作模式1即可。8位UART,波特率可变的模式。

其他三种工作模式不用理会。

查询方式处理串口发送数据: CPU并不知道串口什么时候将数据发送完,因此,CPU需要一直守着串口工作,效率低下。

中断方式:串口将数据发送完成后,硬件会自动将TI这个标志位置1,CPU收到此中断信号后,会去执行相关的中断处理函数。

注意:一般处理方式,发送数据使用轮询方式,接收使用中断方式。

  • 发送代码编写

拷贝模板工程文件,修改组名:

  • 串口初始化
  • 波特率计算

 

 软件生成代码如下:

#include <reg51.h>

void InitUART(void)
{
    TMOD = 0x20;
    SCON = 0x50;
    TH1 = 0xF4;
    TL1 = TH1;
    PCON = 0x80;
    EA = 1;
    ES = 1;
    TR1 = 1;
}

void SendOneByte(unsigned char c)
{
    SBUF = c;
    while(!TI);
    TI = 0;
}

void main(void)
{
    InitUART();
}

void UARTInterrupt(void) interrupt 4
{
    if(RI)
    {
        RI = 0;
        //add your code here!
    }
    else
        TI = 0;
}

实际使用的程序:

 实验效果:

Rs485

  stm32调试接口:

JTAG

SWG

常用调试器:

JLINK

STLINK

stm32编程方式:

1.寄存器操作:容易出错,关注细节太多。

2.标准库:提供各种标准外设的驱动库。

2.hal库开发:集成各种第三方库。进行配置即可。

内存与IO统一编地址,像操作内存一样来操作这些寄存器。

stm32的存储器映像

上电复位,进行GPIO等状态的初始化。

数据总线32位,地址线32位。

逻辑地址(理论可以访问的地址),实际地址(实际可以访问的地址)。

内存与IO统一编址,操作内存一样的来操作IO。

内部外设的地址从0x4000 0000开始。

参考手册中就给了内部外设的内存映像。

stm32的位段操作:即地址映射

别名存储区:  字(32位)

                      映射

位段存储区:  位

别名存储区和位段存储区为存储器中的2个地方。

有位段操作的原因?

51单片机支持位操作。stm32本身不支持位操作,只支持32位、8位和16位的操作,所以发明了此操作。将一位映射到其他的32位,操作32位就相当于操作这个位。

别名存储器区大小是位带存储器区大小的32倍。

stm32启动模式

三种启动模式:

ISP:在系统编程。可以在单片机运行过程中烧录程序。PC机通过串口将bin/hex文件直接isp到单片机flash中。

IAP:在应用编程。在线升级功能。自己更新自己。

电源管理系统(PWR)

CPU睡眠状态:CPU停,外设运行,唤醒源为所有中断。

CPU停止状态:CPU停,时钟停,外设停,只有SRAM和寄存器还保持原来的值,唤醒源为外部中断。

待机模式:CPU停,时钟停,外设停,SRAM和寄存器停,相当于断电,只有备份电路和备份寄存器工作,唤醒源为IWDG中断等。

复位和时钟

系统启动刚开始是使用内部的时钟,一些初始化完成后,才开启外部时钟进行工作。 

上电复位:执行复位中断函数。

时钟源:时钟产生源头,纯内部、内外部、纯外部

PLL:锁相环电路,功能就是倍频。

时钟通道与流向、分频

完全独立的多个时钟

完全独立的多个时钟。

系统上电后,默认时钟都是关闭的。使用内部的时钟。

ISP自动下载:不推荐使用。

GPIO控制LED

原理图分析

 

分析:共2个LED可以进行控制,PF9控制LED0,PF10控制LED1。输出低电平,则LED亮。

编程思路:将PF9和PF10配置为输出,输出低电平就可以点亮LED。

mdk4工程建立

创建工程模板Template:

选择开发板芯片:

关闭即可:

工程建立完成:

修改keil字体大小:

设置编码为utf8:

起始代码

从CPU复位开始执行的第一条指令都main函数开始执行之前的代码。这段代码涉及CPU架构、CPU运行环境,编译器环境等。

不同CPU的起始代码是不同的。

相关寄存器

GPIOF

地址:

模式寄存器:        GPIOF_MODER    偏移量:0x00 实际地址:0x4002 1400

输出类型寄存器:    GPIOF_OTYPER    偏移量:0x04 实际地址:0x4002 1404

输出速度寄存器:    GPIOF_OSPEEDR   偏移量:0x08 实际地址:0x4002 1408

输出上下拉寄存器:  GPIOF_PUPDR     偏移量:0x0C 实际地址:0x4002 140C

输出数据寄存器:    GPIOF_ODR       偏移量:0x14 实际地址:0x4002 1414

位复位/置位寄存器:  GPIOF_BSRR      偏移量:0x18 实际地址:0x4002 1418

C语言操作寄存器

ARM是内存与Io统一编址的。C语言通过操作这些地址来操作寄存器的。

模式寄存器配置

配置GPIOF9和GPIOF10为输出模式:

即0X500。

输出上下拉寄存器 

配置GPIOF9和GPIOF10为输出上拉:

即0X500。

输出数据寄存器 

配置GPIOF9和GPIOF10为输出高电平:

即0X600。

调试器配置

注意:需要将此选项去掉,否则下载程序后,无法自动复位运行。

下载后,发现无现象。原因是时钟模块未开启。

时钟驱动移植

由于时钟模块相对来说较复杂,从0开始容易出错,需要关注多个寄存器的细节。因此,对于这类问题,一般采用移植的方法。在别人的代码基础上进行修改。

这里选择忽略此时钟驱动的编写。

修改工程模板组名

获取此开发板芯片的启动代码:

拷贝下图中文件到工程目录下:

添加到项目结构中:

添加头文件包含:

时钟相关寄存器

RCC:

地址:0x4002 3800

AHB1 peripheral clock enable register:即AHB1外设时钟使能寄存器

实际地址为:0x4002 3830

标准外设库的引入

传统单片机软件开发方式

芯片产商提供数据手册和参考手册、实例代码、开发环境。

单片机软件工程师面向产品功能,查阅参考手册进行开发。

调试各种外设,而是实现产品功能。

外设库是芯片公司提供的示例代码的标准化产物。

创建SI工程

 

标准库文件结构:

 CMSIS:ARM内核相关资料(CPU本身的东西)

STM32F4xx_StdPeriph_Driver:内部外设相关驱动

分析:学习过程中,一个一个模块进行代码分析。

使用结构体访问内存。结构体指针。

rcc模块分析

.c文件和.h文件都有宏定义。

.c文件中定义的宏定义只是给该C文件使用的,其他文件使用不了。而.h文件中定义的宏定义不仅对应的.c文件能使用,而且其他文件也能使用。

断言:用于判断传参是否可用。

HAL库开发

创建cubemx工程

配置界面如下:

配置LED引脚GPIOF9和GPIOF10:

配置为输出模式:

时钟配置:

默认使用的配置是使用内部提供的16MHz:

 现在需要配置为使用外部晶振来生成最大工作频率:

生成后的时钟配置:

工程配置:

其他配置保持默认。

生成mdk代码

使用mdk打开项目:

生成的项目结构如下:

编译项目:

下载:注意只需要设置如下即可。

串口实验

f4开发板原理图分析:

使用的是串口1

生成代码:

配置串口接收中断: 

RS485(RS422)通信

RS232通信距离不超过15m。

远距离传输要求:

提高电压标准;提供通信线抗干扰能力、降低阻抗;使用差分信号。

串口通信常用波特率为:9600和115200。

RS485最大通信距离1200M,最快通信速度为10Mps,距离和速度成反比。

差分信号负逻辑。

更远距离可以加中继。

半双工通信。

RS485只提供物理层通信能力,不提供数据层协议,需要用户自定义,或者使用标准协议,如MODBUS协议。

CPU本身只会提供UART接口,而不会提供RS485接口。

使用方法:UARTàRS485-àUART

RS485是纯硬件实现的,软件工程师只要关注串口就行,只通过串口将数据发送出去或者接收就可以了,UART转485和485转UART对CPU来说是透明的。

原理图分析:

连接的是UART2,其中的PG8用于控制数据的收发。

默认为接收模式。

功能需求:

默认485芯片是接收功能,每隔1s发送一个0x88,如果接收到0x55那么返回0x01,如果接收到的数据不是0x55就返回0x00。

运行结果:

MODBUS协议

可以基于串口(RS232、RS485和RS422)和以太网。主要分为3类。属于应用层接口。

Modbus ASCII

Modbus TCP/IP

Modbus RTU

关键在于编码和解码的过程。

STM32定时器实验

5种定时器介绍

看门狗定时器(iwdg)

分为独立看门狗和窗口看门狗。用于防止程序跑飞。

systick定时器:操作系统中使用,作为系统运行的滴答时钟。

可以用于产生RTOS的系统滴答时钟。

可以用于裸机程序中的短时间精确延时函数,HAL函数中的延时函数使用的就是这个。

可以用作普通定时器中断功能。

功能强弱分类:高级定时器(tim1-tim8)> 通用定时器(tim2-tim5、tim9-tim14)> 基本定时器(tim6-tim7)

实际开发过程中使用通用定时器就可以。

对于stm32f4定时器来说,具有14个定时器。比较复杂,学习思路如下:

首先学会基本功能的使用。就是定时,定一个时间,时间到就会执行中断服务函数。其他的高级功能可以等以后工作的时候使用到的时候再说。

定时器4实验

选择通用功能定时器进行演示。

timer时钟频率为84MHz:

使能定时器4,预分频系数为4200-1,对应的分频频率为84MHz/4200=20KHz,自动重载值设置为35,得到超时时间1750us。

注意:定时1750us,则计数个数为:1750us/(1/20K)=35

若定时1s,,则计数个数为:1s/(1/20K)=20000

注意:实验过程中,发现这个位置设置成false和true都是可以的。

自动生成代码:

开启定时器中断:MX_TIM4_Init();

基于STM32CubeMX移植freeModbusRTU(从站)

参考教程:https://blog.csdn.net/ASWaterbenben/article/details/105549750

为了简单处理,以串口1为例进行演示。

开启中断:

以定时器4为例,进行演示:

使能定时器4,预分频系数为4200-1,对应的分频频率为84MHz/4200=20KHz,自动重载值设置为35,得到超时时间1750us。

注意:定时1750us,则计数个数为:1750us/(1/20K)-1=35-1=34

打开定时器中断:

配置中断优先级:

配置中断优先级,定时器中断优先级低于串口中断即可

生成代码:

打开freeModbus代码包的demo文件夹,新建一个名为STM32MB的文件夹,之后将BARE文件夹内所有内容复制到STM32MB文件夹下,回到freeModbus代码包,复制整个modbus文件夹也粘贴到STM32MB文件夹内。

将STM32MB文件夹移动到stm32cubeMX生成的工程目录下,如图

打开工程,引入STM32MB内的所有头文件,并新建名为MB和MB_Port的组,MB内添加STM32MB文件夹下modbus文件夹内所有c文件以及根目录的demo.c文件,MB_Port内添加STM32MB文件夹下port文件夹内所有c文件,如图所示

编译报错:

修改demo中的main函数名称为host:

修改MB_Port下的portserial.c文件(串口设置)

其他移植过程省略:

测试:

软件配置:

移植成功:

NodeRed读取:

freertos开发

简介:实时操作系统

可以嵌套中断。

会什么要使用实时操作系统?

原因在于:为了实现多任务。

rtos学习什么?

应用开发,核心是任务创建、IPC、内存管理等。

应用开发(重点)à内核开发

cubemx移植

功能实现:2颗LED以不同频率闪烁。

CMSIS:ARM Cortex微控制器软件接口标准。

use preemption:使用抢占。

max priorities

minimal stack size

idle should yield

use_mutexes

use recursive mutexes:使用递归缩

use counting semaphored:使用计数信号量

queue registry size:队列注册表大小

use application task tag:使用应用程序任务标签

enable backword compatibility:启用向后兼容性

use port optimized task selection:使用端口优化任务选择

use tickless idle: 使用无滴答空闲

内存管理:

use daemon task startup hook:使用守护进程任务启动钩子

check for stack overflow:检查堆栈溢出

generate run time stats:生成运行时统计信息

use trace facility:使用跟踪工具

max co routine priorities:最大协程优先级

interrupt nesting behavior configuration:中断嵌套行为配置

library lowest interrupt priority:库最低中断优先级

message buffer length type:消息缓冲区长度类型

use posix errno:使用 posix 错误号

heap still available

use newlib reentrant:使用 newlib 可重入

一共三个任务:

生成代码:

原来的tick设置:

修改后:

lwip开发

PING功能实现

后面已经说明需要开启中断功能。

auto negotiation:自动协商

duplex mode:双工模式

Isolate phy from mll:从 mll 中分离 phy

 valid link established:建立有效链接

其中Bits4:2就包含了PHY Speed mask和PHY Duplex mask的掩码,

Bits2代表两种速度10MB/s和100MB/s;PHY Speed mask(0x0004)

Bits4代表两种工作方式半双工和全双工;PHY Duplex mask(0x0010)

开启ETH中断:

注意:对于正点原子的板子,需要重映射:

注意PD3引脚的设置:

默认配置如下:

此处需要修改配置:

freeRTOS配置

LWIP配置

生成代码:

实验过程中发现,静态分配的Ip地址,过一会就失效了。

修改操作:

将freertos的标准重新进行修改:其他配置不用修改。

NVIC

嵌套向量中断控制器

起始代码:帮我们建立起来了中断向量表。

外部中断实际编程过程:

1)设置时钟,打开相应GPIO模块时钟。

2)NVIC设置

3)将外部中断线使能触发

4)准备好ISR,在ISR处等待执行中断程序即可。

注意:NVIC和jtag调试并不是属于内部外设,而是属于CPU内部的东西,所以标准库中并不存在对应模块的库文件。

优先级:包含抢占优先级和次优先级,数字越小则优先级越高。

hal库中断检测按键

原理图分析:

取KEY0,PE4做实验。

设置下降沿触发:

配置NVIC设置中断优先级:

STM32的CPU判断优先级的方法如下:

1)先判断抢占优先级,数字越小,优先级越高;

2)若抢占优先级相同,判断子优先级,同样,数字越小,优先级越高;

配置使用中断优先级分组规则NVIC_PriorityGroup_2:

根据中断优先级分组规则NVIC_PriorityGroup_2来设置具体的优先级大小:

生成代码

先打开stm32l4xx_it.c文件:

打开stm32l4xx_hal_gpio.c文件,看一下该函数的原型:

HAL_GPIO_EXTI_Callback(GPIO_Pin);

该函数称为EXIT中断的回调函数,用来处理所有发生的EXIT中断事件。

同样在stm32l4xx_hal_gpio.c文件中找到该函数的原型:

自己实现EXIT中断处理回调函数

放在gpio.c的最后:

编译下载工程:

注意需要给配置为中断检测引脚的初始状态为高电平。否则,实验无效果。

  • 13
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

荒先生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值