打印
[CW32F030系列]

ADC转换之DMA传输

[复制链接]
273|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
51xlf|  楼主 | 2022-9-11 20:42 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#define DMA_CYCLE_EN  1
uint32_t ADC_Result_Array[16] = {0};

/******************************************************************************
* Local pre-processor symbols/macros ('#define')
******************************************************************************/

/*****************************************************************************
* Function implementation - global ('extern') and local ('static')
******************************************************************************/
static void ZeroMemory(uint8_t *buf,uint32_t size)
{
  uint32_t i = 0;
  for(i = 0;i < size;i ++)
  {
    *buf = 0x0;
  }
}

static void Error_Handle()
{
  while(1);
}

void DMA_CHANNEL1_IRQ_FUNCTION(void)
{
  if( DMA_GetITStatus(DMA_IT_TC1) )
  {
    DMA_ClearITPendingBit(DMA_IT_TC1);

#ifdef DMA_CYCLE_EN
                CW_DMACHANNEL1->CNT      = 0x10010;                              //重置CNT计数
                CW_DMACHANNEL1->DSTADDR  = (uint32_t)( &ADC_Result_Array[0] );   //重置目的地址
    DMA_Cmd(CW_DMACHANNEL1, ENABLE);  //使能DMA
#else
    ADC_Disable();    //传输完成,停止ADC
#endif
  }

  if( DMA_GetITStatus(DMA_IT_TE1) )
  {
    DMA_ClearITPendingBit(DMA_IT_TE1);
    Error_Handle();
  }
}
/**
  * [url=home.php?mod=space&uid=247401]@brief[/url]  Configure the nested vectored interrupt controller.
  * @param  None
  * @retval None
  */
void NVIC_Configuration(void)
{
    __disable_irq();

    NVIC_ClearPendingIRQ(DMACH1_IRQn);

    NVIC_EnableIRQ(DMACH1_IRQn);

    __enable_irq();  
}


/**
******************************************************************************
** \brief  Main function of project
**
** \return uint32_t return value, if needed
**
**
**
******************************************************************************/

int32_t main(void)
{
    ADC_InitTypeDef   ADC_InitStruct;          
          DMA_InitTypeDef   DMA_InitStruct;

    RCC_AHBPeriphClk_Enable(RCC_AHB_PERIPH_DMA | RCC_AHB_PERIPH_GPIOA | RCC_AHB_PERIPH_GPIOB, ENABLE);  //Open DMA and GPIOA/B Clk
    RCC_APBPeriphClk_Enable2(RCC_APB2_PERIPH_ADC, ENABLE);    //Open ADC Clk

    //PB8/PB9 推挽输出
          GPIO_InitTypeDef GPIO_InitStruct;
                GPIO_InitStruct.Pins = GPIO_PIN_8 | GPIO_PIN_9;
                GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
                GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
                GPIO_Init(CW_GPIOB, &GPIO_InitStruct);
                PB08_SETLOW();
                PB09_SETLOW();
       
          //配置ADC测试IO口
    PA00_ANALOG_ENABLE() ;      //PA00 (AIN0)
       
    //ADC初始化
    ADC_InitStruct.ADC_OpMode = ADC_SingleChOneMode; //单通道单次转换模式
    ADC_InitStruct.ADC_ClkDiv = ADC_Clk_Div128; //PCLK
    ADC_InitStruct.ADC_SampleTime = ADC_SampTime5Clk; //5个ADC时钟周期
    ADC_InitStruct.ADC_VrefSel = ADC_Vref_VDDA; //VDDA参考电压
    ADC_InitStruct.ADC_InBufEn = ADC_BufEnable; //开启跟随器
    ADC_InitStruct.ADC_TsEn = ADC_TsDisable; //内置温度传感器禁用
    ADC_InitStruct.ADC_DMAEn = ADC_DmaEnable; //ADC转换完成触发DMA传输
    ADC_InitStruct.ADC_Align = ADC_AlignRight; //ADC转换结果右对齐
    ADC_InitStruct.ADC_AccEn = ADC_AccDisable; //转换结果累加不使能
    ADC_Init(&ADC_InitStruct);                                  //初始化ADC配置
    CW_ADC->CR1_f.DISCARD = FALSE;                              //配置数据更新策略,不包含在ADC结构体中               
    CW_ADC->CR1_f.CHMUX = ADC_Vref1P2Input;   //ADC_ExInputCH0; //配置ADC输入通道,不包含在ADC结构体中

    ADC_ClearITPendingBit(ADC_IT_EOC);
    ADC_ITConfig(ADC_IT_EOC, ENABLE);
    ADC_EnableNvic(ADC_INT_PRIORITY);
   
    DMA_StructInit( &DMA_InitStruct );
    ZeroMemory((uint8_t *)&ADC_Result_Array[0],sizeof(ADC_Result_Array));
    DMA_InitStruct.DMA_Mode = DMA_MODE_BLOCK;
    DMA_InitStruct.DMA_TransferWidth = DMA_TRANSFER_WIDTH_32BIT;
    DMA_InitStruct.DMA_SrcInc = DMA_SrcAddress_Fix;
        #ifdef DMA_CYCLE_EN
    DMA_InitStruct.DMA_DstInc = DMA_DstAddress_Increase;
        #else
    DMA_InitStruct.DMA_DstInc = DMA_DstAddress_Fix;
        #endif

    DMA_InitStruct.DMA_TransferCnt = 16;
    DMA_InitStruct.DMA_SrcAddress = (uint32_t) &(CW_ADC->RESULT0);
    DMA_InitStruct.DMA_DstAddress = (uint32_t)&ADC_Result_Array[0];
    DMA_InitStruct.TrigMode = DMA_HardTrig;
    DMA_InitStruct.HardTrigSource = DMA_HardTrig_ADC_TRANSCOMPLETE;
    DMA_Init(CW_DMACHANNEL1,&DMA_InitStruct);
    DMA_ClearITPendingBit(DMA_IT_ALL);
    DMA_ITConfig(CW_DMACHANNEL1, DMA_IT_TC|DMA_IT_TE , ENABLE);  //使能DMA_CHANNEL1中断
    NVIC_Configuration();   //使能DMA_CHANNEL1中断
    DMA_Cmd(CW_DMACHANNEL1, ENABLE);  //使能DMA

    //ADC使能
    ADC_Enable();
    ADC_SoftwareStartConvCmd(ENABLE);

                while(1)
                {
                        PB08_TOG();   
                        PB09_TOG();
                        FirmwareDelay(1000000);
                }
   
}


使用特权

评论回复
沙发
gouguoccc| | 2022-9-11 23:26 | 只看该作者
学习了,谢谢分享,精度咋样呢?

使用特权

评论回复
板凳
Bowclad| | 2022-10-4 19:15 | 只看该作者
精度怎么样?

使用特权

评论回复
地板
AloneKaven| | 2022-10-5 20:13 | 只看该作者
能分享一下精度咋样吗

使用特权

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

本版积分规则

534

主题

9359

帖子

19

粉丝