历史上的今天
今天是:2025年02月09日(星期日)
2020年02月09日 | STM8L101F3输入捕获测脉宽及占空比
2020-02-09 来源:eefocus
近期空闲时做了一个STM8L101芯片的PWM检测程序,在此发表个人见解。
预备知识:
STM8L库函数的使用、STM8L定时器的使用,相关资料自行百度
目标:通过TIM3输出PWM波,将输出的波输入至TIM2的捕获通道。
好了,接下来进入正题。
STM8L10X的定时器的功能比较丰富,而且价格低廉,做输入捕获还是挺好的
首先介绍一个STM8L101X固件库的一个函数,在固件库的
line 444 of file stm8l10x_tim2.c.
TIM2_PWMIConfig是专门用来配置PWM输入模式的库函数,网上关于此处的介绍比较少,这里简要介绍并应用
该函数原型如下:
00420 /**
00421 * @brief Configures the TIM2 peripheral in PWM Input Mode according to the
00422 * specified parameters.
00423 * @param TIM2_Channel: TIM2 Channel 输入捕获的通道
00424 * This parameter can be one of the following values:
00425 * @arg TIM2_Channel_1: Channel 1
00426 * @arg TIM2_Channel_2: Channel 2
00427 * @param TIM2_ICPolarity: Input Capture Polarity PWM开始的极性,可选为上升沿/下降沿
00428 * This parameter can be one of the following values:
00429 * @arg TIM2_ICPolarity_Rising: Input Capture on Rising Edge
00430 * @arg TIM2_ICPolarity_Falling: Input Capture on Falling Edge
00431 * @param TIM2_ICSelection: Input Capture Selection 输入通道与捕获通道的连接,此处
TIM2_ICSelection_DirectTI表示捕获通道1与输入通道1连接
TIM2_ICSelection_IndirectTI表示捕获通道1与输入通道2连接
第三个值好像是与另外一个管脚连接,应该是TRGI
00432 * This parameter can be one of the following values:
00433 * @arg TIM2_ICSelection_DirectTI: Input Capture mapped on the direct input
00434 * @arg TIM2_ICSelection_IndirectTI: Input Capture mapped on the indirect input
00435 * @arg TIM2_ICSelection_TRGI: Input Capture mapped on the Trigger Input
00436 * @param TIM2_ICPrescaler: Input Capture Prescaler 分频,表示多少个电位突变触发一个事件
00437 * This parameter can be one of the following values:
00438 * @arg TIM2_ICPSC_DIV1: Input Capture Prescaler = 1 (one capture every 1 event)
00439 * @arg TIM2_ICPSC_DIV2: Input Capture Prescaler = 2 (one capture every 2 events)
00440 * @arg TIM2_ICPSC_DIV4: Input Capture Prescaler = 4 (one capture every 4 events)
00441 * @arg TIM2_ICPSC_DIV8: Input Capture Prescaler = 8 (one capture every 8 events)
00442 * @retval None
00443 */
00444 void TIM2_PWMIConfig(TIM2_Channel_TypeDef TIM2_Channel,
00445 TIM2_ICPolarity_TypeDef TIM2_ICPolarity,
00446 TIM2_ICSelection_TypeDef TIM2_ICSelection,
00447 TIM2_ICPSC_TypeDef TIM2_ICPrescaler,
00448 uint8_t TIM2_ICFilter)
00449 {
00450 uint8_t icpolarity = (uint8_t)TIM2_ICPolarity_Rising;
00451 uint8_t icselection = (uint8_t)TIM2_ICSelection_DirectTI;
00452
00453 /* Check the parameters */
00454 assert_param(IS_TIM2_CHANNEL(TIM2_Channel));
00455
00456 /* Select the Opposite Input Polarity */
00457 if (TIM2_ICPolarity == TIM2_ICPolarity_Rising) //配置开始时触发方式
00458 {
00459 icpolarity = (uint8_t)TIM2_ICPolarity_Falling;
00460 }
00461 else
00462 {
00463 icpolarity = (uint8_t)TIM2_ICPolarity_Rising;
00464 }
00465
00466 /* Select the Opposite Input */
00467 if (TIM2_ICSelection == TIM2_ICSelection_DirectTI) //另外一个捕获通道触发方式相反
00468 {
00469 icselection = (uint8_t)TIM2_ICSelection_IndirectTI;
00470 }
00471 else
00472 {
00473 icselection = (uint8_t)TIM2_ICSelection_DirectTI;
00474 }
00475
00476 if (TIM2_Channel == TIM2_Channel_1)
00477 {
00478 /* TI1 Configuration */
00479 TI1_Config(TIM2_ICPolarity, TIM2_ICSelection,
00480 TIM2_ICFilter);
00481
00482 /* Set the Input Capture Prescaler value */
00483 TIM2_SetIC1Prescaler(TIM2_ICPrescaler);
00484
00485 /* TI2 Configuration */
00486 TI2_Config((TIM2_ICPolarity_TypeDef)icpolarity, (TIM2_ICSelection_TypeDef)icselection, TIM2_ICFilter);
00487
00488 /* Set the Input Capture Prescaler value */
00489 TIM2_SetIC2Prescaler(TIM2_ICPrescaler);
00490 }
00491 else
00492 {
00493 /* TI2 Configuration */
00494 TI2_Config(TIM2_ICPolarity, TIM2_ICSelection,
00495 TIM2_ICFilter);
00496
00497 /* Set the Input Capture Prescaler value */
00498 TIM2_SetIC2Prescaler(TIM2_ICPrescaler);
00499
00500 /* TI1 Configuration */
00501 TI1_Config((TIM2_ICPolarity_TypeDef)icpolarity, (TIM2_ICSelection_TypeDef)icselection, TIM2_ICFilter);
00502
00503 /* Set the Input Capture Prescaler value */
00504 TIM2_SetIC1Prescaler(TIM2_ICPrescaler);
00505 }
00506 }
00507
部分注释见上,简要分析可知,该函数将选择的输入通道连接到定时器的捕获通道1和捕获通道2上,并且捕获通道1为检测开始沿,捕获通道2则检测
第二个电位沿,比如配置为上升沿为PWM开始,则PWM中间为下降沿
好了,该函数功能就是这样了,下面是一些检测函数,环境为STVD:
Tim2_Impulse_Detection.h头文件
#ifndef Tim2_Impulse_Detection
#define Tim2_Impulse_Detection
/*
此库文件用于捕获Tim2通道1的输入并检测频率以及脉宽
*/
#include #include #include #include #include extern u8 temp; //中间变量,用于判断上升0/下降1 extern int ICValue1; //上升沿记录的值 extern int ICValue2; //下降沿记录的值 extern int ICValue3; //第二个上升沿记录的值 extern u8 update_high; //高电位溢出总数 extern u8 update_count; //溢出总数 extern u8 rate; //占空比,丢弃小数位 void Tim2_Impulse_Detection_Init(void); //Tim2_Impulse_Detection初始化 @far @interrupt void TIM2_Capture_Compare_HandledInterrupt (void);//捕获中断服务函数 @far @interrupt void TIM2_Update_Overflow_Trigger_Break_HandledInterrupt (void);//溢出中断服务函数 void Tim2_Impulse_Detection_Get_Cycle(int* cycle_ms,int* cycle_us,u8* rate);//获得输入信号周期以及脉宽 void Tim3_PWM_Out(void); //Tim3输出PWM波 #endif Tim2_Impulse_Detection.c源文件 #include /* 脉冲周期范围(建议值):50us~1s 脉宽时间范围(建议值):50us~1s */ u8 temp; //中间变量,用于判断第一次进入上升沿捕获0/第二次上升沿捕获1 int ICValue1; //上升沿记录的值 int ICValue2; //下降沿记录的值 int ICValue3; //第二个上升沿记录的值 u8 update_high; //高电位溢出总数 u8 update_count; //溢出总数 /************************************** 函数名:Tim2_Impulse_Detection_Init 功能:初始化Tim2为输入捕获 参数:无 返回值:无 描述: **************************************/ void Tim2_Impulse_Detection_Init(void) //Tim2_Impulse_Detection初始化 { CLK_MasterPrescalerConfig(CLK_MasterPrescaler_HSIDiv8);//系统时钟频率2Mhz GPIO_Init(GPIOB , GPIO_Pin_0 , GPIO_Mode_In_PU_No_IT);//TIM2_CH1 PB0端口 CLK_PeripheralClockConfig(CLK_Peripheral_TIM2,ENABLE);//使能时钟 TIM2_DeInit(); TIM2_TimeBaseInit(TIM2_Prescaler_2, TIM2_CounterMode_Up, 30000);//计数周期1us,向上计数,溢出值为30000 TIM2_PWMIConfig(TIM2_Channel_1, TIM2_ICPolarity_Rising, TIM2_ICSelection_DirectTI, 0x00, 0x00); //PWN输入配置:通道1,上升沿,直接输入,无分频,无滤波 //该函数配置捕获通道1为上升沿,捕获通道2为下降沿 } /************************************** 函数名:TIM2_Capture_Compare_HandledInterrupt 功能:TIM2_Capture_Compare_HandledInterrupt中断服务程序 参数:无 返回值:无 描述: **************************************/ @far @interrupt void TIM2_Capture_Compare_HandledInterrupt (void)//捕获中断服务函数 { if((TIM2_GetITStatus(TIM2_FLAG_CC1)) != RESET) { if(temp) { ICValue3=TIM2_GetCapture1(); TIM2_ClearFlag(TIM2_FLAG_CC1);//清除通道中断标志 TIM2_ClearITPendingBit(TIM2_IT_CC1); TIM2_ITConfig( TIM2_IT_Update, DISABLE);//关闭溢出中断 TIM2_CCxCmd(TIM2_Channel_1, DISABLE);//关闭通道1 TIM2_ITConfig(TIM2_IT_CC1, DISABLE);//关闭捕获通道1中断 TIM2_CCxCmd(TIM2_Channel_2, DISABLE);//关闭通道2 TIM2_ITConfig(TIM2_IT_CC2, DISABLE);//关闭捕获通道2中断 temp=0; } else { ICValue1=TIM2_GetCapture1(); TIM2_ITConfig( TIM2_IT_Update, ENABLE);//使能溢出中断 TIM2_ClearITPendingBit(TIM2_IT_Update); TIM2_ClearITPendingBit(TIM2_IT_CC1); TIM2_ClearFlag(TIM2_FLAG_CC1);//清除中断标志 TIM2_CCxCmd(TIM2_Channel_2,ENABLE);//使能捕获通道2 TIM2_ITConfig( TIM2_IT_CC2 , ENABLE);//使能TIM2输入通道2中断 TIM2_ClearFlag(TIM2_FLAG_CC2);//清除通道中断标志 TIM2_ClearITPendingBit(TIM2_IT_CC2); temp=1; } } if((TIM2_GetITStatus(TIM2_FLAG_CC2)) != RESET) { ICValue2=TIM2_GetCapture2(); update_high=update_count; TIM2_ClearFlag(TIM2_FLAG_CC2);//清除通道中断标志 TIM2_ClearITPendingBit(TIM2_IT_CC2); TIM2_CCxCmd(TIM2_Channel_2,DISABLE);//失能捕获通道2 TIM2_ITConfig( TIM2_IT_CC2 , DISABLE);//失能TIM2输入通道2中断 } } /************************************** 函数名:TIM2_Update_Overflow_Trigger_Break_HandledInterrupt 功能:TIM2_Update_Overflow_Trigger_Break_HandledInterrupt中断服务程序 参数:无 返回值:无 描述: **************************************/ @far @interrupt void TIM2_Update_Overflow_Trigger_Break_HandledInterrupt (void)//溢出中断服务函数 { update_count++; TIM2_ClearITPendingBit(TIM2_IT_Update); TIM2_ClearFlag(TIM2_IT_Update); } /************************************** 函数名:Tim2_Impulse_Detection_Get_Cycle 功能:Tim2_Impulse_Detection_Get_Cycle获取输入PWM波的脉宽与占空比 参数: cycle_ms 一个储存周期毫秒数的指针 cycle_us 一个储存周期微秒数的指针 rate 一个储存占空比的指针 返回值:无 描述:初始化完毕后,直接调用即可取得脉宽与占空比 **************************************/ void Tim2_Impulse_Detection_Get_Cycle(int* cycle_ms,int* cycle_us,u8* rate)//获得输入信号周期以及脉宽
史海拾趣
|
本人使用CC2430作为无线收发模块,使用CC2430手册配置的外围器件,只是在晶振方面由于起先使用SMD的4脚无 源32M晶振,发现不起振,后使用普通的两脚的32M晶振,挂接仿真器后工作正常,但是无法无线发信号和收信号 (另一块CC2430模块没反应),但 ...… 查看全部问答> |
|
如题,wince镜像都已经下好,怎样才能实现向wince端下载文件,通过什么途径都可以,比如串口,网口,usb口等。 请帮帮忙吧 谢谢了… 查看全部问答> |
|
Nios里如何做软件看门狗? 求代码及解释 如何初始化、喂狗、设置中断周期等? SOPC中有何特殊设置? 间隔一段时间喂狗,里面有那么多的寄存器,看书也没很明白哪个是设置周期的,哪个是喂狗时写的, 如果超时没有喂狗,该如何中断实现复位? ...… 查看全部问答> |
|
锁是通过高电压控制的,老师说他那个变压器连在锁上就能打开锁 通过串口发控制命令,控制一个元件,来产生功率足以打开锁的高电压 老师说这个和控制电机是一个道理 各位大侠,帮帮忙吧… 查看全部问答> |
|
请问关于Wince6 HalUpdateOverlay函数中获取dwFourCC的问题 我想在HalUpdateOverlay函数中获取到 ddpfSurface.dwFourCC 但不知道如何获取。在CE5中可以通过lpSource->ddpfSurface.dwFourCC得到 但CE6在某些结构上变化了,目前还未找到方法,请教下大家。… 查看全部问答> |




