ADC DMA 定时器

2019-08-19 18:03发布

求助,用定时器的PWM触发ADC,再用DMA将所得数据存放到一个数组。  再有是不是定时器中断可以不开?我感觉没什么用?大家帮忙看看,刚弄这个有些生疏

void TIM_Init(u16 arr,u16 psc)  //定时器中断
{
        TIM_TimeBaseInitTypeDef  TIM_TimeInitStructure;
        TIM_OCInitTypeDef TIM_OCInitStructure;
        NVIC_InitTypeDef NVIC_InitStructure;
       
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
       
        TIM_TimeInitStructure.TIM_Period = arr; //重装载值
        TIM_TimeInitStructure.TIM_Prescaler = psc;//预分频
        TIM_TimeInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;//设置时钟分割:TDTS = Tck_tim
        TIM_TimeInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数
  TIM_TimeBaseInit(TIM2,&TIM_TimeInitStructure);
       
        TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
        TIM_ClearITPendingBit(TIM2, TIM_IT_Update);//清中断,以免一启用中断后立即产生中断
        //TIM_SelectOutputTrigger(TIM2,TIM_TRGOSource_OC2Ref);

        NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; //定时器2中断
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //抢占优先级0级
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //从优先级3级
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);
       
        TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_Pulse = 50;
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
  TIM_OC2Init(TIM2,&TIM_OCInitStructure);
       
        TIM_Cmd(TIM2,ENABLE);
}

void TIM2_IRQHandler()
{
  if(TIM_GetFlagStatus(TIM2,TIM_FLAG_Update)!=RESET)
                {
                         TIM_ClearFlag(TIM2,TIM_FLAG_Update);
                }
}

u8 SendBuff[200];

void DMA_Config()    //从存储器->外设模式/8位数据宽度/存储器增量模式
{
        DMA_InitTypeDef DMA_InitStructure;
        NVIC_InitTypeDef    NVIC_InitStructure;
        ADC_InitTypeDef   ADC_InitTStructure;
        GPIO_InitTypeDef   GPIO_InitStructure;
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_ADC1,ENABLE);
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);        //使能DMA传输
       
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //PA6  ADC12_IN4
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
        GPIO_Init(GPIOA,&GPIO_InitStructure);
       
  DMA_DeInit(DMA1_Channel1);   //将DMA的通道1寄存器重设为缺省值

        DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&ADC1->DR;  //DMA外设基地址
        DMA_InitStructure.DMA_MemoryBaseAddr = (u32)SendBuff;  //DMA内存基地址
        DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;  //搬运到内存
        DMA_InitStructure.DMA_BufferSize = 200;  //DMA通道的DMA缓存的大小
        DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;  //外设地址寄存器不变
        DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;  //内存地址寄存器递增
        DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;  //数据宽度为8位
        DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //数据宽度为8位
        DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;  //工作在正常模式
        DMA_InitStructure.DMA_Priority = DMA_Priority_High; //DMA通道拥有高优先级
        DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;  //DMA通道x没有设置为内存到内存传输
        DMA_Init(DMA1_Channel1, &DMA_InitStructure);  //根据DMA_InitStruct中指定的参数初始化DMA的通道USART1_Tx_DMA_Channel所标识的寄存器
       
  NVIC_InitStructure.NVIC_IRQChannel=DMA1_Channel1_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;
        NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
        NVIC_Init(&NVIC_InitStructure);
       
        DMA_ITConfig(DMA1_Channel1,DMA_IT_TC,ENABLE); //开启完成中断
        DMA_ClearFlag(DMA1_FLAG_TC1);//清除Channel1中断
        DMA_Cmd(DMA1_Channel1, ENABLE);       
       
        RCC_ADCCLKConfig(RCC_PCLK2_Div6);   //设置ADC分频因子6 72M/6=12,ADC最大时间不能超过14M
        ADC_DeInit(ADC1); //复位ADC1
        ADC_InitTStructure.ADC_ContinuousConvMode = DISABLE; //单次转换模式
        ADC_InitTStructure.ADC_DataAlign = ADC_DataAlign_Right; //数据右对齐
        ADC_InitTStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_CC2; //由TIM2的CC2触发
        ADC_InitTStructure.ADC_Mode = ADC_Mode_Independent; //ADC工作模式:ADC1和ADC2工作在独立模式
        ADC_InitTStructure.ADC_NbrOfChannel = 1;  //顺序进行规则转换的ADC通道的数目
        ADC_InitTStructure.ADC_ScanConvMode = DISABLE;//模数转换工作在单通道模式
  ADC_Init(ADC1,&ADC_InitTStructure);
       
        ADC_ExternalTrigConvCmd(ADC1,ENABLE); //使能ADC1外部触发功能
       
        ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 1, ADC_SampleTime_239Cycles5);  //配置规则通道
       
        ADC_DMACmd(ADC1, ENABLE);
        ADC_Cmd(ADC1, ENABLE);
        /**********校准***************/
        ADC_ResetCalibration(ADC1); //使能复位校准
        while(ADC_GetResetCalibrationStatus(ADC1)); //等待复位校准结束
       
        ADC_StartCalibration(ADC1);    //开启AD校准
        while(ADC_GetCalibrationStatus(ADC1)); //等待校准结束
        /**********************/
}

void DMA1_Channel1_IRQHandler()
{
        if(DMA_GetFlagStatus(DMA1_FLAG_TC1)!=RESET)
                {       
                        u8 i;
                        for(i = 0;i < 200;i++) USART_SendData(USART1,SendBuff[i]);
      DMA_ClearFlag(DMA1_FLAG_TC1);
                       
                        DMA_Cmd(DMA1_Channel1, DISABLE);
                        DMA_SetCurrDataCounter(DMA1_Channel1,200);//DMA通道的DMA缓存的大小
                        DMA_Cmd(DMA1_Channel1, ENABLE);
                }
}

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
3条回答
liujie136997963
1楼-- · 2019-08-19 23:05
来个人看看吧?
正点原子
2楼-- · 2019-08-19 23:19
帮顶
Electronic
3楼-- · 2019-08-20 00:24
  帮顶

一周热门 更多>