打印
[RISC-V MCU 应用开发]

CH32V307VCT6 多通道DMA

[复制链接]
1229|15
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
piczero|  楼主 | 2022-9-1 06:48 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
/********************************** (C) COPYRIGHT *******************************
* File Name          : main.c
* Author             : WCH
* Version            : V1.0.0
* Date               : 2021/06/06
* Description        : Main program body.
*******************************************************************************/

/*
*@NOTE
ADC使用DMA采样例程:
ADC通道2(PA2),规则组通道通过DMA获取 ADC连续1024次转换数据。

*/
#define  length  5
#include "debug.h"
//extern u16 ADC_ConvertedValue[length];
u16 ADC_ConvertedValue[length]={0,0,0};
/* Global Variable */
u16 TxBuf[1024];
s16 Calibrattion_Val = 0;

/*******************************************************************************
* Function Name  : ADC_Function_Init
* Description    : Initializes ADC collection.
* Input          : None
* Return         : None
*******************************************************************************/
void ADC_Function_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    ADC_InitTypeDef ADC_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1 , ENABLE ); //使能GPIOA时钟和ADC

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5; //PA1~5对应ADC通道1~5
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //GPIO模式为模拟输入
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;  //配置ADC为独立模式
    ADC_InitStructure.ADC_ScanConvMode = ENABLE;        //多通道模式下开启扫描模式
    ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;  //设置开启连续转换模式
    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //设置转换不是由外部触发启动,软件触发启动
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //设置ADC数据右对齐
    ADC_InitStructure.ADC_NbrOfChannel = length;           //规则转换的ADC通道的数目
    ADC_Init(ADC1, &ADC_InitStructure);                    //根据ADC_InitStructure中指定的参数初始化ADC1寄存器

    RCC_ADCCLKConfig(RCC_PCLK2_Div6); //设置ADC时钟分频为6分频

    ADC_Cmd(ADC1, ENABLE);      //使能ADC1

    ADC_ResetCalibration(ADC1); //重置ADC1校准寄存器。

    while(ADC_GetResetCalibrationStatus(ADC1)); //等待复位校准结束

    ADC_StartCalibration(ADC1); //开启AD校准

    while(ADC_GetCalibrationStatus(ADC1));      //等待校准结束
}

/*******************************************************************************
* Function Name  : Get_ADC_Val
* Description    : Returns ADCx conversion result data.
* Input          : ch: ADC channel.
*                    ADC_Channel_0: ADC Channel0 selected.   PA0
*                    ADC_Channel_1: ADC Channel1 selected.   PA1
*                    ADC_Channel_2: ADC Channel2 selected.   PA2
*                    ADC_Channel_3: ADC Channel3 selected.   PA3
*                    ADC_Channel_4: ADC Channel4 selected.   PA4
*                    ADC_Channel_5: ADC Channel5 selected.   PA5
*                    ADC_Channel_6: ADC Channel6 selected.   PA6
*                    ADC_Channel_7: ADC Channel7 selected.   PA7
*                    ADC_Channel_8: ADC Channel8 selected.   PB0
*                    ADC_Channel_9: ADC Channel9 selected.   PB1
*                    ADC_Channel_10: ADC Channel10 selected. PC0
*                    ADC_Channel_11: ADC Channel11 selected. PC1
*                    ADC_Channel_12: ADC Channel12 selected. PC2
*                    ADC_Channel_13: ADC Channel13 selected. PC3
*                    ADC_Channel_14: ADC Channel14 selected. PC4
*                    ADC_Channel_15: ADC Channel15 selected. PC5
*                    ADC_Channel_16: ADC Channel16 selected.
*                    ADC_Channel_17: ADC Channel17 selected.
* Return         : val: The Data conversion value.
*******************************************************************************/
u16 Get_ADC_Val(u8 ch)
{
        u16 val;

        ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5 );
        ADC_SoftwareStartConvCmd(ADC1, ENABLE);

        while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));
        val = ADC_GetConversionValue(ADC1);

        return val;
}

/*******************************************************************************
* Function Name  : DMA_Tx_Init
* Description    : Initializes the DMAy Channelx configuration.
* Input          : DMA_CHx:
*                    x can be 1 to 7.
*                  ppadr: Peripheral base address.
*                  memadr: Memory base address.
*                  bufsize: DMA channel buffer size.
* Return         : None
*******************************************************************************/
void DMA_Tx_Init( void )
{
    DMA_InitTypeDef DMA_InitStructure;

    RCC_AHBPeriphClockCmd( RCC_AHBPeriph_DMA1, ENABLE ); //使能开启DMA时钟

    DMA_DeInit(DMA1_Channel1); //复位DMA控制器

    DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&ADC1->RDATAR;  //配置外设地址为ADC数据寄存器地址
    DMA_InitStructure.DMA_MemoryBaseAddr = (u32)ADC_ConvertedValue; //配置存储器地址为读取ADC值地址
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;              //配置数据源为外设,即DMA传输方式为外设到存储器
    DMA_InitStructure.DMA_BufferSize = length;                      //设置DMA数据缓冲区大小,此处设置为length
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//设置DMA外设递增模式关闭
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;         //设置DMA存储器递增模式开启
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //设置外设数据大小为半字,即两个字节
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;         //设置存储器数据大小为半字,即两个字节
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;     //设置DMA模式为循环传输模式
    DMA_InitStructure.DMA_Priority = DMA_Priority_High; //设置DMA传输通道优先级为高,当使用一 DMA通道时,优先级设置不影响
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;        //因为此DMA传输方式为外设到存储器,因此禁用存储器到存储器传输方式
    DMA_Init( DMA1_Channel1, &DMA_InitStructure );      //初始化DMA
    DMA_Cmd(DMA1_Channel1 , ENABLE);  //使能DMA
    // 配置 ADC 通道转换顺序为1,第一个转换,采样时间为55.5个时钟周期
    ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_55Cycles5);
    ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 2, ADC_SampleTime_55Cycles5);
    ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 3, ADC_SampleTime_55Cycles5);
    ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 4, ADC_SampleTime_55Cycles5);
    ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 5, ADC_SampleTime_55Cycles5);

    // 使能ADC DMA 请求
    ADC_DMACmd(ADC1, ENABLE);

    // 由于没有采用外部触发,所以使用软件触发ADC转换
    ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}

/*******************************************************************************
* Function Name  : main
* Description    : Main program.
* Input          : None
* Return         : None
*******************************************************************************/
int main(void)
{
        u16 i;

        Delay_Init();
        USART_Printf_Init(115200);
        printf("SystemClk:%d\r\n",SystemCoreClock);

  ADC_Function_Init();
  printf("CalibrattionValue:%d\n", Calibrattion_Val);
//
        DMA_Tx_Init(  );
//        DMA_Cmd( DMA1_Channel1, ENABLE );
//
//        ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 1, ADC_SampleTime_239Cycles5 );
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
//  Delay_Ms(50);
//        ADC_SoftwareStartConvCmd(ADC1, DISABLE);

//        for(i=0; i<1024; i++)
//        {
//                printf( "%04d\r\n", TxBuf+Calibrattion_Val );
//                Delay_Ms(10);
//        }

//        while(1);
  
  while (1)
   {

       printf("\r\n The current ADCH1 value = %d \r\n", ADC_ConvertedValue[0]);
       printf("\r\n The current ADCH2 value = %d \r\n", ADC_ConvertedValue[1]);
       printf("\r\n The current ADCH3 value = %d \r\n", ADC_ConvertedValue[2]);
       printf("\r\n The current ADCH4 value = %d \r\n", ADC_ConvertedValue[3]);
       printf("\r\n The current ADCH5 value = %d \r\n", ADC_ConvertedValue[4]);

       Delay_Ms(500);
   }












}







使用特权

评论回复

相关帖子

沙发
linfelix| | 2022-9-5 15:38 | 只看该作者
如何做多通道ADC?

使用特权

评论回复
板凳
51xlf| | 2022-9-5 16:33 | 只看该作者
采集到的数据相互有干扰,该怎么破?

使用特权

评论回复
地板
earlmax| | 2022-9-5 17:13 | 只看该作者
可以同时采集吗?

使用特权

评论回复
5
yujielun| | 2022-9-8 08:49 | 只看该作者
多通道转换,是怎么样读取转换的结果的 ?

使用特权

评论回复
6
fentianyou| | 2022-9-8 09:35 | 只看该作者
两路数据相同怎么解决

使用特权

评论回复
7
ghuca| | 2022-9-8 10:21 | 只看该作者
AD转换的DMA方式和非DMA方式有什么不同

使用特权

评论回复
8
iyoum| | 2022-9-8 11:11 | 只看该作者
adc多通道采集可以不采用dma吗

使用特权

评论回复
9
sheflynn| | 2022-9-8 12:02 | 只看该作者
怎么2个adc一起用

使用特权

评论回复
10
sdlls| | 2022-9-8 12:52 | 只看该作者
如何使用ADC+DMA每隔一小段时间连续采集两个通道的数据

使用特权

评论回复
11
mikewalpole| | 2022-9-8 13:43 | 只看该作者
数据传输适合用DMA吗?

使用特权

评论回复
12
minzisc| | 2022-9-10 21:08 | 只看该作者
怎么样读取转换的结果的 ?

使用特权

评论回复
13
mollylawrence| | 2022-9-11 11:37 | 只看该作者
沁恒CH32V307不错。   

使用特权

评论回复
14
maudlu| | 2022-9-11 12:34 | 只看该作者
DMA寄存器配置可以参考《CH32FV2x_V3x 应用手册》的第11章

使用特权

评论回复
15
xietingfeng| | 2022-9-11 13:24 | 只看该作者
CH32V307 一款超实用的MCU  

使用特权

评论回复
16
xiaoyaodz| | 2022-9-11 14:16 | 只看该作者
adc多通道采集可以不采用dma吗

使用特权

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

本版积分规则

2

主题

12

帖子

1

粉丝