今天针对通用定时器的输入捕获和PWM输出进行了学习测试,使用库函数进行。
1. PWM输出测试
1.1 测试方法
输出测试使用软件调试方法,直接在MDK调试界面的逻辑分析仪进行。软件调试设置网上一堆一堆的,我只描述一下遇到问题点。
图中,软件仿真只用设1、2项,加入硬件调需设第3项。
打开逻辑分析仪,在setup中输入想看的端口,如下图设置。
在端口号上右击,选择bit,然后运行即可看PWM输出的效果。
1.2测试的程序
① GPIO设置,主要是时钟、复用时钟、推挽输出、由于用默认的映射所以不用GPIO_PinRemapConfig。
void PWMOut_GPIO_Init()
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能PA端口时钟//GPIO 时钟使能
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //复用时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7; //复用推挽输出
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3,ENABLE ); //00,不映射
}
void TIM3_Init()
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
//②TIM3 时钟,设置分频器
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
/*③设置计数方式、分频器值
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1 ;
TIM_TimeBaseStructure.TIM_CounterMode =TIM_CounterMode_Up; //向上计数
TIM_TimeBaseStructure.TIM_Prescaler =0 ;
//此处为ARR的值。
TIM_TimeBaseStructure.TIM_Period = 900;
TIM_TimeBaseInit(TIM3,& TIM_TimeBaseStructure);
//④设置输出模式、通道
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
//此处为CCR的值,也可以先设0,在主函数中重设,但不能比ARR大。
TIM_OCInitStructure.TIM_Pulse = 200;//CCR
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(TIM3, & TIM_OCInitStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse =100;//CCR
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC2Init(TIM3, & TIM_OCInitStructure);
//⑤使能TIMx在CCR2上的预装载寄存器和ARR预装载寄存器
TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);
TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); // TIM_ARRPreloadConfig(TIM3,ENABLE );
//⑥使能TIMx外设
TIM_Cmd(TIM3, ENABLE);
}
2. PWM输入测试
2.1 测试方法
将输出的PWM口输入到PWM输入口中,然后将测试值从串口输出。
测试结果与输出结果略有出入。PWM输出周期400,高电平200,输入测试为周期398,高电平197,这与事件更新时序有关,但出入不大。设计时需考虑到。
2.2测试的程序
u16 PWM_Circle;
u16 PWM_Rise;
① GPIO设置,主要是时钟、复用时钟、浮空输入、由于用默认的映射所以不用GPIO_PinRemapConfig。
//端口PA1
//TIM2_CH2,端口不重映射
void PWMIN_GPIO_Init()
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能PA端口时钟//GPIO 时钟使能
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //复用时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; //复用推挽输出
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//GPIO_Mode_IPD;//输入下拉
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
void TIM2_Init()
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
// TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_ICInitTypeDef TIM_ICInitStruct;
NVIC_InitTypeDef NVIC_InitStructure;
//②TIM2 时钟,设置分频器、设置计数方式、分频器值
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1 ;
TIM_TimeBaseStructure.TIM_CounterMode =TIM_CounterMode_Up; //向上计数
TIM_TimeBaseStructure.TIM_Prescaler =0 ;
TIM_TimeBaseInit(TIM2,& TIM_TimeBaseStructure);
//③有两种方法进行通道设置,经测两种均可用。深入库函数分析,实现方式一致。
//方法一:
//TIM_ICInitStruct.TIM_Channel = TIM_Channel_2;
//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_PWMIConfig(TIM2, &TIM_ICInitStruct);
// //设置输入模式、通道
//方法二:
TIM_ICInitStruct.TIM_Channel = TIM_Channel_2;
//TIM_ICInitStruct.TIM_ICFilter =
TIM_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_Rising;
TIM_ICInitStruct.TIM_ICPrescaler =TIM_ICPSC_DIV1;
TIM_ICInitStruct.TIM_ICSelection =TIM_ICSelection_DirectTI ;
TIM_ICInit( TIM2, &TIM_ICInitStruct);
TIM_ICInitStruct.TIM_Channel = TIM_Channel_1; // 从通道,
//TIM_ICInitStruct.TIM_ICFilter =
TIM_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_Falling;
TIM_ICInitStruct.TIM_ICPrescaler =TIM_ICPSC_DIV1;
TIM_ICInitStruct.TIM_ICSelection =TIM_ICSelection_IndirectTI ;//ch2上
TIM_ICInit( TIM2, &TIM_ICInitStruct);
//④选择触发源、设置从模式、使能主模式
TIM_SelectInputTrigger(TIM2,TIM_TS_TI2FP2);// 选择触发源
TIM_SelectSlaveMode(TIM2,TIM_SlaveMode_Reset); //配置从模式为复位
TIM_SelectMasterSlaveMode(TIM2, TIM_MasterSlaveMode_Enable);//开启主/从模式
//⑤中断设置
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2 ;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器USART1
//⑥ 开定时器、开中断。
TIM_Cmd(TIM2, ENABLE); //使能TIMx外设
TIM_ITConfig(TIM2,TIM_IT_CC2, ENABLE);//开中断
}
//⑦中断函数
void TIM2_IRQHandler (void)
{
PWM_Rise = TIM_GetCapture1(TIM2);
PWM_Circle =TIM_GetCapture2(TIM2);
printf("周期为%d,高电平为%dtn",PWM_Circle,PWM_Rise);
TIM_ClearITPendingBit(TIM2,TIM_IT_CC2);
}
期间还测过呼吸灯,方法也比较简单就不描述了。
上一篇:STM32开发环境(3)----下载调试
下一篇:STM32中EXTI,EXTI和NVIC的关系
推荐阅读最新更新时间:2024-11-07 06:53