野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 17020|回复: 13

stm32 adc 多通道采集

[复制链接]
发表于 2013-12-24 19:11:02 | 显示全部楼层 |阅读模式
哪位大虾指点一下!!!我使用2通道采样DMA传输的时候怎么只有一个通道的数据正确的这是为什么呢?另一路就是屏幕上会出现很多黑色的竖线!!!求指导啊!!!



/******************** (C) COPYRIGHT 2012 WildFire Team ***************************
* 文件名  :adc.c
* 描述    :adc应用函数库        
* 实验平台:野火STM32开发板
* 硬件连接:----------------------------------------------------
*          |                                                    |
*          | PC1 - ADC1 连接外部电压(通过一个滑动变阻器分压而来)|
*          |                                                    |
*           ----------------------------------------------------
* 库版本  :ST3.5.0
*
* 作者    :wildfire team
* 论坛    :http://www.amobbs.com/forum-1008-1.html
* 淘宝    :http://firestm32.taobao.com
**********************************************************************************/
#include "adc.h"

#define ADC1_DR_Address    ((u32)0x40012400+0x4c)
__IO uint16_t AD_Value[2];          //定义数组AD_Value[2];  存放2个通道的值

__IO uint16_t ADC_ConvertedValue;
//__IO u16 ADC_ConvertedValueLocal;


/*
* 函数名:ADC1_GPIO_Config
* 描述  :使能ADC1和DMA1的时钟,初始化PC.01
* 输入  : 无
* 输出  :无
* 调用  :内部调用
*/
static void ADC1_GPIO_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
   
    /* Enable DMA clock */
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
   
    /* Enable ADC1 and GPIOC clock */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOC, ENABLE);
   
    /* Configure PC.01  as analog input */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
    GPIO_Init(GPIOC, &GPIO_InitStructure);                // PC0,输入时不用设置速率
        /* Configure PC.01  as analog input */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
    GPIO_Init(GPIOC, &GPIO_InitStructure);                // PC2,输入时不用设置速率
}


/* 函数名:ADC1_Mode_Config
* 描述  :配置ADC1的工作模式为MDA模式
* 输入  : 无
* 输出  :无
* 调用  :内部调用
*/
static void ADC1_Mode_Config(void)
{
    DMA_InitTypeDef DMA_InitStructure;
    ADC_InitTypeDef ADC_InitStructure;
     RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);//使能DMA时钟
   
    /* DMA channel1 configuration */
    DMA_DeInit(DMA1_Channel1);
    DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;     //ADC地址
    DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&AD_Value;//内存地址
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
    //BufferSize=2,因为ADC转换序列有2个通道
    //如此设置,使序列1结果放在AD_Value[0],序列2结果放在AD_Value[1]
    DMA_InitStructure.DMA_BufferSize = 64;
    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;
    //循环模式开启,Buffer写满后,自动回到初始地址开始传输
    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);           //配置完成后,启动DMA通道
   
    /* ADC1 configuration */
   
    ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;    //独立ADC模式
    ADC_InitStructure.ADC_ScanConvMode = ENABLE ;      //禁止扫描模式,扫描模式用于多通道采集
    ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;    //开启连续转换模式,即不停地进行ADC转换
    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;    //不使用外部触发转换
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;     //采集数据右对齐
    ADC_InitStructure.ADC_NbrOfChannel = 2;         //要转换的通道数目2
    ADC_Init(ADC1, &ADC_InitStructure);
   
    /*配置ADC时钟,为PCLK2的8分频,即9Hz*/
    RCC_ADCCLKConfig(RCC_PCLK2_DiARM);
    /*配置ADC1的通道11为55.    5个采样周期,序列为1 */
    ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_55Cycles5);
    ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 2, ADC_SampleTime_55Cycles5);
    /* Enable ADC1 DMA */
    ADC_DMACmd(ADC1, ENABLE);
   
    /* Enable ADC1 */
    ADC_Cmd(ADC1, ENABLE);
   
    /*复位校准寄存器 */   
    ADC_ResetCalibration(ADC1);
    /*等待校准寄存器复位完成 */
    while(ADC_GetResetCalibrationStatus(ADC1));
   
    /* ADC校准 */
    ADC_StartCalibration(ADC1);
    /* 等待校准完成*/
    while(ADC_GetCalibrationStatus(ADC1));
   
    /* 由于没有采用外部触发,所以使用软件触发ADC转换 */
    ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}

/*
* 函数名:ADC1_Init
* 描述  :无
* 输入  :无
* 输出  :无
* 调用  :外部调用
*/
void ADC1_Init(void)
{
    ADC1_GPIO_Config();
    ADC1_Mode_Config();
}



/******************* (C) COPYRIGHT 2012 WildFire Team *****END OF FILE************/


回复

使用道具 举报

发表于 2013-12-24 19:26:22 | 显示全部楼层
看看板子的引脚有没有复用
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-12-24 20:36:59 | 显示全部楼层
随风 发表于 2013-12-24 19:26
看看板子的引脚有没有复用

谢谢您的答复!引脚没有复用的,因为我之前分别单路AD采集PC0,PC2,都是可以的,但是两路AD采集就出问题了
回复 支持 反对

使用道具 举报

发表于 2013-12-24 20:50:55 | 显示全部楼层
adc.c (5.21 KB, 下载次数: 63)
adc.h (292 Bytes, 下载次数: 56)
之前调过4通道的,你下载了试试看,我看你的代码没有什么问题哈
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-12-25 10:25:40 | 显示全部楼层
♂荻夜 发表于 2013-12-24 20:50
之前调过4通道的,你下载了试试看,我看你的代码没有什么问题哈

谢谢您啦!!可是看了您的改了,采集2路信号还是不行,于是我单独显示一路还是不行,就是很多竖的黑线在屏幕上增加!!!对了,您的代码也是野火stm32吗??
回复 支持 反对

使用道具 举报

发表于 2013-12-25 10:42:05 | 显示全部楼层
南宫若郁 发表于 2013-12-25 10:25
谢谢您啦!!可是看了您的改了,采集2路信号还是不行,于是我单独显示一路还是不行,就是很多竖的黑线在屏 ...

我的就是在STM32上跑的啊,我跑的很正常。有很多黑线可能是显示屏显示的问题,你用串口看看这个第二个通道出来的是什么。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-12-25 20:48:59 | 显示全部楼层
♂荻夜 发表于 2013-12-25 10:42
我的就是在STM32上跑的啊,我跑的很正常。有很多黑线可能是显示屏显示的问题,你用串口看看这个第二个通道 ...

谢谢亲的细心答复,我在main函数里代码为以下,可是还是会有许多黑线,我贴张照片,亲,再帮我分析分析呗
ADC_ConvertedValueLocal =(float)(ADC_Value[0])/(4096*3.3);         // 读取转换的 AD 值
                        LCD_Point(i,220-ADC_ConvertedValueLocal*440);                                         //在指定坐标处显示一个点
                        Delay(0x3ffee);                                                                                                          // 延时
                        if(i>21)
                        LCD_Line(i-1,y0,i,220-ADC_ConvertedValueLocal*440) ;                                   //在指定两点之间画直线
                        i=i+1;
                        y0=220-ADC_ConvertedValueLocal*440;          
                        if(i>315)
                        {
                                i=20;
                            LCD_Rectangle(0,0,320,240,WHITE);                                                //在指定坐标处显示指定长宽的矩形
                       
                     }

回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-12-26 15:59:39 | 显示全部楼层
南宫若郁 发表于 2013-12-25 10:25
谢谢您啦!!可是看了您的改了,采集2路信号还是不行,于是我单独显示一路还是不行,就是很多竖的黑线在屏 ...

亲,我现在搞定了,是我把ADC-Value[2]这个数组定义错了,数据没有通过DMA传输!!!
回复 支持 反对

使用道具 举报

发表于 2013-12-26 17:42:00 | 显示全部楼层
南宫若郁 发表于 2013-12-26 15:59
亲,我现在搞定了,是我把ADC-Value[2]这个数组定义错了,数据没有通过DMA传输!!!

呵呵,看来编程 ,一个不小心,就忽略了细节,导致出错
回复 支持 反对

使用道具 举报

发表于 2014-3-24 12:19:05 | 显示全部楼层
南宫若郁 发表于 2013-12-26 15:59
亲,我现在搞定了,是我把ADC-Value[2]这个数组定义错了,数据没有通过DMA传输!!!

请问楼主怎么个定义法
回复 支持 反对

使用道具 举报

发表于 2014-8-13 19:12:30 | 显示全部楼层
你好 我现在使用单通道德ad 怎么换个管脚就不行了呢
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
比如吧c0改成c2
是不是修改GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
难道还要修改什么东西吗
强烈支持,非常感谢哥们
回复 支持 反对

使用道具 举报

发表于 2014-8-14 06:22:03 来自手机 | 显示全部楼层
电子555 发表于 2014-8-13 19:12
你好 我现在使用单通道德ad 怎么换个管脚就不行了呢
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
比如吧c ...

貌似ADC没个通道对应的引脚是特定的,你引脚变了,通道也要改一下
回复 支持 反对

使用道具 举报

发表于 2015-5-31 16:17:11 | 显示全部楼层
学习学习 了
回复 支持 反对

使用道具 举报

发表于 2015-8-14 10:16:13 | 显示全部楼层
学习了,还是不怎么懂多通道的采集
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-11-24 03:04 , Processed in 0.037965 second(s), 27 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表