ADC1多通道_DMA_内部温度传感器+内部VREFINT

实现目标:

  使用ADC1的16和17通道(对应内部温度传感器和内部VREFINT),DMA通道1(Only)管理,存储到内存并串口输出。

Ready

  • 时钟
    • ADC:RCC_APB2Periph_ADC1,RCC_ADCCLKConfig(RCC_PCLK2_Div6);
    • DMA:RCC_AHBPeriph_DMA1
  • NVIC:DMA1_Channel1_IRQn //传输完成中断DMA_IT_TC
  • DMA:
    • 起点/终点地址
    • 数据数量/单位
    • 传输方向
    • 地址是否自动加
    • 单次/连续模式
    • 是否M2M
    • 中断:DMA_IT_TC
  • ADC:
    • ADC间合作方式:ADC_Mode = ADC_Mode_Independent
    • 单次/连续
    • 是否开启扫描模式
    • 触发方式:ADC_ExternalTrigConv_None;//软件触发
    • 数据对齐
    • 通道数

    • 逐个配置通道:

      ADC_RegularChannelConfig(ADC1, 16, 1, ADC_SampleTime_239Cycles5 );
      ADC_RegularChannelConfig(ADC1, 17, 2, ADC_SampleTime_239Cycles5 );


    • 打开DMA信号:ADC_DMACmd(ADC1,ENABLE);
  • Sensor:ADC_TempSensorVrefintCmd(ENABLE);//打开内部温度和电压传感器的DMA连接

Go

#include "delay.h"#include "sys.h"
#include "usart.h"
#include "timer.h"
u16 data[2];
void NVIC_ADC1_DMA1_Init()
{
    DMA_InitTypeDef DMA_InitStructure; 
    ADC_InitTypeDef ADC_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_InitStructure.NVIC_IRQChannel=DMA1_Channel1_IRQn ;
    NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
    NVIC_Init(&NVIC_InitStructure);
    
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);   
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);//DMA时钟
    RCC_ADCCLKConfig(RCC_PCLK2_Div6);
    ADC_DeInit(ADC1);
    ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//规则组和注入组独立
    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_InitStructure.ADC_NbrOfChannel = 2;
  ADC_Init(ADC1, &ADC_InitStructure);
    
    ADC_TempSensorVrefintCmd(ENABLE);//打开内部温度和电压传感器的DMA连接
    ADC_RegularChannelConfig(ADC1, 16, 1, ADC_SampleTime_239Cycles5 );
    ADC_RegularChannelConfig(ADC1, 17, 2, ADC_SampleTime_239Cycles5 );
    
    ADC_DMACmd(ADC1,ENABLE);
    ADC_Cmd(ADC1, ENABLE);


    ADC_ResetCalibration(ADC1);    //重置指定的ADC1的复位寄存器

  while(ADC_GetResetCalibrationStatus(ADC1));    //获取ADC1重置校准寄存器的状态,设置状态则等待

    ADC_StartCalibration(ADC1);     //

    while(ADC_GetCalibrationStatus(ADC1));        //获取指定ADC1的校准程序,设置状态则等待

    DMA_DeInit(DMA1_Channel1);
    DMA_InitStructure.DMA_PeripheralBaseAddr =  (uint32_t) & (ADC1->DR); //外设寄存器基地址
    DMA_InitStructure.DMA_MemoryBaseAddr =(u32)data; //RAM基地址
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //传输方向
    DMA_InitStructure.DMA_BufferSize = 2;//Size
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设的地址是否自动增加
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //RAM的地址是否自动增加
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
    DMA_InitStructure.DMA_MemoryDataSize =DMA_MemoryDataSize_HalfWord; //传输单位
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;//DMA_Mode_Normal; //是否不断传输
    DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //优先组
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //是不是RAM2RAM
    DMA_Init(DMA1_Channel1, &DMA_InitStructure); 
    
    DMA_ITConfig(DMA1_Channel1,DMA_IT_TC,ENABLE ); //DMA中断(别忘了NVIC)

    DMA_Cmd(DMA1_Channel1,ENABLE);//开启DMA


}
int main(void)
{    
        
    NVIC_ADC1_DMA1_Init();
    uart_init(9600);
    delay_init();
    printf("START
");
    ADC_SoftwareStartConvCmd(ADC1, ENABLE);
    while(1);
}
void DMA1_Channel1_IRQHandler()
{
    if(DMA_GetITStatus(DMA_IT_TC)==SET)
    {
        double tp=(1.43-data[0]*(3.3/4096))/0.0043+25;    
        printf("TEMORI:%x	TEM:%f	VOT:%x
",data[0],tp,data[1]);
        DMA_ClearITPendingBit(DMA_IT_TC);
    }
}

  • DMA数据单位:

  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;

  DMA_InitStructure.DMA_MemoryDataSize =DMA_MemoryDataSize_HalfWord; 

原文地址:https://www.cnblogs.com/2cats/p/3592953.html