蓝桥杯嵌入式 ---- “空手套白狼“ 之 PWM捕获


前言

本文是基于嵌入式开发板CT117E,stm32f103RBT6。"空手套白狼"就是直接利用官方给的库(v3.5),进行拷贝修改形成可以正常运行的代码。

一、芯片手册

在这里插入图片描述

二、PWM捕获原理

  • 捕获模式我这里使用的是定时器2,通道2,也就是PA1,捕获的基本编程思路:首先需要捕获两个变量,第一个是高电平的时间,和整个周期时间。
  • 这里先设置高电平触发,也就是说遇到高电平就触发中断,触发中断后我们需要在中断里面搞一个小顺序捕获,就是先捕获高电平的时间,再捕获整个周期的时间,我们在第一次中断里面把CNT寄存器清0,把我们的两个变量清0,然后设置为下降沿触发,一遇到下降沿就触发中断,这时候获取CNT寄存器的值就是高电平的时间,然后我们再重新设置为上升沿触发,然后等待下次中断,中断来的时候,捕获到CNT寄存器的值就是整个pwm波的周期。

三、定时器2初始化

  1. 捕获模式需要初始化4个结构体,分别是gpio,中断控制器,基本配置TIM_TimeBaseStructure,捕获配置结构体TIM_ICInitStructure,开启2个时钟使能;
  2. 除了基本配置TIM_TimeBaseStructure,其他都可以在TIM\InputCapture里面复制稍加修改就行;TIM_TimeBaseStructure的配置无非就是之前输出比较那样子的正常配置。

STM32固件库代码V3.5版\STM32F10x_StdPeriph_Lib_V3.5.0\Project\STM32F10x_StdPeriph_Examples\TIM\OCToggle\main.c

STM32固件库代码V3.5版\STM32F10x_StdPeriph_Lib_V3.5.0\Project\STM32F10x_StdPeriph_Examples\TIM\InputCapture\main.c 和 stm32f10xx_it.c

u32 ch1_val,ch1_duty;//全局变量,供主函数调用,解析频率和占空比
u8 ch1_mode=0;
void tim2_capture_init(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
  NVIC_InitTypeDef NVIC_InitStructure;
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  TIM_ICInitTypeDef  TIM_ICInitStructure;

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

  /* GPIOA and GPIOB clock enable */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  /* TIM3 channel 2 pin (PA.07) configuration */

  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_1;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_Init(GPIOA, &GPIO_InitStructure);

  NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

  TIM_TimeBaseStructure.TIM_Period = 65535;
  TIM_TimeBaseStructure.TIM_Prescaler = 71;
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

  TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

  TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
  TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
  TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
  TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
  TIM_ICInitStructure.TIM_ICFilter = 0x0;

  TIM_ICInit(TIM2, &TIM_ICInitStructure);
  
  /* TIM enable counter */
  TIM_Cmd(TIM2, ENABLE);

  /* Enable the CC2 Interrupt Request */
  TIM_ITConfig(TIM2, TIM_IT_CC2, ENABLE);
}

四、定时器2捕获pwm

  • 中断的编写:复制TIM\InputCapture里的stm32f10xx_it.c里面的定时器3中断,改为2,开头的判断中断通道和清除标志都一样,其他内容我们需要直接编写,按照前面的思路进行编写;
void TIM2_IRQHandler(void)
{ 
  if(TIM_GetITStatus(TIM2, TIM_IT_CC2) == SET) 
  {
     TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);
	 switch(ch1_mode)    //判断当前的顺序,发生中断进来按我们想要顺序执行
	 {
	 	case 0:                          //第一次进来中断
				ch1_val=0;             //频率值清0
				ch1_duty=0;            //占空比清0
				TIM_SetCounter(TIM2,0);     //cnt清0
				TIM_OC2PolarityConfig(TIM2,TIM_OCPolarity_Low); //触发中断的极性改为低电平
				ch1_mode=1;    //顺序变为1
				break;

		case 1: ch1_duty=TIM_GetCounter (TIM2);   //获取计数值,该值就是高电平的时间
				TIM_OC2PolarityConfig(TIM2,TIM_OCPolarity_High); //再次改变中断触发的极性
				ch1_mode=2;    //顺序变为2
				break;

		case 2: ch1_val=TIM_GetCounter (TIM2);   //获取计时值,该值就是高电平时间加低电平时间,也就是说整个周期的时间
				TIM_OC2PolarityConfig(TIM2,TIM_OCPolarity_High); 
				ch1_mode=3;  //捕获成功,告诉主函数,进行数据解析
				break;

		default:break;
	 }
  }
}

五、在主函数中的应用方法

tim3_pwm_init();  //产生pwm初始化
set_pwm(1000,50,100,20);  //产生频率为1000HZ,占空比为50%,频率为100HZ,占空比为20的两路pwm波
tim2_capture_init();  //捕获初始化
while(1)
{
		if(ch1_mode==3)   //捕获结束标志,进行数据处理
		{
			sprintf((char *)buff,"val: %d     w ",1000000/ch1_val);  //数据转换成频率hz,定时器2程序初始化的一个计数值是1us
			LCD_DisplayStringLine(Line7,buff);

			sprintf((char *)buff,"duty: %d%%     ",ch1_duty*100/ch1_val);//数据转换成占空比,定时器2程序初始化的一个计数值是1us
			LCD_DisplayStringLine(Line8,buff);

			ch1_mode=0;    //重新捕获标志
		}
}
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值