8、【STM32】定时器(TIM)——中断、PWM、输入捕获实验(一文精通定时器)_tim3->cr1-程序员宅基地

技术标签: stm32  # 一、STM32F407基础教程(寄存器)  TIM  arm  单片机  

目录

前言

理论学习

一、定时器中断

1.1、时基单元包括:

1.2、通用定时器功能

1.3、计数器模式

1.3 相关寄存器

二、定时器PWM输出

2.1、PWM输入模式

2.2、定时器PWM输出

2.3、PWM输出相关寄存器

三、定时器输入捕获

 3.1、简介      

3.2、寄存器配置

3.3、发生输入捕获时:

实战演练 

一、定时器中断配置步骤

1.1、TIM3 时钟设置与使能

1.2、设置  TIM3_ARR 和 TIM3_PSC的值

1.3、设置 TIM3_DIER 允许更新中断

1.4、允许 TIM3 工作(TIM3_CR1)

1.5、TIM3 中断分组与中断服务函数设置

1.6、主函数的编写

二、定时器PWM输出配置步骤

2.1、配置TIM14的输出端口

2.2、设置 TIM14 的 ARR 和 PSC

2.3、TIM14-CH1设置为PWM输出 模式

2.4、TIMx_CR1控制寄存器 1,使能 TIM14

2.5、主函数的编写和占空比控制

三、定时器输入捕获配置步骤

3.1、配置TIM5输入端口

3.2、设置 TIM5 的 ARR 和 PSC

3.3、TIM5-CH1(TI1)设置为输入捕获模式

3.4、设置 TIM5->DIER,使能捕获和更新中断。

3.5、TIMx_CR1控制寄存器 1,使能 TIM5

3.6、设置中断分组及编写中断函数

3.7、输入捕获主函数


前言

使用的是正点原子的探索者开发板进行学习,芯片:STM32F407ZGTx

学习说明此文档为本人的学习笔记,注重实践,关于理论部分会给出相应的学习链接。

本文参考了《正点原子的寄存器开发指南》、《STM32F4参考手册》


 详细介绍的时钟的配置与,定时器时钟如何从时钟树而来的。


理论学习

包括TIM1和TIM8高级控制定时器、TIM2-5和TIM9-14通用定时器、TIM6和TIM7基本定时器。

一、定时器中断

        这里使用的是32的通用定时器,通用定时器包含一个 16 位或 32 位自动重载计数器( CNT),该计数器由可编程预分频器( PSC )驱动。 STM32F4 的通用定时器可以被用于:测量输入信号的脉冲长度 (输入捕获 ) 或者产生输出波形 ( 输出比较和 PWM) 等。 使用定时器预分频器和 RCC 时钟控制器预分频器,脉冲长度和波形周期可以在几个微秒到几个毫秒间调整。 STM32F4 的每个通用定时器都是完全独立的,没有互相共享的任何资源。

1.1、时基单元包括:

  • 计数器寄存器 (TIMx_CNT)
  • 预分频器寄存器 (TIMx_PSC)
  • 自动重载寄存器 (TIMx_ARR)

1.2、通用定时器功能

  • 16 /32 (TIM2 TIM5)向上、向下、向上/向下自动装载计数器(TIMx_CNT),注意:TIM9~TIM14 只支持向上(递增)计数方式。
  • 16 位可编程(可以实时修改)预分频器(TIMx_PSC),计数器时钟频率的分频系数为 165535 之间的任意数值。
  • 4 个独立通道(TIMx_CH1~4TIM9~TIM14 最多 2 个通道),这些通道可以用来作为:
        A.输入捕获
        B.输出比较
        C. PWM 生成 ( 边缘或中间对齐模式 ) ,注意: TIM9~TIM14 不支持中间对齐模式
        D.单脉冲模式输出
  • 4)可使用外部信号(TIMx_ETR)控制定时器和定时器互连(可以用 1 个定时器控制另外一个定时器)的同步电路。
  • 5)如下事件发生时产生中断/DMATIM9~TIM14 不支持 DMA):
        A.更新:计数器向上溢出 / 向下溢出,计数器初始化 ( 通过软件或者内部 / 外部触发 )
        B.触发事件 ( 计数器启动、停止、初始化或者由内部 / 外部触发计数 )
        C.输入捕获
        D.输出比较
        E.支持针对定位的增量 ( 正交 ) 编码器和霍尔传感器电路( TIM9~TIM14 不支持)
        F.触发输入作为外部时钟或者按周期的电流管理( TIM9~TIM14 不支持)

1.3、计数器模式

  • 递增计数模式
        在递增计数模式下,计数器从 0 计数到自动重载值( TIMx_ARR 寄存器的内容),然后重新
0 开始计数并生成计数器上溢事件。每次发生计数器上溢时会生成更新事件,或将 TIMx_EGR 寄存器中的 UG 位置 1(通过软件或使用从模式控制器)也可以生成更新事件。
        发生更新事件时,将更新所有寄存器且将更新标志(TIMx_SR 寄存器中的 UIF 位)置 1 (取
决于 URS 位):
  1. 预分频器的缓冲区中将重新装载预装载值(TIMx_PSC 寄存器的内容)
  2. 自动重载影子寄存器将以预装载值进行更新
  • 递减计数模式
        在递减计数模式下,计数器从自动重载值(TIMx_ARR 寄存器的内容)开始递减计数到 0
然后重新从自动重载值开始计数并生成计数器下溢事件。每次发生计数器下溢时会生成更新事件,或将 TIMx_EGR 寄存器中的 UG 位置 1 (通过软件或使用从模式控制器)也可以生成更新事件
        发生更新事件时,将更新所有寄存器且将更新标志(TIMx_SR 寄存器中的 UIF 位)置 1 (取
决于 URS 位):
  1. 预分频器的缓冲区中将重新装载预装载值(TIMx_PSC 寄存器的内容)。
  2. 自动重载活动寄存器将以预装载值( TIMx_ARR 寄存器的内容)进行更新。注意,自动
    重载寄存器会在计数器重载之前得到更新,因此,下一个计数周期就是我们所希望的新
    的周期长度。
  • 中心对齐模式(递增 / 递减计数)
        在中心对齐模式下,计数器从 0 开始计数到自动重载值( TIMx_ARR 寄存器的内容) — 1
生成计数器上溢事件;然后从自动重载值开始向下计数到 1 并生成计数器下溢事件。之后从 0 开始重新计数。
        发生更新事件时,将更新所有寄存器且将更新标志(TIMx_SR 寄存器中的 UIF 位)置 1 (取
决于 URS 位):
  1. 预分频器的缓冲区中将重新装载预装载值(TIMx_PSC 寄存器的内容)。
  2. 自动重载活动寄存器将以预装载值 ( TIMx_ARR 寄存器的内容)进行更新。注意,如
    果更新操作是由计数器上溢触发的,则自动重载寄存器在重载计数器之前更新,因此,
    下一个计数周期就是我们所希望的新的周期长度(计数器被重载新的值)。

1.3 相关寄存器

  • TIMx_CR1控制寄存器
  • TIMx_DIER中断/DMA使能寄存器
  • TIMx_PSC预分频器
  • TIMx_CNT 计数器(存储计数值)
  • TIMx_ARR自动重装载寄存器

二、定时器PWM输出

2.1、PWM输入模式

此模式是输入捕获模式的一个特例。其实现步骤与输入捕获模式基本相同,仅存在以下不同
之处:
  • 两个 ICx 信号被映射至同一个 TIx 输入。
  • 这两个 ICx 信号在边沿处有效,但极性相反。
  • 选择两个 TIxFP 信号之一作为触发输入,并将从模式控制器配置为复位模式。

2.2、定时器PWM输出

        脉冲宽度调制(PWM) ,是英文“ Pulse Width Modulation ”的缩写,简称脉宽调制,是利用
微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。简单一点,就是对脉冲宽
度的控制。

上图定时器工作在向上计数 PWM模式,当 CNT<CCRx 时,输出 0 ,当 CNT>=CCRx 时输出 1

STM32F4 的定时器除了 TIM6 7。其他的定时器都可以用来产生 PWM 输出。其中高级定时器 TIM1 TIM8 可以同时产生多达 7 路的 PWM 输出。而通用定时器也能同时产生多达 4路的 PWM 输出!这里我们仅使用 TIM14 CH1 产生一路 PWM 输出。

关于PWM在FPGA上的产生更加有助于理解

二、15【FPGA】呼吸灯实现_追逐者-桥的博客-程序员宅基地_fpga 呼吸灯

        脉冲宽度调制模式可以生成一个信号,该信号频率由 TIMx_ARR 寄存器值决定,其占空比则
TIMx_CCRx 寄存器值决定。        
        在 PWM 模式( 1 2 )下, TIMx_CNT 始终与 TIMx_CCRx 进行比较,以确定是TIMx_CCRx TIMx_CNT 还是 TIMx_CNT TIMx_CCRx(取决于计数器计数方向)。不过,为了与 ETRF 相符(在下一个 PWM 周期之前, ETR 信号上的一个外部事件能够清除OCxREF ), OCREF 信号仅在以下情况下变为有效状态:
  • 比较结果发生改变,或 输出比较模式(TIMx_CCMRx 寄存器中的 OCxM 位)从“冻结”配置(不进行比较, OCxM=“000”)切换为任一 PWM 模式(OCxM=110”或“111”)。
定时器运行期间,可以通过软件强制 PWM 输出。根据 TIMx_CR1 寄存器中的 CMS 位状态,定时器能够产生边沿对齐模式或中心对齐模式的PWM 信号。

2.3、PWM输出相关寄存器

除了使用到了定时器中断的那几个寄存器外还用到了以下寄存器

  • TIMx_CCMR1/2捕获 / 比较模式寄存器
  • TIMx_CCER捕获 / 比较使能寄存器
  • TIMx_CCR1~4捕获 / 比较寄存器

三、定时器输入捕获

 3.1、简介      

        输入捕获模式可以用来测量脉冲宽度或者测量频率。我们以测量脉宽为例,用一个简图来
说明输入捕获的原理,如图 15.1.1 所示:

        就是输入捕获测量高电平脉宽的原理,假定定时器工作在向上计数模式,图中 t1~t2 时间,就是我们需要测量的高电平时间。测量方法如下: 首先设置定时器通道 x 为上升沿捕获,这样,t1 时刻,就会捕获到当前的 CNT 值,然后立即清零 CNT,并设置通道 x为下降沿捕获,这样到 t2 时刻,又会发生捕获事件,得到此时的 CNT 值,记为 CCRx2。 这样,根据定时器的计数频率,我们就可以算出 t1~t2 的时间,从而得到高电平脉宽。

        在 t1~t2 之间,可能产生 N 次定时器溢出,这就要求我们对定时器溢出,做处理,防止高电平太长,导致数据不准确。如图15.1.1所示,t1~t2之间,CNT计数的次数等于:N*ARR+CCRx2,有了这个计数次数,再乘以 CNT 的计数周期,即可得到 t2-t1 的时间长度,即高电平持续时间。

        STM32F4 的定时器,除了 TIM6 和 TIM7,其他定时器都有输入捕获功能

3.2、寄存器配置

        在输入捕获模式下,当相应的 ICx 信号检测到跳变沿后,将使用捕获 / 比较寄存器(TIMx_CCRx) 来锁存计数器的值。发生捕获事件时,会将相应的 CCXIF 标志( TIMx_SR 寄存器)置 1 , 并可发送中断或 DMA 请求(如果已使能)。如果发生捕获事件时 CCxIF 标志已处于高位, 则会将重复捕获标志 CCxOF TIMx_SR 寄存器)置 1 。可通过软件向 CCxIF 写入 0 来给
CCxIF 清零,或读取存储在 TIMx_CCRx 寄存器中的已捕获数据。向 CCxOF 写入 0 后会将其清零。
        以下示例说明了如何在 TI1 输入出现上升沿时将计数器的值捕获到 TIMx_CCR1 中。具体操
作步骤如下:
  • 选择有效输入: TIMx_CCR1 必须连接到 TI1 输入,因此向 TIMx_CCMR1 寄存器中的
    CC1S 位写入 01 。只要 CC1S 不等于 00 ,就会将通道配置为输入模式,并且 TIMx_CCR1
    寄存器将处于只读状态。
  • 根据连接到定时器的信号,对所需的输入滤波时间进行编程(如果输入为 TIx 输入之
    一,则对 TIMx_CCMRx 寄存器中的 ICxF 位进行编程)。假设信号变化时,输入信号
    最多在 5 个内部时钟周期内发生抖动。因此, 我们必须将滤波时间设置为大于 5 个内部
    时钟周期 。在检测到 8 个具有新电平的连续采样(以 f DTS 频率采样)后,可以确认 TI1
    上的跳变沿。然后向 TIMx_CCMR1 寄存器中的 IC1F 位写入 0011。
  • 通过向 TIMx_CCER 寄存器中的 CC1P 位和 CC1NP 位写入 0 ,选择 TI1 通道的有效转
    换边沿(本例中为上升沿)。
  • 对输入预分频器进行编程。在本例中,我们希望每次有效转换时都执行捕获操作,因此
    需要禁止预分频器(向 TIMx_CCMR1 寄存器中的 IC1PS 位写入 00 )。
  • 通过将 TIMx_CCER 寄存器中的 CC1E 位置 1 ,允许将计数器的值捕获到捕获寄存器中。
  • 如果需要,可通过将 TIMx_DIER 寄存器中的 CC1IE 位置 1 来使能相关中断请求,并且 /
    或者通过将该寄存器中的 CC1DE 位置 1 来使能 DMA 请求。

3.3、发生输入捕获时:

  • 发生有效跳变沿时, TIMx_CCR1 寄存器会获取计数器的值。
  • CC1IF 标志置 1 (中断标志)。如果至少发生了两次连续捕获,但 CC1IF 标志未被
    清零,这样 CC1OF 捕获溢出标志会被置 1
  • 根据 CC1IE 位生成中断。
  • 根据 CC1DE 位生成 DMA 请求。
        要处理重复捕获,建议在读出捕获溢出标志之前读取数据。这样可避免丢失在读取捕获溢出
标志之后与读取数据之前可能出现的重复捕获信息。
注意: 通过软件将 TIMx_EGR 寄存器中的相应 CCxG 位置 1 可生成 IC 中断和/或 DMA 请求。
需要用到的寄存器有: TIMx_ARR 、 TIMx_PSC、 TIMx_CCMR1 TIMx_CCER TIMx_DIER TIMx_CR1 TIMx_CCR1

实战演练 

一、定时器中断配置步骤

1.1、TIM3 时钟设置与使能

//设置时钟频率:HSE=8M  M=8  N=336 P=2 Q=7
//PLL=HSE/M=1M  PLLCLK=PLL*N/P=168M  USB=PLL*N/Q=48M
Stm32_Clock_Init(336,8,2,7);
  • RCC_CFGR  RCC时钟配置寄存器

 想CFGR[12:10]位写5,即4分频,因此APB1=PLLCLK/4=42M

RCC->CFGR|=(0<<4)|(5<<10)|(4<<13);

  • TIM3 时钟使能

TIM3挂载在APB1时钟总线上,

TIM3由于在配置APB1的时候使用了4分频,所以定时器进行了2倍频,为84MHz。 

RCC->APB1ENR |= 1<<1;

1.2、设置  TIM3_ARR 和 TIM3_PSC的值

时间计算公式:Tout =  ( (arr+1) * (psc+1) )  /  Tclk;

Tclk:TIM3 的输入时钟频率(单位为 Mhz)
Tout:TIM3 溢出时间(单位为 us)
TIM3->ARR=arr;        //设置TIM3的自动装载值
TIM3->PSC=psc;        //预分频器设置

1.3、设置 TIM3_DIER 允许更新中断

TIM3->DIER|=1<<0;

1.4、允许 TIM3 工作(TIM3_CR1)

TIM3->CR1|=0x01; 

 使能定时计数器器,且为递增计数

1.5、TIM3 中断分组与中断服务函数设置

  • 中断分组,TIM3优先级配置
MY_NVIC_Init(1,3,TIM3_IRQn,2);
  • 编写中断服务函数

TIMX-SR状态寄存器:

void TIM3_IRQHandler(void)
{ 		    		  			    
	if(TIM3->SR&0X0001)    //中断发生,最低位由硬件置1
	{
		LED1=!LED1;			    				   				     	    	
	}				   
	TIM3->SR&=~(1<<0);      //必须将最低位软件置0,等待下次中断的到来
}

1.6、主函数的编写

TIM(定时器)=84MHz       psc(分频系数)=8400     arr(重装在值)=5000

定时器计数频率 = 84MHz / 8400 =10KHz

Tout = 5000 / 10KHz = 0.5s

int main(void)
{  
	Stm32_Clock_Init(336,8,2,7);  //pll=1M pllclk=168M 
	delay_init(168);			
	LED_Init();		  			
 	TIM3_Int_Init(5000-1,8400-1);  //arr psc
	while(1)
	{
		LED0=!LED0;
		delay_ms(200);
	};
}

二、定时器PWM输出配置步骤

2.1、配置TIM14的输出端口

TIM14这里我们还要配置 PF9 为复用( AF9 )输出,才可以实现 TIM14_CH1的 PWM 经过 PF9 输出。
RCC->APB1ENR|=1<<8;    //使能TIM13定时器的时钟
RCC->AHB1ENR|=1<<5;    //使能端口FA9的端口时钟
GPIO_Set(GPIOF,PIN9,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_PU);
GPIO_AF_Set(GPIOF,9,9);	//PF9,AF9 

2.2、设置 TIM14 ARR PSC

TIM14->ARR=arr;          //重装载值
TIM14->PSC=psc;          //分频系数

2.3、TIM14-CH1设置为PWM输出 模式

TIM14-CCMR1捕获比较寄存器1相关位描述

 TIMx_CCER捕获/比较使能寄存器相关位描述

TIM14->CCMR1|=6<<4;    //打开TIM14的CH1
TIM14->CCMR1|=1<<3;    //使能与 TIM14_CCR1 相关的预装载寄存器
TIM14->CCER|=1<<0;     //下降沿触发,低电平有效
TIM14->CCER|=1<<1;     //使能CH1输出

2.4、TIMx_CR1控制寄存器 1,使能 TIM14

TIMx_CR1控制寄存器 1的相应位配置

TIM14->CR1|=1<<7;    //自动装载进行缓存
TIM14->CR1|=1<<0;    //定时计数器使能

2.5、主函数的编写和占空比控制

TIMx_CCR1捕获 / 比较寄存器 1相应位配置

#define LED0_PWM_VAL TIM14->CCR1    
int main(void)
{  
	u16 led0pwmval=0;              //TIM14-CCR1的值,及占空比的计数值
	u8 dir=1;
	Stm32_Clock_Init(336,8,2,7);    
	delay_init(168);			
 	TIM14_PWM_Init(500-1,84-1);	   //1MHz的计数频率,PWM频率2KHz,  T=0.5ms
   	while(1)
	{
 		delay_ms(10);	            //10ms重载一次占空比,20次PWM的输出
		if(dir)led0pwmval++;        //占空比增加
		else led0pwmval--;	        //占空比减小
 		if(led0pwmval>300)dir=0;    
		if(led0pwmval==0)dir=1;	
		LED0_PWM_VAL=led0pwmval;    //重新装载占空比值
	}
}

三、定时器输入捕获配置步骤

3.1、配置TIM5输入端口

捕获TIM5_CH1 上面的高电平脉宽,所以先配置 PA0 为带下拉的复用功能,PA0 的复用功能为 AF2。
RCC->APB1ENR|=1<<3;   	
RCC->AHB1ENR|=1<<0;   
GPIO_Set(GPIOA,PIN0,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_PD);
GPIO_AF_Set(GPIOA,0,2);	//PA0,AF2 (TIM5-CH1)

3.2、设置 TIM5 ARR PSC

计数分频系数与计数器数设置,在定时器中断有相关描述

TIM5->ARR=arr;
TIM5->PSC=psc;

3.3、TIM5-CH1(TI1)设置为输入捕获模式

TIM5-CCMR1捕获比较寄存器1相关位描述

TIM5_CCER捕获/比较使能寄存器相关位描述

TIM5->CCMR1|=1<<0;	     //CCIS位,将CC1设置成输入且映射到TI1
TIM5->CCMR1|=0<<4; 	     //IC1PSC,无分频
TIM5->CCMR1|=0<<10;      //IC1F,无滤波器
TIM5->CCER|=0<<1;        //CC1P,无反向,上升沿触发
TIM5->CCER|=1<<0;        //CC1E,使能输入捕获

3.4、设置 TIM5->DIER,使能捕获和更新中断。

TIM5->DIER|=1<<1; 
TIM5->DIER|=1<<0; 
//设置软件控制产生更新事件,是载入PSC值立刻生效,否则要等到溢出后才生效
TIM5->EGR=1<<0;

3.5、TIMx_CR1控制寄存器 1,使能 TIM5

TIM5->CR1|=0x01; 

3.6、设置中断分组及编写中断函数

MY_NVIC_Init(2,0,TIM5_IRQn,2)
u8  TIM5CH1_CAPTURE_STA=0;		     //捕获标志0x40上升沿捕获,0x80下降沿捕获			
u32	TIM5CH1_CAPTURE_VAL;	         //捕获计数值存储空间
void TIM5_IRQHandler(void)
{ 		    
	u16 tsr;
	tsr=TIM5->SR;                    //定时器状态寄存器
 	if((TIM5CH1_CAPTURE_STA&0X80)==0)                     //捕获未完成
	{
		if(tsr&0X01)                                      //定时器溢出标志
		{	     
			if(TIM5CH1_CAPTURE_STA&0X40)                  //上升沿被捕获到后
			{
				if((TIM5CH1_CAPTURE_STA&0X3F)==0X3F)      //达到计数器溢出值 
				{
					TIM5CH1_CAPTURE_STA|=0X80;		      //标记捕获到了一个定时计数器周期
					TIM5CH1_CAPTURE_VAL=0XFFFFFFFF;       //保存一个完成的计数周期
				}else TIM5CH1_CAPTURE_STA++;              //计数器未溢出
			}	 
		}
		if(tsr&0x02)                                  //发生上升沿捕获事件进入中断                
		{	
			if(TIM5CH1_CAPTURE_STA&0X40)		    //上升沿捕获已完成,下降沿捕获中断进入
			{	  			
				TIM5CH1_CAPTURE_STA|=0X80;		    //已经捕获到下降沿标志
			    TIM5CH1_CAPTURE_VAL=TIM5->CCR1;	    //储存捕获计数器值
	 			TIM5->CCER&=~(1<<1);			    //设置为上升沿捕获进入中断
			}else  						             //将计数器清零,重新计数		
			{
				TIM5CH1_CAPTURE_STA=0;		        
				TIM5CH1_CAPTURE_VAL=0;
				TIM5CH1_CAPTURE_STA|=0X40;		    //已经捕获到上升沿标志
				TIM5->CR1&=~(1<<0);    	            //使能定时器
	 			TIM5->CNT=0;					    //清空计数器
	 			TIM5->CCER|=1<<1; 			        //设置为下降沿捕获进入中断
				TIM5->CR1|=0x01;    			    //开启定时器
			}		    
		}			     	    					   
 	}
	TIM5->SR=0;  
}

3.7、输入捕获主函数

extern u8  TIM5CH1_CAPTURE_STA;		
extern u32	TIM5CH1_CAPTURE_VAL;	
int main(void)
{  
	long long temp=0;  
	Stm32_Clock_Init(336,8,2,7);
	delay_init(168);			
	uart_init(84,115200);		
 	TIM14_PWM_Init(500-1,84-1);	
 	TIM5_CH1_Cap_Init(0XFFFFFFFF,84-1);
   	while(1)
	{
 		delay_ms(10);
		LED0_PWM_VAL++;
		if(LED0_PWM_VAL==300)LED0_PWM_VAL=0;
 		if(TIM5CH1_CAPTURE_STA&0X80)         //捕获到了一个定时器计数周期或者下降沿
		{
			temp=TIM5CH1_CAPTURE_STA&0X3F;   //提取捕获值
			temp*=0XFFFFFFFF;		 		 //计算捕获时间
			temp+=TIM5CH1_CAPTURE_VAL;		 //加入定时器周期时间和下降沿捕获时间
			printf("HIGH:%lld us\r\n",temp); //输出捕获总时间
			TIM5CH1_CAPTURE_STA=0;			 //将捕获标志位清0,进入下一次捕获
		}
	}
}

输入捕获功能应用

        电容触摸按键:电容按键是接触式的,点一下就松开(与微动开关类似),因此需要消除抖。在之前的微动开关使用时间延迟判断两次,状态相同时才认为是按下。这里同理,这里使用的是输入捕获即手指接触一定时间后到达B认为电容按键按下。

 正点原子中的文档内容描述:

 对于电容按键用的不是特别多,这里不进行实验,有需要的可以自己去看一下正点原子的相关实验。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/ARM_qiao/article/details/125375663

智能推荐

滑动窗口协议(GBN, SR)_gbn协议-程序员宅基地

文章浏览阅读2.5w次,点赞30次,收藏189次。文章目录前言一、流水线协议二、滑动窗口协议1.GBN(回退N重传协议)2.SR(选择重传协议)总结前言提示:以下是本篇文章正文内容一、流水线协议我们知道Rdt 3.0: 停等操作过程中浪费了大量的时间:从而在Rdt 3.0上引入了流水线机制:为了提高资源利用率流水线协议:允许发送方在收到ACK之前连续发送多个分组,更大的序列号范围,同时发送方和/或接收方需要更大的存储空间以缓存分组如图:二、滑动窗口协议滑动窗口协议:发送方和接收方各有一个缓存数组,发送方存放着:已发送且.._gbn协议

写给学生看的系统分析与验证笔记(十三)——线性时序逻辑(Linear temporal logic,LTL)-程序员宅基地

文章浏览阅读6.5k次,点赞8次,收藏51次。线性时序逻辑提供了一种非常直观但是在数学上又很精确的表示方法来描述LT性质,70年代后期,Pnueli提出将线性时序逻辑应用于验证复杂计算机系统。_线性时序逻辑

mavros和PX4中的海拔高与椭球高转换_椭球高转换海拔高-程序员宅基地

文章浏览阅读976次,点赞19次,收藏20次。同一个位置的两种高度值一般可以相差几十米,只是因为当地平均海平面是和地形有关的,凹凸不平没有规律。而ellipsoid height采用的基准是地球标准椭球模型,它的高度值和地形没有关系,只和到地心的距离有关。下文的mavros指ros1 noetic版本的,ros2版本的我还没研究。_椭球高转换海拔高

matlab模拟gpd,GPD WIN1流畅玩游戏之DOS游戏,阿猫阿狗大作战 大宇16个DOS游戏全合集...-程序员宅基地

文章浏览阅读1.3k次。提取码: 2i5t++++++++++++++++++++收集了大宇的16个DOS游戏,WIN10可以直接玩,具体的都忘记了,有轩辕剑什么的但是阿猫阿狗大作战这个游戏画风可是真喜欢!!非常喜欢,这里就放出来给大家共享了。+++++++++++++++++++++++++++++++++++++++++《阿猫阿狗大作战Online》是由大宇集团旗下的上海软星于2005年研发的新一代3D休闲类网络对战..._win10 64位 怎么运行阿猫阿狗1

AutoHotkey博客转Markdown-程序员宅基地

文章浏览阅读211次,点赞10次,收藏2次。本文使用AutoHotkey定义快捷键打开对话框,用户粘贴博客地址,通过命令行调用clean-mark将网页博客转为Markdown文件。

一文读懂Python复杂网络分析库networkx | CSDN博文精选-程序员宅基地

文章浏览阅读2.5k次,点赞5次,收藏42次。作者 |yyl424525来源 | 程序员宅基地文章目录1. 简介安装支持四种图绘制网络图基本流程2. Graph-无向图节点边属性有向图和无向图互转3. DiGrap..._多层复杂网络 绘制

随便推点

(有码)UIView常用方法_有码 插入-程序员宅基地

文章浏览阅读356次。UIView//建立父子关系时,父视图,会保存一个子视图的强指针[self.view addSubView:view];//将视图插入到指定位置[self.view insertSubview:view addIndex:2];//将视图插入到指定视图的下面[self.view insertSubview:subView belowSubview:view]_有码 插入

Linux进程的软中断通信(signal和kill)_进程软中断通信-程序员宅基地

文章浏览阅读9.4k次,点赞44次,收藏216次。Linux的进程软中断通信一、软中断信号二、函数介绍(1)wait函数(2)signal函数(3)sleep函数(4)kill函数三、示例一、软中断信号软中断信号(signalsignalsignal,又简称为信号)用来通知进程发生了事件。进程之间可以通过调用kill函数发送软中断信号。LinuxLinuxLinux 内核也可能给进程发送信号,通知进程发生了某个事件(例如内存越界)。注意:信号只是用来通知某进程发生了什么事件,无法给进程传递任何数据,进程对信号的处理方法有三种:① 忽略某个信号,对该_进程软中断通信

java计算机毕业设计定西扶贫惠农推介系统源码+数据库+系统+lw文档+部署_基于java的西部惠农平台实验报告-程序员宅基地

文章浏览阅读94次。java计算机毕业设计定西扶贫惠农推介系统源码+数据库+系统+lw文档+部署。springboot疫情期间中小学生作业线上管理系统设计与实现。ssh基于java的网上手机销售管理系统的开发与实现mysql。springboot基于JSP的企业办公管理系统设计与实现。springboot校园二手电动车交易平台的设计与实现。JSP网上商城与拍卖系统的设计与实现sqlserver。JSP宠物食品店系统的设计与实现sqlserver。springboot基于智慧推荐的在线教育管理系统。_基于java的西部惠农平台实验报告

Proxmox VE 6.0管理指南——3.主机系统管理_未启用proxmox ve存储库-程序员宅基地

文章浏览阅读1w次。3.主机系统管理Proxmox VE基于著名的DebianLinux发行版。这意味着您可以访问Debian软件包的整个领域,并且基本系统的文档记录非常详尽。在Debian的管理员手册可在网上,并提供了一个全面介绍了Debian的操作系统(请参阅[Hertzog13])。标准的Proxmox VE安装使用De​​bian的默认存储库,因此您可以通过该渠道获得错误修复和安全更新。此..._未启用proxmox ve存储库

JAVA的数据类型_java数据类型-程序员宅基地

文章浏览阅读426次。Java的数据类型包括基本数据类型和引用数据类型。基本数据类型有byte、short、int、long、float、double、char和boolean,用于处理简单类型的数据。引用数据类型有class、interface和array,用于处理复杂类型的数据。在程序开发中,应根据具体情况选择合适的数据类型,以实现数据存储和计算的需要。_java数据类型

latex中如何正确输入 双引号_latex 双引号-程序员宅基地

文章浏览阅读9.6w次,点赞50次,收藏30次。latex中输入双引号时,如果都直接用键盘上的双引号键,打出的是一顺撇的。左面引号的正确输入法是:按两次“Tab上面,数字1左面那个键”。至于后边的引号,与老方法是一样的,即按两次单引号键(或一次SHIFT+单引号键---也就是一次双引号键啦怎么输入左单引号、左双引号、右单引号、有双引号?左单引号:`(键盘上1旁边的那个);左双引号:``;右单引号:'(键盘分号的右边那个);右双引号:''或"。在_latex 双引号

推荐文章

热门文章

相关标签