stm32f407之三ADC交替采样(操作寄存器)

三ADC交替采样

       在多ADC模式中,ADC1为主,ADC2或ADC3为从,交替或者同时触发,工作模式取决于ADC_CCR寄存器的MULTI[4:0]。

       多ADC模式中,转换后的数据可以多模式的数据寄存器(ADC_CDR)中读取。状态可以在多模式的状态寄存器(ADC_CSR)读取。

        

 

 

 

多ADC模式下的DMA传输方式:

    方式1:每个AD转换完都发出DMA请求,多模式的数据寄存器(ADC_CDR)用低位保存转换结果。

1st request: ADC_CDR[31:0] = ADC1_DR[15:0]

2nd request: ADC_CDR[31:0] = ADC2_DR[15:0]

3rd request: ADC_CDR[31:0] = ADC3_DR[15:0]

4th request: ADC_CDR[31:0] = ADC1_DR[15:0]

 

      方式2:每两个AD转换完都发出DMA请求。

双ADC模式:

高十六位保存ADC2结果,低十六位保存ADC1结果

1st request: ADC_CDR[31:0] = ADC2_DR[15:0] |ADC1_DR[15:0]

2nd request: ADC_CDR[31:0] = ADC2_DR[15:0] |ADC1_DR[15:0]

三ADC模式:

1st request: ADC_CDR[31:0] = ADC2_DR[15:0] |ADC1_DR[15:0]

2nd request: ADC_CDR[31:0] = ADC1_DR[15:0] |ADC3_DR[15:0]

3rd request: ADC_CDR[31:0] = ADC3_DR[15:0] |ADC2_DR[15:0]

4th request: ADC_CDR[31:0] = ADC2_DR[15:0] |ADC1_DR[15:0]

 

        方式2:每两个AD转换完都发出DMA请求。与方式2相似,但是DMA以半字方式传输。

用于6位或者8位分辨率中。

 双ADC模式:

高8位保存ADC2结果,低8位保存ADC1结果

1st request: ADC_CDR[15:0] = ADC2_DR[7:0] | ADC1_DR[7:0]

2nd request: ADC_CDR[15:0] = ADC2_DR[7:0] | ADC1_DR[7:0]

 三ADC模式:

1st request: ADC_CDR[15:0] = ADC2_DR[7:0] | ADC1_DR[7:0]

2nd request: ADC_CDR[15:0] = ADC1_DR[7:0] | ADC3_DR[7:0]

3rd request: ADC_CDR[15:0] = ADC3_DR[7:0] | ADC2_DR[7:0]

4th request: ADC_CDR[15:0] = ADC2_DR[7:0] | ADC1_DR[7:0]

 

 

 

多ADC转换模式:

1.     注入同步模式

2.     规则同步模式

3.     交替模式

4.     交替触发模式

5.     规则同步+注入同步模式

6.     规则同步+交替触发模式

 

 

 

交替模式配置步骤:

1. 配置相关输入通道的IO口。

2. 设置DMA

3. 如果双重ADC或三重采样,设置ADC的公共寄存器

       a.     设置公共寄存器首先要打开任意一个ADC的时钟,否则这部分数字电路是没有开始工作的。

        b.     设置DMA模式

        c.     设置ADC转换完成后,发送DMA请求

        d.     设置多ADC模式

        e.     设置两次采样间隔周期

4. 配置要使用到的ADC(必须ADC1为主,其他为从)。

 

 程序:

/************************************
    标题:ADC
    软件平台:IAR for ARM6.21
    硬件平台:stm32f4-discovery
    主频:168M
    
    author:小船
    data:2012-02-16
*************************************/

#include <stm32f4xx.h> 
#include "MyDebugger.h"

__IO uint16_t ADCConvertedVault[10000];
char TXbuffer[] = "PC1输入电压为:x.xxxV\n\r";

void ADC_IO_Config(void);
void ADC_DMA_Config(void);

void ADC_Common_Config(void);

void ADC3_IN11_Config(void);
void ADC2_IN11_Config(void);
void ADC1_IN11_Config(void);

void main ()
{   
  SCB->AIRCR = 0x05FA0000 | 0x400;  //中断优先级分组 抢占:响应=3:1
 
  ADC_IO_Config();
  ADC_DMA_Config();
  
  ADC_Common_Config();
  
  ADC3_IN11_Config();
  ADC2_IN11_Config(); 
  ADC1_IN11_Config();
  
  ADC3->CR2 |= (1<<0);   //开启ADC3转换
  ADC2->CR2 |= (1<<0);   //开启ADC2转换
  ADC1->CR2 |= (1<<0);   //开启ADC1转换
   
  ADC1->CR2 |= (1<<30); //触发转换开始 
  
  MyDebugger_Init();

  while(1)
  {
  };
}

void ADC_Common_Config(void)
{
  RCC->APB2ENR |= ( (1<<8) | (1<<9) | (1<<10) ); //使能ADC时钟
  ADC->CCR &= 0x00000000;
  
  /*
  DMA模式1
  最后一次ADC转换后发出dma请求
  交错模式
  2次采样之间的延迟5个周期
  */
  ADC->CCR |= ( 0x00004000 | (1<<13) | 0x00000017 | 0x00000000);
    
}

/***ADC1设置***/
void ADC1_IN11_Config(void)
{   
  ADC1->SQR1 = 0x00000000;//转换一个通道
  ADC1->SQR3 = 0x0000000B;//第一个通道为ADC1_in11
  ADC1->CR1 &= 0x00000000; 
  ADC1->CR2 &= 0x00000000;  
  ADC1->CR2 |= (1<<1);  //连续转换
  ADC1->CR2 |= (1<<9); //最后一次ADC转换后发出dma请求

  ADC1->CR2 |= (1<<8);//ADC dma发送模式使能
}

/***ADC2设置***/
void ADC2_IN11_Config(void)
{   
  ADC2->SQR1 = 0x00000000;//转换一个通道
  ADC2->SQR3 = 0x0000000B;//第一个通道为ADC1_in11
  ADC2->CR1 &= 0x00000000; 
  ADC2->CR2 &= 0x00000000;  
  ADC2->CR2 |= (1<<1);  //连续转换
  ADC2->CR2 |= (1<<9); //最后一次ADC转换后发出dma请求
}

/***ADC3设置***/
void ADC3_IN11_Config(void)
{   
  ADC3->SQR1 = 0x00000000;//转换一个通道
  ADC3->SQR3 = 0x0000000B;//第一个通道为ADC3_in11
  ADC3->CR1 &= 0x00000000; 
  ADC3->CR2 &= 0x00000000;  
  ADC3->CR2 |= (1<<1);  //连续转换
  ADC3->CR2 |= (1<<9); //最后一次ADC转换后发出dma请求
}

/***GPIO设置***/
void ADC_IO_Config(void)
{
  RCC->AHB1ENR |= (1<<2); //打开GPIOC时钟
  GPIOC->MODER &= 0xfffffff3;//PC1模拟模式
  GPIOC->MODER |= 0x0000000C;
  GPIOC->PUPDR &= 0xfffffff3;//无上拉无下拉  
}

/***DMA设置***/
void ADC_DMA_Config(void)
{   
  RCC->AHB1ENR |= (1<<22); //使能DMA2时钟
  ADC3->CR2 &= ~(1<<8);//ADC3 dma发送模式除能
  DMA2_Stream0->CR &= 0xFFFFFFFE; //除能DMA2_Stream0
  while(DMA2_Stream0->CR & 0x00000001);//确保DMA可以被设置 
  DMA2->LIFCR |= 0x0000003D;//传送前清空DMA2_Stream0所有中断标志 
  DMA2_Stream0->PAR = (uint32_t)&ADC->CDR;//设置外设地址
  DMA2_Stream0->M0AR = (uint32_t)ADCConvertedVault; //设置内存地址
  DMA2_Stream0->CR |= 0x0002800;//16位数据
  DMA2_Stream0->NDTR = 10000; //设置dma传输数据的数量
  /*
    设置dma2通道0,即ADC1
    优先级Medium
    传输方向外设到内存
    内存递增模式
    循环模式
    传输完成中断
  */
  DMA2_Stream0->CR |= ( 0x00000000 | 0x00010000 | 0x0 | (1<<10) | (1<<8) | (1<<4) ); 
  
  NVIC->IP[56] = 0xB0;
  NVIC->ISER[1] |= (1<<(56-32));
  
  DMA2_Stream0->CR |= 1; //DMA2数据流0使能
}

void DMA2_Stream0_IRQHandler (void)
{
  uint32_t i;
  uint32_t Average;
  if(DMA2->LISR & 0x00000010)
  {
      DMA2->LIFCR |= 0x00000010;
      for(i = 0; i < 10000; i++)  // 对一万个数据取平均值
        Average += ADCConvertedVault[i];
      Average *= 3;
      Average /= 40960;
      TXbuffer[14] = ( Average / 1000 ) % 10 + 0x30;//转换成ASCII码
      TXbuffer[16] = ( Average / 100 ) % 10 + 0x30;
      TXbuffer[17] = ( Average / 10 ) % 10 + 0x30;
      TXbuffer[18] = Average % 10 + 0x30;
      MyDebugger_Message(TXbuffer, sizeof(TXbuffer)/sizeof(char));  
  }
}



 

 运行结果:






  • 4
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
STM32微控制器系列中的ADC(Analog-to-Digital Converter,模拟数字转换器)支持双通道采样,这允许同时对两个输入信号进行数字化处理。要配置STM32 ADC进行双通道采样,通常需要以下几个步骤: 1. **初始化ADC**: - 首先,在HAL库中初始化ADC模块,选择需要使用的模数转换器,如ADC1或ADC2,并设置分辨率、参考电压等。 2. **配置通道**: - 定义要采集的通道,STM32ADC一般有多个通道可以配置。例如,如果你有两个独立的输入A和B,你需要分别为它们分配通道编号,比如CH1和CH2。 3. **启动连续转换模式**: - 如果你想在两个通道之间切换持续采样,通常会开启连续转换模式,以便在前一个通道采样完成后自动开始下一个通道的采样。 4. **配置扫描顺序**: - 可以设置扫描顺序,决定ADC如何在两个或更多通道间切换,是交替还是按某种特定顺序。 5. **读取数据**: - 当所有通道的转换都完成后,通过ADC的数据寄存器读取每个通道的结果。 ```c ADC_HandleTypeDef hadc1; // 初始化ADC1 hadc1.Instance = ADC1; hadc1.Init.Channel = ADC_CHANNEL_0 | ADC_CHANNEL_1; // 设置通道为CH1和CH2 // ...其他初始化配置... // 开始转换 HAL_ADC_Start(&hadc1); while (HAL_ADC_GetState(&hadc1) != HAL_ADC_STATE_REG ConversionEnd) { // 等待转换完成 ADC_ChannelDataTypeDef channelData; HAL_ADC_PollForConversion(&hadc1, 1000); // 检查是否完成并超时等待 HAL_ADC_GetChannelValue(&hadc1, &channelData); if (channelData.Channel == ADC_CHANNEL_1) { // 处理第二个通道的采样结果 } else { // 处理第一个通道的采样结果 } } ```
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值