野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 10651|回复: 2

关于F767的ADC+DMA+TIM的配置怎么弄?

[复制链接]
发表于 2018-3-27 16:18:27 | 显示全部楼层 |阅读模式
// ADC DR寄存器宏定义,ADC转换后的数字值则存放在这里
#define RHEOSTAT_ADC_DR_ADDR                ((uint32_t)ADC1+0x4c)
u8 FinishFlag = 0;
u16 DMA_ADVaule[100][10];
DMA_HandleTypeDef  ADC1_DMA_Handler;      //DMA句柄
ADC_HandleTypeDef ADC1_Handler;//ADC句柄
ADC_ChannelConfTypeDef ADC_Config;
/***********************************************************************************************************         
ADC1的DMA采样传输初始化                                                                  
***********************************************************************************************************/                                                                                                                                                     
void  ADC1_DMA1_Init(void)                //用DMA采样时
{                                                    
    GPIO_InitTypeDef GPIO_Initure;     //GPIO初始化结构体
    __HAL_RCC_GPIOA_CLK_ENABLE();                        //开启GPIOA时钟
                __HAL_RCC_GPIOB_CLK_ENABLE();                        //开启GPIOB时钟
                __HAL_RCC_GPIOC_CLK_ENABLE();                        //开启GPIOC时钟
       
    GPIO_Initure.Pin=GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7;            //PA0-7
    GPIO_Initure.Mode=GPIO_MODE_ANALOG;     //模拟
    GPIO_Initure.Pull=GPIO_NOPULL;          //不带上下拉
    HAL_GPIO_Init(GPIOA,&GPIO_Initure);
    GPIO_Initure.Pin=GPIO_PIN_0 | GPIO_PIN_1;            //PB0-1
    GPIO_Initure.Mode=GPIO_MODE_ANALOG;     //模拟
    GPIO_Initure.Pull=GPIO_NOPULL;          //不带上下拉
    HAL_GPIO_Init(GPIOB,&GPIO_Initure);
               
        {
                TIM_HandleTypeDef TIM2_Handler;         //定时器句柄
                TIM_OC_InitTypeDef TIM2_CH2Handler;     //定时器2通道2句柄
               
                //5ms取一个值  t=50*1080000/108000000=5ms
    TIM2_Handler.Instance=TIM2;            //定时器2
    TIM2_Handler.Init.Prescaler=1080000-1;       //定时器分频
    TIM2_Handler.Init.CounterMode=TIM_COUNTERMODE_UP;//向上计数模式
    TIM2_Handler.Init.Period=50-1;          //自动重装载值
    TIM2_Handler.Init.ClockDivision=TIM_CLOCKDIVISION_DIV1;
    HAL_TIM_PWM_Init(&TIM2_Handler);       //初始化PWM

    TIM2_CH2Handler.OCMode=TIM_OCMODE_PWM1; //模式选择PWM1
    TIM2_CH2Handler.Pulse=25;            //设置比较值,此值用来确定占空比,
                                            //默认比较值为自动重装载值的一半,即占空比为50%
    TIM2_CH2Handler.OCPolarity=TIM_OCPOLARITY_LOW; //输出比较极性为低
    HAL_TIM_PWM_ConfigChannel(&TIM2_Handler,&TIM2_CH2Handler,TIM_CHANNEL_2);//配置TIM2通道2
    HAL_TIM_PWM_Start(&TIM2_Handler,TIM_CHANNEL_2);//开启PWM通道2               
       
        }
       

       
        {               

                __HAL_RCC_DMA2_CLK_ENABLE();//DMA2时钟使能       
               
                __HAL_LINKDMA(&ADC1_Handler,DMA_Handle,ADC1_DMA_Handler);    //将DMA与ADC1联系起来(发送DMA)
               
                //Tx DMA配置
                ADC1_DMA_Handler.Instance=DMA2_Stream0;                           //数据流选择
                ADC1_DMA_Handler.Init.Channel=DMA_CHANNEL_0;                      //通道选择
                ADC1_DMA_Handler.Init.Direction=DMA_PERIPH_TO_MEMORY;             //外设到存储器
                ADC1_DMA_Handler.Init.PeriphInc=DMA_PINC_DISABLE;                 //外设非增量模式
                ADC1_DMA_Handler.Init.MemInc=DMA_MINC_ENABLE;                     //存储器增量模式
                ADC1_DMA_Handler.Init.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD;    //外设数据长度:16位
                ADC1_DMA_Handler.Init.MemDataAlignment=DMA_MDATAALIGN_HALFWORD;       //存储器数据长度:16位
                ADC1_DMA_Handler.Init.Mode=DMA_CIRCULAR;                            //循环传输模式
                ADC1_DMA_Handler.Init.Priority=DMA_PRIORITY_HIGH;               // DMA 传输通道优先级为高,当使用一个DMA通道时,优先级设置不影响
                ADC1_DMA_Handler.Init.FIFOMode=DMA_FIFOMODE_DISABLE;              // 禁止DMA FIFO        ,使用直连模式
                ADC1_DMA_Handler.Init.FIFOThreshold=DMA_FIFO_THRESHOLD_FULL;      // FIFO 大小,FIFO模式禁止时,这个不用配置       
                ADC1_DMA_Handler.Init.MemBurst=DMA_MBURST_SINGLE;                 //存储器突发单次传输
                ADC1_DMA_Handler.Init.PeriphBurst=DMA_PBURST_SINGLE;              //外设突发单次传输
               
                HAL_DMA_DeInit(&ADC1_DMA_Handler);   
                HAL_DMA_Init(&ADC1_DMA_Handler);       //初始化DMA流,流相当于一个大的管道,管道里面有很多通道
                HAL_DMA_Start (&ADC1_DMA_Handler,RHEOSTAT_ADC_DR_ADDR,(uint32_t)&DMA_ADVaule,10*100);

          __HAL_DMA_ENABLE_IT(&ADC1_DMA_Handler,DMA_IT_TC);                                    //开启传输完成中断
          HAL_NVIC_SetPriority(DMA2_Stream0_IRQn,1,2);                                                  //抢占1,子优先级2,组1
    HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);                                                        //使能中断
        }
       
       
        {
                __HAL_RCC_ADC1_CLK_ENABLE();                                 //使能ADC1时钟
    ADC1_Handler.Instance=ADC1;                                  // ADC1
    ADC1_Handler.Init.ClockPrescaler=ADC_CLOCK_SYNC_PCLK_DIV4;   //4分频,ADCCLK=PCLK2/4=108/4=27MHZ
    ADC1_Handler.Init.Resolution=ADC_RESOLUTION_12B;             //12位模式
    ADC1_Handler.Init.DataAlign=ADC_DATAALIGN_RIGHT;             //右对齐
    ADC1_Handler.Init.ScanConvMode=ENABLE;                       // 扫描模式,多通道采集才需要
    ADC1_Handler.Init.EOCSelection=DISABLE;                      //关闭EOC中断
    ADC1_Handler.Init.ContinuousConvMode=DISABLE;                //关闭连续转换
    ADC1_Handler.Init.NbrOfConversion=1;                         //1个转换在规则序列中 也就是只转换规则序列1
    ADC1_Handler.Init.DiscontinuousConvMode=DISABLE;             //禁止不连续采样模式
    ADC1_Handler.Init.NbrOfDiscConversion=10;                     //转换通道个数
    ADC1_Handler.Init.ExternalTrigConv=ADC_EXTERNALTRIGCONV_T2_CC2;       //定时器触发触发
    ADC1_Handler.Init.ExternalTrigConvEdge=ADC_EXTERNALTRIGCONVEDGE_NONE;//使用软件触发
    ADC1_Handler.Init.DMAContinuousRequests=ENABLE;             //开启DMA请求
    HAL_ADC_Init(&ADC1_Handler);                                 //初始化

    ADC_Config.Channel      = ADC_CHANNEL_0;
    ADC_Config.Rank         = 1;   
    ADC_Config.SamplingTime = ADC_SAMPLETIME_144CYCLES;// 采样时间间隔       
    ADC_Config.Offset       = 0;
    HAL_ADC_ConfigChannel(&ADC1_Handler, &ADC_Config);

    ADC_Config.Channel      = ADC_CHANNEL_1;
    ADC_Config.Rank         = 2;
    ADC_Config.SamplingTime = ADC_SAMPLETIME_144CYCLES; // 采样时间间隔       
    ADC_Config.Offset       = 0;
    HAL_ADC_ConfigChannel(&ADC1_Handler, &ADC_Config);

    ADC_Config.Channel      = ADC_CHANNEL_2;
    ADC_Config.Rank         = 3;           
    ADC_Config.SamplingTime = ADC_SAMPLETIME_144CYCLES;// 采样时间间隔
    ADC_Config.Offset       = 0;
    HAL_ADC_ConfigChannel(&ADC1_Handler, &ADC_Config);

    ADC_Config.Channel      = ADC_CHANNEL_3;
    ADC_Config.Rank         = 4;   
    ADC_Config.SamplingTime = ADC_SAMPLETIME_144CYCLES;// 采样时间间隔       
    ADC_Config.Offset       = 0;
    HAL_ADC_ConfigChannel(&ADC1_Handler, &ADC_Config);

    ADC_Config.Channel      = ADC_CHANNEL_4;
    ADC_Config.Rank         = 5;
    ADC_Config.SamplingTime = ADC_SAMPLETIME_144CYCLES; // 采样时间间隔       
    ADC_Config.Offset       = 0;
    HAL_ADC_ConfigChannel(&ADC1_Handler, &ADC_Config);

    ADC_Config.Channel      = ADC_CHANNEL_5;
    ADC_Config.Rank         = 6;           
    ADC_Config.SamplingTime = ADC_SAMPLETIME_144CYCLES;// 采样时间间隔
    ADC_Config.Offset       = 0;
    HAL_ADC_ConfigChannel(&ADC1_Handler, &ADC_Config);

    ADC_Config.Channel      = ADC_CHANNEL_6;
    ADC_Config.Rank         = 7;   
    ADC_Config.SamplingTime = ADC_SAMPLETIME_144CYCLES;// 采样时间间隔       
    ADC_Config.Offset       = 0;
    HAL_ADC_ConfigChannel(&ADC1_Handler, &ADC_Config);

    ADC_Config.Channel      = ADC_CHANNEL_7;
    ADC_Config.Rank         = 8;
    ADC_Config.SamplingTime = ADC_SAMPLETIME_144CYCLES; // 采样时间间隔       
    ADC_Config.Offset       = 0;
    HAL_ADC_ConfigChannel(&ADC1_Handler, &ADC_Config);

    ADC_Config.Channel      = ADC_CHANNEL_8;
    ADC_Config.Rank         = 9;           
    ADC_Config.SamplingTime = ADC_SAMPLETIME_144CYCLES;// 采样时间间隔
    ADC_Config.Offset       = 0;
    HAL_ADC_ConfigChannel(&ADC1_Handler, &ADC_Config);

               
    HAL_ADC_Start_DMA(&ADC1_Handler, (uint32_t*)&DMA_ADVaule,10*100);       

        }       
       
}

//DMA2_Stream0中断服务函数
void DMA2_Stream0_IRQHandler(void)
{
        if(__HAL_DMA_GET_FLAG(&ADC1_DMA_Handler,DMA_FLAG_HTIF0_4)!=RESET) //DMA半传输完成
        {
                 FinishFlag =Ture;//用来判断是否要处理AD数据
                 __HAL_DMA_CLEAR_FLAG(&ADC1_DMA_Handler,DMA_FLAG_HTIF0_4);     //清除DMA半传输完成中断标志位               
        }
        if(__HAL_DMA_GET_FLAG(&ADC1_DMA_Handler,DMA_FLAG_TCIF0_4)!=RESET) //DMA传输完成
        {
                 FinishFlag =Ture;//用来判断是否要处理AD数据
                 __HAL_DMA_CLEAR_FLAG(&ADC1_DMA_Handler,DMA_FLAG_TCIF0_4);     //清除DMA传输完成中断标志位

        }                                                                                                                
}

这是我配置的程序,仿真后都没进入DMA中断,请问这是什么情况?

回复

使用道具 举报

发表于 2018-3-27 17:45:58 | 显示全部楼层
没试过,帮顶
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-4-23 16:05:50 | 显示全部楼层
问题解决了,在DMA 中断函数关闭cache就可以了。
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-11-23 05:05 , Processed in 0.054613 second(s), 23 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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