矩形波输出与输入捕获

本程序对应的开发板为蓝桥杯嵌入式开发板stm32f103rbt6,为中型mcu。本程序用TIM1通道2(PA9)输出1kHz、占空比为25%的矩形波,并用TIM2(PA1)测量矩形波周期和脉冲宽度。

初始化程序

//TIM1通道2(PA9)输出矩形波初始化子程序  频率1kHz,(72000000/(999+1)*(71+1))占空比25%  (249+1)/(999+1)
void TIM1_OCInit(void)
{
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_OCInitTypeDef  TIM_OCInitStructure;
	GPIO_InitTypeDef GPIO_InitStructure;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

	TIM_TimeBaseStructure.TIM_Period = 999;
	TIM_TimeBaseStructure.TIM_Prescaler = 71;
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseStructure.TIM_RepetitionCounter=0;
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);

	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
	TIM_OCInitStructure.TIM_Pulse = 250;
	TIM_OCInitStructure.TIM_OCNIdleState=TIM_OutputNState_Disable;
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
	TIM_OC2Init(TIM1, &TIM_OCInitStructure);

	TIM_CtrlPWMOutputs(TIM1,ENABLE);
	TIM_Cmd(TIM1,ENABLE);
	
}
//tim2通道2(pa1)测量矩形波周期和脉冲宽度初始化子程序
void TIM2_ICInit(void)
{

	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_ICInitTypeDef  TIM_ICInitStructure;
	GPIO_InitTypeDef GPIO_InitStructure;

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

	TIM_TimeBaseStructure.TIM_Period = 65535;
	TIM_TimeBaseStructure.TIM_Prescaler = 71;
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	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 = 0;
	TIM_PWMIConfig(TIM2, &TIM_ICInitStructure);

	TIM_SelectSlaveMode(TIM2,TIM_SlaveMode_Reset);
	TIM_SelectInputTrigger(TIM2,TIM_TS_TI2FP2);

	TIM_Cmd(TIM2, ENABLE);



}

捕获程序

//TIM2测量方波周期和脉冲处理子程序
unsigned char TIM2_Cap(unsigned int* puiTim_Val)
{
if(TIM_GetFlagStatus(TIM2,TIM_FLAG_CC2))
{
puiTim_Val[0]=TIM_GetCapture2(TIM2)+1;
puiTim_Val[1]=TIM_GetCapture1(TIM2)+1;
return 1;
}

return 0;

}

显示函数

void TIM_Proc(void)
{
if(ucSec!=ucSec1)
{
ucSec1=ucSec;
TIM2_Cap(uiTim_Val);
sprintf((char*)string,"sec:%3u %4u %1ums",ucSec,uiTim_Val[0],uiTim_Val[0]/1000);
LCD_DisplayStringLine(Line1,string);

sprintf((char*)string,"%4u %2u%%",uiTim_Val[1],uiTim_Val[1]*100/uiTim_Val[0]);
LCD_DisplayStringLine(Line3,string);




}

}

滴答定时器

void SysTick_Handler(void)
{
		TimingDelay--;
		ulTick_ms++;
		if(ulTick_ms%1000==0)
		{
		ucSec++;
		}
}


主程序

#include "stm32f10x.h"
#include "lcd.h"
#include "stdio.h"

u32 TimingDelay = 0;

void Delay_Ms(u32 nTime);
void TIM1_OCInit(void);
void TIM2_ICInit(void);
unsigned char TIM2_Cap(unsigned int* puiTim_Val);
void TIM_Proc(void);

unsigned long ulTick_ms=0;
unsigned char ucSec=0,ucSec1=0;
unsigned int uiTim_Val[2];
u8 string[20];

int main(void)
{
  
    STM3210B_LCD_Init();
	LCD_Clear(Blue);
	LCD_SetBackColor(Blue);
	LCD_SetTextColor(White);
	
	SysTick_Config(SystemCoreClock/1000);

	TIM1_OCInit();
	TIM2_ICInit();

	
	LCD_DisplayStringLine(Line0,"                    ");	
	LCD_DisplayStringLine(Line1,"                    ");	
	LCD_DisplayStringLine(Line2,"                    ");
	LCD_DisplayStringLine(Line3,"                    ");
	LCD_DisplayStringLine(Line4,"                    ");
	LCD_DisplayStringLine(Line5,"                    ");
	LCD_DisplayStringLine(Line6,"                    ");
	LCD_DisplayStringLine(Line7,"                    ");	
	LCD_DisplayStringLine(Line8,"                    ");
	LCD_DisplayStringLine(Line9,"                    ");	
	

  while (1)
  {
  TIM_Proc();
  }
}


void Delay_Ms(u32 nTime)
{
	TimingDelay = nTime;
	while(TimingDelay != 0);	
}

 

### STM32 输入捕获功能概述 STM32 的输入捕获功能主要用于捕捉外部事件的时间戳,通常用于测量脉冲宽度、频率或其他时间间隔。此功能通过定时器通道来实现,在特定条件下触发中断并记录当前计数值。 #### 测量方法的选择 对于不同类型的信号测量需求,可以选择不同的方式: - **测频法**:适用于高频信号的频率测量。通过对一定时间内发生的边沿次数进行统计计算得出频率值[^1]。 - **测周法**:适合低频信号周期测定。利用两次相邻有效边沿之间的时间差作为该信号的一个完整周期长度。 当面对非矩形波或者模拟信号时,则需先经过适当变换使其成为适合MCU处理的形式——即高低电平交替变化的数字信号[^2]。 #### 初始化设置编程要点 为了启用输入捕获特性,需要完成如下几项工作: - 配置GPIO引脚为复用推挽输出/开漏输出模式; - 设置相应TIMx_CCRy寄存器以指定要使用的通道及其极性(上升沿、下降沿或双边沿); - 编写回调函数响应每次成功捕获到的数据更新事件; 下面是一份基于标准外设库简化版的例子代码片段展示如何开启 TIM2 CH1 上升沿检测,并读取捕获值: ```c #include "stm32f10x.h" void TIM_Config(void){ GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_ICInitTypeDef TIM_ICInitStruct; // RCC配置省略... /* GPIOB Configuration: PB8 -> TIM4 Channel 1 */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); /* Time base configuration */ TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); TIM_TimeBaseStructure.TIM_Period = 65535; TIM_TimeBaseStructure.TIM_Prescaler = 72 - 1; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); /* Input Capture configuration */ TIM_ICInitStruct.TIM_Channel = TIM_Channel_1; TIM_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_Rising; TIM_ICInitStruct.TIM_ICSelection = TIM_ICSelection_DirectTI; TIM_ICInitStruct.TIM_ICPrescaler = TIM_ICPSC_DIV1; TIM_ICInitStruct.TIM_ICFilter = 0x0; TIM_ICInit(TIM4,&TIM_ICInitStruct); /* Enable the CC1 Interrupt Request */ TIM_ITConfig(TIM4,TIM_IT_CC1 ,ENABLE ); /* Start input capture on channel 1 */ TIM_Cmd(TIM4, ENABLE); } u16 GetCaptureValue(){ return TIM_GetCapture1(TIM4); } ``` 上述程序实现了对PB8上的PWM信号周期测量的基础框架构建[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

身在江湖的郭大侠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值