完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
各位大侠,本人在用STM32F051R8T6 DMA方式实现采样ADC数据时,结果发现,从串口输出来的数值不对,一路数据很大,一路数据为零,弄了半天,也没有解决这个问题,只好请各位大侠们帮忙给看看,非常感谢!
【说明】:利用DMA中断方式,进行一路数据采集时是正常的。 相关源码如下: /* ADC1数据寄存器地址 */ #define ADC1_DR_Address 0x40012440 /* 宏定义 -------------------------------------------------------------*/ /* 变量定义 ---------------------------------------------------------*/ extern float AD_CH_1 = 0; extern float AD_CH_2 = 0 ; extern unsigned int ADC_Value[2]={0,0};//内存数组 /******************************************************************************* * 函数名称: ADC_GPIO_Init(); * 功能描述: ADC--GPIO输入引脚配置---在此可以设置16路外部输入通道 * 输入参数: void * 返回参数: 无 ********************************************************************************/ void ADC_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 |GPIO_Pin_1; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOB, &GPIO_InitStructure); } /******************************************************************************* * 函数名称: ADC_DMA_Reset() * 功能描述: ADC模块初始化 * 输入参数: void * 返回参数: 无 ********************************************************************************/ void ADC_DMA_Reset(void) { ADC_InitTypeDef ADC_InitStructure; DMA_InitTypeDef DMA_InitStructure; ADC_DeInit(ADC1); //复位ADC1,将外设 ADC1 的全部寄存器重设为缺省值 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); // 使能ADC1通道时钟 RCC_AHBPeriphClockCmd( RCC_AHBPeriph_DMA1 , ENABLE); // 使能DMA通道时钟 ADC_GPIO_Init(); //ADC-GPIO引脚初始化 ////////////////////////////////////////////////////////////////////////////////// /* DMA1 通道1配置设置*/ DMA_DeInit(DMA1_Channel1); DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_Address; //DMA对应的外设基地址 DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADC_Value; //内存存储基地址,定义的一个数组 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //DMA转换模式为SRC模式,由外设搬移到内存 DMA_InitStructure.DMA_BufferSize = 2; // DMA缓存大小,2个(设置DMA在传输时缓冲区的长度) DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//接收一次数据后,设备地址禁止后移(设置DMA的外设递增模式) DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //关闭接收一次数据后,目标内存地址后移(设置DMA的内存递增模式) DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//定义外设数据长度--16位 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; // 循环模式开启,Buf写满后,自动回到初始地址开始传输 DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; //DMA_Priority_High; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel1, &DMA_InitStructure); DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE); DMA_Cmd(DMA1_Channel1, ENABLE); // DMA1 Channel1 使能 ADC_DMARequestModeConfig(ADC1, ADC_DMAMode_Circular); // ADC DMA 配置在循环模式下面 //////////////////////////////////////////////////////////////////////////////////// ADC_Structinit(&ADC_InitStructure); ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; //12位精度 ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; // 连续转换模式 ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; //转换由软件而不是外部触发启动 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //数据右对齐 ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Backward; //后前:0--18通道 ADC_Init(ADC1, &ADC_InitStructure); ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // ADC_ChannelConfig(ADC1, ADC_Channel_TempSensor, ADC_SampleTime_239_5Cycles ); // ADC_TempSensorCmd(ENABLE); //使能内部温度传感器 // ADC_ChannelConfig(ADC1, ADC_Channel_Vrefint,ADC_SampleTime_239_5Cycles); //ADC_VrefintCmd(ENABLE); ADC_ChannelConfig(ADC1, ADC_Channel_8 , ADC_SampleTime_71_5Cycles ); ADC_ChannelConfig(ADC1, ADC_Channel_9 , ADC_SampleTime_71_5Cycles ); //////////////////////////////////////////////////////////////////////////////////////// ADC_GetCalibrationFactor(ADC1); // 开始ADC校准 ADC_Cmd(ADC1, ENABLE); // 使能指定的ADC1 while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADEN)); /* 等待ADC准备好 */ ADC_DMACmd(ADC1, ENABLE); // 使能 ADC_DMA ADC_StartOfConversion(ADC1); //开始温度转换; } DMA中断函数 void DMA1_Channel1_IRQHandler(void) { if(DMA_GetFlagStatus(DMA1_FLAG_TC1) != RESET ) //检测DMA1TC1标志 { Delay(50000); AD_CH_1 = (float)ADC_Value[0]; AD_CH_1 = AD_CH_1 /4096*3.3; AD_CH_2 = (float)ADC_Value[1]; AD_CH_2 = AD_CH_2/4096*3.3; DMA_ClearFlag(DMA1_FLAG_TC1);//清除DMA TC1标志 } } |
|
相关推荐
8个回答
|
|
把工程放上来看看。
|
|
|
|
初看一下应该是DMA中断函数考虑的不太完整吧,有更完整的代码才好
|
|
|
|
你先把你输出的值 给固定值 输出 看看对不对 ,如果不对的话 就是DMA 配置有问题,如果对的话 就说明你AD采集的函数 跟配置有问题 ,你这样分开来查查
|
|
|
|
你看看这个初始化:
/*----------------------------------------------------------* | ADC Initialisation | *----------------------------------------------------------*/ void adc_Init (void) { // GPIOA->CRL &= ~0x0000000F; /* set PIN1 analog input (see stm32_Init.c) */ RCC->AHBENR |= (1CPAR = (unsigned long)&(ADC1->DR); /* set chn1 peripheral address */ DMA1_Channel1->CNDTR = 3; /* transmit 3 words */ // DMA1_Channel1->CCR = 0x00002520; /* configure DMA channel 1 */ DMA1_Channel1->CCR = 0x000025A0; /* configure DMA channel 1 */ /* circular mode, memory increment mode */ /* memory & peripheral size 16bit */ /* channel priotity high */ DMA1_Channel1->CCR |= (1 APB2ENR |= (1SQR3 = (3 |
|
|
|
单步跟踪下,我用的DMA当时是一个通道转换完成就中断,单步的时候,你看下你的转换值,两通道的话,就得中端两次
|
|
|
|
非常感谢各位大侠的回复,本人已经顺利解决了这个问题,原来 extern unsigned int ADC_Value[2]={0,0};//内存数组,
unsigned int 变量改为_IO uint16后,就可以了。费了几天,还是出在一个小问题上。非常感谢! |
|
|
|
学习了,我也碰到这个问题
|
|
|
|
为什么这个类型会导致问题呢?
|
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
2136 浏览 1 评论
AD7686芯片不传输数据给STM32,但是手按住就会有数据。
1970 浏览 3 评论
4566 浏览 0 评论
如何解决MPU-9250与STM32通讯时,出现HAL_ERROR = 0x01U
2116 浏览 1 评论
hal库中i2c卡死在HAL_I2C_Master_Transmit
2629 浏览 1 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-24 06:28 , Processed in 0.785193 second(s), Total 85, Slave 69 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号