stm32 adcstm32f0多通道adc采集采集可以不采用dma吗

STM32F非ADC模式的多通道DMA
STM32F的ADC,有多种分类,如单次/连续,间断/不间断,规则组/注入组等。
1、当设为连续模式时,即continuous convert mode = enable。间断模式(discontinuous convert mode)无效。连续模式,用于描述转换序列(sequencer)在整个序列(序列,即包括若干个通道)转换完成后,是否再次从头开始扫描。
2、当设为连续模式时,即continuous convert mode = disable。间断模式(discontinuous convert mode)有效。间断模式用于描述转换序列是否分成若干小的序列(小序列的大小根据(number of discontinuous conversion)。如果间断模式使能,每个小序列转换完成后,便会停止,等待下一个转换开始指令。每个小序列,在读取数据前,均需启动转换,因为每次转换完成后,都停止了。
下面是代码中,对连续模式和间断模式的描述。
uint32_t ContinuousConvM /*!& Specifies whether the conversion is performed in single mode (one conversion) or continuous mode for regular group,
after the selected trigger occurred (software start or external trigger).
This parameter can be set to ENABLE or DISABLE. */
uint32_t DiscontinuousConvM /*!& Specifies whether the conversions sequence of regular group is performed in Complete-sequence/Discontinuous-sequence (main sequence subpided in successive parts).
Discontinuous mode is used only if sequencer is enabled (parameter &ScanConvMode&). If sequencer is disabled, this parameter is discarded.
Discontinuous mode can be enabled only if continuous mode is disabled. If continuous mode is enabled, this parameter setting is discarded.
This parameter can be set to ENABLE or DISABLE. */
下面是对于Poll方法下,多通道采集的配置。
static void MX_ADC1_Init(void)
ADC_ChannelConfTypeDef sC
/**Common config
hadc1.Instance = ADC1;
hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
hadc1.Init.ContinuousConvMode = DISABLE;
hadc1.Init.DiscontinuousConvMode = ENABLE;
hadc1.Init.NbrOfDiscConversion = 1;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.NbrOfConversion = 2;
if (HAL_ADC_Init(&hadc1) != HAL_OK)
_Error_Handler(__FILE__, __LINE__);
/**Configure Regular Channel
sConfig.Channel = ADC_CHANNEL_8;
sConfig.Rank = 1;
sConfig.SamplingTime = ADC_SAMPLETIME_55CYCLES_5;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
_Error_Handler(__FILE__, __LINE__);
/**Configure Regular Channel
sConfig.Channel = ADC_CHANNEL_9;
sConfig.Rank = 2;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
_Error_Handler(__FILE__, __LINE__);
注:此处配置为,每个小序列为1,即每个通道转换完就停止。如果大于1,转换完读取到的数据是最后一个通道的值。查看: 992|回复: 0
STM32 ADC规则组注入组多通道多次采集 DMA传输 KEIL
0.png (69.6 KB, 下载次数: 10)
17:41 上传
stm32单片机源程序:
//通过串口实时打印KEY3 KEY4电压值。
//每个通道采集50次
#include &pbdata.h&
void RCC_Configuration(void);
void GPIO_Configuration(void);
void NVIC_Configuration(void);
void USART_Configuration(void);
void ADC1_Configuration(void);
void DMA_Configuration(void);
vu16 AD_Value[N][M];& & & & //用来存放ADC转换结果,也是DMA的目标地址 define a N line and M row array
vu16 filterAD[M+1];& & & & & & & & & & & & //滤波后AD值
vu16 MM;
int fputc(int ch,FILE *f)
{
& & & & USART_SendData(USART1,(u8)ch);
& & & & while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
& & & &
}
int main(void)
{
& & & & RCC_Configuration();& & & &
& & & & GPIO_Configuration();
& & & & USART_Configuration();
& & & & NVIC_Configuration();
& & & & ADC1_Configuration();
& & & & DMA_Configuration();
& & & &&&
& & & & while(1)
& & & & {& & & &
& & & & & & & & delay_ms(10);& & & & & & & & //延时,防止第一次上电或复位时,ADC没有转换完成
& & & & & & & & filter();
& & & & & & & & printf(&key3=%f\r\n&,filterAD[0]*3.3/4095);
& & & & & & & & printf(&key4=%f\r\n&,filterAD[1]*3.3/4095);
& & & & & & & & printf(&pot =%f\r\n&,filterAD[2]*3.3/4095);
& & & & & & & & printf(&\r\n&);
& & & & & & & & delay_ms(1000);
& & & & }& & & &
}
void filter(void)
{
& & & & vu32 sum=0;& & & & & & & & //必须初始化为0,否则初值将保持上次调用值。
& & & & vu8 i=0,j=0;
& & & & for(i=0;i&M;i++)& & & & & & & & //M row
& & & & {
& & & & & & & & for(j=0;j&N;j++)& & & & //N line
& & & & & & & & {
& & & & & & & & & & & & sum+=AD_Value[j][i];
& & & & & & & & }
& & & & & & & & filterAD[i]=sum/N;
& & & & & & & & sum=0;
& & & & }& & & &
}
void RCC_Configuration(void)
{
&&SystemInit();//72m
& & & & RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);& & & & //GPIOA
& & & & RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);& & & & //USART
& & & & RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);& & & & & & & & //AFIO
& & & & RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);& & & & //GPIOC
& & & & RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);& & & & & & & & //ADC
& & & & RCC_ADCCLKConfig(RCC_PCLK2_Div6);& & & & & & & & & & & & & & & & & & & & & & & & //12M&&最大14M
& & & & RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); & & & & & & & & //使能DMA传输
void GPIO_Configuration(void)
{
&&GPIO_InitTypeDef GPIO_InitS& & & &
& & & & GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;//TX
& & & & GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
& & & & GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
& & & & GPIO_Init(GPIOA,&GPIO_InitStructure);
& & & & GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;//RX
& & & & GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;
& & & & GPIO_Init(GPIOA,&GPIO_InitStructure);
& & & & GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_2|GPIO_Pin_3;//ADin: POT K3 K4
& & & & GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;& & & & & & & & //模拟输入
& & & & GPIO_Init(GPIOC,&GPIO_InitStructure);
& & & &
void NVIC_Configuration(void)
{
&&NVIC_InitTypeDef NVIC_InitS
& & & & NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
& & & & NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
& & & & NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
& & & & NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
& & & & NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
& & & & NVIC_Init(&NVIC_InitStructure);
& & & & NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;//中断向量
& & & & NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;& & & & //1
& & & & NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;& & & & & & & & & & & & //0
& & & & NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
& & & & NVIC_Init(&NVIC_InitStructure);& & & &
& & & & NVIC_InitStructure.NVIC_IRQChannel = ADC1_2_IRQn;//中断向量
& & & & NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;& & & & //1
& & & & NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;& & & & & & & & & & & & //0
& & & & NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
& & & & NVIC_Init(&NVIC_InitStructure);& & & &
void USART_Configuration(void)
{
& & USART_InitTypeDef&&USART_InitS
& & & & USART_InitStructure.USART_BaudRate=9600;
& & & & USART_InitStructure.USART_WordLength=USART_WordLength_8b;
& & & & USART_InitStructure.USART_StopBits=USART_StopBits_1;
& & & & USART_InitStructure.USART_Parity=USART_Parity_No;
& & & & USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_N
& & & & USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;
& & & & USART_Init(USART1,&USART_InitStructure);
& & & & USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
& & & & USART_Cmd(USART1,ENABLE);
& & & & USART_ClearFlag(USART1,USART_FLAG_TC);
}
void ADC1_Configuration(void)
{
& & & & ADC_InitTypeDef&&ADC_InitS
& & & & ADC_DeInit(ADC1);& & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & //将外设 ADC1 的全部寄存器重设为缺省值
& & & & ADC_StructInit(&ADC_InitStructure);
& & & &
& & & & ADC_InitStructure.ADC_Mode=ADC_Mode_I& & & & & & & & & & & & //ADC1 ADC2工作在独立模式
& & & & ADC_InitStructure.ADC_ScanConvMode=ENABLE;& & & & & & & & & & & & & & & & & & & & & & & & //工作在单通道模式(还是扫描模式:多通道模式)
& & & & ADC_InitStructure.ADC_ContinuousConvMode=ENABLE;& & & & & & & & & & & & //模数转换工作在单次模式(还是连续模式)
& & & & ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_N//转换由软件而不是外部触发启动
& & & & ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_R& & & & //ADC数据右对齐
& & & & ADC_InitStructure.ADC_NbrOfChannel=M;& & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & //顺序进行转换的通道数
& & & & ADC_Init(ADC1, &ADC_InitStructure); & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器
& & & &
& & & & //设置指定ADC的规则组通道,设置它们的转化顺序和采样时间
& & & & //ADC1,ADC通道x,规则采样顺序值为y,采样时间为239.5周期
& & & & ADC_RegularChannelConfig(ADC1,ADC_Channel_12,1,ADC_SampleTime_239Cycles5);//选择ADC1通道12-PC2 KEY3
& & & & ADC_RegularChannelConfig(ADC1,ADC_Channel_13,2,ADC_SampleTime_239Cycles5);//选择ADC1通道13-PC3 KEY4
//& & & & ADC_RegularChannelConfig(ADC1,ADC_Channel_10,3,ADC_SampleTime_239Cycles5);//选择ADC1通道10-PC0 POT
& & & &
& & & & ADC_InjectedSequencerLengthConfig(ADC1,1);//设置注入组通道的转换序列长度&&
& & & & //设置指定 ADC 的注入组通道,设置它们的转化顺序和采样时间
& & & & ADC_InjectedChannelConfig(ADC1, ADC_Channel_10, 1,ADC_SampleTime_239Cycles5);& & & & //& &&&
& & & & ADC_SetInjectedOffset(ADC1,ADC_InjectedChannel_1,0);
& & & & ADC_ExternalTrigInjectedConvConfig(ADC1, ADC_ExternalTrigInjecConv_None); & & & & & & & & //选择定时器 1 的 TRGO 作为注入转换外部触发& &
& & & & ADC_AutoInjectedConvCmd(ADC1, ENABLE);& & & & & & & & & & & & //规则组转换完成自动转换注入组,适合做ADC通道的扩展。
& & & &
//& & & & ADC_ExternalTrigInjectedConvCmd(ADC1,ENABLE);& & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & //使用外部触发转换时使能。
//& & & & ADC_ITConfig(ADC1,ADC_IT_EOC,ENABLE);& & & & & & & & & & & & //规则组中断使能
& & & & ADC_ITConfig(ADC1, ADC_IT_JEOC, ENABLE);& & & & & & & & //注入组中断使能
& & & & ADC_ClearFlag(ADC1, ADC_FLAG_JEOC);&&& & & & & & & & & & & & & & & & //注入组转换结束标志位 清零 防止第一次转换时出错。
& & & &
& & & & ADC_DMACmd(ADC1, ENABLE);& & & & & & & & & & & & & & & & // 开启ADC的DMA支持(要实现DMA功能,还需独立配置DMA通道等参数)
& & & & ADC_Cmd(ADC1, ENABLE); & & & & & & & & & & & & & & & & & & & & //使能指定的ADC1
& & & & & & & &
& & & & ADC_ResetCalibration(ADC1);& & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & //重置校准器
& & & & while(ADC_GetResetCalibrationStatus(ADC1));& & & & & & & & //获取校准状态
& & & & ADC_StartCalibration(ADC1);& & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & //开始指定ADC的校准状态
& & & & while(ADC_GetCalibrationStatus(ADC1));& & & & & & & & & & & & & & & & //获取指定ADC的校准程序
&&& & & & & & & &
& & & & ADC_SoftwareStartConvCmd(ADC1,ENABLE);& & & & & & & & & & & & & & & & //使能软件启动规则组转换功能&&
//& & & & ADC_SoftwareStartInjectedConvCmd(ADC1,ENABLE);& & & & //使能ADCx 软件启动注入组转换功能 启动转换
}
void DMA_Configuration(void)
{& &
& & & & DMA_InitTypeDef DMA_InitS&&
& & & & DMA_DeInit(DMA1_Channel1); & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & //将DMA的通道1寄存器重设为缺省值&&
& & & & DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&ADC1-&DR; & & & & & & & & //DMA外设ADC基地址
& & & & DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&AD_V & & & & & & & & & & & & & & & & //DMA内存基地址&&
& & & & DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; & & & & & & & & & & & & & & & & & & & & & & & & //内存作为数据传输的目的地 外设作为数据传输的来源
& & & & DMA_InitStructure.DMA_BufferSize = M*N; & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & //DMA通道的DMA缓存的大小&&
& & & & DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_D //外设地址寄存器不变
& & & & DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_E & & & & & & & & & & & & //内存地址寄存器递增
& & & & DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfW //外设数据宽度为16位&&
& & & & DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfW & & & & & & & & & & & & & & & & //内存数据宽度为16位&&
& & & & DMA_InitStructure.DMA_Mode = DMA_Mode_C & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & //工作在循环缓存模式,当传输完一次后,重新接着传送,永不停息。
& & & & DMA_InitStructure.DMA_Priority = DMA_Priority_H & & & & & & & & & & & & & & & &
…………限于本文篇幅 余下代码请从51黑下载附件…………复制代码
完整代码下载:
(2.21 MB, 下载次数: 11)
17:02 上传
点击文件名下载附件
下载积分: 黑币 -5
Powered bySTM32 ADC DMA 中断模式多通道读取ADC转换值 - 追寻梦想的路 - 博客园
因为做一个电机控制项目,其中需要用到用PWM触发ADC,读取ADC的转换值。
这里有两个关键问题:
第一,如何使PWM触发ADC转换?
第二,如何在ADC多通道扫描模式下,读取各个channel的adc转换值?
第三,如何使用DMA读取多通道ADC转换值?
第一个问题,首先需要将ADC设置成外部触发转换,第二需要选择触发是发生在Timer的上升沿还是下降沿。程序如下:
adc.ADC_Resolution = ADC_Resolution_12b;
adc.ADC_ScanConvMode =ENABLE;
//&&&I&&&A&&&&
adc.ADC_ContinuousConvMode = ENABLE;
//&A&Ð&&&&&
adc.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_R
adc.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T8_CC1;
adc.ADC_DataAlign = ADC_DataAlign_R
//&O&O&&O&AE&&½&E½
adc.ADC_NbrOfConversion = 2;
ADC_Init(ADC1,&adc);
ADC_RegularChannelConfig(ADC1,ADC_Channel_1,1,ADC_SampleTime_56Cycles);
ADC_RegularChannelConfig(ADC1,ADC_Channel_2,2,ADC_SampleTime_56Cycles);
ADC_Cmd(ADC1,ENABLE);
//ADC_ITConfig(ADC1,ADC_IT_EOC,ENABLE);
//&E&&O&A&&&&ADC&OÐ&&I&&A&OÐ&&I&O&
ADC_DMACmd(ADC1, ENABLE);
ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);
第二个问题,如果是使用ADC1的多个通道进行转换,那么使用DMA,使每个通道转换成功的数据存入响应的内存位置中,会是一个很好的选择,DMA选择外设到内存,外设地址不增加,内存地址增加。
第三个问题,DMA的拓扑图如下,记得使用对应的DMA请求,需要设置好对应的DMAy、streamx和channelz,否则没法触发DMA中断。
这里使用的是ADCDMA请求,选择了DMA2 stream0 channel0。 对应的DMA配置程序如下
DMA_DeInit(DMA2_Stream0);
dma.DMA_Channel= DMA_Channel_0;
dma.DMA_PeripheralBaseAddr = (uint32_t)&(ADC1-&DR);
dma.DMA_Memory0BaseAddr = (uint32_t)ad_
dma.DMA_DIR = DMA_DIR_PeripheralToM
dma.DMA_BufferSize = 2;
dma.DMA_PeripheralInc = DMA_PeripheralInc_D
dma.DMA_MemoryInc = DMA_MemoryInc_E
dma.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfW//DMA_PeripheralDataSize_B
dma.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfW//DMA_MemoryDataSize_B
dma.DMA_Mode = DMA_Mode_C
dma.DMA_Priority = DMA_Priority_H
dma.DMA_FIFOMode = DMA_FIFOMode_D
dma.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterF
dma.DMA_MemoryBurst = DMA_Mode_N
dma.DMA_PeripheralBurst = DMA_PeripheralBurst_S
DMA_Init(DMA2_Stream0,&dma);
DMA_ITConfig(DMA2_Stream0,DMA_IT_TC,ENABLE);
DMA_Cmd(DMA2_Stream0,ENABLE);21ic官方微信-->
后使用快捷导航没有帐号?
ST MCU Finder
安装免费手机应用,
寻找理想的ST MCU
请完成以下验证码
查看: 11328|回复: 29
关于STM32 ADC用DMA采多通道时数据错位的问题
&&已结帖(0)
主题帖子积分
中级技术员, 积分 189, 距离下一级还需 111 积分
中级技术员, 积分 189, 距离下一级还需 111 积分
主题帖子积分
专家等级:结帖率:0%
主题帖子积分
中级技术员, 积分 189, 距离下一级还需 111 积分
中级技术员, 积分 189, 距离下一级还需 111 积分
我们现在用到STM32的两种CPU&STM32F101C8T6&和&STM32F103都出现相同的问题,ADC采样用DMA方式采集多个通道时出现数据通道错位的问题,一般情况下都是正常的,我们在实验室测试也没有问题,但是在客户现场用上一个多月后就会出现这种现象,我们的产品主要是电力测控,出现这种问题就很严重了,可能出现很大的事故,希望ST公司的的技术人员能及时给予我们帮助.DMA错位问题:关于采样处理:1.&&&&小表采ADC1的三个通道CH1/&CH2/&CH3,用DMA1传送到缓冲区ADCRegValue&[3]&中;2.&&&&然后用定进器Tim1定时中断(50*128&Hz)从ADCRegValue&[3]读数据到数组ADC_ConvertedTEMP[3*128]中;3.&&&&当128次采完时启用DMA2将ADC_ConvertedTEMP[3*128]传到ADC_ConvertedValue[3*128]数组中用于计算;4.&&&&正常情况下,ADCRegValue&[3]内的数据应为CH1/&CH2/&CH3ADC_ConvertedTEMP[3*128]&内的数据应为CH1/&CH2/&CH3&/&CH1/&CH2/&CH3…….ADC_&ConvertedValue&[3*128]&内的数据应为CH1/&CH2/&CH3&/&CH1/&CH2/&CH3…….急!急!急!&&(邱工)
, , , , , , ,
主题帖子积分
主题帖子积分
专家等级:结帖率:85%打赏:3.00受赏:0.00
主题帖子积分
应该用定时器中断(或定时器事件触发)启动采样,DMA完成中断
主题帖子积分
主题帖子积分
专家等级:结帖率:26%打赏:0.00受赏:12.00
主题帖子积分
你的问题好像与硬件无关,应该是软件处理的问题
我有几个问题:1)ADC的采样速率是多少?为什么要用定进器中断把数据从ADCRegValue[3]搬到ADC_ConvertedTEMP[3*128]中?这一步应该使用DMA1传送结束中断实现才对。2)如果用定进器中断实现数据从ADCRegValue[3]传送到ADC_ConvertedTEMP[3*128]中,如何保证数据传送过程中没有正在进行的ADC采样?3)如何保证DMA2将ADC_ConvertedTEMP[3*128]传到ADC_ConvertedValue[3*128]数组的过程中(你的描述3),没有正在进行的ADC采样(你的描述1),并且没有正在进行的定进器中断搬运数据(你的描述2)?4)非正常情况下错位的结果是什么样的?请问你在哪个城市?ST或ST代理商的哪个FAE负责支持你的?你可以通过站内短信高速我,谢谢。
主题帖子积分
主题帖子积分
专家等级:结帖率:3%
主题帖子积分
这不是开玩笑的了。
楼主拿自己的前途与公司的前提做赌注了啊!&&太冒险了。产品都有经过严格测试,软件反复推敲`,最坏打算~,绝对不可以发生的情况~
主题帖子积分
中级技术员, 积分 189, 距离下一级还需 111 积分
中级技术员, 积分 189, 距离下一级还需 111 积分
主题帖子积分
专家等级:结帖率:0%
主题帖子积分
中级技术员, 积分 189, 距离下一级还需 111 积分
中级技术员, 积分 189, 距离下一级还需 111 积分
关于STM32 ADC用DMA采多通道时数据错位的问题
ADC的时钟频率为9MHz,第个通道的采样时间为ADC_SampleTime_41Cycles5,为什么要用定进器中断把数据从ADCRegValue[3]搬到ADC_ConvertedTEMP[3*128]中呢?是因为我要根据外界的频率不断来调整我的定时器时间来采取数据,外界的频率不一定是50Hz,有可能为40Hz~70Hz的任意值,但我要保证一个周期采样128个点.2、对于用定进器中断实现数据从ADCRegValue[3]传送到ADC_ConvertedTEMP[3*128]中,数据传送过程中没有正在进行的ADC采样,我不用管它,因为数据都是一样的,不管它是新的数据,还是上一次的数据。3、如何保证DMA2将ADC_ConvertedTEMP[3*128]传到ADC_ConvertedValue[3*128]数组的过程中(你的描述3),没有正在进行的ADC采样(你的描述1),并且没有正在进行的定进器中断搬运数据(你的描述2),我们也不用管它,只要它在相同的地方,数据就是一样的,我也不用管它是新的数据,还是上一次的数据。&
主题帖子积分
中级技术员, 积分 189, 距离下一级还需 111 积分
中级技术员, 积分 189, 距离下一级还需 111 积分
主题帖子积分
专家等级:结帖率:0%
主题帖子积分
中级技术员, 积分 189, 距离下一级还需 111 积分
中级技术员, 积分 189, 距离下一级还需 111 积分
关于STM32 ADC用DMA采多通道时数据错位的问题
我们是深圳的公司
主题帖子积分
主题帖子积分
专家等级:结帖率:85%打赏:3.00受赏:0.00
主题帖子积分
有点无语……这真是一个奇特的采样方法...
主题帖子积分
中级技术员, 积分 189, 距离下一级还需 111 积分
中级技术员, 积分 189, 距离下一级还需 111 积分
主题帖子积分
专家等级:结帖率:0%
主题帖子积分
中级技术员, 积分 189, 距离下一级还需 111 积分
中级技术员, 积分 189, 距离下一级还需 111 积分
关于STM32 ADC用DMA采多通道时数据错位的问题
非正常情况下错位的结果是ADCRegValue&[3]内的数据为&CH2/&CH3/CH1&或 CH3/CH1/CH2ADC_ConvertedTEMP[3*128]&内的数据应为CH2/&CH3/CH1/&CH2/&CH3/CH1…….或&CH3/CH1/&CH2/&CH3/CH1/CH2/…….
主题帖子积分
主题帖子积分
专家等级:结帖率:26%打赏:0.00受赏:12.00
主题帖子积分
这2个DMA通道的优先级是如何设置的?
DMA1相对DMA2应该具有较高的优先级,这里是不是设置错误。怀疑是在DMA2传送数据时,正好碰上ADC采样需要DMA1的操作,但因为优先级的问题,ADC的数据没有及时地传送到ADCRegValue[3]中,造成了错位。另外,根据5楼的描述,DMA1应该使用循环模式,连续不断地从ADC获取采样数据。同时DMA1可以直接把从ADC获取的数据传送到ADC_ConvertedTEMP[3*128]缓冲区中,省掉ADCRegValue[3]这个中间环节。最后定时地把ADC_ConvertedTEMP[3*128]的内容拷贝到ADC_ConvertedValue[3*128]数组中进行计算。
主题帖子积分
主题帖子积分
专家等级:结帖率:100%
主题帖子积分
小板凳,学习
DMA是个好东西,我把原来的一些东西改到DMA下面。CPU的空余时间更多了,得再多给些活给它干,不能让它闲着。
主题帖子积分
主题帖子积分
专家等级:结帖率:3%
主题帖子积分
哈哈!楼主的程序有问题!
这样很明显了啊!程序问题。
主题帖子积分
初级技术员, 积分 86, 距离下一级还需 14 积分
初级技术员, 积分 86, 距离下一级还需 14 积分
主题帖子积分
专家等级:结帖率:0%
主题帖子积分
初级技术员, 积分 86, 距离下一级还需 14 积分
初级技术员, 积分 86, 距离下一级还需 14 积分
回复Netjob
楼上,很明显吗?你是不是看出哪的问题了?分享下嘛
主题帖子积分
助理工程师, 积分 1128, 距离下一级还需 872 积分
助理工程师, 积分 1128, 距离下一级还需 872 积分
主题帖子积分
专家等级:结帖率:6%
主题帖子积分
助理工程师, 积分 1128, 距离下一级还需 872 积分
助理工程师, 积分 1128, 距离下一级还需 872 积分
呵呵,你的处理太复杂了
即使要用DMA,为什么还要用定时器中断去读数据,128点采样,你可以通过DMA放到一个数据空间里,用DMA传输完毕后,再去分解数据。如果你要不想停AD,再定义一个比较大的空间采样就可以了吗?还有你要跟频率,直接用定时器捕捉频率就可以了,根据上个周期的电网信号频率来定下个电网频率的周期。况且电网信号一般不会很快波动,即时波动也只是测误差相对大一点。如果你是电网保护设备,这点波动根本是没有关系的
主题帖子积分
中级技术员, 积分 189, 距离下一级还需 111 积分
中级技术员, 积分 189, 距离下一级还需 111 积分
主题帖子积分
专家等级:结帖率:0%
主题帖子积分
中级技术员, 积分 189, 距离下一级还需 111 积分
中级技术员, 积分 189, 距离下一级还需 111 积分
关于STM32 ADC用DMA采多通道时数据错位的问题
不用定时器去读数据,我怎么样在一个周期波上采样均等的128个点呢?如果不用定时间器,我用DMA直接传128个采样数据不一定的我要的采样点数据,而且这128个采样点的时间周期是要根据输入的电网信号频率改变需改变的.
主题帖子积分
中级技术员, 积分 189, 距离下一级还需 111 积分
中级技术员, 积分 189, 距离下一级还需 111 积分
主题帖子积分
专家等级:结帖率:0%
主题帖子积分
中级技术员, 积分 189, 距离下一级还需 111 积分
中级技术员, 积分 189, 距离下一级还需 111 积分
STM32 ADC用DMA采多通道时数据错位的问题
不用定时器去读数据,我怎么样在一个周期波上采样均等的128个点呢?如果不用定时间器,我用DMA直接传128个采样数据不一定的我要的采样点数据,而且这128个采样点的时间周期是要根据输入的电网信号频率改变而改变的.我的产品在一般情况下是正常的,而且在实验室通过了所有需要的测试项目,但在客户现场用上几个月后就出现数据错位
主题帖子积分
中级技术员, 积分 189, 距离下一级还需 111 积分
中级技术员, 积分 189, 距离下一级还需 111 积分
主题帖子积分
专家等级:结帖率:0%
主题帖子积分
中级技术员, 积分 189, 距离下一级还需 111 积分
中级技术员, 积分 189, 距离下一级还需 111 积分
STM32 ADC用DMA采多通道时数据错位的问题
现在基本要确认是干拢产生的数据通道错位,我们在实验室用20KV的静电水平耦合,大概几秒钟就出现数据通道错位.
主题帖子积分
主题帖子积分
专家等级:结帖率:85%打赏:3.00受赏:0.00
主题帖子积分
ADC的数据不是你去读的时候才采样的呀,控制时间的是启动
建议你参考我的程序吧,我直接用DMA加定时器采样的,44.1KBps的。我的这个芯片是可以直接将定时器的比较信号启动ADC的。如果你的没有这个功能,那么在定时器中断中启动ADC即可。启动后它就开始转换了,这时才是真正的采样,转换完成后,它会自动去触发DMA去读数据。当指定的数据个数达到时,DMA会产生中断(或者你去查询也得),这时候就可以去处理这一些数据了。当然在数据处理之前,你可以先设置好DMA,指向另外一个缓冲区,同时又采样了。你要搞清楚这个关系:定时器是用来启动ADC的,而不是用来去读数据。ADC转换完毕会自动触发DMA读数据,DMA数据足够后,产生中断,处理数据。/club/bbs/showEssence.asp?id=10676
主题帖子积分
资深工程师, 积分 11272, 距离下一级还需 8728 积分
资深工程师, 积分 11272, 距离下一级还需 8728 积分
主题帖子积分
专家等级:结帖率:75%
主题帖子积分
资深工程师, 积分 11272, 距离下一级还需 8728 积分
资深工程师, 积分 11272, 距离下一级还需 8728 积分
出错情况要分清楚
&&出错情况要分清楚:是只在在施加干扰时出错,还是干扰消失后仍然出错。前一种情况或许可以忍受,后一种情况不能忍受、必须修正。
主题帖子积分
主题帖子积分
专家等级:结帖率:26%打赏:0.00受赏:12.00
主题帖子积分
16楼给出的信息是楼主位没有提到的,而这是一个非常关键的
18楼的问题是个实质问题,楼主如何看待这个问题呢?
主题帖子积分
主题帖子积分
专家等级:结帖率:3%
主题帖子积分
等着瞧, 我可以保证100%是程序问题。
永恒之光奖章
等级类勋章
技术导师奖章
人才类勋章
时间类勋章
坚毅之洋流
发帖类勋章
荣誉元老奖章
等级类勋章
时间类勋章
技术领袖奖章
人才类勋章
核心会员奖章
等级类勋章
技术新星奖章
人才类勋章
社区建设奖章
等级类勋章
欢快之小溪
发帖类勋章

我要回帖

更多关于 stm32 adc多通道非dma 的文章

 

随机推荐