本帖最后由 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]
解决方法及原因分析:
外接了个电压源,测量基本正常了,可能是DAC->ADC,回采,然后再开外部输入的话,芯片的电流总和超标了,自动降低了DAC的输出导致的。
一周热门 更多>