STM32输出脉冲频率极限试验
经常会用到单片机到输出一定频率的脉冲信号,也没频率的极限是多少呢?近期我做了一些简单的试验,结果分享给大家供参考。
如何输出更高频率的脉冲?对于STM32F103(Cortex-M3内核)来说,即使中断服务程序(ISR)里什么都不做,从硬件触发中断到开始执行程序的第一条指令,固定需要12个时钟周期。在此基础上,再加上从ISR返回主程序的时间(出栈),总共大约需要 18个时钟周期。以主频72MHz计算,约250ns。若考虑在中断程序中进行电平翻转,所花时间更长,应该超过500ns。因此,通过定时器中断输出脉冲的频率很难达到1MHz。想要更高的频率只能另想办法。即使用定时器的PWM模式实现,而不能通过代码循环翻转GPIO电平。
定时器PWM模式是生成精确、稳定高频方波的标准方法,整个过程由硬件自动完成,不占用 CPU 资源。其频率由决定于公式:Fpwm = 72MHz / ((ARR+1) * (PSC+1)),72MHz为stm32主频,ARR定时器的自动重装载值,决定输出脉冲的周期即频率;PSC为预分频系数。而输出脉冲的占空比由定时器输出比较相关寄存器中的TIM_Pulse决定。理论上设ARR=0,PSC=0,可输出72MHz。但若ARR=0,则无法实现电平翻转,因为硬件也必须在一个主频有效边沿信号到来时动作一次。因此ARR必须大于等于1,在上一个主频周期内输出维持一个电平,下一个主频周期到来时电平翻转,即输出频率理论极限为主频的一半。
以TIM2_CH4在PWM模式下输出脉冲,程序代码如下:
void TIM2_CH4_PWM_Init(void)
{
uint16_t arr = 1; //设定输出脉冲周期
GPIO_InitTypeDef GPIO_InitStruct;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct;
TIM_OCInitTypeDef TIM_OCInitStruct;
// 1. 端口及定时器时钟使能:GPIOA + TIM2
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
// 2. 引脚PA3初始化
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);
// 3. 时基配置
TIM_TimeBaseStruct.TIM_Prescaler = 0;
TIM_TimeBaseStruct.TIM_Period = arr;
TIM_TimeBaseStruct.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStruct.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStruct);
// 4. CH4 PWM1模式配置
TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStruct.TIM_Pulse = (arr+1)>>1; // 设置输出脉冲占空比
TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC4Init(TIM2, &TIM_OCInitStruct);
// 使能TIM2
TIM_Cmd(TIM2, ENABLE);
}
更改以上代码中的arr与TIM_Pulse值即可输出不同频率的脉冲。
需要说明的是:理想电路情况下,stm32引脚数字输出要么高电平要么低电平,为方波信号或一条直线。但是电路实际总存在我们不想用到的寄生、耦合电容电感,导致理想信号输出的延迟及变形。
试验是在相对粗糙的情况下进行,利用的是自制它用的现成的一块stm32平台的PCB,并未对电路高频输出做特殊处理且接线也有一定距离,结果供学习参考。






|ARR|设置频率MHz| 检出频率 MHz|峰峰值V
| 0 | - | - |
| 1 | 36 | 35.71 | 1.44
| 2 | 24 | 24.03 | 3.92
| 3 | 18 | 18.05 | 2.72
| 4 | 14.4 | 14.36 | 3.92
| 5 | 12 | 11.96 | 4.40
| 6 | 9 | 9.001 | 4.76
从以上结果看,最高可以输出36MHz脉冲信号,但波形变化及与理论偏差较大。无聊的将ARR设为0,输出为一条直线。9MHz输出的波形、频率、幅度均正常,频率偏差小,仅万分之一以内;12、14.4、18、24MHz输出频率偏差相当,千分之三以内;但自14.4MHz起波形看不出方波形状,先是峰顶变尖,接着峰谷也变尖,说明还未“充电”至高电平水平硬件已转为低电平,或还未放电至低电平硬件已翻转为高电平;因此频率增加会导致输出波形的峰峰值变小,奇怪的是24MHz输出时的峰峰值突然变大了不少,重测几次似乎一样,一下子没太想明白原因,有兴趣的朋友可以帮助分析一下。
总体而言,利用stm32输出10MHz脉冲是靠谱的,再高需谨慎。多花点精力优化电路原理及布板设计,可能达到更高的频率。
注:实际使用芯片为Geehy APM32E103VET6.
更多推荐



所有评论(0)