stm32输入捕获,捕获高电平

发布者:Changfeng520最新更新时间:2019-09-05 来源: eefocus关键字:stm32  输入捕获  捕获高电平 手机看文章 扫描二维码
随时随地手机看文章

输入捕获就是用定时器检测引脚上的电平时间,可以检测高电平时间和低电平时间,然后可以算引脚上信号的频率和占空比。


基本思路就是利用定时器的输入捕获功能。


定时器捕获到高电平或低电平就会进入捕获中断


例如:


我们要捕获高电平时间


0 设置定时器计数频率和装载值,一般设置1MHz,65535


1 设置定时器捕获为高电平捕获


2 进入捕获中断后,获取CNT计数值或CCRx值,定时器捕获到电平后会把CNT的值保存到CCRx。


   设置成低电平捕获。


3 再次进入捕获中断,获取CNT计数值-上次的CNT值=总高电平时间。


   设置成高电平捕获。


4 重复2-3即可完成下一次捕获。当然还要考虑溢出的情况,代码里有处理。


下面我写的一个实例:


1 定时器1 PA8产生PWM信号,可改变占空比,检测高电平时间


2 捕获定时器是定时器2,初始化如上例。


3 仿真改变PA8占空比,查看捕获出的高电平时间。


实测:


duty=1000就是高电平维持1000us,


捕获时间也是对应的1000us,一点误差都没有。


代码如下:


//高电平标志

u8  gao_flag=0;

//高电平时间

u32 gao_timer=0;

//捕获成功标志

u8  buhuo_flag=0;

//溢出次数

u8  yichu_c=0;

 

//定时器 5 中断服务程序

extern "C" void TIM2_IRQHandler(void)

{

  if((TIM2CH1_CAPTURE_STA&0X80)==0)//还未成功捕获

   {

 

 

if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) //这个是溢出中断

{

//如果已经得到高电平了,CNT溢出了

if(gao_flag==1)

{

 

yichu_c++;  //溢出加1

 

}

 

}

 

if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET)//捕获 1 发生捕获事件

{

  if(0==gao_flag&&buhuo_flag==0) //说明之前没有捕获到高电平

{

gao_timer=TIM2->CCR1;  //获取高电平时间

 

yichu_c=0;       //溢出清零

gao_flag=1; //高电平标志

TIM_OC1PolarityConfig(TIM2,TIM_ICPolarity_Falling); //改成下降沿捕获

}

//再一次进入捕获中断说明是捕获到下降沿了

else

{

if(buhuo_flag==0)   //判断是否捕获成功了,如果捕获成功了就不在捕获了

{

gao_timer=TIM2->CCR1-gao_timer;  //获取捕获到的高电平时间

gao_timer+=yichu_c*65536;       //加上溢出时间

 

TIM2->CNT=0; //计数清零

gao_flag=0;                   //高电平标志清零

buhuo_flag=1;             //标志捕获成功了

TIM_OC1PolarityConfig(TIM2,TIM_ICPolarity_Rising); //改成上沿捕获

}

}

 

}

}

TIM_ClearITPendingBit(TIM2, TIM_IT_CC1|TIM_IT_Update); //清除中断标志位

}

 

void TIM1_PWM_Init(u16 arr,u16 psc)

{

GPIO_InitTypeDef     GPIO_InitStrue;

    TIM_OCInitTypeDef     TIM_OCInitStrue;

    TIM_TimeBaseInitTypeDef     TIM_TimeBaseInitStrue;

    

    

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);        //使能TIM3和相关GPIO时钟

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);// 使能GPIOB时钟(LED在BP5引脚),使能AFIO时钟(定时器3通道2需要重映射到BP5引脚)

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);

    

    GPIO_InitStrue.GPIO_Pin=GPIO_Pin_8;     // TIM_CH2

    GPIO_InitStrue.GPIO_Mode=GPIO_Mode_AF_PP;    // 复用推挽

    GPIO_InitStrue.GPIO_Speed=GPIO_Speed_50MHz;    //设置最大输出速度

    GPIO_Init(GPIOA,&GPIO_InitStrue);                //GPIO端口初始化设置

    

//TIM1->CCMR1&=0xF7F7; //关闭事件更新值

//TIM1->CCMR1|=0x808; //开启事件更新值

 

    TIM_TimeBaseInitStrue.TIM_Period=50000;    //设置自动重装载值

    TIM_TimeBaseInitStrue.TIM_Prescaler=71;        //预分频系数

    TIM_TimeBaseInitStrue.TIM_CounterMode=TIM_CounterMode_Up;    //计数器向上溢出

    TIM_TimeBaseInitStrue.TIM_ClockDivision=TIM_CKD_DIV1;        //时钟的分频因子,起到了一点点的延时作用,一般设为TIM_CKD_DIV1

    TIM_TimeBaseInit(TIM1,&TIM_TimeBaseInitStrue);        //TIM3初始化设置(设置PWM的周期)

    

    TIM_OCInitStrue.TIM_OCMode=TIM_OCMode_PWM2;        // PWM模式2:CNT>CCR时输出有效

    TIM_OCInitStrue.TIM_OCPolarity=TIM_OCPolarity_Low;// 设置极性-有效为高电平

    TIM_OCInitStrue.TIM_OutputState=TIM_OutputState_Enable;// 输出使能

TIM_OCInitStrue.TIM_Pulse=100;

    TIM_OC1Init(TIM1,&TIM_OCInitStrue);        //TIM3的通道2PWM 模式设置

 

    TIM_OC1PreloadConfig(TIM1,TIM_OCPreload_Enable);        //使能预装载寄存器

    

    TIM_Cmd(TIM1,ENABLE);        //使能TIM3

TIM_CtrlPWMOutputs(TIM1, ENABLE);  

TIM1->CCMR1&=0xF7F7; //关闭事件更新值

}

 

void capture_init(u16 arr,u16 psc)

{

TIM_OCInitTypeDef TIM2_OCInitStructure;

TIM_ICInitTypeDef TIM2_ICInitStructure;

GPIO_InitTypeDef GPIO_InitStructure;

TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

NVIC_InitTypeDef NVIC_InitStructure;

 

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //使能 TIM2 时钟

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能 GPIOA 时钟

 

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //PA0 清除之前设置

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //PA0 输入

GPIO_Init(GPIOA, &GPIO_InitStructure);

GPIO_ResetBits(GPIOA,GPIO_Pin_0); //PA0 下拉

 

//初始化定时器 2 TIM2

TIM_TimeBaseStructure.TIM_Period = arr; //设定计数器自动重装值

TIM_TimeBaseStructure.TIM_Prescaler =psc; //预分频器

TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割

TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数

TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //初始化 TIMx 的时间基数单位

 

//初始化 TIM2 输入捕获参数

 

TIM2_ICInitStructure.TIM_Channel = TIM_Channel_1; //选择输入端 IC1 映射到 TI1 上

TIM2_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //上升沿捕获

TIM2_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到 TI1 上

TIM2_ICInitStructure.TIM_ICPrescaler = TIM_CKD_DIV1; //配置输入分频,不分频

TIM2_ICInitStructure.TIM_ICFilter = 0x00;//IC1F=0000 配置输入滤波器 不滤波

TIM_ICInit(TIM2, &TIM2_ICInitStructure);

 

 

//中断分组初始化

NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; //TIM2 中断

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //先占优先级 2 级

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //从优先级 0 级

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ 通道被使能

NVIC_Init(&NVIC_InitStructure); //初始化外设 NVIC 寄存器

TIM_ITConfig(TIM2,TIM_IT_Update|TIM_IT_CC1,ENABLE);

 

TIM_Cmd(TIM2,ENABLE ); //使能定时器3

}

 

u16 duty=1000;

 

int main(void)

{

 

   

   serial_init(115200); //串口初始化为 9600

   

   TIM1_PWM_Init(1000,71); //

PAout(1)=1;

   capture_init(0XFFFF,72-1); //以 1Mhz 的频率计

printf("initrn");

  while(1)

   {

 

//测试位运算和逻辑运算的速度

 

PAout(1)=1;

  

 

 

TIM1->CCR1=duty;

 

    delay_ms(10);

 

if(buhuo_flag==1)

{

printf("HIGH1:%d us rn",gao_timer); //打印总的高点平时间

buhuo_flag=0;  //重新捕获

}

PAout(1)=0;

  delay_ms(10);

 

   }

 

}



关键字:stm32  输入捕获  捕获高电平 引用地址:stm32输入捕获,捕获高电平

上一篇:STM32 I/O口不能正常输出高低电平问题的解决方案
下一篇:判断STM32 GPIO输入口的输入状态(高电平或低电平)

推荐阅读最新更新时间:2024-11-09 12:01

stm32ad采样测电压范围
AD(模拟数字)转换模块是嵌入式系统中经常使用的一个功能模块,它可以将模拟电压信号转换成数字信号,以便后续处理。在STM32系列微控制器中,AD采样测电压范围是一个重要的参数,它决定了我们可以测量的电压的范围。在本文中,我们将详细介绍STM32AD采样测电压范围及其相关的知识。 一、STM32AD转换模块简介: STM32系列微控制器广泛应用于各种嵌入式系统中,其中的AD转换模块被用于测量电压信号。STM32的AD转换模块具有以下特点: 多通道:STM32的AD转换模块通常具有多个输入通道,可以同时对多个模拟信号进行采样。 高分辨率:STM32的AD转换模块通常具有12位或16位的分辨率,可以实现较高的精度。 快速转换速
[单片机]
stm32的IO模式具体意义
Ⅰ、写在前面 在开发STM32的时候,都需要对IO的模式进行配置(GPIO_InitStructure. GPIO_Mode = xxx)。但是,你们都知道各种模式的具体意义吗? 有的人问:IO口输出可以上拉吗? 开漏输出是干什么用的? 其实这些问题并不难,只要你了解到每一种模式的真正意思,相信这些问题都不会难道你。本文的内容比较基础,也比较实用,希望对你有所帮助。 关于本文的详细内容请看下面章节 Ⅱ、模式说明 STM32芯片的IO有8中模式: (1)GPIO_Mode_AIN 模拟输入 (2)GPIO_Mode_IN_FLOATING 浮空输入 (3)GPIO_Mode_IPD 下拉输入 (4)GPIO_Mode_IPU 上
[单片机]
<font color='red'>stm32</font>的IO模式具体意义
STM32 DMA简述
STM32 DMA简述 **DMA (Direct Memory Access) ** 直接内存存储器,在做数据传输时能够大大减轻CPU的负担。 DMA的作用 DMA提供了一个关于数据的高数传输通道,这个通道不占用CPU的资源。换句话说,通过DMA通道,你在传输大规模数据的时候CPU同时也能够去干其他事。 你可以控制DMA通道的接入口,灵活配置传输的数据源和目的地。以下几个是常用的DMA传输路径: 从外设到内存 从内存A区域传到内存B区域 从一个外设传输到另一个外设 从内存传输数据到外设 .... DMA流程分析 在stm32中,DMA是以类似外设的形式添加到内核之外的,下面我们来看具体的框图: 从上图我们可以看到,DMA通过
[单片机]
stm32 常量 指定位置_STM32寄存器讲解
原理讲解芯片讲解STM32F103芯片 我们看到的 STM32 芯片是已经封装好的成品,主要由内核和片上外设组成。若与电脑类比,内核与外设就如同电脑上的 CPU与主板、内存、显卡、硬盘的关系。 STM32F103采用的是 Cortex-M3内核,内核即 CPU,由 ARM公司设计。ARM公司并不生产芯片,而是出售其芯片技术授权。芯片生产厂商(SOC)如 ST、TI、Freescale,负责在内核之外设计部件并生产整个芯片,这些内核之外的部件被称为核外外设或片上外设。如 GPIO、USART(串口)、I2C、SPI等都叫做片上外设。(采用野火官方的介绍)。 芯片(这里指内核,或者叫 CPU)和外设之间通过各种总线连接,其中驱动
[单片机]
<font color='red'>stm32</font> 常量 指定位置_<font color='red'>STM32</font>寄存器讲解
基于AD9854与STM32设计的频率特性测试仪
随着现代电子技术的飞速发展,频率特性测试仪作为现代电子测量领域的一种重要工具,其设计理念也在不断地革新。频率特性测试仪是一种测试网络或者电路的频率特性的仪器,又称扫频仪;可以用来测量信号传输网络、信号放大电路及滤波电路等双端口网络的幅频特性与相频特性。由于在传统的扫频仪设计方法中,被测网络幅频特性与相频特性的获取,需要通过不同的电路模块分别进行峰值检测与相位差测量,导致其系统由多个模块构成,电路复杂且体积较大。因此本文设计了一种新的频率特性测试仪,其采用直接频率合成(DDS)芯片AD9854产生正交扫频信号,并以低功耗单片机STM32作为任务控制与数据处理的核心部件。 1.总体方案 该频率特性测试仪的设计基于零中频正交解调原
[单片机]
基于AD9854与<font color='red'>STM32</font>设计的频率特性测试仪
006_STM32程序移植之_SYN6288语音模块
1. 测试环境:STM32C8T6 2. 测试模块:SYN6288语音模块 3. 测试接口: SYN6288语音模块: VCC------------------3.3V GND------------------GND TXD-----------------PB11 RXD-----------------PB10 BY------------------PB1 2. 串口使用串口一,波特率9600 单片机引脚------------CH340引脚 VCC--------------------VCC GND-------------------GND PA9--------------------RXD PA10------
[单片机]
006_STM32程序移植之_SYN6288语音模块
stm32 DMA 多通道数据采集
程序如下: /******************** (C) COPYRIGHT 2012 *************************** * 文件名 :adc.c * 描述 :adc应用函数库 * 库版本 :ST3.5.0 **********************************************************************************/ #include bsp.h #define ADC1_DR_Address ((u32)0x40012400+0x4c) __IO uint16_t ADC_ConvertedValue ; //__IO
[单片机]
STM32时钟源
PLLK,SYSK,HCKL,PK1,PK2 之间的关系要弄清楚; 1、HSI:高速内部时钟信号 stm32单片机内带的时钟 (8M频率) 精度较差 2、HSE:高速外部时钟信号 精度高 来源(1)HSE外部晶体/陶瓷谐振器(晶振) (2)HSE用户外部时钟 3、LSE:低速外部晶体 32.768kHz 主要提供一个精确的时钟源 一般作为RTC时钟使用 在STM32中,有五个时钟源,为HSI、HSE、LSI、LSE、PLL。   ①、HSI是高速内部时钟,RC振荡器,频率为8MHz。   ②、HSE是高速外部时钟,可接石英/陶瓷谐振器,或者接外部时钟源,频率范围为4MHz~16MHz。   ③、LSI是低速内部时钟,RC振荡器
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved