本帖最后由 风子 于 2017-2-16 18:02 编辑
本帖用高级定时器TIM1产生一组互补PWM,用通用定时器TIM3输入捕获,测量PWM的频率和占空比。 1、互补PWM输出 使用高级定时器1的CH1和CH1N通道,该定时器可以选用144M的高频率,对应选用输出引脚PA8和PA7,参考库函数使用手册的步骤,大概概括一下: 1.使能时钟和配置相应GPIO,几乎所有外设使用的第一步 2.配置定时器分频值,重装载值,计数模式等基本参数 3.配置OC参数,也就是OCInitStructure结构体,注意CHxN的输出状态要使能,才能输出互补 4.完成上面步骤就可以输出互补PWM了,如果需要死区等功能,再配置BDTR 5.打开定时器,使能PWM输出 下面是使用144M频率产生100k PWM的主要部分代码: - RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);
- RCC_TIMCLKConfig(RCC_TIM1CLK_PLLCLK); // 选择144M时钟
- TIM_TimeBaseInitStructure.TIM_Prescaler = 0;
- TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
- TIM_TimeBaseInitStructure.TIM_Period = 1440-1;//144M/100k=1440
- TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1 ;
- TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0x00;
- TIM_TimeBaseInit(TIM1,&TIM_TimeBaseInitStructure);
- TIM_OCStructInit(&TIM_OCInitStructure);
- TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
- TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
- TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;//开启互补通道
- TIM_OCInitStructure.TIM_Pulse =720;//脉宽,50%占空比,1440/2
- TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
- TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
- TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
- TIM_OC1Init(TIM1,&TIM_OCInitStructure);
- TIM_OC1PreloadConfig(TIM1,TIM_OCPreload_Enable);
- TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;
- TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Disable;
- TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1;
- TIM_BDTRInitStructure.TIM_DeadTime =1440*4/100;//5%死区,则实际占空比45%
- TIM_BDTRInitStructure.TIM_Break = TIM_Break_Enable;
- TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High;
- TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;
- TIM_BDTRConfig(TIM1,&TIM_BDTRInitStructure);
- TIM_Cmd(TIM1,ENABLE);
- TIM_CtrlPWMOutputs(TIM1,ENABLE);
复制代码用示波器可以查看输出波形。 2、PWM输入捕获 用这个功能可以测量输入波形的频率或(和)占空比,使用的是定时器TIM3的Input capture mode,可以测量频率或者占空比,为了方便同时测量这两个量,使用该模式中的特殊情况PWM input mode,如图:
(截图自ST参考手册) 根据库函数说明手册的步骤: 1.开启时钟和配置GPIO 2.如果需要,配置定时器基本参数,如果不配置,将按默认配置运行 3.配置输入参数TIM_ICInitStruct,调用Call TIM_ICInit(TIMx, &TIM_ICInitStruct)配置测量频率或占空比中的一个,或者调用TIM_PWMIConfig(TIMx, &TIM_ICInitStruct)同时测量者两个量 4.开启中断或者DMA并初始化,用来读取结果数据 5.如果用PWM input mode需要把定时器设为主从Reset模式 6.打开定时器,在中断或者DMA读取数据 (细节参考ST参考手册PWM input mode部分和库函数说明手册Input Capture management functions部分) 主要代码: - TIM_ICInitStructure.TIM_Channel=TIM_Channel_2;
- TIM_ICInitStructure.TIM_ICFilter=0x0;
- TIM_ICInitStructure.TIM_ICPolarity=TIM_ICPolarity_Rising;
- TIM_ICInitStructure.TIM_ICPrescaler=TIM_ICPSC_DIV1;
- TIM_ICInitStructure.TIM_ICSelection=TIM_ICSelection_DirectTI;
- TIM_PWMIConfig(TIM3,&TIM_ICInitStructure);
- TIM_SelectInputTrigger(TIM3,TIM_TS_TI2FP2);
- TIM_SelectSlaveMode(TIM3,TIM_SlaveMode_Reset);
- TIM_SelectMasterSlaveMode(TIM3,TIM_MasterSlaveMode_Enable);
- TIM_Cmd(TIM3,ENABLE);
- TIM_ITConfig(TIM3,TIM_IT_CC2,ENABLE);
- NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&NVIC_InitStructure);
复制代码中断处理函数: - volatile uint16_t IC2Value = 0;
- volatile uint16_t DutyCycle = 0;
- volatile uint32_t Frequency = 0;
- void TIM3_IRQHandler(void)
- {
- TIM_ClearITPendingBit(TIM3, TIM_IT_CC2);
- IC2Value = TIM_GetCapture2(TIM3);
- if (IC2Value != 0)
- {
- DutyCycle = (TIM_GetCapture1(TIM3) * 100) / IC2Value;
- Frequency = 72000000 / IC2Value;
- }
- else
- {
- DutyCycle = 0;
- Frequency = 0;
- }
- printf("DutyCycle= %d\n",DutyCycle);
- printf("Frequency= %d\n",Frequency);
- }
复制代码将1、中输出引脚短接到2、中的输入引脚,即可以在串口打印出测量的结果,在一定误差范围内测量正确。 完整的源码:
TIM_PWM.rar
(1.64 KB, 下载次数: 414)
|
恩恩,理解,论坛帖子太多了,不过这也是论坛人气越来越旺的象征嘛
https://www.stmcu.org.cn/module/forum/thread-601980-1-1.html
https://www.stmcu.org.cn/module/forum/thread-602002-1-1.html
就是这两个
对啊,就是以这个话题参与活动的有的帖子没送
谢谢,学习有一段时间了,基础还是有一定了解,还有很多东西需要继续学习啊
https://www.stmcu.org.cn/module/forum/thread-602010-1-1.html
多谢分享。。。楼主可否发个完整的工程包?这样方便新手学习。。。
还没有呢,不过准备开始学HAL库了
在一楼评论中那个帖子里的第一个,有个工程模板,是我发的,把文件加进去就可以了
是的,,,
多谢楼主答复,如果能用HAL 库就更完美了。。。。。
HAL库还没上手,正准备学习
这个库资料不多,入门要自己琢磨,比较慢,用的人确实少