我是靠谱客的博主 深情百合,最近开发中收集的这篇文章主要介绍STM32----ADC进行信号(跳变沿、PWM)的捕获,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

      一般情况下进行信号的捕获,如上升沿或者下降沿。均可采用外部触发进行捕获。这是基于信号比较稳定的情况,如信号出现较大的纹波或者易受到干扰。会出现“误触”的现象,此时用外部中断难以捕获到正确的信号。

       这种情况的解决办法,可以采用以下办法:

(1)使用定时器进行捕获,并开启定时器的滤波功能。在库函数结构体中,为:

        TIM_ICInitStruct.TIM_ICFilter = 0x0f;(滤波系数可填0x00~0x0f)

        当系数开到最大(0x0f)可有效过滤大部分纹波以及干扰信号,但对于持续时间较长的干扰无法过滤。

(2)使用ADC模拟看门狗功能。

        比如当前信号为高电平,触发信号为下降沿,存在着一定的纹波以及偶发的干扰如图:

        

        这种信号,采用第一种方法并不能很好地捕获。但如果使用ADC模拟看门狗功能则能很好地识别。方法如下:

   (1)初始化看门狗触发阈值为低电平触发。假设触发信号的电平为0.2V,干扰信号最低达到0.6V。设置看门狗阈值为:0.4V~3.3V(STM32F1供电3.3V),此时0.4V~3.3V的信号不会触发看门狗中断,但0.2V(触发信号)可成功触发中断。达到了过滤干扰信号的目的。

   (2)当触发信号触发模拟看门狗中断后,处理完触发信号的程序后,更改看门狗触发阈值为高电平状态。如0V~2V。目的是防止触发信号时间过长,频繁进入看门狗中断。当触发信号恢复高电平状态,因为已经设置了看门狗中断为高电平触发,此时会进入一次中断。中断中只需要将看门狗触发阈值改为低电平触发,即可等待下一次的触发信号。

 

具体实现代码如下:

void
ADC2_AWGZcpInit(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
ADC_InitTypeDef
ADC_InitStruct;
NVIC_InitTypeDef
NVIC_InitStruct;
/*********************初始化ADC GPIO********************/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
GPIO_Init(GPIOB,&GPIO_InitStruct);
/**********************ADC2 NVIC************************/
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStruct.NVIC_IRQChannel = ADC1_2_IRQn;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 2;
NVIC_Init(&NVIC_InitStruct);
/************************初始化ADC2************************/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2, ENABLE);
RCC_ADCCLKConfig(RCC_PCLK2_Div6);
//72M/6 = 12M
ADC_InitStruct.ADC_ContinuousConvMode = ENABLE;
ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStruct.ADC_Mode = ADC_Mode_Independent;
ADC_InitStruct.ADC_NbrOfChannel = 1;
ADC_InitStruct.ADC_ScanConvMode = ENABLE;
ADC_Init(ADC2,&ADC_InitStruct);
ADC_RegularChannelConfig(ADC2, ADC_Channel_8, 1, ADC_SampleTime_7Cycles5);
/***************************ADC看门狗设置****************************/
ADC_AnalogWatchdogThresholdsConfig(ADC2,ADC2_AEG[2],ADC2_AEG[3]);
ADC_AnalogWatchdogSingleChannelConfig(ADC2, ADC_Channel_8);
ADC_AnalogWatchdogCmd(ADC2,ADC_AnalogWatchdog_SingleRegEnable);
/***************************ADC校准****************************/
ADC_Cmd(ADC2, ENABLE);
ADC_ResetCalibration(ADC2);
while(ADC_GetResetCalibrationStatus(ADC2)&&(timeout--));
ADC_StartCalibration(ADC2);
while(ADC_GetCalibrationStatus(ADC2)&&(timeout--));
ADC_ITConfig(ADC2,ADC_IT_AWD, ENABLE);
ADC_SoftwareStartConvCmd(ADC2, ENABLE);
}
u16 ADC2_AEG[5]={4095,250,3850,0,1};
//模拟看门狗阈值数组,第0、1元素为监测低电平触发信号阈值,2、3为高阈值
void ADC1_2_IRQHandler(void)
{
ADC2_AEG[4] = !ADC2_AEG[4]*2;
ADC2->HTR = ADC2_AEG[0+ADC2_AEG[4]];
//更改ADC看门狗阈值
ADC2->LTR = ADC2_AEG[1+ADC2_AEG[4]];
if(ADC2_AEG[4]<1)
//下降沿触发输出
{
//code
}
ADC2->SR &= 0xfffe;
//清除标志位
}

 

 

 

 

 

最后

以上就是深情百合为你收集整理的STM32----ADC进行信号(跳变沿、PWM)的捕获的全部内容,希望文章能够帮你解决STM32----ADC进行信号(跳变沿、PWM)的捕获所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(63)

评论列表共有 0 条评论

立即
投稿
返回
顶部