【stm32】用从模式控制器 完成PWM的测量
🌞学习视频还是来自于 铁头山羊
🌿主要是回顾一下他讲的这一章的定时器的部分,具体的话 还是看一下具体铁头山羊的视频,讲的很清楚~~
整体流程是这样的,首先通过定时器的输出比较功能,配置好PA6产生一个特定的PWM,然后再利用PWM输入捕获+从模式 测量出该PWM的占空比和周期
也就是自产自测的过程
产生一个PWM
首先需要一个PWM,这样才有信号给测嘛,这个过程我们用TIM3进行
也就是:
主要步骤和关键函数
//1.时基单元配置
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStruct);
//配置预加载 防止寄存器跑飞
TIM_ARRPreloadConfig(TIM3,ENABLE);
//闭合时基单元开关
TIM_Cmd(TIM3,ENABLE);
//2.初始化输出比较
初始化输出的引脚 PA6
//配置输出比较
TIM_OC1Init(TIM3, &TIM_OCInitStruct);
//闭合开关 MOE
TIM_CtrlPWMOutputs(TIM3,ENABLE);
//使能CCRx预加载
TIM_CCPreloadControl(TIM3,ENABLE);
具体的代码如下
void PWM1_Init(void){
//1.时基单元配置
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;
TIM_TimeBaseInitStruct.TIM_Period=999;
TIM_TimeBaseInitStruct.TIM_Prescaler=71;
TIM_TimeBaseInitStruct.TIM_RepetitionCounter=0;
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStruct);
//配置预加载 防止寄存器跑飞
TIM_ARRPreloadConfig(TIM3,ENABLE);
//闭合时基单元开关
TIM_Cmd(TIM3,ENABLE);
//2.初始化输出比较
//初始化输出的引脚 PA6
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitTypeDef gpio_init_struct;
gpio_init_struct.GPIO_Mode=GPIO_Mode_AF_PP;
gpio_init_struct.GPIO_Pin=GPIO_Pin_6;
gpio_init_struct.GPIO_Speed=GPIO_Speed_2MHz;
GPIO_Init(GPIOA,&gpio_init_struct);
//配置输出比较
TIM_OCInitTypeDef TIM_OCInitStruct;
TIM_OCInitStruct.TIM_OCMode=TIM_OCMode_PWM1;
TIM_OCInitStruct.TIM_OCPolarity=TIM_OCPolarity_High;
TIM_OCInitStruct.TIM_OutputState=ENABLE;
TIM_OCInitStruct.TIM_Pulse=0;
TIM_OC1Init(TIM3, &TIM_OCInitStruct);
//闭合开关 MOE
TIM_CtrlPWMOutputs(TIM3,ENABLE);
//使能CCRx预加载
TIM_CCPreloadControl(TIM3,ENABLE);
}
通过从模式完成输入捕获
主要完成下面几个块的配置
后面的测量部分,需要配置下面的部分
//1.时基单元配置 TIM1 这里用的是另一个TIM
TIM_TimeBaseInit(TIM1,&TIM_TimeBaseInitStruct);
//配置预加载 防止寄存器跑飞
TIM_ARRPreloadConfig(TIM1,ENABLE);
//闭合时基单元开关
TIM_Cmd(TIM1,ENABLE);
//2.初始化输入捕获
//输入捕获引脚 输入上拉IPU PA8
//配置输入捕获通道1和通道2
TIM_ICInit
//初始化从模式输入
TIM_SelectInputTrigger(TIM1, TIM_TS_TI1FP1);
//初始化 从模式控制器
TIM_SelectSlaveMode(TIM1, TIM_SlaveMode_Reset);
具体代码如下
//时基单元初始化
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
TIM_TimeBaseInitStruct.TIM_Prescaler=71;
TIM_TimeBaseInitStruct.TIM_Period=65535;
TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;
TIM_TimeBaseInitStruct.TIM_RepetitionCounter=0;
TIM_TimeBaseInit(TIM1,&TIM_TimeBaseInitStruct);
//配置预加载 防止寄存器跑飞
TIM_ARRPreloadConfig(TIM1,ENABLE);
//闭合时基单元开关
TIM_Cmd(TIM1,ENABLE);
//初始化输入捕获引脚 输入上拉IPU PA8
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitTypeDef gpio_init_struct;
gpio_init_struct.GPIO_Mode=GPIO_Mode_AF_PP;
gpio_init_struct.GPIO_Pin=GPIO_Pin_8;
gpio_init_struct.GPIO_Speed=GPIO_Speed_2MHz;
GPIO_Init(GPIOA,&gpio_init_struct);
//初始化输入捕获通道1
TIM_ICInitTypeDef TIM_ICInitStruct;
TIM_ICInitStruct.TIM_Channel=TIM_Channel_1;
TIM_ICInitStruct.TIM_ICFilter=0;//不用滤波器
TIM_ICInitStruct.TIM_ICPolarity=TIM_ICPolarity_Rising;
TIM_ICInitStruct.TIM_ICPrescaler=TIM_ICPSC_DIV1;
TIM_ICInitStruct.TIM_ICSelection=TIM_ICSelection_DirectTI;
TIM_ICInit(TIM1, &TIM_ICInitStruct);
//初始化输入捕获通道2
TIM_ICInitStruct.TIM_Channel=TIM_Channel_2;
TIM_ICInitStruct.TIM_ICFilter=0;//不用滤波器
TIM_ICInitStruct.TIM_ICPolarity=TIM_ICPolarity_Falling;
TIM_ICInitStruct.TIM_ICPrescaler=TIM_ICPSC_DIV1;
TIM_ICInitStruct.TIM_ICSelection=TIM_ICSelection_IndirectTI;
TIM_ICInit(TIM1, &TIM_ICInitStruct);
//初始化从模式输入
TIM_SelectInputTrigger(TIM1, TIM_TS_TI1FP1);
//初始化 从模式控制器
TIM_SelectSlaveMode(TIM1, TIM_SlaveMode_Reset);
主函数
主要的逻辑是长这样的,当完成出发时候Trigger 从0变成1 这个时候就可以计算CCR1 CCR2的值,然后就可以计算PWM的占空比和周期了
int main(void)
{
My_Usart_Init1();
TIM1_Slave_Init();
PWM1_Init();
TIM_SetCompare1(TIM3,200);//产生一个20%占空比的信号 周期1ms
while(1){
//1.清除Trigger标志位
TIM_ClearFlag(TIM1,TIM_FLAG_Trigger);
//2.等待Trigger标志位从0变成1
while(TIM_GetFlagStatus(TIM1,TIM_FLAG_Trigger)==RESET);
//3.计算
uint16_t ccr1=TIM_GetCapture1(TIM1);
uint16_t ccr2=TIM_GetCapture2(TIM1);
float period=ccr1*1.0e-5;
float duty=(float)ccr2/ccr1*100;
My_USART_Printf(USART1,"period=%.3fms,duty=%.2f%%\r\n",period,duty);
Delay(100);
}
}