分享与讨论:GD32的adc操作使用

[复制链接]
5459|21
手机看帖
扫描二维码
随时随地手机跟帖
firstblood|  楼主 | 2015-6-11 19:24 | 显示全部楼层 |阅读模式
GD32跟STM32在很大程度上,包括各个资源分配上都是有相似之处的,,这个现在利用stm32的adc的操作的来讨论下gd32的adc的操作的吧。。大家支持下啊。

我先抛砖引玉的,,介绍下stm32的adc的使用的,有不对的地方大家给指出来的啊。
firstblood|  楼主 | 2015-6-11 19:26 | 显示全部楼层
12位ADC是一种逐次逼近型模拟数字数字转换器。它有多达18个通道,可测量16个外部和2个内部信号源。
ADC的输入时钟不得超过14MHZ,它是由PCLK2经分频产生。
如果被ADC转换的模拟电压低于低阀值或高于高阀值,AWD模拟看门狗状态位被设置。

这个是比较基本的介绍的。。。

使用特权

评论回复
firstblood|  楼主 | 2015-6-11 19:26 | 显示全部楼层
ADC通常要与DMA一起使用 这里只是简单的用库配置ADC 不断扫描来实现ADC的应用。

首先配置GPIO与ADC的时钟:

ADC_InitTypeDef  ADC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);

GPIO_InitStructure.GPIO_Pin  =GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode =GPIO_Mode_AIN;
GPIO_Init(GPIOB,&GPIO_InitStructure); //默认速度为两兆

使用特权

评论回复
评论
lh930469433 2018-1-15 22:56 回复TA
楼主、指导下小弟,扣扣930469433 
firstblood|  楼主 | 2015-6-11 19:27 | 显示全部楼层
配置ADC的运行:

ADC_InitStructure.ADC_Mode              = ADC_Mode_Independent;  //独立模式
ADC_InitStructure.ADC_ScanConvMode      =DISABLE;      //连续多通道模式
ADC_InitStructure.ADC_ContinuousConvMode =ENABLE;      //连续转换
ADC_InitStructure.ADC_ExternalTrigConv  = ADC_ExternalTrigConv_None; //转换不受外界决定
ADC_InitStructure.ADC_DataAlign         =ADC_DataAlign_Right;   //右对齐
ADC_InitStructure.ADC_NbrOfChannel      =1;       //扫描通道数
ADC_Init(ADC1,&ADC_InitStructure);
ADC_RegularChannelConfig(ADC1,ADC_Channel_9, 1,ADC_SampleTime_1Cycles5); //通道X,采样时间为1.5周期,1代表规则通道第1个这个1是啥意思我不太清楚只有是1的时候我的ADC才正常。
ADC_Cmd  (ADC1,ENABLE);             //使能或者失能指定的ADC
ADC_SoftwareStartConvCmd(ADC1,ENABLE);//使能或者失能指定的ADC的软件转换启动功能

使用特权

评论回复
firstblood|  楼主 | 2015-6-11 19:27 | 显示全部楼层
ADC_InitTypeDef structureADC_InitTypeDef定义于文件“stm32f10x_adc.h”:

typedef struct

{

u32 ADC_Mode; FunctionalState ADC_ScanConvMode; FunctionalStateADC_ContinuousConvMode; u32 ADC_ExternalTrigConv; u32ADC_DataAlign; u8 ADC_NbrOfChannel;

} ADC_InitTypeDef

注意:为了能够正确地配置每一个ADC通道,用户在调用ADC_Init()之后,必须调用ADC_ChannelConfig()来配置每个所使用通道的转换次序和采样时间。

然后就是不停的读;

使用特权

评论回复
firstblood|  楼主 | 2015-6-11 19:28 | 显示全部楼层
这里需要补充一个知识点DMA,DMA就相当与CPU的一个秘书,他的作用就是帮CPU减轻负担的。说的再具体点就是帮CPU来转移数据的。我们都知道,AD每次转换结束后会将转换的结果放到一个固定的寄存器里,以往我们如果想将该寄存器中的值赋给某一变量时会用到赋值语句,如果不用DMA,则赋值语句便要CPU来完成,CPU本来就要忙着处理其他事情,现在还要来解决赋值语句这么简单的问题,肯到会蛋疼。所以需要DMA这个秘书来帮他解决这个问题。由于DMA只是个秘书,所以比较笨,你只有把任务交代清楚了她才能很好的完成任务。那么怎样来给DMA吩咐任务呢,聪明的人肯定想到了,那当然是“DMA_Init(DMA1_Channel1, &DMA_InitStructure)”这个函数啦。

使用特权

评论回复
firstblood|  楼主 | 2015-6-11 19:29 | 显示全部楼层
本帖最后由 firstblood 于 2015-6-11 19:32 编辑

* 函数名:ADC1_Mode_Config   * 描述 :配置ADC1的工作模式为MDA模式 * 输入 : 无 * 输出 :无  * 调用 :内部调用 */   static void ADC1_Mode_Config(void)
{
   DMA_InitTypeDef  DMA_InitStructure;
  ADC_InitTypeDef  ADC_InitStructure;     /* 将与DMA有关的寄存器设我初始值 */  
  DMA_DeInit(DMA1_Channel1);  
  /*定义DMA外设基地址, 这里的ADC1_DR_Address 是用户自己定义的,即为存放转换结果的寄存器 ,他的作用就是告诉DMA取数就到                                                       ADC1_DR_Address 这里来取。*/  
  DMA_InitStructure.DMA_PeripheralBaseAddr =ADC1_DR_Address;
   /*定义内存基地址,即告诉DMA要将从AD中取来的数放到ADC_ConvertedValue中 */      
  DMA_InitStructure.DMA_MemoryBaseAddr =(u32)&ADC_ConvertedValue;  
  /*定义AD外设作为数据传输的来源,即告诉DMA是将AD中的数据取出放到内存中,不能反过来*/
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;  
  /*指定DMA通道的DMA缓存的大小,即告诉DMA开辟几个内存空间,由于我们只取通道10的AD数据所以只需开辟一个内存空间*/  
  DMA_InitStructure.DMA_BufferSize = 1;
   /*设定寄存器地址固定,即告诉DMA,只从固定的一个地方取数*/
  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工作再循环缓存模式,即告诉DMA要不停的搬运,不能偷懒*/  
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;  
/*设定DMA选定的通道软件优先级*/   
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
   DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;   
DMA_Init(DMA1_Channel1, &DMA_InitStructure);  
  /* Enable DMA channel1,CPU有好几个DMA秘书,现在只用 DMA1_Channel1这个秘书*/  
  DMA_Cmd(DMA1_Channel1, ENABLE);   

使用特权

评论回复
firstblood|  楼主 | 2015-6-11 19:33 | 显示全部楼层
/*设置ADC工作在独立模式*/   
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
  /*规定AD转换工作在单次模式,即对一个通道采样*/
  ADC_InitStructure.ADC_ScanConvMode = DISABLE
   /*设定AD转化在连续模式*/   
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
   /*不使用外部促发转换*/  
  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;  
/*采集的数据在寄存器中以右对齐的方式存放*/
   ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
   /*设定要转换的AD通道数目*/
    ADC_InitStructure.ADC_NbrOfChannel = 1;  
ADC_Init(ADC1, &ADC_InitStructure);   
/*配置ADC时钟,为PCLK2的8分频,即9MHz*/
  RCC_ADCCLKConfig(RCC_PCLK2_Div8);
   /*配置ADC1的通道11为55.5个采样周期 */   
ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_55Cycles5);

使用特权

评论回复
firstblood|  楼主 | 2015-6-11 19:34 | 显示全部楼层
/* Enable ADC1 DMA */  
  ADC_DMACmd(ADC1, ENABLE);  
/* Enable ADC1 */  
  ADC_Cmd(ADC1, ENABLE);  
/*复位校准寄存器 */
   ADC_ResetCalibration(ADC1);
  /*等待校准寄存器复位完成 */  
  while(ADC_GetResetCalibrationStatus(ADC1));
  /* ADC校准 */  
  ADC_StartCalibration(ADC1);
  /* 等待校准完成*/  
  while(ADC_GetCalibrationStatus(ADC1));
   /* 由于没有采用外部触发,所以使用软件触发ADC转换 */
  ADC_SoftwareStartConvCmd(ADC1, ENABLE); }
  配置完以上的程序,那么AD每转换一次,DMA都会将转换结果搬到变量  ADC_ConvertedValue中,而不需用每次都用赋值语句来取值AD转换的值。

使用特权

评论回复
firstblood|  楼主 | 2015-6-11 19:35 | 显示全部楼层
置于其多路采集的会在后边继续介绍的啊。。

使用特权

评论回复
sunmeat| | 2015-6-13 08:43 | 显示全部楼层
GD的ADC和STM32有一个小小的区别,GD的输入阻抗和采样时间的设置和ST有一定差异,相同配置GD采样的输入阻抗相对来说要小。

使用特权

评论回复
comeon201208| | 2015-6-13 22:36 | 显示全部楼层
12位ADC是一种逐次逼近型模拟数字数字转换器。它有多达18个通道,可测量16个外部和2个内部信号源。

使用特权

评论回复
STM32初学者| | 2015-6-14 14:23 | 显示全部楼层
相同配置GD采样的输入阻抗相对来说要小。这个落实到具体的程序,需要修改啥呢?

使用特权

评论回复
angerbird| | 2015-6-15 21:08 | 显示全部楼层
12位ADC是一种逐次逼近型模拟数字数字转换器。它有多达18个通道,可测量16个外部和2个内部信号源。

使用特权

评论回复
smilingangel| | 2015-6-16 20:44 | 显示全部楼层
firstblood 发表于 2015-6-11 19:28
这里需要补充一个知识点DMA,DMA就相当与CPU的一个秘书,他的作用就是帮CPU减轻负担的。说的再具体点就是帮 ...

DMA的运用提高了AD的采集数据的效率的,,这个比较好。

使用特权

评论回复
baimiaocun2015| | 2015-6-17 21:42 | 显示全部楼层
希望从STM32的直接移植过去的可以使用的啊。。

使用特权

评论回复
lwsn| | 2015-7-3 21:31 | 显示全部楼层
为了能够正确地配置每一个ADC通道,调用ADC_Init()之后,必须调用ADC_ChannelConfig()来配置每个所使用通道的转换次序和采样时间。

使用特权

评论回复
芙蓉洞| | 2015-7-6 14:39 | 显示全部楼层
GD虽然大部分和ST相同,但是还是有区别的

使用特权

评论回复
vivilzb1985| | 2015-7-11 10:07 | 显示全部楼层
为了能够正确地配置每一个ADC通道,用户在调用ADC_Init()之后,必须调用ADC_ChannelConfig()来配置每个所使用通道的转换次序和采样时间。,后就是不停的读。

使用特权

评论回复
comeon201208| | 2015-7-11 16:16 | 显示全部楼层
AD数据采集的也可以不用DMA方式的。

使用特权

评论回复
评论
小景报到 2021-6-21 23:29 回复TA
当然,如果对采集数据没有太高的要求,采用查询转换完成标志位或中断的方式也是可以的; 
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

86

主题

4492

帖子

9

粉丝