完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
|
|
相关推荐
8个回答
|
|
你现在有几个问题,
一,LCD显示问题,你需要写LCD的硬件驱动程序,也就是控制LCD显示部分的程序,这样你才能在LCD上显示,最好先把这部分程序调通,这样后面的调试过程中可以在LCD上显示必要的调试信息。 二,DMA部分,用DMA方式做ADC,在DMA设置时有一个缓存区是编程时指定的,在你的程序里是 DMA_InitStructure.DMA_MemoryBaseAddr=(uint32_t)ADC_Value; ,所以你的ADC结果都在ADC_Value里。 三,对AD结果取平均值的问题,最简单的平均就是所有AD的结果累加,再除以AD的次数,这里DMA_InitStructure.DMA_BufferSize=ADC_NUM;应该是决定了AD的次数,这里需要查看库函数手册和芯片手册,你用了2个AD通道,在DMA里会有一个AD结果排列次序的问题。 四,AD触发启动的问题,你这里是软件触发ADC_SoftwareStartConvCmd(ADC1, ENABLE);,但是没有判断AD转换是否结束,而且需要查手册软件触发是不是启动一次,就会不停的自动转换下去,还是每次AD转换都需要进行一次软件触发。
最佳答案
|
|
|
|
做什么用 1 0 0 2 9 2 5 0 9 4
|
|
|
|
在学习ADC多通道DMA采样,程序老是调不对,感觉自己的采样显示函数写的不对。
|
|
|
|
最好是把程序贴出来,或者是把显示那部分贴出来,还有LCD是什么型号的
|
|
|
|
ADC: #include "adc.h" #include "delay.h" //³õʼ»¯ADC //ÕâÀïÎÒÃǽöÒÔ¹æÔòͨµÀΪÀý //ÎÒÃÇĬÈϽ«¿ªÆôͨµÀ0~3 void Adc_Init(void) { ADC_InitTypeDef ADC_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1 , ENABLE ); //ʹÄÜADC1ͨµÀʱÖÓ RCC_ADCCLKConfig(RCC_PCLK2_Div6); //ÉèÖÃADC·ÖƵÒò×Ó6 72M/6=12,ADC×î´óʱ¼ä²»Äܳ¬¹ý14M //PA1 ×÷ΪģÄâͨµÀÊäÈëÒý½Å GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //Ä£ÄâÊäÈëÒý½Å GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //Ä£ÄâÊäÈëÒý½Å GPIO_Init(GPIOA, &GPIO_InitStructure); ADC_DeInit(ADC1); //¸´Î»ADC1,½«ÍâÉè ADC1 µÄÈ«²¿¼Ä´æÆ÷ÖØÉèΪȱʡֵ ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //ADC¹¤×÷ģʽ:ADC1ºÍADC2¹¤×÷ÔÚ¶ÀÁ¢Ä£Ê½ ADC_InitStructure.ADC_ScanConvMode = ENABLE; //Ä£Êýת»»¹¤×÷ÔÚ¶àͨµÀģʽ ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //Ä£Êýת»»¹¤×÷ÔÚÁ¬Ðøת»» ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //ת»»ÓÉÈí¼þ¶ø²»ÊÇÍⲿ´¥·¢Æô¶¯ ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //ADCÊý¾ÝÓÒ¶ÔÆë ADC_InitStructure.ADC_NbrOfChannel = 2; //˳Ðò½øÐйæÔòת»»µÄADCͨµÀµÄÊýÄ¿ ADC_Init(ADC1, &ADC_InitStructure); //¸ù¾ÝADC_InitStructÖÐÖ¸¶¨µÄ²ÎÊý³õʼ»¯ÍâÉèADCxµÄ¼Ä´æÆ÷ ADC_RegularChannelConfig(ADC1,ADC_Channel_1, 1, ADC_SampleTime_239Cycles5 ); ADC_RegularChannelConfig(ADC1,ADC_Channel_2, 2, ADC_SampleTime_239Cycles5 ); //ADC_SoftwareStartConvCmd(ADC1, ENABLE); ADC_DMACmd(ADC1, ENABLE); ADC_Cmd(ADC1, ENABLE); //ʹÄÜÖ¸¶¨µÄADC1 ADC_ResetCalibration(ADC1); //ʹÄܸ´Î»Ð£×¼ while(ADC_GetResetCalibrationStatus(ADC1)); //µÈ´ý¸´Î»Ð£×¼½áÊø ADC_StartCalibration(ADC1); //¿ªÆôADУ׼ while(ADC_GetCalibrationStatus(ADC1)); //µÈ´ýУ׼½áÊø // ADC_SoftwareStartConvCmd(ADC1, ENABLE); //ʹÄÜÖ¸¶¨µÄADC1µÄÈí¼þת»»Æô¶¯¹¦ÄÜ } DMA: #include "dma.h" #define ADC_NUM 2 //ͨµÀÊýÄ¿ //#define Sample_NUM 20 //²ÉÑù´ÎÊý extern u16 ADC_Value[ADC_NUM]; //u16 After_filter[Sample_NUM]; void DMA_Config(void) { DMA_InitTypeDef DMA_InitStructure; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE); DMA_DeInit(DMA1_Channel1); DMA_InitStructure.DMA_PeripheralBaseAddr=(uint32_t)&ADC1->DR; DMA_InitStructure.DMA_MemoryBaseAddr=(uint32_t)ADC_Value; DMA_InitStructure.DMA_DIR=DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_BufferSize=ADC_NUM; 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_InitStructure.DMA_Priority=DMA_Priority_High; DMA_InitStructure.DMA_M2M=DMA_M2M_Disable; DMA_Init(DMA1_Channel1,&DMA_InitStructure); DMA_Cmd(DMA1_Channel1,ENABLE); } TIM: #include "led.h" #include "delay.h" #include "key.h" #include "sys.h" #include "lcd.h" #include "usart.h" #include "dma.h" #include "adc.h" #include "timer.h" #define ADC_NUM 2 u16 ADC_Value[ADC_NUM]={0,1}; float temp; //ͨÓö¨Ê±Æ÷3Öжϳõʼ»¯ //ÕâÀïʱÖÓÑ¡ÔñΪAPB1µÄ2±¶£¬¶øAPB1Ϊ36M //arr£º×Ô¶¯ÖØ×°Öµ¡£ //psc£ºÊ±ÖÓÔ¤·ÖƵÊý //ÕâÀïʹÓõÄÊǶ¨Ê±Æ÷3! void TIM3_Int_Init(u16 arr,u16 psc) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //ʱÖÓʹÄÜ //¶¨Ê±Æ÷TIM3³õʼ»¯ TIM_TimeBaseStructure.TIM_Period = arr; //ÉèÖÃÔÚÏÂÒ»¸ö¸üÐÂʼþ×°Èë»î¶¯µÄ×Ô¶¯ÖØ×°ÔؼĴæÆ÷ÖÜÆÚµÄÖµ TIM_TimeBaseStructure.TIM_Prescaler =psc; //ÉèÖÃÓÃÀ´×÷ΪTIMxʱÖÓƵÂʳýÊýµÄÔ¤·ÖƵֵ TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //ÉèÖÃʱÖÓ·Ö¸î:TDTS = Tck_tim TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIMÏòÉϼÆÊýģʽ TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //¸ù¾ÝÖ¸¶¨µÄ²ÎÊý³õʼ»¯TIMxµÄʱ¼ä»ùÊýµ¥Î» TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); //ʹÄÜÖ¸¶¨µÄTIM3ÖжÏ,ÔÊÐí¸üÐÂÖÐ¶Ï //ÖжÏÓÅÏȼ¶NVICÉèÖà NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; //TIM3ÖÐ¶Ï NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //ÏÈÕ¼ÓÅÏȼ¶0¼¶ NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //´ÓÓÅÏȼ¶3¼¶ NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQͨµÀ±»Ê¹ÄÜ NVIC_Init(&NVIC_InitStructure); //³õʼ»¯NVIC¼Ä´æÆ÷ TIM_Cmd(TIM3, ENABLE); //ʹÄÜTIMx } //¶¨Ê±Æ÷3ÖжϷþÎñ³ÌÐò void TIM3_IRQHandler(void) //TIM3ÖÐ¶Ï { if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //¼ì²éTIM3¸üÐÂÖжϷ¢ÉúÓë·ñ { TIM_ClearITPendingBit(TIM3, TIM_IT_Update ); //Çå³ýTIMx¸üÐÂÖжϱêÖ¾ LCD_ShowxNum(156,130,ADC_Value[0],4,16,0);//ÏÔʾADCµÄÖµ temp=(float)ADC_Value[0]*(3.3/4096); ADC_Value[0]=temp; LCD_ShowxNum(156,150,ADC_Value[0],1,16,0);//ÏÔʾµçѹֵ temp-=ADC_Value[0]; temp*=1000; LCD_ShowxNum(172,150,temp,3,16,0X80); LCD_ShowxNum(156,130,ADC_Value[1],4,16,0);//ÏÔʾADCµÄÖµ temp=(float)ADC_Value[1]*(3.3/4096); ADC_Value[1]=temp; LCD_ShowxNum(156,150,ADC_Value[1],1,16,0);//ÏÔʾµçѹֵ temp-=ADC_Value[1]; temp*=1000; LCD_ShowxNum(172,150,temp,3,16,0X80); LED0=!LED0; delay_ms(250); } } main: #include "led.h" #include "delay.h" #include "key.h" #include "sys.h" #include "lcd.h" #include "usart.h" #include "dma.h" #include "adc.h" #include "timer.h" //#define ADC_NUM 2 //#define Sample_NUM 10 //extern u16 ADC_Value[ADC_NUM]; //u16 ADC_Value[Sample_NUM][ADC_NUM]; //u16 adcx1; //u16 adcx2; //float temp[ADC_NUM]; int main(void) { delay_init(); //ÑÓʱº¯Êý³õʼ»¯ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//ÉèÖÃÖжÏÓÅÏȼ¶·Ö×éΪ×é2£º2λÇÀÕ¼ÓÅÏȼ¶£¬2λÏìÓ¦ÓÅÏȼ¶ uart_init(115200); //´®¿Ú³õʼ»¯Îª115200 LED_Init(); //LED¶Ë¿Ú³õʼ»¯ LCD_Init(); Adc_Init(); //ADC³õʼ»¯ DMA_Config(); ADC_SoftwareStartConvCmd(ADC1, ENABLE); POINT_COLOR=RED;//ÉèÖÃ×ÖÌåΪºìÉ« LCD_ShowString(60,50,200,16,16,"Elite STM32"); LCD_ShowString(60,70,200,16,16,"ADC TEST"); LCD_ShowString(60,90,200,16,16,"ATOM@ALIENTEK"); LCD_ShowString(60,110,200,16,16,"2015/1/14"); //ÏÔʾÌáʾÐÅÏ¢ POINT_COLOR=BLUE;//ÉèÖÃ×ÖÌåΪÀ¶É« LCD_ShowString(60,130,200,16,16,"ADC_CH0_VAL:"); LCD_ShowString(60,150,200,16,16,"ADC_CH0_VOL:0.000V"); LCD_ShowString(60,180,200,16,16,"ADC_CH1_VAL:"); LCD_ShowString(60,200,200,16,16,"ADC_CH1_VOL:0.000V"); TIM3_Int_Init(2199,7199); while(1); } 就是怎样读取DMA传输的值,再用LCD显示出来,这部分程序不太会写 |
|
|
|
|
|
|
|
#include "adc.h" __IO uint16_t ADC_ConvertedValue[3];//分别存储AD三个通道的采样值 void ADC_Config() { GPIO_InitTypeDef GPIO_InitStructure; ADC_InitTypeDef ADC_InitStructure; DMA_InitTypeDef DMA_Initstructure; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);//使能DMA时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC , ENABLE ); //配置外设AD对应IO GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;//模拟输入模式 GPIO_Init(GPIOA , &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_Init(GPIOC , &GPIO_InitStructure); DMA_DeInit(DMA1_Channel1);//ADC1对应的DMA通道数 DMA_Initstructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;//外设AD的地址数据寄存器地址,数据手册上有 DMA_Initstructure.DMA_MemoryBaseAddr = (u32)ADC_ConvertedValue;//内存地址,就是你想要把采样值存在那个变量的地址 DMA_Initstructure.DMA_DIR = DMA_DIR_PeripheralSRC ;//方向(从外设到内存) DMA_Initstructure.DMA_BufferSize = 3;//几个通道,几个开辟连续的DMA存储单元 DMA_Initstructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable ;//外设地址不变 DMA_Initstructure.DMA_MemoryInc = DMA_MemoryInc_Enable ;//内存地址自增,因为3个通道嘛 DMA_Initstructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord ;//设置外设数据长度为半字,即16位 DMA_Initstructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord ;//设置DMA存储数据长度为半字,即16位 DMA_Initstructure.DMA_Mode = DMA_Mode_Circular ;//循环模式 DMA_Initstructure.DMA_Priority = DMA_Priority_VeryHigh ;//优先级 DMA_Initstructure.DMA_M2M = DMA_M2M_Disable ; DMA_Init(DMA1_Channel1 , &DMA_Initstructure ); DMA_Cmd(DMA1_Channel1 , ENABLE ); ADC_InitStructure.ADC_Mode = ADC_Mode_Independent ;//独立模式,不是多个AD共用一个通道 ADC_InitStructure.ADC_ScanConvMode = ENABLE ;//开启扫描模式,针对多通道时 ADC_InitStructure.ADC_ContinuousConvMode = ENABLE ;//开启连续转换模式 ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None ; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right ;//数据右对齐 ADC_InitStructure.ADC_NbrOfChannel = 3;//打来的ADC通道数目 ADC_Init(ADC1, &ADC_InitStructure ); RCC_ADCCLKConfig(RCC_PCLK2_Div6);//配置ADC时钟,为PCLK2的6分频,即12Mhz ADC_RegularChannelConfig(ADC1 , ADC_Channel_1 , 1 , ADC_SampleTime_1Cycles5 );//设置AD采集扫描顺序和采样周期为1.5ADC的时钟周期 ADC_RegularChannelConfig(ADC1 , ADC_Channel_2 , 2 , ADC_SampleTime_1Cycles5 );//所以ADC的转换速率为(1.5+12.5)/12=1.167us ADC_RegularChannelConfig(ADC1 , ADC_Channel_15 , 3 , ADC_SampleTime_1Cycles5 ); ADC_DMACmd(ADC1 , ENABLE );//使能AD DMA ADC_Cmd(ADC1 , ENABLE ); //AD校验 ADC_ResetCalibration(ADC1); while(ADC_GetResetCalibrationStatus(ADC1)); ADC_StartCalibration(ADC1); while(ADC_GetCalibrationStatus(ADC1)); ADC_SoftwareStartConvCmd(ADC1 , ENABLE );//采用软件触发方式 } 这是别人的代码,这些我都懂,就是不懂怎么再像读取ADC平均值那样把DMA传输得数据在通过程序读取,然后显示出来。 |
|
|
|
人中狼 发表于 2017-7-12 10:06 多谢,问题解决了 |
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
嵌入式学习-飞凌嵌入式ElfBoard ELF 1板卡-LCD显示图片编程示例之介绍mmap
238 浏览 0 评论
《DNESP32S3使用指南-IDF版_V1.6》第二章 常用的C语言知识点
629 浏览 0 评论
【RA-Eco-RA2E1-48PIN-V1.0开发板试用】(第三篇)ADC采集+PWM输出
552 浏览 0 评论
《DNK210使用指南 -CanMV版 V1.0》第四十五章 人脸识别实验
552 浏览 0 评论
1074 浏览 0 评论
【youyeetoo X1 windows 开发板体验】少儿AI智能STEAM积木平台
11764 浏览 31 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-23 04:49 , Processed in 0.598722 second(s), Total 58, Slave 48 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号