探索者F4 ADC1 CH5 输入受TIM2 ETR输入影响

2019-07-20 07:10发布

本帖最后由 hjywlj 于 2018-7-16 12:41 编辑

我在使用探索者F4进行实验时,采用TIM2 ETR进行外部脉冲计数,使用ADC1 CH5采集外部模拟信号,采用DAC1进行模拟输出。各个外设配置好后,出现奇怪的现象,当没有外部脉冲输入的时候,ADC1回采DAC1的输出,一切正常,但是,当有外部脉冲输入的时候ADC1的回采值会变成0.7V左右,无论怎样设置DAC1,ADC的回采值都不改变,关掉外部脉冲输入,ADC1又可以准确采集DAC1的输出值;单独使用万用表测量DAC1的输出值时,无论有没有外部脉冲输入,DAC1输出都正常。希望各位大神不吝赐教,先感谢了。所用代码,大部分为探索者所带的例程代码。附件是现象的视频演示。
代码如下
定时器配置代码
[mw_shl_code=c,true]#include "timer.h"
u32 t5Reload = 10*_1S;//TIM5重装值

void TIM2_Init(u32 arr,u16 psc)//TIM2初始化
{
        GPIO_InitTypeDef GPIO_InitStructure;
        TIM_TimeBaseInitTypeDef TIM_TimBaseStructure;
        
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
        
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
        GPIO_InitStructure.GPIO_PuPd =GPIO_PuPd_NOPULL;
        GPIO_Init(GPIOA,&GPIO_InitStructure);//初始化PA0
        
        GPIO_PinAFConfig(GPIOA,GPIO_PinSource0,GPIO_AF_TIM2);//PA0复用 定时器2
        
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
        
        TIM_TimBaseStructure.TIM_Prescaler = psc;
        TIM_TimBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
        TIM_TimBaseStructure.TIM_Period = arr;
        TIM_TimBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
        TIM_TimeBaseInit(TIM2,&TIM_TimBaseStructure);
        
        TIM_ETRClockMode2Config(TIM2,TIM_ExtTRGPSC_OFF,TIM_ExtTRGPolarity_NonInverted,0);
        TIM_SetCounter(TIM2,0);//清零
}

void TIM5_Init(u32 arr, u16 psc)//TIM5初始化
{
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5,ENABLE);
        
        TIM_TimeBaseInitTypeDef TIM_TimBaseInitStructure;
        TIM_TimBaseInitStructure.TIM_Period = arr;
        TIM_TimBaseInitStructure.TIM_Prescaler =psc;
        TIM_TimBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;
        TIM_TimBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
        
        TIM_TimeBaseInit(TIM5,&TIM_TimBaseInitStructure);
        
        TIM_ITConfig(TIM5,TIM_IT_Update|TIM_IT_CC1,ENABLE);//允许更新中断 ,允许CC1IE捕获中断
        
        NVIC_InitTypeDef NVIC_Init_Structure;
        NVIC_Init_Structure.NVIC_IRQChannel = TIM5_IRQn;
        NVIC_Init_Structure.NVIC_IRQChannelPreemptionPriority = 0x01;
        NVIC_Init_Structure.NVIC_IRQChannelSubPriority =0x03;
        NVIC_Init_Structure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_Init_Structure);
  TIM_Cmd(TIM5,ENABLE);
}

void TIM5_IRQHandler(void)
{
        static u8 fliper = 0;
        if(TIM_GetITStatus(TIM5,TIM_IT_Update !=RESET))//更新中断(溢出中断)
        {               
                if(fliper)
                {                        
                        TIM_Cmd(TIM2,DISABLE);//停止计数
                        TIM_SetAutoreload(TIM5,3*_1S);        
                }
                else
                {
                        TIM_SetCounter(TIM2,0);;//清零计数器
                        TIM_Cmd(TIM2,ENABLE);;   //启动计数器
                        TIM_SetAutoreload(TIM5,t5Reload);                                       
                }
                fliper =!fliper;
        }
        TIM_ClearITPendingBit(TIM5,TIM_IT_CC1|TIM_IT_Update);//清中断标志
}

void TIM3_Init(u32 arr,u16 psc)//TIM3初始化
{
        GPIO_InitTypeDef GPIO_InitStructure;
        TIM_TimeBaseInitTypeDef TIM_TimBaseStructure;
        
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD,ENABLE);
        
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
        GPIO_InitStructure.GPIO_PuPd =GPIO_PuPd_NOPULL;
        GPIO_Init(GPIOD,&GPIO_InitStructure);//初始化PD2
        
        GPIO_PinAFConfig(GPIOD,GPIO_PinSource2,GPIO_AF_TIM3);//PD2复用 定时器3
        

        GPIO_InitStructure.GPIO_Pin =GPIO_Pin_3;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
        GPIO_InitStructure.GPIO_PuPd =GPIO_PuPd_NOPULL;
        GPIO_Init(GPIOD,&GPIO_InitStructure);//初始化PD3
        
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
        
        TIM_TimBaseStructure.TIM_Prescaler = psc;
        TIM_TimBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
        TIM_TimBaseStructure.TIM_Period = arr;
        TIM_TimBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
        TIM_TimeBaseInit(TIM3,&TIM_TimBaseStructure);
        
        TIM_ITConfig(TIM3,TIM_IT_Update|TIM_IT_CC1,ENABLE);//允许更新中断 ,允许CC1IE捕获中断
        
        NVIC_InitTypeDef NVIC_Init_Structure;
        NVIC_Init_Structure.NVIC_IRQChannel = TIM3_IRQn;
        NVIC_Init_Structure.NVIC_IRQChannelPreemptionPriority = 0x02;
        NVIC_Init_Structure.NVIC_IRQChannelSubPriority =0x03;
        NVIC_Init_Structure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_Init_Structure);
        
        TIM_ETRClockMode2Config(TIM3,TIM_ExtTRGPSC_OFF,TIM_ExtTRGPolarity_NonInverted,0);
        TIM_SetCounter(TIM3,2048);//清零
        TIM_ClearFlag(TIM3,TIM_FLAG_Update);
        TIM_Cmd(TIM3,ENABLE);//启动定时器3
}

void SetTim3Dir(u8 dir)//设置计数器3计数方向
{
        if(dir)
        {
                TIM_CounterModeConfig(TIM3,TIM_CounterMode_Up);                        
        }else
        {
                TIM_CounterModeConfig(TIM3,TIM_CounterMode_Down);                        
        }
}

void TIM3_IRQHandler(void)
{
        if(TIM_GetITStatus(TIM3,TIM_IT_Update !=RESET))//更新中断(溢出中断)
        {        
                if(TIM3->CR1&(1<<4))
                {
                        TIM_SetCounter(TIM3,0);
                } else
                {                        
                        TIM_SetCounter(TIM3,4095);
                }               
        }
        TIM_ClearITPendingBit(TIM3,TIM_IT_CC1|TIM_IT_Update);//清中断标志
        
}[/mw_shl_code]ADC配置代码
[mw_shl_code=c,true]#include "adc.h"
#include "delay.h"

void iADC_Init(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;
        
        ADC_CommonInitTypeDef ADC_CommonInitStructure;
        
        ADC_InitTypeDef ADC_InitStructure;
        
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);//使能GPIOA时钟
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);//使能ADC1时钟
        
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;//PA5 通道5
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;//模拟输入        
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;//不带上下拉
        
        GPIO_Init(GPIOA,&GPIO_InitStructure);
        
        

        RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,ENABLE);//复位
        RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,DISABLE);//复位结束
        
        //初始化ADC通用配置
        ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;//独立模式
        ADC_CommonInitStructure.ADC_TwoSamplingDelay =
                                                ADC_TwoSamplingDelay_5Cycles;//两个采样阶段之间延时5个时钟;
        ADC_CommonInitStructure.ADC_DMAAccessMode=
                          ADC_DMAAccessMode_Disabled;//不使用DMA
        ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;//预分频4
                                 //ADCCLK = PCLK2/4 = 84/4=21MHz,ADC时钟最好不超过36MHz
  ADC_CommonInit(&ADC_CommonInitStructure);
        
        //初始化ADC1
        ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;//12位ADC
        ADC_InitStructure.ADC_ScanConvMode = DISABLE;//非扫描模式;
        ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//关闭连续转换
        ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
                                                                                                                                                                                        //禁止触发检测,软件触发
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//右对齐
        ADC_InitStructure.ADC_NbrOfConversion = 1;//1个转换在规则序列中
        ADC_Init(ADC1,&ADC_InitStructure);
        //开启ADC1
        ADC_Cmd(ADC1,ENABLE);
}

u16 Get_ADC(u8 ch)
{
        //设置指定ADC的规则组通道,一个序列,采样时间
        ADC_RegularChannelConfig(ADC1,ch,1,ADC_SampleTime_480Cycles);
        ADC_SoftwareStartConv(ADC1);
        while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC));//等待转换结束
        return ADC_GetConversionValue(ADC1);//返回最近一次转换结果
}

u16 Get_iADC_Average(u8 ch, u8 times)
{
        u32 temp_val =0;
        u8 t;
        for(t=0;t<times;t++)
        {
                temp_val+=Get_ADC(ch);
//                delay_ms(5);
        }
        return temp_val/times;
}
[/mw_shl_code]

DAC配置代码(DAC输出值由数字旋钮设置)
[mw_shl_code=c,true]#include "dac.h"

void iDAC_Init(void)//DAC1初始化        
{
        GPIO_InitTypeDef GPIOInitStructure;
        
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC,ENABLE);
//        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
        
        GPIOInitStructure.GPIO_Pin=GPIO_Pin_4;
        GPIOInitStructure.GPIO_Mode=GPIO_Mode_AN;
        GPIOInitStructure.GPIO_PuPd=GPIO_PuPd_UP;
        GPIOInitStructure.GPIO_OType=GPIO_OType_OD;
        GPIOInitStructure.GPIO_Speed=GPIO_Speed_100MHz;        
        GPIO_Init(GPIOA,&GPIOInitStructure);
        
        DAC_InitTypeDef DACInitStructure;
        DACInitStructure.DAC_Trigger=DAC_Trigger_None;
        DACInitStructure.DAC_WaveGeneration=DAC_WaveGeneration_None;
        DACInitStructure.DAC_LFSRUnmask_TriangleAmplitude = DAC_LFSRUnmask_Bit0;
        DACInitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Disable;
        DAC_Init(DAC_Channel_1,&DACInitStructure);
        
        DAC_Cmd(DAC_Channel_1,ENABLE);
        DAC_SetChannel1Data(DAC_Align_12b_R,0);
}

void SetDAC1(u16 dac)//设置DAC值
{
        DAC_SetChannel1Data(DAC_Align_12b_R,dac);
}[/mw_shl_code]

main函数

[mw_shl_code=applescript,true]#include "stm32f4xx.h"
#include "usart.h"
#include "delay.h"
#include "timer.h"
#include "lcd.h"
#include "stdio.h"
#include "adc.h"
#include "counterDriver.h"
#include "dac.h"
int main(void)
{
        u16 adcx = 0;
        float temp;
        u8 ch = 5;
        char LCD_Buffer[64];
        u32 TIM2_Counter = 0;
        
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
        TIM2_Init(PRELOAD,0);//定时器2初始化
        TIM3_Init(DAC_RESOLUTION,0);//定时器3初始化
        TIM5_Init(3*_1S,TIM5_PSC);
        delay_init(168);
        uart_init(115200);
        iADC_Init();
        iDAC_Init();
        LCD_Init();
        LCD_Clear(WHITE);
        POINT_COLOR = BLACK;
  while(1)
        {
               
                TIM2_Counter=TIM_GetCounter(TIM2);
                sprintf(LCD_Buffer,"The counter of Timer2 is : %10d",TIM2_Counter);        
                POINT_COLOR = BLACK;
                LCD_ShowString(20,60,450,24,24,(u8*)LCD_Buffer);
               
//                adcx = Get_ADC(ch);//获取当前值
                adcx = Get_iADC_Average(ch,30);//获取平均值
                POINT_COLOR = BLUE;
               
                LCD_ShowxNum(20,100,adcx,4,16,0);//显示ADC原始值
                temp = adcx*3.3/4095;//转换为实际电压值        
                sprintf(LCD_Buffer,"Voltage of ADC1 Channel %d is %.3f",ch,temp);
                LCD_ShowString(20,130,450,24,24,(u8*)LCD_Buffer);
               
                SetCounterThr();        
                delay_ms(100);                                
        }               
}

[/mw_shl_code]
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
4条回答
hjywlj
1楼-- · 2019-07-20 08:50
唉,没人回答,这两天较劲脑汁,跟朋友探讨,最终发现问题。
解决方法及原因分析:
外接了个电压源,测量基本正常了,可能是DAC->ADC,回采,然后再开外部输入的话,芯片的电流总和超标了,自动降低了DAC的输出导致的。
hjywlj
2楼-- · 2019-07-20 10:34
大神们,加油啊!!
hjywlj
3楼-- · 2019-07-20 16:22
 精彩回答 2  元偷偷看……
Z一叶孤舟
4楼-- · 2019-07-20 22:20
 精彩回答 2  元偷偷看……

一周热门 更多>