此贴为慢更重原理及推到开始讲解进度会比较慢。讲的有问题可提醒楼主哦
我想论坛里的坛友学习过单片机都知道怎么用单片机的AD采样吧!
但都会碰到很多问题 如输出数值乱跳 不准等现象 ,碰到这样的问题大多数是加上了均值滤波、滑动平均、中值滤波甚至是在循环里加上延时等等。但是还是会碰到无论加多少次的平均还是不理想。下面就是我要分享的数字处理的简单方法,在讲之前我先问几个问题:
1、你们AD采样用的是什么方法呢?
2、采样率、与采样结果有什么样的关系呢?
3、各位觉得你们的你们猜出来的数据理想吗?如果有不错的方法可以分享出来。
下n层开始讲采样率对输出结果的优化
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
先放了定时器触发的例子可以试一下哦
#define ADC1_DR_Address ((uint32_t)0x4001244C)
#define ADC_CH_NUM 1 /*通道数*/
#define ADC_CONV_COUNT 64 /*转换次数*/
__IO uint16_t ADC_RegularConvertedValueTab[ADC_CH_NUM * ADC_CONV_COUNT]/*, ADC_InjectedConvertedValueTab[32]*/;
__IO uint32_t Index;
uint8_t ADC_ACMP_flag = 0;
/*初始化定时器、ADC、DMA*/
void Tim_ADC_Init(uint32_t _ulFreq, uint32_t _ulDutyCycle)
{
ADC_InitTypeDef ADC_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
uint16_t usPeriod;
uint16_t usPrescaler;
uint32_t uiTIMxCLK;
/* Enable peripheral clocks ------------------------------------------------*/
/* Enable DMA1 clock */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
/* Enable GPIOA, GPIOC, ADC1 and TIM1 clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD |RCC_APB2Periph_GPIOE |
RCC_APB2Periph_ADC1 | RCC_APB2Periph_TIM1, ENABLE);
/* Configure TIM1_CH1 (PA8) as alternate function push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Configure PC.06 as output push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOC, &GPIO_InitStructure);
/* Configure PA.01 、PA.02 and PC.03 (ADC Channel1、 Channel2 and Channel3) as analog input */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/*-----------------------------------------------------------------------
system_stm32f4xx.c 文件中 void SetSysClock(void) 函数对时钟的配置如下:
HCLK = SYSCLK / 1 (AHB1Periph)
PCLK2 = HCLK / 2 (APB2Periph)
PCLK1 = HCLK / 4 (APB1Periph)
因为APB1 prescaler != 1, 所以 APB1上的TIMxCLK = PCLK1 x 2 = SystemCoreClock / 2;
因为APB2 prescaler != 1, 所以 APB2上的TIMxCLK = PCLK2 x 2 = SystemCoreClock;
APB1 定时器有 TIM2, TIM3 ,TIM4, TIM5, TIM6, TIM6, TIM12, TIM13,TIM14
APB2 定时器有 TIM1, TIM8 ,TIM9, TIM10, TIM11
----------------------------------------------------------------------- */
uiTIMxCLK = SystemCoreClock;
if (_ulFreq < 100)
{
usPrescaler = 10000 - 1; /* 分频比 = 10000 */
usPeriod = (uiTIMxCLK / 10000) / _ulFreq - 1; /* 自动重装的值 */
}
else if (_ulFreq < 3000)
{
usPrescaler = 100 - 1; /* 分频比 = 100 */
usPeriod = (uiTIMxCLK / 100) / _ulFreq - 1; /* 自动重装的值 */
}
else /* 大于4K的频率,无需分频 */
{
usPrescaler = 0; /* 分频比 = 1 */
usPeriod = uiTIMxCLK / _ulFreq - 1; /* 自动重装的值 */
}
/* TIM1 configuration ------------------------------------------------------*/
/* Time Base configuration */
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
TIM_TimeBaseStructure.TIM_Period = usPeriod;
TIM_TimeBaseStructure.TIM_Prescaler = usPrescaler;
TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
/* TIM1 channel1 configuration in PWM mode */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = (_ulDutyCycle * usPeriod) / 1000;//0x7F;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(TIM1, &TIM_OCInitStructure);
/* DMA1 Channel1 Configuration ----------------------------------------------*/
DMA_DeInit(DMA1_Channel1);
DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADC_RegularConvertedValueTab;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = ADC_CH_NUM * ADC_CONV_COUNT;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;//DMA_Mode_Circular循环 DMA_Mode_Normal单次
DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
/* Enable DMA1 channel1 */
DMA_Cmd(DMA1_Channel1, ENABLE);
/* Enable DMA1 Channelx Transfer Complete interrupt */
DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn; //设置中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //主优先级设置
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //设置优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //打开中断
NVIC_Init(&NVIC_InitStructure);
/* ADC1 configuration ------------------------------------------------------*/
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = ADC_CH_NUM;/*ADC_CH_NUM*/
ADC_Init(ADC1, &ADC_InitStructure);
/* ADC1 regular channel14 configuration */
ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_13Cycles5);
// ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 2, ADC_SampleTime_7Cycles5);
// ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 3, ADC_SampleTime_7Cycles5);
// ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 4, ADC_SampleTime_7Cycles5);
// ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 5, ADC_SampleTime_7Cycles5);
// ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 6, ADC_SampleTime_7Cycles5);
// /* Set injected sequencer length */
// ADC_InjectedSequencerLengthConfig(ADC1, 1);
// /* ADC1 injected channel Configuration */
// ADC_InjectedChannelConfig(ADC1, ADC_Channel_11, 1, ADC_SampleTime_71Cycles5);
// /* ADC1 injected external trigger configuration */
// ADC_ExternalTrigInjectedConvConfig(ADC1, ADC_ExternalTrigInjecConv_None);
// /* Enable automatic injected conversion start after regular one */
// ADC_AutoInjectedConvCmd(ADC1, ENABLE);
/* Enable ADC1 DMA */
ADC_DMACmd(ADC1, ENABLE);
/* Enable ADC1 external trigger */
ADC_ExternalTrigConvCmd(ADC1, ENABLE);
/* Enable JEOC interrupt */
// ADC_ITConfig(ADC1, ADC_IT_JEOC, ENABLE);
/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);
/* Enable ADC1 reset calibration register */
ADC_ResetCalibration(ADC1);
/* Check the end of ADC1 reset calibration register */
while (ADC_GetResetCalibrationStatus(ADC1));
/* Start ADC1 calibration */
ADC_StartCalibration(ADC1);
/* Check the end of ADC1 calibration */
while (ADC_GetCalibrationStatus(ADC1));
/* TIM1 counter enable */
TIM_Cmd(TIM1, ENABLE);
/* TIM1 main Output Enable */
TIM_CtrlPWMOutputs(TIM1, ENABLE);
// /* Test on channel1 transfer complete flag */
// while(!DMA_GetFlagStatus(DMA1_FLAG_TC1));
// /* Clear channel1 transfer complete flag */
// DMA_ClearFlag(DMA1_FLAG_TC1);
// /* TIM1 counter disable */
// TIM_Cmd(TIM1, DISABLE);
}
void DMA1_Channel1_IRQHandler(void)
{
if (DMA_GetITStatus(DMA1_IT_TC1) != RESET)
{
/* TIM1 counter disable */
//TIM_Cmd(TIM1, DISABLE);
ADC_ACMP_flag = 1;
/* Clear channel1 transfer complete flag */
DMA_ClearITPendingBit(DMA1_IT_TC1);
}
}
Tim_ADC_Init(50*64,200); /*ADC初始化 采样率:50HZ*64点 20ms*/
一周热门 更多>