专家
公告
财富商城
电子网
旗下网站
首页
问题库
专栏
标签库
话题
专家
NEW
门户
发布
提问题
发文章
STM32
请问STM32L053怎么设置ADC实现多通道采集?
2019-07-14 14:14
发布
×
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
站内问答
/
STM32/STM8
18144
6
1305
请问哪位高手用过
STM32
L053 ,怎样设置ADC实现多通道采集
友情提示:
此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
6条回答
60user124
2019-07-14 20:20
/**
* @file ADC_Configuration
* @brief 完成ADC和DMA的初始化
* @param 无
* @retval 无
*/
void ADC_Configuration(uint32_t _ulFreq)
{
GPIO_InitTypeDef GPIO_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
TIM_TimeBaseInitTypeDef timer_init_structure;
NVIC_InitTypeDef NVIC_InitStructure;
uint16_t usPeriod;
uint16_t usPrescaler;
uint32_t uiTIMxCLK;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
/*设置ADC分频因子为4 ,ADC最大时间不能超过14M*/
RCC_ADCCLKConfig(RCC_ADCCLK_PCLK_Div4);
/* ADC1 Periph clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
/* 使能DMA时钟 */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1 , ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_5 | GPIO_Pin_6 ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
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; /* 自动重装的值 */
}
/*复位TIM2*/
TIM_DeInit(TIM2);
/*初始化TIMBASE结构体*/
TIM_TimeBaseStructInit(&timer_init_structure);
/*系统时钟,不分频,48M*/
timer_init_structure.TIM_ClockDivision = TIM_CKD_DIV1;
/*向上计数模式*/
timer_init_structure.TIM_CounterMode = TIM_CounterMode_Up;
/*每312 uS触发一次中断,开启ADC*/
timer_init_structure.TIM_Period = usPeriod;
/*计数时钟预分频,f=1M,systick=1 uS */
timer_init_structure.TIM_Prescaler = usPrescaler;
/*发生0+1次update事件产生中断 */
timer_init_structure.TIM_RepetitionCounter = 0x00;
TIM_TimeBaseInit(TIM2, &timer_init_structure);
/*使能TIM2中断 */
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
/*选择TIM2的update事件更新为触发源*/
TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update);
/*使能TIM2*/
TIM_Cmd(TIM2, ENABLE);
/* ADC1 DeInit */
ADC_DeInit(ADC1);
/*初始化ADC结构体,此句必须加,不加的话多路ADC数据会交换*/
ADC_StructInit(&ADC_InitStructure);
/*配置ADC分辨率为12位*/
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
/*开启连续转换*/
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
/*禁止触发检测,使用软件触发*/
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConv_T2_TRGO;
/*ADC采集数据右对齐*/
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
/*向上扫描*/
ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Upward;
/*ADC初始化*/
ADC_Init(ADC1, &ADC_InitStructure);
/*配置采样通道及时间*/
ADC_ChannelConfig(ADC1, GPIO_Pin_2 | ADC_Channel_3 | ADC_Channel_5 | GPIO_Pin_6 , ADC_SampleTime_28_5Cycles);
/* ADC 校准 */
ADC_GetCalibrationFactor(ADC1);
/* 循环模式下的 ADC DMA 请求 */
ADC_DMARequestModeConfig(ADC1, ADC_DMAMode_Circular);
/* 使能 ADC_DMA */
ADC_DMACmd(ADC1, ENABLE);
/* 使能 ADC1 */
ADC_Cmd(ADC1, ENABLE);
/* 等待 ADCEN 标志 */
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADEN));
/* ADC1 常规软件启动转换 */
ADC_StartOfConversion(ADC1);
/* 复位DMA1_Channel1 */
DMA_DeInit(DMA1_Channel1);
/*DMA外设ADC基地址*/
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_Address;
/*DMA内存基地址*/
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADC_ConvertedValue;
/*外设作为数据传输源*/
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
/*DMA通道的DMA缓存的大小*/
DMA_InitStructure.DMA_BufferSize = 4 * AD_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循环模式,即完成后重新开始覆盖*/
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
/*DMA优先级设置为高*/
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
/*DMA通道x禁用内存到内存传输*/
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
/*DMA初始化*/
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
/*清除一次DMA中断标志*/
DMA_ClearITPendingBit(DMA1_IT_TC1);
/*使能DMA传输完成中断*/
DMA_ITConfig(DMA1_Channel1, DMA1_IT_TC1, ENABLE);
/*选择DMA1通道中断*/
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;
/*中断使能*/
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
/*优先级设为0 */
NVIC_InitStructure.NVIC_IRQChannelPriority = 0;
/*使能 DMA 中断*/
NVIC_Init(&NVIC_InitStructure);
/* DMA1 Channel1 enable */
DMA_Cmd(DMA1_Channel1, ENABLE);
}
/**
* @brief ADC滤波
* @param 无
* @retval 无
*/
void ADC_Filter(void)
{
uint8_t i, j;
/*从DMA缓存中取出AD数据*/
for(i=0; i<4; i++)
{
for(j=0; j<AD_Count; j++)
{
ADCresults
[j] = ADC_ConvertedValue[j]
;
}
}
/*取值求和取平均*/
for(i=0; i<4; i++)
{
AD_Data
= 0;
for(j=0; j<AD_Count; j++)
{
AD_Data
+= ADCresults
[j];
}
AD_Data
=(AD_Temp
*75 + ((AD_Data
)/ (AD_Count))*25)/100;
AD_Temp
= AD_Data
;
}
// printf(" AD_value1=%d AD_value2=%d ",AD_Data[0], AD_Data[1]);
}
/**
* @brief DMA1_Channel1中断服务函数
* @param 无
* @retval 无
*/
void DMA1_Channel1_IRQHandler()
{
/*判断DMA传输完成中断*/
if(DMA_GetITStatus(DMA1_IT_TC1) != RESET)
{
// AD_Count_flag++;
// if(AD_Count_flag==64)
flag_ADC = 1;
}
/*清除DMA中断标志位*/
DMA_ClearITPendingBit(DMA1_IT_TC1);
}
加载中...
查看其它6个回答
一周热门
更多
>
相关问题
STM32F4上I2C(在PROTEUS中模拟)调试不通的问题
6 个回答
芯片供应紧张,准备换个MCU,MM32L系列替换STM32L系列的怎么样?
7 个回答
STM32同时使用两个串口进行数据收发时数据丢包的问题
5 个回答
STM32F103串口通信死机问题
4 个回答
STM32WLE5CC连接SX1268在LoRa模式下能与 SX1278互通吗?
2 个回答
相关文章
ST公司第一款无线低功耗单片机模块有效提高物联网设计生产效率
0个评论
如何实现对单片机寄存器的访问
0个评论
通过USB用STM32片内自带Bootloader下载程序及注意事项
0个评论
欲练此功必先自宫之STM32汇编启动,放慢是为了更好的前行
0个评论
×
关闭
采纳回答
向帮助了您的知道网友说句感谢的话吧!
非常感谢!
确 认
×
关闭
编辑标签
最多设置5个标签!
STM32
保存
关闭
×
关闭
举报内容
检举类型
检举内容
检举用户
检举原因
广告推广
恶意灌水
回答内容与提问无关
抄袭答案
其他
检举说明(必填)
提交
关闭
×
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
×
付费偷看金额在0.1-10元之间
确定
×
关闭
您已邀请
0
人回答
查看邀请
擅长该话题的人
回答过该话题的人
我关注的人
* @file ADC_Configuration
* @brief 完成ADC和DMA的初始化
* @param 无
* @retval 无
*/
void ADC_Configuration(uint32_t _ulFreq)
{
GPIO_InitTypeDef GPIO_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
TIM_TimeBaseInitTypeDef timer_init_structure;
NVIC_InitTypeDef NVIC_InitStructure;
uint16_t usPeriod;
uint16_t usPrescaler;
uint32_t uiTIMxCLK;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
/*设置ADC分频因子为4 ,ADC最大时间不能超过14M*/
RCC_ADCCLKConfig(RCC_ADCCLK_PCLK_Div4);
/* ADC1 Periph clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
/* 使能DMA时钟 */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1 , ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_5 | GPIO_Pin_6 ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
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; /* 自动重装的值 */
}
/*复位TIM2*/
TIM_DeInit(TIM2);
/*初始化TIMBASE结构体*/
TIM_TimeBaseStructInit(&timer_init_structure);
/*系统时钟,不分频,48M*/
timer_init_structure.TIM_ClockDivision = TIM_CKD_DIV1;
/*向上计数模式*/
timer_init_structure.TIM_CounterMode = TIM_CounterMode_Up;
/*每312 uS触发一次中断,开启ADC*/
timer_init_structure.TIM_Period = usPeriod;
/*计数时钟预分频,f=1M,systick=1 uS */
timer_init_structure.TIM_Prescaler = usPrescaler;
/*发生0+1次update事件产生中断 */
timer_init_structure.TIM_RepetitionCounter = 0x00;
TIM_TimeBaseInit(TIM2, &timer_init_structure);
/*使能TIM2中断 */
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
/*选择TIM2的update事件更新为触发源*/
TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update);
/*使能TIM2*/
TIM_Cmd(TIM2, ENABLE);
/* ADC1 DeInit */
ADC_DeInit(ADC1);
/*初始化ADC结构体,此句必须加,不加的话多路ADC数据会交换*/
ADC_StructInit(&ADC_InitStructure);
/*配置ADC分辨率为12位*/
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
/*开启连续转换*/
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
/*禁止触发检测,使用软件触发*/
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConv_T2_TRGO;
/*ADC采集数据右对齐*/
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
/*向上扫描*/
ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Upward;
/*ADC初始化*/
ADC_Init(ADC1, &ADC_InitStructure);
/*配置采样通道及时间*/
ADC_ChannelConfig(ADC1, GPIO_Pin_2 | ADC_Channel_3 | ADC_Channel_5 | GPIO_Pin_6 , ADC_SampleTime_28_5Cycles);
/* ADC 校准 */
ADC_GetCalibrationFactor(ADC1);
/* 循环模式下的 ADC DMA 请求 */
ADC_DMARequestModeConfig(ADC1, ADC_DMAMode_Circular);
/* 使能 ADC_DMA */
ADC_DMACmd(ADC1, ENABLE);
/* 使能 ADC1 */
ADC_Cmd(ADC1, ENABLE);
/* 等待 ADCEN 标志 */
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADEN));
/* ADC1 常规软件启动转换 */
ADC_StartOfConversion(ADC1);
/* 复位DMA1_Channel1 */
DMA_DeInit(DMA1_Channel1);
/*DMA外设ADC基地址*/
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_Address;
/*DMA内存基地址*/
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADC_ConvertedValue;
/*外设作为数据传输源*/
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
/*DMA通道的DMA缓存的大小*/
DMA_InitStructure.DMA_BufferSize = 4 * AD_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循环模式,即完成后重新开始覆盖*/
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
/*DMA优先级设置为高*/
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
/*DMA通道x禁用内存到内存传输*/
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
/*DMA初始化*/
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
/*清除一次DMA中断标志*/
DMA_ClearITPendingBit(DMA1_IT_TC1);
/*使能DMA传输完成中断*/
DMA_ITConfig(DMA1_Channel1, DMA1_IT_TC1, ENABLE);
/*选择DMA1通道中断*/
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;
/*中断使能*/
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
/*优先级设为0 */
NVIC_InitStructure.NVIC_IRQChannelPriority = 0;
/*使能 DMA 中断*/
NVIC_Init(&NVIC_InitStructure);
/* DMA1 Channel1 enable */
DMA_Cmd(DMA1_Channel1, ENABLE);
}
/**
* @brief ADC滤波
* @param 无
* @retval 无
*/
void ADC_Filter(void)
{
uint8_t i, j;
/*从DMA缓存中取出AD数据*/
for(i=0; i<4; i++)
{
for(j=0; j<AD_Count; j++)
{
ADCresults[j] = ADC_ConvertedValue[j];
}
}
/*取值求和取平均*/
for(i=0; i<4; i++)
{
AD_Data = 0;
for(j=0; j<AD_Count; j++)
{
AD_Data += ADCresults[j];
}
AD_Data =(AD_Temp*75 + ((AD_Data)/ (AD_Count))*25)/100;
AD_Temp = AD_Data;
}
// printf(" AD_value1=%d AD_value2=%d ",AD_Data[0], AD_Data[1]);
}
/**
* @brief DMA1_Channel1中断服务函数
* @param 无
* @retval 无
*/
void DMA1_Channel1_IRQHandler()
{
/*判断DMA传输完成中断*/
if(DMA_GetITStatus(DMA1_IT_TC1) != RESET)
{
// AD_Count_flag++;
// if(AD_Count_flag==64)
flag_ADC = 1;
}
/*清除DMA中断标志位*/
DMA_ClearITPendingBit(DMA1_IT_TC1);
}
一周热门 更多>