OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 5931|回复: 4

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

[复制链接]

4

主题

9

帖子

0

精华

初级会员

Rank: 2

积分
161
金钱
161
注册时间
2016-3-5
在线时间
33 小时
发表于 2018-3-27 16:54:16 | 显示全部楼层 |阅读模式
1金钱
// 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_HT);        //开启半传输完成中断
          __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中断,请问这是什么情况?

最佳答案

查看完整内容[请看2#楼]

这么久居然这么冷清。。。。。。 问题解决了,只要在DMA中断函数关闭关闭cache,接收完之后再开启就可以了。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

4

主题

9

帖子

0

精华

初级会员

Rank: 2

积分
161
金钱
161
注册时间
2016-3-5
在线时间
33 小时
 楼主| 发表于 2018-3-27 16:54:17 | 显示全部楼层
这么久居然这么冷清。。。。。。
问题解决了,只要在DMA中断函数关闭关闭cache,接收完之后再开启就可以了。
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165377
金钱
165377
注册时间
2010-12-1
在线时间
2111 小时
发表于 2018-3-28 01:18:59 | 显示全部楼层
帮顶
回复

使用道具 举报

1

主题

7

帖子

0

精华

初级会员

Rank: 2

积分
86
金钱
86
注册时间
2019-7-12
在线时间
16 小时
发表于 2019-8-11 14:13:32 | 显示全部楼层
有用,帮顶
回复

使用道具 举报

16

主题

90

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
368
金钱
368
注册时间
2019-10-24
在线时间
153 小时
发表于 2021-3-31 16:26:43 | 显示全部楼层
你好,中断为啥只能进一次啊
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-28 07:30

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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