打印
[STM32F4]

STM32内置AD加DMA

[复制链接]
2237|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
虫虫欲动|  楼主 | 2014-4-14 21:04 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
写了个AD采样程序,结果仿真时RTD_DMA_RX_BUF里边的数值一直为0,求大神解答
/*********************************************************************
*   Filename:         temperature_ad.c
*   Dependencies:     测温模块初始化
*-----------------------------------------------------------------------
*        Function List:
************************************************************************/
#include "device.h"   

/*定义ADC3的数据寄存器地址,DMA功能要用到外设的数据地址
*ADC3的数据地址为外设基地址+偏移地址,基地址在RM0090 Reference
*manual(参考手册)的地址映射表里,为0x40012200,ADC_DR
*偏移地址为0x4C,故实际地址为0x40012200+0x4C = 0x4001224C */
#define ADC3_DR_Addr   ((uint32_t)0x4001224C)
Uint16 RTD_RX_NO = 20;
/******************************************************************************
* 函数名:   Temperature_INTT  
* 功能:    初始化STM32接口
*      
******************************************************************************/
void RTD_INTT(void)
{
    GPIO_InitTypeDef    GPIO_InitStructure;
    DMA_InitTypeDef     DMA_InitStructure;
    NVIC_InitTypeDef    NVIC_InitStructure;

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2,  ENABLE);     
    SCB->AIRCR = 0x05AF0000 | 0x400;

    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_10;   
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AN;   
    GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
//   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  
    GPIO_Init(GPIOF, &GPIO_InitStructure);   
   
    DMA_DeInit( DMA2_Stream1 );
    ADC3->CR2 &= ~(1<<8);//ADC3dma 发送模式除能   
//   DMA_StructInit( &DMA_InitStructure);    //???
    DMA_InitStructure.DMA_Channel            = DMA_Channel_2;   
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(uint32_t)ADC3_DR_Addr;;             
    DMA_InitStructure.DMA_Memory0BaseAddr    = (uint32_t)&RTD_DMA_RX_BUF;
    DMA_InitStructure.DMA_DIR                = DMA_DIR_PeripheralToMemory;  
    DMA_InitStructure.DMA_BufferSize         = RTD_RX_NO;                 
    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_PeripheralDataSize_HalfWord;
    DMA_InitStructure.DMA_Mode               = DMA_Mode_Normal;           
    DMA_InitStructure.DMA_Priority           = DMA_Priority_High;     
    DMA_InitStructure.DMA_FIFOMode           = DMA_FIFOMode_Disable;      
    DMA_InitStructure.DMA_MemoryBurst        = DMA_MemoryBurst_Single;   
    DMA_InitStructure.DMA_PeripheralBurst    = DMA_PeripheralBurst_Single;
    DMA_Init(DMA2_Stream1, &DMA_InitStructure);
    DMA_Cmd(DMA2_Stream1, ENABLE);      //使能DMA2_Stream1通道
    /* DMA中断开 */
    DMA_ITConfig(DMA2_Stream1, DMA_IT_TC, ENABLE);

    /* DMA中断配置 */
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);        //嵌套优先级分组为 1
    NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream1_IRQn;   //嵌套通道为DMA2_Stream1_IRQn
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //抢占优先级为 1
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;    //响应优先级为 1
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;     //通道中断使能
    NVIC_Init(&NVIC_InitStructure);

    /* ADC中断配置 */
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);        //嵌套优先级分组为 1
    NVIC_InitStructure.NVIC_IRQChannel = ADC_IRQn;           //嵌套通道为ADC_IRQn
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //抢占优先级为 1
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;    //响应优先级为 2
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;     //通道中断使能
    NVIC_Init(&NVIC_InitStructure);
   
/* 是否需要和ADE7878的中断优先级区分开,程序中的各优先级顺序
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
    NVIC_InitStructure.NVIC_IRQChannel                   = DMA2_Stream1_IRQn;   
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //抢占和响应优先级待定
    NVIC_InitStructure.NVIC_IRQChannelSubPriority        = 0;         
    NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
    DMA_Init(DMA2_Stream1, &DMA_InitStructure);
  //DMA_Cmd(DMA2_Stream1, ENABLE);
*/            
}
/*************************************************
Function:    void ADC_Config(void)      
Description: ADC配置函数            
Input: 无                              
Output:无                              
Return:无                              
*************************************************/

void RTD_ADC_Config(void)
{
    ADC_InitTypeDef ADC_InitStructure;
    ADC_CommonInitTypeDef ADC_CommonInitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3, ENABLE);
   
    ADC_DeInit();
    ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;         
    ADC_InitStructure.ADC_ScanConvMode = DISABLE;   //扫描转换模式失能,单通道不用
    ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;  //连续转换使能
    ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; //不用外部触发,软件触发转换
    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //数据右对齐,低字节对齐
    ADC_InitStructure.ADC_NbrOfConversion = 1;    //规定了顺序进行规则转换的ADC通道的数目
    ADC_Init(ADC3, &ADC_InitStructure);      

    ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
    ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;
    ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; //失能DMA_MODE
    ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
    ADC_CommonInit(&ADC_CommonInitStructure);

    ADC_RegularChannelConfig(ADC3, ADC_Channel_8, 1, ADC_SampleTime_15Cycles); //规则通道配置,1表示规则组采样顺序
    //ADC_ITConfig(ADC3, ADC_IT_EOC, ENABLE); //使能ADC转换结束中断
    ADC_Cmd(ADC3, ENABLE);  //使能ADC3

    /*********************ADC看门狗配置***************************/
/*   ADC_AnalogWatchdogCmd(ADC3, ADC_AnalogWatchdog_SingleRegEnable);
    ADC_AnalogWatchdogThresholdsConfig(ADC3, 0x0E8B, 0x0555);  //阈值设置。高:3V 低:1V
    ADC_AnalogWatchdogSingleChannelConfig(ADC3, ADC_Channel_8);
    ADC_ITConfig(ADC3, ADC_IT_AWD, ENABLE);

    ADC_DMACmd(ADC3, ENABLE);   //使能ADC3的DMA  
*/   
    ADC_DMARequestAfterLastTransferCmd(ADC3, ENABLE); //单通道模式下上次转换完成后DMA请求允许,也就是持续DMA

}
/*
    *名称:DMA中断服务程序
    *作用:ADC3_DMA数据完全完成后产生中断
*/
void DMA2_Stream1_IRQHandler (void)
{
   
    uint32_t i,valMax, valMin, sum;   
    uint32_t Average = 0;
//    if(DMA2->LISR & 0x00000800)
    ADC_SoftwareStartConv(ADC3);     //如果不是外部触发则必须软件开始转换
    if (DMA_GetITStatus(DMA2_Stream1, DMA_IT_TCIF1) != RESET)
    {
    DMA_ClearITPendingBit(DMA2_Stream1, DMA_IT_TCIF1);  //  DMA2->LIFCR |= 0x00000800;
  /*数据接收与处理*/  
    valMax = RTD_DMA_RX_BUF[0];
    valMin = RTD_DMA_RX_BUF[0];
    sum    = RTD_DMA_RX_BUF[0];
    for(i = 0; i < RTD_RX_NO; i++)  
        {
            if (RTD_DMA_RX_BUF[i] > valMax )  valMax = RTD_DMA_RX_BUF[i];
            if (RTD_DMA_RX_BUF[i] < valMin )  valMin = RTD_DMA_RX_BUF[i];
            sum += RTD_DMA_RX_BUF[i];
        }
        sum = sum - valMax - valMin;
        Average = sum/(RTD_RX_NO-2);   
    }
}
沙发
airwill| | 2014-4-15 10:14 | 只看该作者
找调试器, 通过 ADC 转换中断, 先验证一下 ADC 的采样过程. 再启用 DMA.

使用特权

评论回复
板凳
lvyunhua| | 2014-4-15 10:16 | 只看该作者
支持下楼主!

使用特权

评论回复
地板
虫虫欲动|  楼主 | 2014-5-8 10:10 | 只看该作者
学艺不精,一开始好多东西都凌乱着,现在弄好了,谢谢各位

使用特权

评论回复
5
yzzly| | 2014-5-9 10:12 | 只看该作者
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; //不用外部触发,软件触发转换
    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
上一行定义外部触发的边沿,下一行定义是否使用外部触发,你这里是TIM1的CC1触发,你不使能TIM1的CC1,ADC怎么可能开始转换?

使用特权

评论回复
6
yzzly| | 2014-5-9 11:50 | 只看该作者
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; //失能DMA_MODE
不使能ADC的DMA功能??

使用特权

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

本版积分规则

1

主题

4

帖子

0

粉丝