ADC的多通道采样LCD显示

2019-07-15 10:16发布

ADC双通道,DMA传输,但是不知道怎么编写在LCD上显示双路采样的值,
在网上搜过很多程序,都是通过串口打印的。求助,怎么编写?

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
6条回答
2017fgl
1楼-- · 2019-07-15 16:34
ST_Lover 发表于 2017-7-11 17:52
做什么用  1 0 0 2 9 2 5 0 9 4

在学习ADC多通道DMA采样,程序老是调不对,感觉自己的采样显示函数写的不对。

USER.zip 下载积分: 积分 -1 分

114.95 KB, 下载次数: 3, 下载积分: 积分 -1 分

人中狼
2楼-- · 2019-07-15 17:30
 精彩回答 2  元偷偷看……
2017fgl
3楼-- · 2019-07-15 18:13
人中狼 发表于 2017-7-11 18:55
最好是把程序贴出来,或者是把显示那部分贴出来,还有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显示出来,这部分程序不太会写
2017fgl
4楼-- · 2019-07-15 19:54
人中狼 发表于 2017-7-11 18:55
最好是把程序贴出来,或者是把显示那部分贴出来,还有LCD是什么型号的

程序贴出来,说要审核
2017fgl
5楼-- · 2019-07-15 23:41
人中狼 发表于 2017-7-11 18:55
最好是把程序贴出来,或者是把显示那部分贴出来,还有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传输得数据在通过程序读取,然后显示出来。
2017fgl
6楼-- · 2019-07-16 05:04
人中狼 发表于 2017-7-12 10:06
你现在有几个问题,
一,LCD显示问题,你需要写LCD的硬件驱动程序,也就是控制LCD显示部分的程序,这样你才能在LCD上显示,最好先把这部分程序调通,这样后面的调试过程中可以在LCD上显示必要的调试信息。
二,DMA部分,用DMA方式做ADC,在DMA设置时有一个缓存区是编程时指定的,在你的程序里是 DMA_InitStructure.DMA_Memo ...

多谢,问题解决了

一周热门 更多>