打印
[应用相关]

Stm32f103 ADC 学习笔记

[复制链接]
525|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
externally|  楼主 | 2019-6-17 16:46 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
在做有AD模块项目的时候遇到几个问题:
1,  ADC配合DMA采样规则是怎样的。
2,  ADC在DMA采可否不连续采样,以提高有效采样使用率和降低功耗。
3,  如何提高有效利用率和降低功耗,并减少CPU的占用时间。
4,  ADC的如何多通道采样。
针对以上几个问题做解答。
ADC的采样模式主要分两个:规则采样和注入采样。规则模式可采样16个通道,注入模式最多只能4个通道。
配合DMA使用时主要是用规则采样模式。在初始化时配置采样端口为规则采样通道即可如下:
列:         ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_239Cycles5);
端口1为规则采样的第一位,239.5的ADC时钟采样周期。
         ADC在DMA下可以不连续采样,既采样一定数据后,关闭ADC及DMA通道。但是这样子存在一些问题。DMA的存储的变量数组中的数据会出现错位问题。
测试过很多方法,包括ADC和DMA一起重新初始化,依然无法解决这个问题。系统只进行一次初始化时,DMA数据无错位现象。 但是对于长时间不关机的产品来说,缺少了几分可靠性。网上也有相关的评测,ADC用DMA工作在强电磁的环境中可能会输出丢失部分数据的可能。
         这里就想到了用中断的方式,进行采样。无法用规则模式,因为只能用单次采样触发中断。由于无法确定第一个通道,这样同样会遇到数据错位的现象。所以这里使用注入模式进行中断出发。

有以下几个优点:
1,  可以最多4路为一组采样,每组采样结束后才产生一次中断,减少了进中断的次数。
2,  在读取数据时几路通道都是预先配置好的。某个变量存放指定某个指定通道。这样永远不可能出现错位现象。
由以总结 在4路及以下通道进行采样时,首选注入模式进行中断采样。超过4路及不是长时间工作的产品(几天以上不断电)可以考虑。
单路采样时,这两种方法都很可靠。
         最近刚好在学习uCosII系统,并参考了下通用驱动程序开发。附上ADC驱动代码,希望有所帮助。


  提示,在使用某路通道 只要 该通道宏定义置1就可以了。
#define ADCx_CHANNEL0_EN  1 //ADCx通道1  1:便能,0:失能
注意: 在使用注入模式时 最多使能4个通道。
/*
********************************************************************************
*                                  uC/OS-II
*                                AD采样驱动程序设计
*                              ARM Cortex-M3 Port
*
* File          : ADCxDrv.C
* Version       : V1.0
* By            : 王宏强
*
* For           : Stm32f10x
* Mode          : Thumb2
* Toolchain     :
*                     RealView Microcontroller Development Kit (MDK)
*                     Keil uVision
* Description   : 定时器驱动
*                    占用ADCx(ADC1,ADC2)
*                    
*                    1,DMA规则模式(可靠性低,多路用此模式) 加宏定义 #define ADC_DMA
*                    2,4路以下,用注入模式(可靠性高,占资源少)
*               
*                    ADCxOpen
*                    ADCxClose
*                    ADCxWrite
*                    ADCxRead
*                    ADCxIoCtl
*                    ADCxInstall
*                    ADCxNuinstall
* Date          : 2012.05.22
*******************************************************************************/

#include "ADCxDrv.h"

//DMA采样缓冲区
static volatile INT16U ADC_ConvertedValueTab[MAX_AD_SAMPLE_COUNTER] = {0};
static INT16U ADCxBuff[CHANNEL_COUNT] = {0};        //缓冲区数据平均值
static INT16U index = 0;

#ifdef UCOSII
static OS_EVENT *adcSem;
static INT8U err;
#endif

//总采样时间(单位ms) = 读样个数 * 采样1个值所用时间 / 72mHz * 1000
//static INT16U sampingTime = (INT16U)(CHANNEL_COUNT * ADCx_SAMPLE_COUNT *
//                                                            239 * 5 / 9e3 + 1);                    

/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
ADC_InitTypeDef ADC_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;



/*******************************************************************************
* Function Name :INT16U GetSampleTemp(INT16U order)
* Description   :获取采样到的数据,并进行平均
* Input         :order:通道序列号
* Output        :返回本通道 采样平均值
* Other         :
* Date          :2012.05.23  14:48:23
*******************************************************************************/
static INT16U GetSampleValue(INT16U order)
{
    u32 sum = 0;
    u16 i = order;
   
    if (order >= CHANNEL_COUNT) return 0;    //序列号超出范围
   
    for (i = order; i < MAX_AD_SAMPLE_COUNTER; i+=CHANNEL_COUNT)
    {
        sum += ADC_ConvertedValueTab[i];
    }
    sum /= ADCx_SAMPLE_COUNT;
   
    return (u16)sum;
}

void StartAdc(FunctionalState stat)
{
    if (stat == ENABLE) index = 0;
   
    ADC_ITConfig(ADCx, ADC_IT_JEOC, stat);
    ADC_Cmd(ADCx, stat);
}


/*******************************************************************************
* Function Name :static INT32S ADCxOpen(void *pd)
* Description   :
* Input         :
* Output        :
* Other         :
* Date          :2012.05.23  10:25:06
*******************************************************************************/
static INT32S ADCxOpen(void *pd)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    INT32U rccApb = 0;
    INT16U gpioPin = 0;

    /* Enable peripheral clocks ----------------------------------------------*/
    /* Enable DMA1 and DMA2 clocks */
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMAx, ENABLE);


#if ADCx_GPIOX_1_EN
    rccApb |= RCC_APBXPeriph_GPIOX_1;
#endif

#if ADCx_GPIOX_2_EN
    rccApb |= RCC_APBXPeriph_GPIOX_2;
#endif

#if ADCx_GPIOX_3_EN
    rccApb |= RCC_APBXPeriph_GPIOX_3;
#endif

    rccApb |= RCC_APBXPeriph_ADCx;
    RCC_APB2PeriphClockCmd(rccApb, ENABLE);
    RCC_ADCCLKConfig(RCC_PCLK2_Div8);

   
#if ADCx_GPIOX_1_EN
    gpioPin = 0;
#if ADCx_CHANNEL0_EN
    gpioPin |= ADCx_GPIOX_PIN_CH0;
#endif
#if ADCx_CHANNEL1_EN
    gpioPin |= ADCx_GPIOX_PIN_CH1;
#endif
#if ADCx_CHANNEL2_EN
    gpioPin |= ADCx_GPIOX_PIN_CH2;
#endif
#if ADCx_CHANNEL3_EN
    gpioPin |= ADCx_GPIOX_PIN_CH3;
#endif
#if ADCx_CHANNEL4_EN
    gpioPin |= ADCx_GPIOX_PIN_CH4;
#endif
#if ADCx_CHANNEL5_EN
    gpioPin |= ADCx_GPIOX_PIN_CH5;
#endif
#if ADCx_CHANNEL6_EN
    gpioPin |= ADCx_GPIOX_PIN_CH6;
#endif
#if ADCx_CHANNEL7_EN
    gpioPin |= ADCx_GPIOX_PIN_CH7;
#endif
    GPIO_InitStructure.GPIO_Pin = gpioPin;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
    GPIO_Init(ADCx_GPIOX_1, &GPIO_InitStructure);
#endif

         
#if ADCx_GPIOX_2_EN
    gpioPin = 0;
#if ADCx_CHANNEL8_EN
    gpioPin |= ADCx_GPIOX_PIN_CH8;
#endif
#if ADCx_CHANNEL9_EN
    gpioPin |= ADCx_GPIOX_PIN_CH9;
#endif
      GPIO_InitStructure.GPIO_Pin = gpioPin;
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
      GPIO_Init(ADCx_GPIOX_2, &GPIO_InitStructure);
#endif


#if ADCx_GPIOX_3_EN
    gpioPin = 0;
#if ADCx_CHANNEL10_EN
      gpioPin |= ADCx_GPIOX_PIN_CH10;
#endif
#if ADCx_CHANNEL11_EN
      gpioPin |= ADCx_GPIOX_PIN_CH11;
#endif
#if ADCx_CHANNEL12_EN
      gpioPin |= ADCx_GPIOX_PIN_CH12;
#endif
#if ADCx_CHANNEL13_EN
      gpioPin |= ADCx_GPIOX_PIN_CH13;
#endif
#if ADCx_CHANNEL14_EN
      gpioPin |= ADCx_GPIOX_PIN_CH14;
#endif
#if ADCx_CHANNEL15_EN
      gpioPin |= ADCx_GPIOX_PIN_CH15;
#endif
    GPIO_InitStructure.GPIO_Pin = gpioPin;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
    GPIO_Init(ADCx_GPIOX_3, &GPIO_InitStructure);
#endif

/* ADCx configuration ---------------------------------------------------*/
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
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 = CHANNEL_COUNT;
ADC_Init(ADCx, &ADC_InitStructure);


#ifdef ADC_DMA
    /* ADCx regular channels configuration */
#if ADCx_CHANNEL0_EN
    ADC_RegularChannelConfig(ADCx, ADC_Channel_0, ORDER_CH0, ADC_SampleTime_239Cycles5);  
#endif
#if ADCx_CHANNEL1_EN
    ADC_RegularChannelConfig(ADCx, ADC_Channel_1, ORDER_CH1, ADC_SampleTime_239Cycles5);
#endif
#if ADCx_CHANNEL2_EN
    ADC_RegularChannelConfig(ADCx, ADC_Channel_2, ORDER_CH2, ADC_SampleTime_239Cycles5);  
#endif
#if ADCx_CHANNEL3_EN
    ADC_RegularChannelConfig(ADCx, ADC_Channel_3, ORDER_CH3, ADC_SampleTime_239Cycles5);
#endif
#if ADCx_CHANNEL4_EN
    ADC_RegularChannelConfig(ADCx, ADC_Channel_4, ORDER_CH4, ADC_SampleTime_239Cycles5);  
#endif
#if ADCx_CHANNEL5_EN
    ADC_RegularChannelConfig(ADCx, ADC_Channel_5, ORDER_CH5, ADC_SampleTime_239Cycles5);
#endif
#if ADCx_CHANNEL6_EN
    ADC_RegularChannelConfig(ADCx, ADC_Channel_6, ORDER_CH6, ADC_SampleTime_239Cycles5);  
#endif
#if ADCx_CHANNEL7_EN
    ADC_RegularChannelConfig(ADCx, ADC_Channel_7, ORDER_CH7, ADC_SampleTime_239Cycles5);
#endif
#if ADCx_CHANNEL8_EN
    ADC_RegularChannelConfig(ADCx, ADC_Channel_8, ORDER_CH8, ADC_SampleTime_239Cycles5);  
#endif
#if ADCx_CHANNEL9_EN
    ADC_RegularChannelConfig(ADCx, ADC_Channel_9, ORDER_CH9, ADC_SampleTime_239Cycles5);
#endif
#if ADCx_CHANNEL10_EN
    ADC_RegularChannelConfig(ADCx, ADC_Channel_10, ORDER_CH10, ADC_SampleTime_239Cycles5);  
#endif
#if ADCx_CHANNEL11_EN
    ADC_RegularChannelConfig(ADCx, ADC_Channel_11, ORDER_CH11, ADC_SampleTime_239Cycles5);
#endif
#if ADCx_CHANNEL12_EN
    ADC_RegularChannelConfig(ADCx, ADC_Channel_12, ORDER_CH12, ADC_SampleTime_239Cycles5);  
#endif
#if ADCx_CHANNEL13_EN
    ADC_RegularChannelConfig(ADCx, ADC_Channel_13, ORDER_CH13, ADC_SampleTime_239Cycles5);
#endif
#if ADCx_CHANNEL14_EN
    ADC_RegularChannelConfig(ADCx, ADC_Channel_14, ORDER_CH14, ADC_SampleTime_239Cycles5);  
#endif
#if ADCx_CHANNEL15_EN
    ADC_RegularChannelConfig(ADCx, ADC_Channel_15, ORDER_CH15, ADC_SampleTime_239Cycles5);
#endif


    /* DMA1 channel1 configuration -------------------------------------------*/
    DMA_DeInit(DMAx_Channelx);
    DMA_InitStructure.DMA_PeripheralBaseAddr = ADCx_DR_Address;
    DMA_InitStructure.DMA_MemoryBaseAddr = (u32)ADC_ConvertedValueTab;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
    DMA_InitStructure.DMA_BufferSize = (u32)MAX_AD_SAMPLE_COUNTER;        //存储的个数
    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_Medium;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    DMA_Init(DMAx_Channelx, &DMA_InitStructure);

    /* Enable ADCx DMA */
    ADC_DMACmd(ADCx, ENABLE);

    /* Enable DMA1 channel1 */
    DMA_Cmd(DMAx_Channelx, ENABLE);
#else

    /* Set injected sequencer length */
    ADC_InjectedSequencerLengthConfig(ADC1, CHANNEL_COUNT);

#if ADCx_CHANNEL0_EN
    ADC_InjectedChannelConfig(ADCx, ADC_Channel_0, ORDER_CH0, ADC_SampleTime_239Cycles5);  
#endif
#if ADCx_CHANNEL1_EN
    ADC_InjectedChannelConfig(ADCx, ADC_Channel_1, ORDER_CH1, ADC_SampleTime_239Cycles5);
#endif
#if ADCx_CHANNEL2_EN
    ADC_InjectedChannelConfig(ADCx, ADC_Channel_2, ORDER_CH2, ADC_SampleTime_239Cycles5);  
#endif
#if ADCx_CHANNEL3_EN
    ADC_InjectedChannelConfig(ADCx, ADC_Channel_3, ORDER_CH3, ADC_SampleTime_239Cycles5);
#endif
#if ADCx_CHANNEL4_EN
    ADC_InjectedChannelConfig(ADCx, ADC_Channel_4, ORDER_CH4, ADC_SampleTime_239Cycles5);  
#endif
#if ADCx_CHANNEL5_EN
    ADC_InjectedChannelConfig(ADCx, ADC_Channel_5, ORDER_CH5, ADC_SampleTime_239Cycles5);
#endif
#if ADCx_CHANNEL6_EN
    ADC_InjectedChannelConfig(ADCx, ADC_Channel_6, ORDER_CH6, ADC_SampleTime_239Cycles5);  
#endif
#if ADCx_CHANNEL7_EN
    ADC_InjectedChannelConfig(ADCx, ADC_Channel_7, ORDER_CH7, ADC_SampleTime_239Cycles5);
#endif
#if ADCx_CHANNEL8_EN
    ADC_InjectedChannelConfig(ADCx, ADC_Channel_8, ORDER_CH8, ADC_SampleTime_239Cycles5);  
#endif
#if ADCx_CHANNEL9_EN
    ADC_InjectedChannelConfig(ADCx, ADC_Channel_9, ORDER_CH9, ADC_SampleTime_239Cycles5);
#endif
#if ADCx_CHANNEL10_EN
    ADC_InjectedChannelConfig(ADCx, ADC_Channel_10, ORDER_CH10, ADC_SampleTime_239Cycles5);   
#endif
#if ADCx_CHANNEL11_EN
    ADC_InjectedChannelConfig(ADCx, ADC_Channel_11, ORDER_CH11, ADC_SampleTime_239Cycles5);
#endif
#if ADCx_CHANNEL12_EN
    ADC_InjectedChannelConfig(ADCx, ADC_Channel_12, ORDER_CH12, ADC_SampleTime_239Cycles5);   
#endif
#if ADCx_CHANNEL13_EN
    ADC_InjectedChannelConfig(ADCx, ADC_Channel_13, ORDER_CH13, ADC_SampleTime_239Cycles5);
#endif
#if ADCx_CHANNEL14_EN
    ADC_InjectedChannelConfig(ADCx, ADC_Channel_14, ORDER_CH14, ADC_SampleTime_239Cycles5);   
#endif
#if ADCx_CHANNEL15_EN
    ADC_InjectedChannelConfig(ADCx, ADC_Channel_15, ORDER_CH15, ADC_SampleTime_239Cycles5);
#endif

    ADC_AutoInjectedConvCmd(ADCx, ENABLE);
    ADC_ITConfig(ADCx, ADC_IT_JEOC, ENABLE);

    /* Configure and enable ADC interrupt */
    NVIC_InitStructure.NVIC_IRQChannel = ADC1_2_IRQChannel;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    StartAdc(DISABLE);
#endif

    /* Enable ADCx */
    ADC_Cmd(ADCx, ENABLE);

    /* Enable ADCx reset calibaration register */   
    ADC_ResetCalibration(ADCx);
    /* Check the end of ADCx reset calibration register */
    while(ADC_GetResetCalibrationStatus(ADCx));

    /* Start ADCx calibaration */
    ADC_StartCalibration(ADCx);
    /* Check the end of ADCx calibration */
    while(ADC_GetCalibrationStatus(ADCx));
   
#ifdef UCOSII
    adcSem = OSSemCreate(0);
#endif
    return (INT32S)DRV_NO_ERR;
}

/*******************************************************************************
* Function Name :static INT32S ADCxClose(void *pd)
* Description   :
* Input         :
* Output        :
* Other         :
* Date          :2012.05.24  09:10:25
*******************************************************************************/
static INT32S ADCxClose(void *pd)
{   
    ADC_SoftwareStartConvCmd(ADCx, DISABLE);
   
    /* Enable DMA1 channel1 */
    DMA_Cmd(DMAx_Channelx, DISABLE);

    /* Enable ADCx DMA */
    ADC_DMACmd(ADCx, DISABLE);

    StartAdc(DISABLE);

    return (INT32S)DRV_NO_ERR;
}

/*******************************************************************************
* Function Name :static INT32S ADCxWrite(INT8S *buffer, INT32U lenToWrite, INT8U waitType)
* Description   :无效
* Input         :
* Output        :
* Other         :
* Date          :2012.05.23  14:19:47
*******************************************************************************/
static INT32S ADCxWrite(INT8S *buffer, INT32U lenToWrite, INT8U waitType)
{
    return (INT32S)DRV_NO_ERR;
}

/*******************************************************************************
* Function Name :static INT32S ADCxRead(INT8S *buffer, INT32U blen, INT32U lenToRead, INT8U waitType)
* Description   :读取采样到的数据
* Input         :*buffer:采样缓冲。lenToRead:采取长度(单位是字节)
* Output        :
* Other         :
* Date          :2012.05.23  14:19:49
*******************************************************************************/
static INT32S ADCxRead(INT8S *buffer, INT32U blen, INT32U lenToRead, INT8U waitType)
{   
    int i = 0;

    if (lenToRead > sizeof(ADCxBuff))
        return (INT32S)DRV_READ_FAIL;
   
    for (i = 0; i < CHANNEL_COUNT; i++)
    {
        ADCxBuff[i] = GetSampleValue(i);
    }
    memcpy(buffer, ADCxBuff, lenToRead);
   
    return (INT32S)DRV_NO_ERR;
}

/*******************************************************************************
* Function Name :static INT32S ADCxIoCtl(INT32U too, void *pd)
* Description   :ADCX采样控制
* Input         :too:     1-停止 AD采样
*                        2-开始    AD采样 延迟直接退出。
*                        3-开始 并等待采样缓冲填满后 停止采样。(UCOSII 系统下)
* Output        :
* Other         :
* Date          :2012.05.23  14:19:51
*******************************************************************************/
static INT32S ADCxIoCtl(INT32U too, void *pd)
{
    switch (too)
    {
        case 1 : StartAdc(DISABLE);    break;
        case 2 : StartAdc(ENABLE);    break;
#ifdef UCOSII   
        case 3 :
            StartAdc(ENABLE);
            OSSemPend(adcSem, 0, &err);
            break;
#endif
        default : return(INT32S)DRV_CTRL_FAIL;

    }
    return (INT32S)DRV_NO_ERR;
}
/*******************************************************************************
* Function Name :INT32S ADCxInstall(UDFOperationsType *op)
* Description   :安装ADCx驱动
* Input         :
* Output        :
* Other         :
* Date          :2012.05.13
*******************************************************************************/
INT32S ADCxInstall(UDFOperationsType *op)
{
    op->devOpen = ADCxOpen;
    op->devClose = ADCxClose;
    op->devWrite = ADCxWrite;
    op->devRead = ADCxRead;
    op->devIoctl = ADCxIoCtl;
   
    return (INT32S)DRV_NO_ERR;
}

/*******************************************************************************
* Function Name :INT32S ADCxNuinstall(UDFOperationsType *op)
* Description   :卸载ADCx驱动
* Input         :
* Output        :
* Other         :
* Date          :2012.05.13
*******************************************************************************/
INT32S ADCxNuinstall(UDFOperationsType *op)
{
    INT32S res = (INT32S)DRV_NO_ERR;
    void *pd = NULL;
   
    if (op->devClose != NULL)
        res = op->devClose(pd);
    op->devOpen = NULL;
    op->devClose = NULL;
    op->devWrite = NULL;
    op->devRead = NULL;
    op->devIoctl = NULL;

    return res;
}

/*******************************************************************************
* Function Name :void ADC_IRQHandler(void)
* Description   :ADC中断函数
* Input         :
* Output        :
* Other         :
* Date          :2012.05.24  14:49:49
*******************************************************************************/
void ADC_IRQHandler(void)
{
#ifdef UCOSII
    OSIntEnter();
#endif
    /* Clear ADC1 EOC pending interrupt bit */
    ADC_ClearITPendingBit(ADC1, ADC_IT_JEOC);    //清除规则采样中断

    if (index >= MAX_AD_SAMPLE_COUNTER)
    {
        StartAdc(DISABLE);
#ifdef UCOSII        
        OSSemPost(adcSem);
#endif        
    }
    else
    {
#if CHANNEL_COUNT > 0
        ADC_ConvertedValueTab[index++] = ADC_GetInjectedConversionValue(ADCx, ADC_InjectedChannel_1);
#endif
#if  CHANNEL_COUNT > 1
        ADC_ConvertedValueTab[index++] = ADC_GetInjectedConversionValue(ADCx, ADC_InjectedChannel_2);
#endif
#if  CHANNEL_COUNT > 2
        ADC_ConvertedValueTab[index++] = ADC_GetInjectedConversionValue(ADCx, ADC_InjectedChannel_3);
#endif
#if  CHANNEL_COUNT > 3
        ADC_ConvertedValueTab[index++] = ADC_GetInjectedConversionValue(ADCx, ADC_InjectedChannel_4);
#endif
    }
#ifdef UCOSII
    OSIntExit();
#endif
}
头文件:
#ifndef _ADCxDrv_h_
#define _ADCxDrv_h_
#include "stm32f10x_adc.h"
#include "stm32f10x_dma.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_nvic.h"
#include "driver.h"
#include <string.h>


//#define ADC_DMA                //DMA模式, 不定义为注入模式(最多为四路)

#define ADCx_SAMPLE_COUNT        10u                        //单通道采的点数


#define ADCx                     ADC1                    //使用的ADC控制器
#define ADCx_DR_Address            ((u32)0x4001244C)
#define RCC_APBXPeriph_ADCx    RCC_APB2Periph_ADC1        //ADC1时钟


#define RCC_AHBPeriph_DMAx        RCC_AHBPeriph_DMA1        //DMA1时钟
#define DMAx_Channelx            DMA1_Channel1

#define RCC_APBXPeriph_GPIOX_1    RCC_APB2Periph_GPIOA    //
#define RCC_APBXPeriph_GPIOX_2    RCC_APB2Periph_GPIOB    //
#define RCC_APBXPeriph_GPIOX_3    RCC_APB2Periph_GPIOC    //

#define ADCx_GPIOX_1             GPIOA
#define ADCx_GPIOX_2            GPIOB
#define ADCx_GPIOX_3            GPIOC

#define ADCx_GPIOX_PIN_CH0        GPIO_Pin_0                //通道端口GPIOX_1
#define ADCx_GPIOX_PIN_CH1        GPIO_Pin_1                //通道端口GPIOX_1
#define ADCx_GPIOX_PIN_CH2        GPIO_Pin_2                //通道端口GPIOX_1
#define ADCx_GPIOX_PIN_CH3        GPIO_Pin_3                //通道端口GPIOX_2
#define ADCx_GPIOX_PIN_CH4        GPIO_Pin_4                //通道端口GPIOX_2
#define ADCx_GPIOX_PIN_CH5        GPIO_Pin_5                //通道端口GPIOX_1
#define ADCx_GPIOX_PIN_CH6        GPIO_Pin_6                //通道端口GPIOX_1
#define ADCx_GPIOX_PIN_CH7        GPIO_Pin_7                //通道端口GPIOX_2
#define ADCx_GPIOX_PIN_CH8        GPIO_Pin_8                //通道端口GPIOX_2
#define ADCx_GPIOX_PIN_CH9        GPIO_Pin_9                //通道端口GPIOX_1
#define ADCx_GPIOX_PIN_CH10    GPIO_Pin_10                //通道端口GPIOX_1
#define ADCx_GPIOX_PIN_CH11    GPIO_Pin_11                //通道端口GPIOX_2
#define ADCx_GPIOX_PIN_CH12    GPIO_Pin_12                //通道端口GPIOX_2
#define ADCx_GPIOX_PIN_CH13    GPIO_Pin_13                //通道端口GPIOX_1
#define ADCx_GPIOX_PIN_CH14    GPIO_Pin_14                //通道端口GPIOX_1
#define ADCx_GPIOX_PIN_CH15    GPIO_Pin_15                //通道端口GPIOX_1

//注意 注入模式 最多先4路通道
#define ADCx_CHANNEL0_EN        0    //ADCx通道1  1:便能,0:失能
#define ADCx_CHANNEL1_EN        1    //ADCx通道2  1:便能,0:失能
#define ADCx_CHANNEL2_EN        0    //ADCx通道3  1:便能,0:失能
#define ADCx_CHANNEL3_EN        1    //ADCx通道4  1:便能,0:失能
#define ADCx_CHANNEL4_EN        0    //ADCx通道5  1:便能,0:失能
#define ADCx_CHANNEL5_EN        0    //ADCx通道6  1:便能,0:失能
#define ADCx_CHANNEL6_EN        0    //ADCx通道7  1:便能,0:失能
#define ADCx_CHANNEL7_EN        0    //ADCx通道8  1:便能,0:失能
#define ADCx_CHANNEL8_EN        0    //ADCx通道9  1:便能,0:失能
#define ADCx_CHANNEL9_EN        0    //ADCx通道10  1:便能,0:失能
#define ADCx_CHANNEL10_EN        0    //ADCx通道11  1:便能,0:失能
#define ADCx_CHANNEL11_EN        0    //ADCx通道12  1:便能,0:失能
#define ADCx_CHANNEL12_EN        0    //ADCx通道13  1:便能,0:失能
#define ADCx_CHANNEL13_EN        0    //ADCx通道14  1:便能,0:失能
#define ADCx_CHANNEL14_EN        0    //ADCx通道15  1:便能,0:失能
#define ADCx_CHANNEL15_EN        0    //ADCx通道16  1:便能,0:失能

//总端口数
#define CHANNEL_COUNT        (ADCx_CHANNEL0_EN + ADCx_CHANNEL1_EN + \
                            ADCx_CHANNEL2_EN + ADCx_CHANNEL3_EN + \
                            ADCx_CHANNEL4_EN + ADCx_CHANNEL5_EN + \
                            ADCx_CHANNEL6_EN + ADCx_CHANNEL7_EN + \
                            ADCx_CHANNEL8_EN + ADCx_CHANNEL9_EN + \
                            ADCx_CHANNEL10_EN + ADCx_CHANNEL11_EN + \
                            ADCx_CHANNEL12_EN + ADCx_CHANNEL13_EN + \
                            ADCx_CHANNEL14_EN + ADCx_CHANNEL15_EN )
//                        
#define ADCx_GPIOX_1_EN    (ADCx_CHANNEL0_EN + ADCx_CHANNEL1_EN + \
                            ADCx_CHANNEL2_EN + ADCx_CHANNEL3_EN + \
                            ADCx_CHANNEL4_EN + ADCx_CHANNEL5_EN + \
                            ADCx_CHANNEL6_EN + ADCx_CHANNEL7_EN)

#define ADCx_GPIOX_2_EN    (ADCx_CHANNEL8_EN + ADCx_CHANNEL9_EN)

#define ADCx_GPIOX_3_EN    (ADCx_CHANNEL10_EN + ADCx_CHANNEL11_EN + \
                            ADCx_CHANNEL12_EN + ADCx_CHANNEL13_EN + \
                            ADCx_CHANNEL14_EN + ADCx_CHANNEL15_EN )


#define ORDER_CH0            ADCx_CHANNEL0_EN
#define ORDER_CH1            (ADCx_CHANNEL1_EN + ORDER_CH0)
#define ORDER_CH2            (ADCx_CHANNEL2_EN + ORDER_CH1)
#define ORDER_CH3            (ADCx_CHANNEL3_EN + ORDER_CH2)
#define ORDER_CH4            (ADCx_CHANNEL4_EN + ORDER_CH3)
#define ORDER_CH5            (ADCx_CHANNEL5_EN + ORDER_CH4)
#define ORDER_CH6            (ADCx_CHANNEL6_EN + ORDER_CH5)
#define ORDER_CH7            (ADCx_CHANNEL7_EN + ORDER_CH6)
#define ORDER_CH8            (ADCx_CHANNEL8_EN + ORDER_CH7)
#define ORDER_CH9            (ADCx_CHANNEL9_EN + ORDER_CH8)
#define ORDER_CH10            (ADCx_CHANNEL10_EN + ORDER_CH9)
#define ORDER_CH11            (ADCx_CHANNEL11_EN + ORDER_CH10)
#define ORDER_CH12            (ADCx_CHANNEL12_EN + ORDER_CH11)
#define ORDER_CH13            (ADCx_CHANNEL13_EN + ORDER_CH12)
#define ORDER_CH14            (ADCx_CHANNEL14_EN + ORDER_CH13)
#define ORDER_CH15            (ADCx_CHANNEL15_EN + ORDER_CH14)

#define MAX_AD_SAMPLE_COUNTER (ADCx_SAMPLE_COUNT * CHANNEL_COUNT)



INT32S ADCxInstall(UDFOperationsType *op);
INT32S ADCxNuinstall(UDFOperationsType *op);





#endif


使用特权

评论回复
沙发
mmuuss586| | 2019-6-29 22:15 | 只看该作者
不错,感谢分享

使用特权

评论回复
板凳
mmuuss586| | 2019-6-29 22:15 | 只看该作者
不错,感谢分享

使用特权

评论回复
地板
xiaoqizi| | 2019-7-8 09:30 | 只看该作者
好长的程序啊

使用特权

评论回复
5
晓伍| | 2019-7-8 09:55 | 只看该作者
这程序还长?!

使用特权

评论回复
6
八层楼| | 2019-7-8 10:04 | 只看该作者
非常感谢楼主分享

使用特权

评论回复
7
观海| | 2019-7-8 10:46 | 只看该作者
非常感谢楼主分享

使用特权

评论回复
8
17883657069| | 2021-2-27 08:55 | 只看该作者
谢谢分享

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

10

主题

285

帖子

0

粉丝