完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
最近在学STM32F0芯片,在网上看到一个网友用DMA传输ADC采样值,并用tiM15间隔触发ADC的思路,觉得不错想把他的代码移植一下,由于我用的是STM32F030K6T6,与网友的芯片不一样,网友做的是三路连续采样,而我的硬件电路采样点只有一个,就是采样外部锂电池电压,锂电池电压约4.1v,用两个10K电阻串联分压,PA3采样分压电压(,图片上是两个100K,由于ADC采样电流的问题后将100K调整成10K),于是准备将通道17(Vref)加进来,也就是用DMA传输2路,后串口打印仿真发现采样值不正确,看规格书发现这句代码配置ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Upward 的解释是:向前扫描 ( 从 CHSEL0 到 CHSEL16) ,那这样可能采样不到通道17上面,将采样2路的想法放弃,于是又只单采样一路再打印值为97,为简单验证是否正确,用芯片供电电压3.3V加到采样通道PA3上,打印值为255,这样肯定采样不对,因我配置的是12位采样(DC_InitStructure.ADC_Resolution = ADC_Resolution_12b),理论值应该在4095左右,反复查询代码找不到问题,后来发现255这个参数好是配置8位采样的理论值,于是又将采样配置成8位,串口打印150,在PA3上加3.3v也是255,这样3.3V*150/255的结果是1.92V,至此排除误差,感觉ADC采样正确。 做这个实验我已经花了很多时间和精力,我不知道是不是因为只有一个ADC通道还配置DMA传输的问题,如果多几个通道(0-16)可能不会这样,能成功配置成12位采样,能力有限,请大神们帮忙指导一下,谢谢! 代码如下: //u16 ADC_Array[SAMPLE_NUM]; //u16 sample0[10],sample1[10]; u16 adc1,adc2; u8 ADC_Updata=0;//DMA传输完成标志 void Adc_Battery_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; ADC_InitTypeDef ADC_InitStructure; DMA_InitTypeDef DMA_InitStructure; NVIC_InitTypeDef NVIC_InitStruct; /*配置DMA中断*/ NVIC_InitStruct.NVIC_IRQChannel = DMA1_Channel1_IRQn; NVIC_InitStruct.NVIC_IRQChannelPriority = 0; NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStruct); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1 , ENABLE); RCC_ADCCLKConfig(RCC_ADCCLK_PCLK_Div4);//12M GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN ; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 ; //用PA3采样一个电压 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOA, &GPIO_InitStructure); ADC_DeInit(ADC1); DMA_DeInit(DMA1_Channel1);//channel1 DMA_StructInit(&DMA_InitStructure); DMA_InitStructure.DMA_BufferSize = 1; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC ; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable ;// DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&adc1; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;DMA_MemoryDataSize_HalfWord; DMA_InitStructure.DMA_MemoryInc= DMA_MemoryInc_Disable ; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular ; DMA_InitStructure.DMA_PeripheralBaseAddr =(uint32_t)(ADC1_BASE+0x40);//(uint32_t)(&ADC1->DR);//网友配置 的 是(uint32_t)ADC1_DR_Address,因为MDK没有这个定义,我修改了下,不知道是否正确,看有数据出来,猜想应该没问题。 DMA_InitStructure.DMA_PeripheralDataSize= DMA_MemoryDataSize_HalfWord; DMA_InitStructure.DMA_PeripheralInc =DMA_PeripheralInc_Disable ; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_Init(DMA1_Channel1, &DMA_InitStructure); ADC_DeInit(ADC1); ADC_StructInit(&ADC_InitStructure); ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;// 关闭连续模式,用定时器触发采样 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConvEdge_Rising;//上升沿触发 ; ADC_InitStructure.ADC_Resolution = ADC_Resolution_8b ; ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConv_T3_TRGO; //网友配置的是TIM15,我的芯片没有TIM15,用TIM3替代 ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Upward ; //向前扫描 ( 从 CHSEL0 到 CHSEL16) ADC_JitterCmd(ADC1, ADC_JitterOff_PCLKDiv4, ENABLE);//12M滤波采样 ADC_OverrunModeCmd(ADC1, ENABLE); ADC_ChannelConfig(ADC1, ADC_Channel_3, ADC_SampleTime_55_5Cycles); ADC_Init(ADC1,&ADC_InitStructure); // ADC_VrefintCmd(ENABLE); ADC_GetCalibrationFactor(ADC1); // ADC_ContinuousModeCmd(ADC1, ENABLE); ADC_Cmd(ADC1,ENABLE); while(ADC_GetFlagStatus(ADC1, ADC_FLAG_ADRDY ) == RESET); DMA_ITConfig(DMA1_Channel1,DMA_IT_TC,ENABLE); DMA_ClearFlag(DMA1_FLAG_TC1); ADC_DMACmd(ADC1, ENABLE); ADC_DMARequestModeConfig(ADC1, ADC_DMAMode_Circular); DMA_Cmd(DMA1_Channel1,ENABLE); ADC_StartOfConversion(ADC1); // while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC)==RESET); } void Adc_TimerInit(void) { TIM_TimeBaseInitTypeDef timer_init_structure; NVIC_InitTypeDef nvic_init_structure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3 , ENABLE); //打开TIM3时钟 nvic_init_structure.NVIC_IRQChannel = TIM3_IRQn; //TIM3中断 nvic_init_structure.NVIC_IRQChannelCmd = ENABLE; // nvic_init_structure.NVIC_IRQChannelPriority = 2; // NVIC_Init(&nvic_init_structure); TIM_DeInit(TIM3); // TIM_TimeBaseStructInit(&timer_init_structure); // timer_init_structure.TIM_ClockDivision = TIM_CKD_DIV1; //TIM3时钟48M timer_init_structure.TIM_CounterMode = TIM_CounterMode_Up; // timer_init_structure.TIM_Period = 999; //怕时间不够ADC采样,配置1S采样1次 timer_init_structure.TIM_Prescaler = 48000-1; timer_init_structure.TIM_RepetitionCounter = 0x00; TIM_TimeBaseInit(TIM3,&timer_init_structure); TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE); //??TIM15?? TIM_SelectOutputTrigger(TIM3, TIM_TRGOSource_Update); //配置TIM3更新触发中断 TIM_Cmd(TIM3, ENABLE); //??TIM15 } void TIM3_IRQHandler() { if(TIM_GetITStatus(TIM3, TIM_IT_Update)) //????update???? { //加一LED指示TIM3是否有工作 if(GPIO_ReadOutputDataBit(LED_PORT, LED3_PIN)==RESET) GPIO_SetBits(LED_PORT, LED3_PIN); else GPIO_ResetBits(LED_PORT, LED3_PIN); TIM_ClearITPendingBit(TIM3, TIM_IT_Update); // } } void DMA1_Channel1_IRQHandler() { /* u8 SampleIndex=0; if(DMA_GetITStatus(DMA1_IT_TC1)) { while(SampleIndex !=10) { sample0[SampleIndex] = ADC_Array[0+SampleIndex*2]&0x00000fff; sample1[SampleIndex] =ADC_Array[1+SampleIndex*2]&0x00000fff; SampleIndex++; } ADC_Updata=1; } DMA_ClearFlag(DMA1_FLAG_TC1);*/ if(DMA_GetITStatus(DMA1_IT_TC1)) { ADC_Updata=1; } DMA_ClearFlag(DMA1_FLAG_TC1); } 主程序 int main(void) { u16 Adc_Value; RCC_ClocksTypeDef RCC_CLOCK; SystemInit();//用的内部时钟,配置最大时钟48MHZ Delay_Init(); //systicK时钟配置 ALL_Config(); RCC_MCOConfig(RCC_MCOSource_HSI); RCC_GetClocksFreq(&RCC_CLOCK); while(1) { if(ADC_Updata==1) { ADC_Updata=0; // Adc_Value = ADC_Get_Average(sample0); printf("ADC_Valeue:%dn",adc1); printf("ADC_Voltage:%fn",3.3*adc1/255); // printf("ADC_Valeue:%fn",3.3*Adc_Value/4095); } delay_ms(1000); delay_ms(1000); }
|
|
相关推荐
2个回答
|
|
dma多通道 采集的数据存储 一般是 建立个 二维数组 存储方式 是按顺序存储 类似{1, 2} {1, 2} {1, 2} 每个数组 第一个数据 才是 第一通道的数据
|
|
|
|
最好是用cubemx进行配置一下再试
|
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
迅为RK3568开发板EMMC镜像导出打包update.img
403 浏览 0 评论
飞凌嵌入式-ELFBOARD 硬件知识分享-ELF 2电源电路讲解
1004 浏览 0 评论
1713 浏览 0 评论
飞凌嵌入式ElfBoard ELF 1板卡-mfgtools烧录流程介绍之烧写所需镜像
1511 浏览 0 评论
飞凌嵌入式ElfBoard ELF 1板卡-mfgtools烧录流程之烧写方法
956 浏览 0 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-26 14:02 , Processed in 0.532079 second(s), Total 45, Slave 37 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号