AD多通道采样???求大神指导哪里有问题??

2019-10-16 04:13发布

思路是这样子的,用ADC1进行四通道采样,并利用DMA存入数组StatusData[4]中去,之后采样完成后进入ADC1的中断对数据进行处理,之后再在主函数中将数据显示出来。
现在的问题是仿真之后是可以进入中断的,但是好像就是无法检测到采样的值??
***********************************************************************************************
*
*                                                                        SampleDriver.c                       
*
------------------------------------------------------------------------------------------------
File Name:                 SampleDriver.c
Description:         按键的驱动程序。
Interface:                void SampleInit(void)                                                显示系统初始化函数
                                void ValueDisplay(unsigned char Tube,                显示数值函数
                                                                  unsigned int Value,
                                                                  unsigned char Digi)
                                void LEDControl(unsigned char Group,                控制LED
                                                            unsigned int Data)
------------------------------------------------------------------------------------------------
Create: 2009.01.11 by Ross Li
Modify:
***********************************************************************************************/

#include "DISPLAYER.h"
#include "SampleDriver.h"
#include "stm32f10x.h"
#include "sys.h"
#include "delay.h"

#define SAMPLE_TIMES                        50                        //数字平滑滤波的采样数
#define ADC1_DR_Address    ((u32)0x40012400+0x4c)


//__IO uint16_t ADC_ConvertedValue;

unsigned long StatusData[4];                                //存放采样值的数组
uint32_t Current[SAMPLE_TIMES], CurrFB;                //存放反馈电流采样数据的数组和变量,用于数字平滑滤波
uint32_t Voltage[SAMPLE_TIMES], VolFB;                //存放反馈电压采样数据的数组和变量,用于数字平滑滤波
uint32_t CurrentSet[SAMPLE_TIMES], Curr;        //存放给定电流采样数据的数组和变量,用于数字平滑滤波
uint32_t VoltageSet[SAMPLE_TIMES], Vol;        //存放给定电压采样数据的数组和变量,用于数字平滑滤波


/***********************************************************************************************
*                                                        void SampleInit(void)
*            用来初始化显示系统硬件,包括SPI总线的初始化和显示刷新信号CLK的初始化,显示刷新信号用
*        PWM0信号来实现。       
------------------------------------------------------------------------------------------------
Para:                void
Return:                void               
***********************************************************************************************/

void SampleInit(void)
{

        GPIO_InitTypeDef GPIO_InitStructure;
        ADC_InitTypeDef ADC_InitStructure;
        DMA_InitTypeDef  DMA_InitStructure;
        NVIC_InitTypeDef NVIC_InitStructure;
       
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_GPIOC|RCC_APB2Periph_ADC1        , ENABLE );          //使能ADC1通道时钟
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

        RCC_ADCCLKConfig(RCC_PCLK2_Div6);   //设置ADC分频因子6 72M/6=12,ADC最大时间不能超过14M

        //PA0、PA1 作为模拟通道输入引脚                        
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;                //模拟输入引脚
        GPIO_Init(GPIOA, &GPIO_InitStructure);       
       
        //PC2、PC3 作为模拟通道输入引脚                        
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;                //模拟输入引脚
        GPIO_Init(GPIOC, &GPIO_InitStructure);       

        ADC_DeInit(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 = 4;        //顺序进行规则转换的ADC通道的数目
        ADC_Init(ADC1, &ADC_InitStructure);        //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器   
       
                /*配置ADC1的通道0为55.        5个采样周期,序列为1 */
        ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5);
                /*配置ADC1的通道1为55.        5个采样周期,序列为2 */
        ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_55Cycles5);
                /*配置ADC1的通道12为55.        5个采样周期,序列为3 */
        ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 3, ADC_SampleTime_55Cycles5);
                /*配置ADC1的通道13为55.        5个采样周期,序列为4 */
        ADC_RegularChannelConfig(ADC1, ADC_Channel_13, 4, ADC_SampleTime_55Cycles5);

        DMA_DeInit(DMA1_Channel1);
        DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;         //ADC地址
        DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&StatusData;//内存地址
        DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
        DMA_InitStructure.DMA_BufferSize = 8;  //DMA通道的DMA缓存的大小
        DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设地址固定
        DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;  //内存地址寄存器递增
        DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;        //半字,数据宽度为16位
        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通道x没有设置为内存到内存传输
        DMA_Init(DMA1_Channel1, &DMA_InitStructure);
       
               
        DMA_Cmd(DMA1_Channel1, ENABLE);//使能DMA1

        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的软件转换启动功能
       
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
  NVIC_InitStructure.NVIC_IRQChannel  = ADC1_2_IRQn;         //ADC1,ADC2全局中断   
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;//先占优先级0   
  NVIC_InitStructure.NVIC_IRQChannelSubPriority   = 1;  //从优先级   
  NVIC_InitStructure.NVIC_IRQChannelCmd   = ENABLE;   
  NVIC_Init(&NVIC_InitStructure);
  ADC_ITConfig(ADC1,ADC_IT_EOC,ENABLE);

}
/***********************************************************************************************
*                                                        uint32_t GetVoltageSet(void)
*                                                         返回给定电压的实际值   
*               
------------------------------------------------------------------------------------------------
Para:                void
Return:                INT32U         给定电压的实际值,格式为xx.x V       
***********************************************************************************************/
uint32_t GetVoltageSet(void){
        uint32_t Voltage;
        if( Mode )
                Voltage = Vol ;
                //Voltage = 80 + Vol * 300 / 1023;
        else
                Voltage = 15 + Vol * 60 / 1023;
        return( Voltage );
}
/***********************************************************************************************
*                                                        INT32U GetCurrentSet(void)
*                                 返回给定电流的实际值
*               
------------------------------------------------------------------------------------------------
Para:                void
Return:                INT32U         给定电流的实际值,格式为xxx A       
***********************************************************************************************/
uint32_t GetCurrentSet(void){                                 //电流给定
        uint32_t Current;
        uint32_t Current_MIN;
        if (AllPara.Dia == 0){
                Current = 40 + ( Vol * 25/82 -20 ) * 180/235 ;
                Current_MIN = 40;
        }
        else if        (AllPara.Dia == 1){
                Current = 60 + ( Vol * 25/82 -20 ) * 200/235 ;
                Current_MIN = 60;
        }
        else if        (AllPara.Dia == 2){
                Current = 80 + ( Vol * 25/82 -20 ) * 220/235 ;
                Current_MIN = 80;
        }
        else if        (AllPara.Dia == 3){
                Current = 80 + ( Vol * 25/82 -20 ) * 320/235  ;
                Current_MIN = 80;
        }
        else if        (AllPara.Dia == 4){
                Current = 80 + ( Vol * 25/82 -20 ) * 420/235 ;
                Current_MIN = 80;
        }
        if((Vol * 25/82)<20)
                Current = Current_MIN;
        //Current = 40 + Curr * 300 / 1023; 原始
        return( Current );
}
/**********************************************************************************************
*                                                        INT32U GetVoltage(void)
*                返回反馈电压的实际值             
*               
-----------------------------------------------------------------------------------------------
Para:                void
Return:                INT32U        反馈电压的实际值,格式为xx.x V                
**********************************************************************************************/
uint32_t GetVoltage(void){
        uint32_t Voltage;
        Voltage = VolFB * 600 / 1023;
        return( Voltage );
}
/**********************************************************************************************
*                                                        INT32U GetCurrent(void)
*                 返回反馈电流的实际值   
*               
-----------------------------------------------------------------------------------------------
Para:                void
Return:                INT32U        反馈电流的实际值,格式为xxx A                
**********************************************************************************************/
uint32_t GetCurrent(void){
        uint32_t Current;
        Current = CurrFB * 600 / 1023;
        return( Current );
}

//ADC中断服务程序
void ADC1_2_IRQHandler(void)
{

        static uint32_t Sum[4];                                                                //用于记录当前记录区间的采样值总和
        static uint8_t Times;                                                                        //用于记录采样次数的变量
               
//        ADCSequenceDataGet(ADC_BASE, 1, StatusData);                //读取采样数据

        /* 进行平滑滤波 */
        Current[Times] = StatusData[0];                                                //平滑滤波算法:求取最近N次采样的平均...
        Voltage[Times] = StatusData[1];                                                //...值作为采样值
        CurrentSet[Times] = StatusData[2];
        VoltageSet[Times] = StatusData[3];       
       
        if( SAMPLE_TIMES == ++Times )
                Times = 0;
               
        Sum[0] += StatusData[0];                                                        //计算最近N个采样周期采样值的总和
        Sum[1] += StatusData[1];                                                        //算法:上次的总和加上最新的采样值...
        Sum[2] += StatusData[2];                                                        //...再减去保留的最早的采样值
        Sum[3] += StatusData[3];       
        Sum[0] -= Current[Times];
        Sum[1] -= Voltage[Times];
        Sum[2] -= CurrentSet[Times];
        Sum[3] -= VoltageSet[Times];
       
        CurrFB = Sum[0] / SAMPLE_TIMES;                                                //求取最近N个采样周期采样值的平均值
        VolFB = Sum[1] / SAMPLE_TIMES;
        Curr = Sum[2] / SAMPLE_TIMES;
        Vol = Sum[3] / SAMPLE_TIMES;

  ADC_ClearITPendingBit(ADC1, ADC_IT_EOC);
}


友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。