历史上的今天
返回首页

历史上的今天

今天是:2024年11月26日(星期二)

正在发生

2021年11月26日 | STM32输入捕获--“PWM输入模式”(可拓展多路同时捕获)

2021-11-26 来源:eefocus

前言

博文基于STM32F103ZET6和标准固件库V3.5.0在MDK5环境下开发;

本博文只讨论输入捕获的PWM输入模式,这个模式是STM32输入捕获检测脉宽和频率的一种硬件处理机制,说白了就是STM32芯片专门用来进行对PWM进行捕获的一个功能;此方法相比较于传统的PWM的捕获方法,大大减小了代码量,提高了检测效率,而实际上对于PWM信号的检测还有其他方法(下面我会介绍,就是原子教程提供的方法),并且关于繁琐的寄存器的介绍这里就不多说了,有兴趣的话可以直接去我的另外一个博客里去看: https://blog.csdn.net/wuyuzun/article/details/73135662 ;(备注:此链接里的博客里有一个配套的例程,例程的思想来自于源子教程,然而本博客是向突出介绍“PWM输入模式”这种我认为更好的方法)

本片博文只介绍单路(一个定时器)的PWM输入模式的,如果想实现多路PWM同时检测,只需要对其他具有输入捕获功能的定时器相同配置即可(我会在另外一个博客里进行介绍);

如有不足之处,多指教;

什么是PWM输入模式以及相应配置流程

在这里插入图片描述

(截图来自《STM32中文参考手册_V10》第216页)

介绍:(我们通过比较原子提供的思路来分析一下“PWM输入模式的比较模式”)

原子的思路:

在这里插入图片描述

如图为某个引脚输入的PWM波,把它分为4~5的阶段进行编程:

① 此时设置好上升沿为触发中断,以及其他定时器配置;

② 此时产生了上升沿,进行捕获操作,CNT内的值捕获到CCR内,此时使CNT=0,CNT继续开始计数;当完成捕获,并且修改捕捉极性为下降沿捕获,当下降沿来到时,将会再次触发此中断函数;

③ 此时产生了下降沿,触发了中断函数;

④ 清0 TIMx_SR寄存器中CCxOF和CCxIF位。


PWM输入模式:

在这里插入图片描述

(图片中为定时器输入捕获模式涉及到的功能模块,来自《STM32中文使用手册》P200页)

如图,举一个输入引脚为例(但是只能举TIMx_CH1和TIMx_CH2,因为TIMx_CH3和TIMx_CH4没有今天所要讨论的PWM输入模式这个功能,),假设这里对TIMx_CH1输入的信号同原子思路中的一样;那么我们同样可以用上面那种图来分析①~⑤五个步骤:

①:配置相对应的输入捕获引脚TIMx_CH1和GPIO管脚的映射关系;

②:选择TIMx_CCR1为有效输入:置TIMx_CCMR1寄存器的CC1S=01(这步的配置决定了此时的CCR1寄存器是输入用的还是输出用的,因为每个可以执行捕获和比较功能的定时器同一时间,只能执行捕获或者输出,两者不能同时进行);

在这里插入图片描述

③:选择TI1FP1的有效极性(用来捕获数据到TIMx_CCR1和清除计数器CNT),置CC1P=0(上升沿有效)

在这里插入图片描述

④:选择TIMx_CCR2的有效输入:置TIMx_CCMR1寄存器的CC2S=10(选中TI1)。(这里是需要特别注意的一个地方,从下图的配置选择或者从上面电路方框图的绿色剪头可以看出来,其实IC1和IC2配置时选择的输入信号都是来自于CH1通道进来的信号)

在这里插入图片描述

⑤:选择TI1FP2的有效极性(捕获CNT的数据到TIMx_CCR2);置CC2P=1(下降沿有效)。(图片参考了CC1P的配置,这里可以注意到一个现象就是IC2选择下降沿触发捕获,而IC1选择的是信号上升沿触发捕获)

在这里插入图片描述

⑥:选择有效的触发输入信号:置TIMx_SMCR寄存器中的TS = 101(选择TI1FP1);

在这里插入图片描述

⑦:配置从模式寄存器为复位模式:置TIMx_SMCR中的SMS=100;(这一步决定每次上升沿出现,CNT就被清零)

在这里插入图片描述

⑧:使能捕获:配置TIMx_CCER寄存器中CC1E=1且CC2E=1;


从波形的角度分析工作原理

在这里插入图片描述

①:在一处完成上述配置(当然,上述的配置只是简单地寄存器配置,并没写中断函数等等,这个工作,可以放在后续):

②:一条路上的CH1,TI1,TI1FP1,TI1FP2的上升沿同时产生,CNT内的值被捕获到了CCR1内并且CNT被清零,从新开始计数;

③:一条路上的CH1,TI1,TI1FP1,TI1FP2的下降沿同时产生,CNT内的值被捕获到了CCR2内,不清零CNT;

④~⑤:在编写的中断函数内即可进行逻辑操作,获取此时CCR1(周期)和CCR2(高电平时间),即可计算占空比 = CCR2/CCR1;

下面即使相对应的代码:


/*---------------PWM输入对应管脚配置-----------------*/

static void PWM_Intput_GPIO_Config(void) 

{

  GPIO_InitTypeDef GPIO_InitStructure;


// TIM1 对应 PA8

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_8;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;  //浮空输入模式;

  GPIO_Init(GPIOA, &GPIO_InitStructure);


}


/*-------------中断嵌套配置------------*/

static void PWM_Intput_NVIC_Config(void)

{

    NVIC_InitTypeDef NVIC_InitStructure; 


    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);

    NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQn;

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

    NVIC_Init(&NVIC_InitStructure);

}


/*-------------TIM1模式配置------------*/

static void PWM_Intput_Mode_Config(void)

{


RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);


/*--------------------时基结构初始化-------------------------*/

TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

TIM_TimeBaseStructure.TIM_Period=0xffff; //ARR=65535us

TIM_TimeBaseStructure.TIM_Prescaler= 72-1; //PSC = 1M = 1us;

TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; //分频因子为0,即不分频;

TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //CNT为向上计数模式;

TIM_TimeBaseStructure.TIM_RepetitionCounter=0;

TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);


/*-------------------输入捕获结构体初始化------------------*/


  TIM_ICInitTypeDef  TIM_ICInitStructure;

  //配置CH1

  TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;

  TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;     //上升沿触发

  TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //IC1直接连接TI1FP1

  TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;           //对输入的PWM信号不分频

  TIM_ICInitStructure.TIM_ICFilter = 0x0;

  TIM_PWMIConfig(TIM1, &TIM_ICInitStructure);

  

  //配置CH2

  TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;

  TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling;      //下降沿触发;

  TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_IndirectTI; //IC2间接连接TI1FP2

  TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //对输入的PWM信号不分频

  TIM_ICInitStructure.TIM_ICFilter = 0x0;

  TIM_PWMIConfig(TIM1, &TIM_ICInitStructure);

  //选择输入捕获的触发信号;

  TIM_SelectInputTrigger(TIM1, TIM_TS_TI1FP1);


  // 选择从模式

  // PWM输入模式时,从模式必须工作在复位模式,当捕获开始时,计数器CNT被复位清零;

  TIM_SelectSlaveMode(TIM1, TIM_SlaveMode_Reset);

  TIM_SelectMasterSlaveMode(TIM1,TIM_MasterSlaveMode_Enable); 


  // 使能捕获中断,这个中断主要针对的是主捕获通道(TI1FP1)

  TIM_ITConfig(TIM1, TIM_IT_CC1, ENABLE);

  // 清除中断标志位

  TIM_ClearITPendingBit(TIM1, TIM_IT_CC1);

  // 计数器开始计数

  TIM_Cmd(TIM1, ENABLE);

}


/*---------------PWM输入对应管脚配置-----------------*/

static void PWM_Intput_GPIO_Config(void) 

{

  GPIO_InitTypeDef GPIO_InitStructure;


// TIM1 对应 PA8

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_8;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;  //浮空输入模式;

  GPIO_Init(GPIOA, &GPIO_InitStructure);


}


/*-------------中断嵌套配置------------*/

static void PWM_Intput_NVIC_Config(void)

{

    NVIC_InitTypeDef NVIC_InitStructure; 


    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);

    NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQn;

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

    NVIC_Init(&NVIC_InitStructure);

}


void TIM1_CC_IRQHandler(void)

{

  uint8_t IC1_CCR1,IC2_CCR2;

  TIM_ClearITPendingBit(TIM1, TIM_IT_CC1);

  IC1_CCR1 = TIM_GetCapture1(TIM1);   //获取周期值CCR1

  IC2_CCR2 = TIM_GetCapture2(TIM1);   //获取高电平时间CCR2

/*逻辑代码*/


}


/*-------------TIM1模式配置------------*/

static void PWM_Intput_Mode_Config(void)

{


RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);


/*--------------------时基结构初始化-------------------------*/

TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

TIM_TimeBaseStructure.TIM_Period=0xffff; //ARR=65535us

TIM_TimeBaseStructure.TIM_Prescaler= 72-1; //PSC = 1M = 1us;

TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; //分频因子为0,即不分频;

TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //CNT为向上计数模式;

TIM_TimeBaseStructure.TIM_RepetitionCounter=0;

TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);


/*-------------------输入捕获结构体初始化------------------*/


  TIM_ICInitTypeDef  TIM_ICInitStructure;

  //配置CH1

  TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;

  TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;     //上升沿触发

  TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //IC1直接连接TI1FP1

  TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;           //对输入的PWM信号不分频

  TIM_ICInitStructure.TIM_ICFilter = 0x0;

  TIM_PWMIConfig(TIM1, &TIM_ICInitStructure);

  

  //配置CH2

  TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;

  TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling;      //下降沿触发;

  TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_IndirectTI; //IC2间接连接TI1FP2

  TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //对输入的PWM信号不分频

  TIM_ICInitStructure.TIM_ICFilter = 0x0;

  TIM_PWMIConfig(TIM1, &TIM_ICInitStructure);

  //选择输入捕获的触发信号;

  TIM_SelectInputTrigger(TIM1, TIM_TS_TI1FP1);


  // 选择从模式

  // PWM输入模式时,从模式必须工作在复位模式,当捕获开始时,计数器CNT被复位清零;

  TIM_SelectSlaveMode(TIM1, TIM_SlaveMode_Reset);

  TIM_SelectMasterSlaveMode(TIM1,TIM_MasterSlaveMode_Enable); 


  // 使能捕获中断,这个中断主要针对的是主捕获通道(TI1FP1)

  TIM_ITConfig(TIM1, TIM_IT_CC1, ENABLE);

  // 清除中断标志位

  TIM_ClearITPendingBit(TIM1, TIM_IT_CC1);

  // 计数器开始计数

  TIM_Cmd(TIM1, ENABLE);

}

推荐阅读

史海拾趣

ASI [ASI Semiconductor, Inc]公司的发展小趣事

随着技术的不断进步和市场的不断扩大,ASI开始积极拓展全球市场。通过设立分支机构和与全球各地的客户建立合作关系,ASI的产品和服务逐渐覆盖了几十个国家。同时,ASI始终坚持以客户为中心的理念,不断提升客户服务的水平和质量。无论是售前咨询、技术支持还是售后服务,ASI都致力于为客户提供最优质、最专业的服务。

CEVA, Inc公司的发展小趣事

CEVA公司在超低功耗技术方面取得了显著突破。公司开发的超低功耗IP包括由专用DSP与AI和其他类型的加速器组成的综合平台。这些加速器针对低功耗工作负载进行了优化,包括5G基带处理、智能视觉、语音识别、物理层处理和传感器融合等。这些技术的突破使得CEVA的产品在保持高性能的同时,能够大幅度降低功耗,满足了市场对节能设备的需求。

Antelec公司的发展小趣事

为了确保产品质量的稳定性和可靠性,Antelec公司高度重视质量管理体系的建设。公司引入了国际先进的质量管理标准,建立了完善的质量管理体系,并不断加强员工的质量意识和技能培训。这些举措使得公司的产品质量得到了持续提升,赢得了客户的广泛认可。

Baton Lock公司的发展小趣事

Baton Lock公司最初是一家小型电子元件制造商,面临着激烈的市场竞争。然而,公司凭借其研发团队对新型半导体技术的深入研究,成功开发出了一种高效能、低成本的芯片。这一技术创新迅速吸引了市场的关注,Baton Lock的订单量激增,公司规模迅速扩大。

Excellence Optoelectronics Inc公司的发展小趣事

在电子行业的早期,Excellence Optoelectronics Inc公司(简称EOI)就致力于LED技术的研发。公司创始人凭借对光电技术的深刻理解和对市场趋势的敏锐洞察,带领团队成功研发出了一系列高性能、高亮度的LED产品。这些产品不仅满足了市场对高品质LED的需求,还为公司赢得了良好的口碑。随着技术的不断进步,EOI不断推出创新产品,逐渐在LED市场中占据了重要地位。

Atmel (Microchip)公司的发展小趣事

2016年,Atmel被美国芯片制造商Microchip以35.6亿美元收购。这一收购事件标志着Atmel发展史上的一个重要转折点。在被收购后,Atmel成为了Microchip的一部分,继续发挥其在微控制器领域的优势,同时也获得了Microchip在技术支持、市场渠道等方面的强大支持。这使得Atmel能够更快地推出新产品、拓展新市场,进一步巩固其市场地位。

问答坊 | AI 解惑

单片机应用技术选编

文件太大了,pdf版本,将近20M,分开传送。…

查看全部问答>

面向未来的IC设计方案

面向未来的IC设计方案随着集成电路制造业的飞速发展,传统的设计方法越来越受到严峻的挑战。每年设计技术的进步大约滞后制造技术20%。在器件的特征线宽进入深亚微米以后,这个矛盾显得越发的突出。主要表现在系统的集成度越来越高,使得单个芯片的 ...…

查看全部问答>

ucf from to 约束

FROM....TO....约束关于from to 的约束是一个比较实用,也比较好用的约束。 尤其在跨时钟域处理中的应用,特别有效。 举例: 设计中有两个时钟,一个是PLL的输入,一个是PLL的输出,当设计中有数据在该两个时钟域中传递时, 又没有用到fifo隔离, ...…

查看全部问答>

请问为什么.out文件无法下载到板子上?

在workbench3.0中建立了一个downloadable Kernel Module Project(一个简单的hello world程序),在vxworks6.x simulator里面运行通过了,也显示了hello world。可是连接8548板子后,选择连接vxworks6.x target server却去下载不进去,显示错误:Po ...…

查看全部问答>

【求助】“阻塞(pend)”与“挂起(suspend)”的区别?

这两个词的英文意思差不多,看孔祥营书也没搞明白这两种任务状态的区别。 google的结果不尽相同。有说阻塞是位于主存,挂起位于外存;有说阻塞占用CPU,挂起不占用CPU…… 书上说:挂起(suspend)状态主要用于调试,不会约束状态转换,仅仅约束 ...…

查看全部问答>

由于PPP没搞出来,刚刚被老板训了,心情很不好,散分!

由于PPP没搞出来,刚刚被老板训了,不过还是要感谢CDSN里帮助过的我人,要不然或者我现在都被老板开了!呵呵!…

查看全部问答>

LoadImage返回失败

CString str = \"D:\\\\zxh\\\\111\\\\res\\\\sa.bmp\"; HBITMAP bim = (HBITMAP)LoadImage(AfxGetInstanceHandle(), str, IMAGE_BITMAP, 0,0,0); if(bim == NULL) {    DWORD errno = GetLastError();    return; } 总 ...…

查看全部问答>

STM32的DFU文件生成方详解

最近好象很多人都在问关于DFU文件的使用问题,正好我们刚研究过,给大家讲讲我们的用法。第一步,准备好要转换的文件,bmp和wav格式,ST原版的DEMO就是这两种格式,后缀改为.bin(也可不改,只是选文件类型过滤选ALL Files(*.*)).第二步 ...…

查看全部问答>

st7LITE05的PLL设置

                                 st7lite05的ST7FLITE05.H头文件中找不到关于PLL的选择字节,请教如何才能解决?如何能实现PLL使cpu工作于8MHz?…

查看全部问答>

DSP菜鸟跪地询问如何学习DSP!!!

应该如何开始学习啊,主要是要做一些工业控制,F2812,是不是从写header file和.cmd文件开始写起?应该如何写呢?望大虾指教 Orz…

查看全部问答>