野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 14306|回复: 7

ADC转换

[复制链接]
发表于 2018-7-23 09:30:42 | 显示全部楼层 |阅读模式
1火花
  如题,我想利用ADC1的两个通道来采样,包含channel1和内部温度channel16,如果不采用DMA方式,如何读取采样值,谢谢。
以下是我对ADC的初始化:
ADC_InitStructure.ADC_ContinuousConvMode=DISABLE;   //非连续转换
  ADC_InitStructure.ADC_DataAlign=ADC_ExternalTrigConv_None;
  ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;   //非外部出发,选择软件触发
  ADC_InitStructure.ADC_Mode=ADC_Mode_Independent;    //  独立模式
  ADC_InitStructure.ADC_NbrOfChannel=2;   //规则通道序列长度设为2,包含一个内部温度,一个外部采样
  ADC_InitStructure.ADC_ScanConvMode=DISABLE;   //非扫描模式
  ADC_Init(ADC1,&ADC_InitStructure);


回复

使用道具 举报

发表于 2018-7-23 10:20:34 | 显示全部楼层
不用DMA就直接查询标志位,标志位表示有数据后就读取adc的数据寄存器
回复

使用道具 举报

 楼主| 发表于 2018-7-23 10:40:54 | 显示全部楼层
你好,我不是很清楚,标志位指的是转换结束EOC吗,我如何区分是通道1,还是内部温度的数据呢。以下方式可以吗
u16 Get_ADCValue(void)
{
  //u16 adc_value;
  ADC_RegularChannelConfig(ADC1,ADC_Channel_1,1,ADC_SampleTime_239Cycles5);   //外部ADC采样
// ADC_RegularChannelConfig(ADC1,ADC_Channel_16,2,ADC_SampleTime_239Cycles5);  //内部温度采样
  
  ADC_SoftwareStartConvCmd(ADC1,ENABLE);  
  while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)!=RESET);
  return ADC_GetConversionValue(ADC1);
// ADC_SoftwareStartConvCmd(ADC1,ENABLE);  
// temp_adc_value=ADC_GetConversionValue(ADC1);
  
}
u16 GET_TEMPADCValue(void)
{
  ADC_RegularChannelConfig(ADC1,ADC_Channel_16,2,ADC_SampleTime_239Cycles5);
  ADC_SoftwareStartConvCmd(ADC1,ENABLE);
  while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)!=RESET);  
  return ADC_GetConversionValue(ADC1);
}
回复

使用道具 举报

 楼主| 发表于 2018-7-23 10:42:10 | 显示全部楼层
flyleaf 发表于 2018-7-23 10:20
不用DMA就直接查询标志位,标志位表示有数据后就读取adc的数据寄存器

你好,我不是很清楚,标志位指的是转换结束EOC吗,我如何区分是通道1,还是内部温度的数据呢。以下方式可以吗
u16 Get_ADCValue(void)
{
  //u16 adc_value;
  ADC_RegularChannelConfig(ADC1,ADC_Channel_1,1,ADC_SampleTime_239Cycles5);   //外部ADC采样
// ADC_RegularChannelConfig(ADC1,ADC_Channel_16,2,ADC_SampleTime_239Cycles5);  //内部温度采样
  
  ADC_SoftwareStartConvCmd(ADC1,ENABLE);  
  while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)!=RESET);
  return ADC_GetConversionValue(ADC1);
// ADC_SoftwareStartConvCmd(ADC1,ENABLE);  
// temp_adc_value=ADC_GetConversionValue(ADC1);
  
}
u16 GET_TEMPADCValue(void)
{
  ADC_RegularChannelConfig(ADC1,ADC_Channel_16,2,ADC_SampleTime_239Cycles5);
  ADC_SoftwareStartConvCmd(ADC1,ENABLE);
  while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)!=RESET);  
  return ADC_GetConversionValue(ADC1);
}
回复

使用道具 举报

 楼主| 发表于 2018-7-26 00:20:37 | 显示全部楼层
u16 adc_array[2]={0,0};
void  Adc_Init(void)
{        
        ADC_InitTypeDef ADC_InitStructure;
        GPIO_InitTypeDef GPIO_InitStructure;
        NVIC_InitTypeDef NVIC_InitStructure;

        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1, ENABLE );          

        RCC_ADCCLKConfig(RCC_PCLK2_Div6);           //PA1 作为模拟通道输入引脚                        
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;                //模拟输入引脚
        GPIO_Init(GPIOA, &GPIO_InitStructure);       

        ADC_DeInit(ADC1);  //复位ADC1

        ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;        //独立模式        ADC_InitStructure.ADC_ScanConvMode = ENABLE;        //模数转换工作在扫描模式
        ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;        //模数转换工作在单次转换模式
        ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;                ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;        //ADC数据右对齐
        ADC_InitStructure.ADC_NbrOfChannel = 2;        //顺序进行规则转换的ADC通道的数目
        ADC_Init(ADC1, &ADC_InitStructure);          

  NVIC_InitStructure.NVIC_IRQChannel=ADC1_2_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;
  NVIC_Init(&NVIC_InitStructure);
  
  ADC_ITConfig(ADC1,ADC_IT_EOC,ENABLE);
   
  ADC_TempSensorVrefintCmd(ENABLE); //开启内部温度
   
  ADC_Cmd(ADC1, ENABLE);        //使能指定的ADC1

       
        ADC_ResetCalibration(ADC1);        //使能复位校准  
         
        while(ADC_GetResetCalibrationStatus(ADC1));        //等待复位校准结束
       
        ADC_StartCalibration(ADC1);         //开启AD校准

        while(ADC_GetCalibrationStatus(ADC1));         
  ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_239Cycles5 );          ADC_RegularChannelConfig(ADC1,ADC_Channel_16,2,ADC_SampleTime_239Cycles5);
  
  ADC_SoftwareStartConvCmd(ADC1,ENABLE);

}                       
void ADC1_2_IRQHandler(void)
{
  static u8 i=1;
  
  
  while(ADC_GetITStatus(ADC1,ADC_IT_EOC))
  {
    if(i==1)
    {
      adc_array[0]=ADC_GetConversionValue(ADC1);
      i++;
    }
    else
    {
      adc_array[1]=ADC_GetConversionValue(ADC1);
      i=1;
    }
    ADC_ClearITPendingBit(ADC1,ADC_IT_EOC);
  }  
}

我这样采取中断,为什么只有复位的时候才会更新第一个通道的ADC采样值
回复

使用道具 举报

 楼主| 发表于 2018-7-27 07:17:55 | 显示全部楼层
已经搞定,
ADC初始化仍旧开启一个通道,转换时切换通道,需要读取那个通道,就在ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_239Cycles5 )中设置那个通道。
回复

使用道具 举报

 楼主| 发表于 2018-7-27 07:20:16 | 显示全部楼层
初始化:
  ADC_InitStructure.ADC_ContinuousConvMode=DISABLE;   //非连续转换
  ADC_InitStructure.ADC_DataAlign=ADC_ExternalTrigConv_None;
  ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;   //非外部出发,选择软件触发
  ADC_InitStructure.ADC_Mode=ADC_Mode_Independent;    //  独立模式
  ADC_InitStructure.ADC_NbrOfChannel=1;   //规则通道序列长度设为2,包含一个内部温度,一个外部采样
  ADC_InitStructure.ADC_ScanConvMode=DISABLE;   //非扫描模式
  ADC_Init(ADC1,&ADC_InitStructure);
电压采样时
  ADC_RegularChannelConfig(ADC1,ADC_Channel_1,2,ADC_SampleTime_239Cycles5);
  ADC_SoftwareStartConvCmd(ADC1,ENABLE);
  while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)!=RESET);  
  return ADC_GetConversionValue(ADC1);
温度adc获取时
   ADC_RegularChannelConfig(ADC1,ADC_Channel_16,2,ADC_SampleTime_239Cycles5);
  ADC_SoftwareStartConvCmd(ADC1,ENABLE);
  while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)!=RESET);  
  return ADC_GetConversionValue(ADC1);
回复

使用道具 举报

 楼主| 发表于 2018-7-28 12:05:15 | 显示全部楼层
DMA方式
u16 ADC_Value[2]={0,0};

void MYADC_DMAInit(void)
{
  DMA_InitTypeDef DMA_InitStructure;
  
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
  
  //DMA初始化
  DMA_InitStructure.DMA_BufferSize=2;  //CNDTR设为1000;
  DMA_InitStructure.DMA_DIR=DMA_DIR_PeripheralSRC;  //外设到存储器
  DMA_InitStructure.DMA_M2M=DMA_M2M_Disable;
  DMA_InitStructure.DMA_MemoryBaseAddr=(u32)&ADC_Value;   //数据存储地址
  DMA_InitStructure.DMA_MemoryDataSize=DMA_MemoryDataSize_HalfWord; //半字,16位
  DMA_InitStructure.DMA_MemoryInc=DMA_MemoryInc_Enable; //存储地址自增
  DMA_InitStructure.DMA_Mode=DMA_Mode_Circular; //循环传输
  DMA_InitStructure.DMA_PeripheralBaseAddr=(u32)&ADC1->DR;//0x4001244c;  //ADC
  DMA_InitStructure.DMA_PeripheralDataSize=DMA_PeripheralDataSize_HalfWord;
  DMA_InitStructure.DMA_PeripheralInc=DMA_PeripheralInc_Disable;  //外设地址不自增
  DMA_InitStructure.DMA_Priority=DMA_Priority_Medium; //通道优先级/
  DMA_Init(DMA1_Channel1,&DMA_InitStructure);
  
  DMA_Cmd(DMA1_Channel1,ENABLE);
  
}

void MyADC_Init(void)
{
  GPIO_InitTypeDef  GPIO_InitStructure;
  ADC_InitTypeDef ADC_InitStructure;
   
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_ADC1,ENABLE);
  
  GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;
  GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1;
  GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
  GPIO_Init(GPIOA,&GPIO_InitStructure);
  
  RCC_ADCCLKConfig(RCC_PCLK2_Div8); //ADC设为8分频即ADCCLK=72/8=9MHz
  
  ADC_DeInit(ADC1);
  
  ADC_InitStructure.ADC_ContinuousConvMode=ENABLE;   //非连续转换
  ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right;
  ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;   //非外部出发,选择软件触发
  ADC_InitStructure.ADC_Mode=ADC_Mode_Independent;    //  独立模式
  ADC_InitStructure.ADC_NbrOfChannel=2;   //规则通道序列长度设为3,包含一个内部温度,一个外部采样,一个光强度采样
  ADC_InitStructure.ADC_ScanConvMode=ENABLE;   //非扫描模式
  ADC_Init(ADC1,&ADC_InitStructure);

  ADC_TempSensorVrefintCmd(ENABLE); //使能内部温度传感器
  
  ADC_DMACmd(ADC1,ENABLE);
  
  ADC_Cmd(ADC1,ENABLE);     //使能ADC1
  
  ADC_ResetCalibration(ADC1);   //复位校准
  while(ADC_GetResetCalibrationStatus(ADC1));   //等待复位校准完成
  ADC_StartCalibration(ADC1);     //启动校准
  while(ADC_GetCalibrationStatus(ADC1));    //等待启动校准完成
  
// DMA_ITConfig(DMA1_Channel1,DMA_IT_TC|DMA_IT_TE,ENABLE); //开启通道传输完成中中断和传输错误中断
   
//配置通道转换
  ADC_RegularChannelConfig(ADC1,ADC_Channel_1,1,ADC_SampleTime_239Cycles5);
  ADC_RegularChannelConfig(ADC1,ADC_Channel_16,2,ADC_SampleTime_239Cycles5);
//开启转换
  ADC_SoftwareStartConvCmd(ADC1,ENABLE);
  
}
回复

使用道具 举报

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

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-11-27 18:44 , Processed in 0.046185 second(s), 22 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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