在做有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
|