请问keil5写代码是直接用C语言就可以吗?

如题,还想问一下对应的stm32f4单片机的像是设置输入的IO口,初始化ADC,设置输出串口之类的函数应该去哪里看啊?新上手完全找不到

  • 你可以参考下这个问题的回答, 看看是否对你有帮助, 链接: https://ask.csdn.net/questions/7450259
  • 我还给你找了一篇非常好的博客,你可以看看是否有帮助,链接:有关用STM32芯片自带的ADC测量电池电压,然后根据放电曲线得到电池容量的问题
  • 除此之外, 这篇博客: STM32F4 ADC (单通道采集、多通道采集、双重交错模式、规则同步模式、三重模式)中的 话不多说,直接上程序,详情请看注释 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • //-------------.c 文件----------------------------------------------------------------------------------------------------------------------------------////

     

    #include "adc.h"
    #include "usart.h"
    
    __IO uint32_t ADC_TripleModeConveredValue[3];
    
    __IO uint16_t ADC_MultiModeConveredValue[8];
    
    __IO uint16_t RegSimultModeConveredValue[4];
    
    __IO uint32_t ADC_DualModeConveredValue;
    
    __IO uint16_t ADC_VBATMeasureValue;
    
    double Single_ADCx_Value = 0;
    
    //DMA2(CH0 CH4)-------------->ADC1
    //DMA2(CH2 CH3)-------------->ADC2
    //DMA2(CH0 CH1)-------------->ADC3
    

    单通道采集

    #if defined  (ADC_Single_Channel) //单通道采集
    
    void ADC_Single_Config(void)
    {
    	ADC_InitTypeDef        ADC_InitStructure;
    	ADC_CommonInitTypeDef  ADC_CommonInitStructure;
    	GPIO_InitTypeDef       GPIO_InitStructure;
    	
    	RCC_AHB1PeriphClockCmd(RCC_Single_GPIO,ENABLE);
    	RCC_APB2PeriphClockCmd(RCC_Single_ADCx,ENABLE);
    	
    	GPIO_InitStructure.GPIO_Pin  = ADC_Single_PIN;
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;   //模拟输入
    	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    	GPIO_Init(ADC_Single_PORT,&GPIO_InitStructure);
    	
    	ADC_CommonInitStructure.ADC_Mode      = ADC_Mode_Independent; //独立模式
    	ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;   //ADC最大时钟是36MHz 故要在这里分频 84/4 = 21
    	ADC_CommonInitStructure.ADC_DMAAccessMode    = ADC_DMAAccessMode_Disabled;   //只有在双重模式或者三重模式时才会设置
    	ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles; //两个采样阶段之间的延迟,仅适用于双重模式或者三重模式
    	ADC_CommonInit(&ADC_CommonInitStructure);
    	
    	ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;             //使能连续转换
    	ADC_InitStructure.ADC_DataAlign          = ADC_DataAlign_Right;//数据右对齐
    	ADC_InitStructure.ADC_NbrOfConversion    = 1;                  //转换通道
    	ADC_InitStructure.ADC_Resolution   = ADC_Resolution_12b;       //分辨率: 12位
    	ADC_InitStructure.ADC_ScanConvMode = DISABLE;  //失能扫描模式,多通道采集才会用得到
    	ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
    //	ADC_InitStructure.ADC_ExternalTrigConv   = //采用软件触发,故这里不需要
    	ADC_Init(Single_ADCx,&ADC_InitStructure);
    	
    	//配置ADCx 通道转换顺序和转换周期
    	ADC_RegularChannelConfig(Single_ADCx,ADC_Single_Channel_x,1,ADC_SampleTime_56Cycles);
    	
    	//使能ADCx转换结束中断,在每次转换结束之后读取数据
    	ADC_ITConfig(Single_ADCx,ADC_IT_EOC,ENABLE);
    	
    	//使能ADCx
    	ADC_Cmd(Single_ADCx,ENABLE);
    	
    	//开启软件转换
    	ADC_SoftwareStartConv(Single_ADCx);
    
    }
    void ADC_Single_NVIC_Config(void)
    {
    	NVIC_InitTypeDef       NVIC_InitStructure;
    
    	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
    	
    	NVIC_InitStructure.NVIC_IRQChannel    = ADC_IRQn;
    	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    	NVIC_Init(&NVIC_InitStructure);
    }
    
    
    void ADC_IRQHandler(void)
    {
    	uint16_t val;
    	if(ADC_GetFlagStatus(Single_ADCx,ADC_FLAG_EOC) == SET)
    	{
    		ADC_ClearITPendingBit(Single_ADCx,ADC_FLAG_EOC);
    		
    		val = ADC_GetConversionValue(Single_ADCx);
    		Single_ADCx_Value = (double)val*3.3/4096;
    		
    		printf("\r\nADCx single value : %lf\n\r",Single_ADCx_Value);
    	
    	}
    }
    

     

    多通道采集

    #elif defined (ADC_Multi_Channel) 
    //多通道采集,采集8个通道的数据
    
    void Multi_ADC_GPIO_Config(void)
    {
    	GPIO_InitTypeDef       GPIO_InitStructure;
    
    	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
    	
    	GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 |
    	                               GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7 ;
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;     //或者GPIO_Mode_AIN
    	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    	GPIO_Init(GPIOA,&GPIO_InitStructure);
    
    }
    
    void ADC_Multi_Config(void)
    {
    	ADC_InitTypeDef        ADC_InitStructure;
    	ADC_CommonInitTypeDef  ADC_CommonInitStructure;
    	DMA_InitTypeDef        DMA_InitStructure;
    	
    	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA_x,ENABLE);
    	
    	DMA_InitStructure.DMA_Mode    = DMA_Mode_Circular;           //循环采集
    	DMA_InitStructure.DMA_Channel = DMA_Channel_x;               //通道  三重模式只需使能 ADC1 的 DMA 通道。
    	DMA_InitStructure.DMA_DIR     = DMA_DIR_PeripheralToMemory;  //外设到内存
    	DMA_InitStructure.DMA_Priority   = DMA_Priority_High;        //数据流优先级
    	DMA_InitStructure.DMA_BufferSize = 8;                        //设定待传输数据通道
    	DMA_InitStructure.DMA_FIFOMode      = DMA_FIFOMode_Disable;  //失能FIFO模式
    	DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;//FIFO阈值,全部使用,由于上面失能该模式,故该设置无效
    	
    	DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADC_MultiModeConveredValue;
    	DMA_InitStructure.DMA_MemoryBurst     = DMA_MemoryBurst_Single;      //ADC是直接传输,要选单次模式
    	DMA_InitStructure.DMA_MemoryDataSize  = DMA_MemoryDataSize_HalfWord; //储存器数据宽度 
    	DMA_InitStructure.DMA_MemoryInc       = DMA_MemoryInc_Enable;        //地址自增 与 DMA_BufferSize 联系,1 --> 不自增
    
    	DMA_InitStructure.DMA_PeripheralBaseAddr = MultiMode_ADC_ADDR;             //ADC1地址基地址 + ADC1数据寄存器偏移地址  
    	DMA_InitStructure.DMA_PeripheralBurst    = DMA_PeripheralBurst_Single;     //ADC是直接传输,要选单次模式
    	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//外设数据宽度 
    	DMA_InitStructure.DMA_PeripheralInc      = DMA_PeripheralInc_Disable;      //无需设置为储存地址自增模式
    	DMA_Init(DMAx_Stream_x,&DMA_InitStructure);
    	
    	DMA_Cmd(DMAx_Stream_x,ENABLE);
    	
    	RCC_APB2PeriphClockCmd(MultiMode_ADCx_CLK,ENABLE);
    	
    	ADC_StructInit(&ADC_InitStructure);
    	
    	ADC_CommonInitStructure.ADC_Mode      = ADC_Mode_Independent;      //独立模式
    	ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;        //4分频
    	ADC_CommonInitStructure.ADC_DMAAccessMode    = ADC_DMAAccessMode_Disabled;//
    	ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_20Cycles;
    	ADC_CommonInit(&ADC_CommonInitStructure);
    	
    	ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;             //使能连续转换
    	ADC_InitStructure.ADC_DataAlign          = ADC_DataAlign_Right;//数据右对齐
    	ADC_InitStructure.ADC_NbrOfConversion    = 8;                  //转换通道
    	ADC_InitStructure.ADC_Resolution   = ADC_Resolution_12b;       //分辨率: 12位
    	ADC_InitStructure.ADC_ScanConvMode = ENABLE;  //使能扫描模式,多通道采集才会用得到
    	ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
    //	ADC_InitStructure.ADC_ExternalTrigConv   = //采用软件触发,故这里不需要
    	ADC_Init(MultiMode_ADCx,&ADC_InitStructure);
    	
    	ADC_RegularChannelConfig(MultiMode_ADCx,ADC_Channel_0,1, ADC_SampleTime_3Cycles);
    
    	ADC_RegularChannelConfig(MultiMode_ADCx,ADC_Channel_1,2, ADC_SampleTime_3Cycles);
    	
    	ADC_RegularChannelConfig(MultiMode_ADCx,ADC_Channel_2,3, ADC_SampleTime_3Cycles);
    
    	ADC_RegularChannelConfig(MultiMode_ADCx,ADC_Channel_3,4, ADC_SampleTime_3Cycles);
    	
    	ADC_RegularChannelConfig(MultiMode_ADCx,ADC_Channel_4,5, ADC_SampleTime_3Cycles);
    
    	ADC_RegularChannelConfig(MultiMode_ADCx,ADC_Channel_5,6, ADC_SampleTime_3Cycles);
    	
    	ADC_RegularChannelConfig(MultiMode_ADCx,ADC_Channel_6,7, ADC_SampleTime_3Cycles);
    
    	ADC_RegularChannelConfig(MultiMode_ADCx,ADC_Channel_7,8, ADC_SampleTime_3Cycles);
    
    	ADC_DMARequestAfterLastTransferCmd(MultiMode_ADCx, ENABLE);// 使能 DMA 请求
    	
    	ADC_DMACmd(MultiMode_ADCx, ENABLE);
    	
    	ADC_Cmd(MultiMode_ADCx, ENABLE);
    	
    	ADC_SoftwareStartConv(MultiMode_ADCx);
    
    }
    
    

     

    双重交错模式

    #elif defined (ADC_DualModeInterleaved) 
    //两个ADC同时采集一个通道
    // ADC_Mode  ADC_DMAAccessMode  DMA_BufferSize  DMA_MemoryDataSize  DMA_MemoryInc  DMA_PeripheralDataSize相互联系
    
    void ADC_DualModeInterleaved_Config(void)
    {
    	ADC_InitTypeDef        ADC_InitStructure;
    	ADC_CommonInitTypeDef  ADC_CommonInitStructure;
    	GPIO_InitTypeDef       GPIO_InitStructure;
    	DMA_InitTypeDef        DMA_InitStructure;
    	
    	RCC_AHB1PeriphClockCmd(DualModeInterleaved_GPIO_CLK,ENABLE);
    	
    	GPIO_InitStructure.GPIO_Pin  = DualModeInterleaved_GPIO_Pinx;
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;    //或者GPIO_Mode_AIN
    	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    	GPIO_Init(DualModeInterleaved_GPIO,&GPIO_InitStructure);
    		
    	// ADC1 使用 DMA2,数据流 0,通道 0,这个是手册固定死的
    	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2,ENABLE);
    	
    	DMA_InitStructure.DMA_Mode    = DMA_Mode_Circular;           //循环采集
    	DMA_InitStructure.DMA_Channel = DMA_Channel_0;               //通道  三重模式只需使能 ADC1 的 DMA 通道。
    	DMA_InitStructure.DMA_DIR     = DMA_DIR_PeripheralToMemory;  //外设到内存
    	DMA_InitStructure.DMA_Priority   = DMA_Priority_High;        //数据流优先级
    	DMA_InitStructure.DMA_BufferSize = 1;                        //设定待传输数据通道 高16位 ADC2  低16位 ADC1
    	DMA_InitStructure.DMA_FIFOMode      = DMA_FIFOMode_Disable;  //失能FIFO模式
    	DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;//FIFO阈值,全部使用,由于上面失能该模式,故该设置无效
    	
    	DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADC_DualModeConveredValue;
    	DMA_InitStructure.DMA_MemoryBurst     = DMA_MemoryBurst_Single;      //ADC是直接传输,要选单次模式
    	DMA_InitStructure.DMA_MemoryDataSize  = DMA_MemoryDataSize_Word;     //储存器数据宽度 
    	DMA_InitStructure.DMA_MemoryInc       = DMA_MemoryInc_Disable;        //地址自增 与 DMA_BufferSize 联系,1 --> 不自增
    
    	DMA_InitStructure.DMA_PeripheralBaseAddr = DualModeInterleaved_ADC_ADDR;   //ADC1地址基地址 + ADC1数据寄存器偏移地址  
    	DMA_InitStructure.DMA_PeripheralBurst    = DMA_PeripheralBurst_Single;     //ADC是直接传输,要选单次模式
    	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;    //外设数据宽度 
    	DMA_InitStructure.DMA_PeripheralInc      = DMA_PeripheralInc_Disable;      //无需设置为储存地址自增模式
    	DMA_Init(DMA2_Stream0,&DMA_InitStructure);
    	
    	DMA_Cmd(DMA2_Stream0,ENABLE);
    	
    	RCC_APB2PeriphClockCmd(DualModeInterleaved_ADC1_CLK,ENABLE);
    	RCC_APB2PeriphClockCmd(DualModeInterleaved_ADC2_CLK,ENABLE);
    	
    	ADC_StructInit(&ADC_InitStructure);
    	
    	ADC_CommonInitStructure.ADC_Mode      = ADC_DualMode_Interl;       //双重ADC交替模式
    	ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;        //4分频
    	ADC_CommonInitStructure.ADC_DMAAccessMode    = ADC_DMAAccessMode_2;//DMA模式 2 高16位 ADC2  低16位 ADC1; 三个模式详细区别参考手册有详解
    	ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_20Cycles;
    	ADC_CommonInit(&ADC_CommonInitStructure);
    	
    	ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;             //使能连续转换
    	ADC_InitStructure.ADC_DataAlign          = ADC_DataAlign_Right;//数据右对齐
    	ADC_InitStructure.ADC_NbrOfConversion    = 1;                  //转换通道
    	ADC_InitStructure.ADC_Resolution   = ADC_Resolution_12b;       //分辨率: 12位
    	ADC_InitStructure.ADC_ScanConvMode = DISABLE;  //失能扫描模式,多通道采集才会用得到
    	ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
    //	ADC_InitStructure.ADC_ExternalTrigConv   =  //采用软件触发,故这里不需要
    
    	ADC_Init(DualModeInterleaved_ADC1,&ADC_InitStructure);
    	ADC_RegularChannelConfig(DualModeInterleaved_ADC1,DualModeInterleaved_ADC_CHx,1, ADC_SampleTime_3Cycles);
    
    	ADC_Init(DualModeInterleaved_ADC2,&ADC_InitStructure);
    	ADC_RegularChannelConfig(DualModeInterleaved_ADC2,DualModeInterleaved_ADC_CHx,1, ADC_SampleTime_3Cycles);
    
    	ADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE);//使能DMA请求,在 ADC 转换完后自动请求 DMA 进行数据传输
    	
    	ADC_DMACmd(DualModeInterleaved_ADC1, ENABLE);
    	
    	ADC_Cmd(DualModeInterleaved_ADC1, ENABLE);
    	ADC_Cmd(DualModeInterleaved_ADC2, ENABLE);
    	
    	ADC_SoftwareStartConv(DualModeInterleaved_ADC1);
    	ADC_SoftwareStartConv(DualModeInterleaved_ADC2);
    	
    }

     

    规则同步模式

    #elif defined (ADC_DualModeRegualSimult) //双ADC规则同步模式
    //两个ADC各同时采集多个通道,ADC1触发
    
    static void GPIO_Config(void)
    {
      GPIO_InitTypeDef GPIO_InitStructure;
      /* ADC123 Channel 10 -> PC0
         ADC123 Channel 11 -> PC1
         ADC123 Channel 12 -> PC2
    	   ADC123 Channel 13 -> PC2
      */
      GPIO_InitStructure.GPIO_Pin = GPIO_Pinx_0 |
                                   	GPIO_Pinx_1 | 
    	                              GPIO_Pinx_2 |
    	                              GPIO_Pinx_3 ;
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
      GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
      GPIO_Init(GPIOC, &GPIO_InitStructure);
    }
    
    static void ADC1_CH_Config(void)
    {
      ADC_InitTypeDef ADC_InitStructure;
    
      ADC_InitStructure.ADC_Resolution   = ADC_Resolution_12b;
      ADC_InitStructure.ADC_ScanConvMode = ENABLE;
      ADC_InitStructure.ADC_ContinuousConvMode   = ENABLE;
      ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
      ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
      ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
      ADC_InitStructure.ADC_NbrOfConversion = 2;
      ADC_Init(ADC1, &ADC_InitStructure);
    
      /* ADC1 regular channels 10, 11 configuration */ 
      ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_3Cycles);
      ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 2, ADC_SampleTime_3Cycles);
    }
    
    static void ADC2_CH_Config(void)
    {
      ADC_InitTypeDef ADC_InitStructure;
    
      ADC_InitStructure.ADC_Resolution   = ADC_Resolution_12b;
      ADC_InitStructure.ADC_ScanConvMode = ENABLE;
      ADC_InitStructure.ADC_ContinuousConvMode   = ENABLE;
      ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
      ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
      ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
      ADC_InitStructure.ADC_NbrOfConversion = 2;
      ADC_Init(ADC2, &ADC_InitStructure);
    
      /* ADC2 regular channels 12, 13 configuration */ 
      ADC_RegularChannelConfig(ADC2, ADC_Channel_12, 1, ADC_SampleTime_3Cycles);
      ADC_RegularChannelConfig(ADC2, ADC_Channel_13, 2, ADC_SampleTime_3Cycles);
    }
    
    static void DMA_Config(void)
    {
      DMA_InitTypeDef DMA_InitStructure;
    
      DMA_InitStructure.DMA_Channel    = DMA_Channel_x; 
      DMA_InitStructure.DMA_DIR        = DMA_DIR_PeripheralToMemory;
      DMA_InitStructure.DMA_Mode       = DMA_Mode_Circular;
      DMA_InitStructure.DMA_BufferSize = 4;               //每个数据流的第十六位放采集的数据
      DMA_InitStructure.DMA_Priority   = DMA_Priority_High;
      DMA_InitStructure.DMA_FIFOMode      = DMA_FIFOMode_Enable; //这里需使能        
      DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
    	
      DMA_InitStructure.DMA_Memory0BaseAddr    = (uint32_t)&RegSimultModeConveredValue;
      DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)DualModeRegualSimult_ADC_ADDR;
    
      DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
      DMA_InitStructure.DMA_MemoryInc     = DMA_MemoryInc_Enable;
    	
      DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
      DMA_InitStructure.DMA_MemoryDataSize     = DMA_MemoryDataSize_HalfWord;
    	
      DMA_InitStructure.DMA_MemoryBurst     = DMA_MemoryBurst_Single;
      DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
      DMA_Init(DMAx_Stream_x, &DMA_InitStructure);
    
      /* DMA2_Stream0 enable */
      DMA_Cmd(DMAx_Stream_x, ENABLE);
    }
    
    
    void ADC_DualModeRegualSimult_Config(void)
    {
      ADC_CommonInitTypeDef ADC_CommonInitStructure;
    
      /* Enable peripheral clocks *************************************************/
      RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA_x, ENABLE);
      RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOx, ENABLE);
      RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
      RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2, ENABLE);
        
      DMA_Config();
      
      GPIO_Config();
     
      /* ADC Common Init */
      ADC_CommonInitStructure.ADC_Mode = ADC_DualMode_RegSimult;
      ADC_CommonInitStructure.ADC_Prescaler     = ADC_Prescaler_Div4;
      ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_1;
      ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
      ADC_CommonInit(&ADC_CommonInitStructure);
     
      /* ADC1 regular channels 10, 11 configuration */
      ADC1_CH_Config();
     
      /* ADC2 regular channels 11, 12 configuration */
      ADC2_CH_Config();
     
      /* Enable DMA request after last transfer (Multi-ADC mode) */
      ADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE);
     
      /* Enable ADC1 */
      ADC_Cmd(ADC1, ENABLE);
     
      /* Enable ADC2 */
      ADC_Cmd(ADC2, ENABLE);
     
      /* Start ADC1 Software Conversion */
      ADC_SoftwareStartConv(ADC1);
    
    }
    

     

    三重模式

    #elif defined (ADC_TripleModeInterleaved) //三通道交错采集
    //对一个ADC通道使用三个ADC轮流交错采样,并通过DMA存储到内存,具体配置过程需参考中文参考手册11.9
    //ADC1为主器件 ADC2、ADC3为从器件
    
    void ADC_TripleModeInterleaved_Config(void)
    {
    	ADC_InitTypeDef        ADC_InitStructure;
    	ADC_CommonInitTypeDef  ADC_CommonInitStructure;
    	GPIO_InitTypeDef       GPIO_InitStructure;
    	DMA_InitTypeDef        DMA_InitStructure;
    	
    	RCC_AHB1PeriphClockCmd(TripleModeInterleaved_GPIO_CLK,ENABLE);
    	
    	GPIO_InitStructure.GPIO_Pin  = TripleModeInterleaved_GPIO_Pinx;
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
    	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    	GPIO_Init(TripleModeInterleaved_GPIO,&GPIO_InitStructure);
    	
    	
    	// ADC1 使用 DMA2,数据流 0,通道 0,这个是手册固定死的
    	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2,ENABLE);
    	
    	DMA_InitStructure.DMA_Mode    = DMA_Mode_Circular;           //循环采集
    	DMA_InitStructure.DMA_Channel = DMA_Channel_0;               //通道  三重模式只需使能 ADC1 的 DMA 通道。
    	DMA_InitStructure.DMA_DIR     = DMA_DIR_PeripheralToMemory;  //外设到内存
    	DMA_InitStructure.DMA_Priority   = DMA_Priority_High;        //数据流优先级
    	DMA_InitStructure.DMA_BufferSize = 3;                        //设定待传输数据通道
    	DMA_InitStructure.DMA_FIFOMode      = DMA_FIFOMode_Disable;  //失能FIFO模式
    	DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;//FIFO阈值,全部使用,由于上面失能该模式,故该设置无效
    	
    	DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADC_TripleModeConveredValue;
    	DMA_InitStructure.DMA_MemoryBurst     = DMA_MemoryBurst_Single;      //ADC是直接传输,要选单次模式
    	DMA_InitStructure.DMA_MemoryDataSize  = DMA_PeripheralDataSize_Word; //储存器数据宽度 整字 这与DMA模式2对应
    	DMA_InitStructure.DMA_MemoryInc       = DMA_MemoryInc_Enable;        //地址自增
    
    	DMA_InitStructure.DMA_PeripheralBaseAddr = TripleModeInterleaved_ADC_ADDR;    //ADC1地址基地址 + ADC1数据寄存器偏移地址  
    	DMA_InitStructure.DMA_PeripheralBurst    = DMA_PeripheralBurst_Single;     //ADC是直接传输,要选单次模式
    	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;    //外设数据宽度 
    	DMA_InitStructure.DMA_PeripheralInc      = DMA_PeripheralInc_Disable;      //无需设置为储存地址自增模式
    	DMA_Init(DMA2_Stream0,&DMA_InitStructure);
    	
    	DMA_Cmd(DMA2_Stream0,ENABLE);//使能(找这个地方的错误找了半小时...)
    	
    	RCC_APB2PeriphClockCmd(TripleModeInterleaved_ADC1_CLK,ENABLE);
    	RCC_APB2PeriphClockCmd(TripleModeInterleaved_ADC2_CLK,ENABLE);
    	RCC_APB2PeriphClockCmd(TripleModeInterleaved_ADC3_CLK,ENABLE);
    	
    	ADC_StructInit(&ADC_InitStructure);
    	
    	ADC_CommonInitStructure.ADC_Mode      = ADC_TripleMode_Interl;     //三重ADC交替模式
    	ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;        //4分频
    	ADC_CommonInitStructure.ADC_DMAAccessMode    = ADC_DMAAccessMode_2;//DMA模式2
    	ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_20Cycles;
    	ADC_CommonInit(&ADC_CommonInitStructure);
    	
    	ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;             //使能连续转换
    	ADC_InitStructure.ADC_DataAlign          = ADC_DataAlign_Right;//数据右对齐
    	ADC_InitStructure.ADC_NbrOfConversion    = 1;                  //转换通道
    	ADC_InitStructure.ADC_Resolution   = ADC_Resolution_12b;       //分辨率: 12位
    	ADC_InitStructure.ADC_ScanConvMode = DISABLE;  //失能扫描模式,多通道采集才会用得到
    	ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
    //	ADC_InitStructure.ADC_ExternalTrigConv   = //采用软件触发,故这里不需要
    
    	ADC_Init(TripleModeInterleaved_ADC1,&ADC_InitStructure);
    	ADC_RegularChannelConfig(TripleModeInterleaved_ADC1,TripleModeInterleaved_ADC_CHx,1, ADC_SampleTime_3Cycles);
    
    	ADC_Init(TripleModeInterleaved_ADC2,&ADC_InitStructure);
    	ADC_RegularChannelConfig(TripleModeInterleaved_ADC2,TripleModeInterleaved_ADC_CHx,1, ADC_SampleTime_3Cycles);
    
    	ADC_Init(TripleModeInterleaved_ADC3,&ADC_InitStructure);
    	ADC_RegularChannelConfig(TripleModeInterleaved_ADC3,TripleModeInterleaved_ADC_CHx,1, ADC_SampleTime_3Cycles);
    
    	ADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE);//使能DMA请求,在 ADC 转换完后自动请求 DMA 进行数据传输
    	
    	ADC_DMACmd(TripleModeInterleaved_ADC1, ENABLE);
    	
    	ADC_Cmd(TripleModeInterleaved_ADC1, ENABLE);
    	ADC_Cmd(TripleModeInterleaved_ADC2, ENABLE);
    	ADC_Cmd(TripleModeInterleaved_ADC3, ENABLE);
    	
    	ADC_SoftwareStartConv(TripleModeInterleaved_ADC1);
    	ADC_SoftwareStartConv(TripleModeInterleaved_ADC2);
    	ADC_SoftwareStartConv(TripleModeInterleaved_ADC3);
    	
    }

     

    电源电压测量

    #elif defined (ADC_VBATMeasurement) 
    
    void ADC_VBATMeasure_Config(void)
    {
      ADC_InitTypeDef       ADC_InitStructure;
      ADC_CommonInitTypeDef ADC_CommonInitStructure;
      DMA_InitTypeDef       DMA_InitStructure;
        
      /* Enable peripheral clocks *************************************************/
      RCC_AHB1PeriphClockCmd(DMAx_CLK, ENABLE);
      RCC_APB2PeriphClockCmd(ADCx_CLK, ENABLE);
    
      /* DMA2_Stream0 channel0 configuration **************************************/
      DMA_DeInit(DMA2_Stream0);
      DMA_InitStructure.DMA_Channel = DMA_Channel_x;  
      DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC_VBATMeasurement_ADDR;
      DMA_InitStructure.DMA_Memory0BaseAddr    = (uint32_t)&ADC_VBATMeasureValue;
      DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
      DMA_InitStructure.DMA_BufferSize = 1;
      DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
      DMA_InitStructure.DMA_MemoryInc     = DMA_MemoryInc_Disable;
      DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
      DMA_InitStructure.DMA_MemoryDataSize     = DMA_MemoryDataSize_HalfWord;
      DMA_InitStructure.DMA_Mode     = DMA_Mode_Circular;
      DMA_InitStructure.DMA_Priority = DMA_Priority_High;
      DMA_InitStructure.DMA_FIFOMode      = DMA_FIFOMode_Disable;         
      DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
      DMA_InitStructure.DMA_MemoryBurst     = DMA_MemoryBurst_Single;
      DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
      DMA_Init(DMAx_Stream_x, &DMA_InitStructure);
      /* DMA2_Stream0 enable */
      DMA_Cmd(DMAx_Stream_x, ENABLE);
        
      /* ADC Common Init **********************************************************/
      ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
      ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;
      ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
      ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
      ADC_CommonInit(&ADC_CommonInitStructure);
    
      /* ADC1 Init ****************************************************************/
      ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
      ADC_InitStructure.ADC_ScanConvMode = DISABLE;
      ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
      ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
      ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
      ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
      ADC_InitStructure.ADC_NbrOfConversion = 1;
      ADC_Init(ADCx, &ADC_InitStructure);
    
      /* Enable ADC1 DMA */
      ADC_DMACmd(ADCx, ENABLE);
      
      /* ADC1 regular channel18 (VBAT) configuration ******************************/
      ADC_RegularChannelConfig(ADCx, ADC_Channel_Vbat, 1, ADC_SampleTime_15Cycles);//此处的通道为ADC_Channel_Vbat
    
      /* Enable VBAT channel */
      ADC_VBATCmd(ENABLE); 
    
      /* Enable DMA request after last transfer (Single-ADC mode) */
      ADC_DMARequestAfterLastTransferCmd(ADCx, ENABLE);
    
      /* Enable ADC1 **************************************************************/
      ADC_Cmd(ADCx, ENABLE);
    	
    	ADC_SoftwareStartConv(ADCx);
    
    }
    
    
    #endif

     

    //---------.h文件--------------------------------------------------------------------------------------------------------------------------------------------////

    #ifndef __ADC_H
    #define __ADC_H
    
    	#include "stm32f4xx.h"
    	
    
    	//=================模式选择===================//
    	//#define ADC_Single_Channel        //单通道独立模式
    
    	//#define ADC_Multi_Channel         //多通道独立模式
    
    	//#define ADC_DualModeInterleaved   //双重交错模式
    
    	//#define ADC_DualModeRegualSimult  //双ADC规则同步模式
    
    	//#define ADC_TripleModeInterleaved //三重交错模式
    
    	#define ADC_VBATMeasurement       //电源电压测量
    
    
    
    	//--------------------------SingleMode-----------------------------//
    
    	#if defined  (ADC_Single_Channel) //单通道采集
    
    		#define RCC_Single_ADCx          RCC_APB2Periph_ADC3
    		#define RCC_Single_GPIO          RCC_AHB1Periph_GPIOC
    		#define ADC_Single_PORT          GPIOC
    		#define ADC_Single_PIN           GPIO_Pin_3 //PC3 --> ADC123_IN13
    		#define ADC_Single_Channel_x     ADC_Channel_13
    		#define Single_ADCx              ADC3
    		
    		void ADC_Single_Config(void);
    		
    		void ADC_Single_NVIC_Config(void);
    		
    
    	//--------------------------MultiMode-----------------------------//
    
    	#elif defined  (ADC_Multi_Channel)
    
    		#define MultiMode_ADCx               ADC1
    		#define MultiMode_ADC_ADDR           ((u32)MultiMode_ADCx+0x4c)
    		#define MultiMode_ADCx_CLK           RCC_APB2Periph_ADC1
    																				 
    		#define RCC_AHB1Periph_DMA_x         RCC_AHB1Periph_DMA2
    		#define DMA_Channel_x                DMA_Channel_0
    		#define DMAx_Stream_x                DMA2_Stream0
    
    	void Multi_ADC_GPIO_Config(void);
    
    	void ADC_Multi_Config(void);
    
    
    	//----------------------DualModeInterleaved-------------------------//
    
    	#elif defined (ADC_DualModeInterleaved) 
    
    		#define DualModeInterleaved_ADC_ADDR   ((uint32_t)0x40012308)
    		#define DualModeInterleaved_ADC1       ADC1
    		#define DualModeInterleaved_ADC2       ADC2
    		
    		#define DualModeInterleaved_ADC1_CLK   RCC_APB2Periph_ADC1
    		#define DualModeInterleaved_ADC2_CLK   RCC_APB2Periph_ADC2
    		
    		#define DualModeInterleaved_ADC_CHx    ADC_Channel_2
    		#define DualModeInterleaved_GPIO_CLK   RCC_AHB1Periph_GPIOA
    		#define DualModeInterleaved_GPIO       GPIOA
    		#define DualModeInterleaved_GPIO_Pinx  GPIO_Pin_2
    
    		void ADC_DualModeInterleaved_Config(void);
    		
    		
    	//---------------------DualModeRegualSimult-------------------------//
    
    	#elif defined (ADC_DualModeRegualSimult)
    
    		#define DualModeRegualSimult_ADC_ADDR    ((uint32_t)0x40012308)
    																					
    		#define RCC_AHB1Periph_GPIOx             RCC_AHB1Periph_GPIOC
    		#define GPIOx                            GPIOC  
    		
    		#define GPIO_Pinx_0                      GPIO_Pin_0 //PC0 --> ADC123_IN10	 
    		#define GPIO_Pinx_1                      GPIO_Pin_1 //PC1 --> ADC123_IN11  
    		#define GPIO_Pinx_2                      GPIO_Pin_2 //PC2 --> ADC123_IN12
    		#define GPIO_Pinx_3                      GPIO_Pin_3 //PC3 --> ADC123_IN13
    		
    		#define RCC_AHB1Periph_DMA_x             RCC_AHB1Periph_DMA2
    		#define DMA_Channel_x                    DMA_Channel_0 //通道0
    		#define DMAx_Stream_x                    DMA2_Stream0  //DMA2的数据流0
    
    	void ADC_DualModeRegualSimult_Config(void);
    
    
    	//---------------------TripleModeInterleaved------------------------//
    
    	#elif defined (ADC_TripleModeInterleaved) 
    
    	//双重或者三重 ADC 需要使用通用规则数据寄存器 ADC_CDR,这点跟独立模式不同
    		#define TripleModeInterleaved_ADC_ADDR   ((uint32_t)0x40012308)
    		#define TripleModeInterleaved_ADC1       ADC1
    		#define TripleModeInterleaved_ADC2       ADC2
    		#define TripleModeInterleaved_ADC3       ADC3
    		#define TripleModeInterleaved_ADC1_CLK   RCC_APB2Periph_ADC1
    		#define TripleModeInterleaved_ADC2_CLK   RCC_APB2Periph_ADC2
    		#define TripleModeInterleaved_ADC3_CLK   RCC_APB2Periph_ADC3
    		#define TripleModeInterleaved_ADC_CHx    ADC_Channel_1
    		#define TripleModeInterleaved_GPIO_CLK   RCC_AHB1Periph_GPIOA
    		#define TripleModeInterleaved_GPIO       GPIOA
    		#define TripleModeInterleaved_GPIO_Pinx  GPIO_Pin_1
    		
    		void ADC_TripleModeInterleaved_Config(void);
    		
    
    	//-----------------------VBATMeasurement--------------------------//
    
    	#elif defined (ADC_VBATMeasurement) 
    
    	//● 在 STM32F40xx 和 STM32F41xx 器件上将 VBAT/2 连接到 ADC1_IN18 输入通道
    	//● 在 STM32F42xx 和 STM32F43xx 器件上将 VBAT/4 连接到 ADC1_IN18 输入通道
    
    		#define VBATDIV                    2   //这里用的是F407
    
    		#define ADC_VBATMeasurement_ADDR   ((uint32_t)0x4001204C)
    		#define ADCx_CLK                   RCC_APB2Periph_ADC1
    		#define ADCx                       ADC1
    		
    		#define DMAx_CLK                   RCC_AHB1Periph_DMA2
    		#define DMA_Channel_x              DMA_Channel_0 //通道0
    		#define DMAx_Stream_x              DMA2_Stream0  //DMA2的数据流0
    
    	 void ADC_VBATMeasure_Config(void);
    	 
    
    	#endif
    
    
    #endif
    
    

     

    //--------main.c--------------------------------------------------------------------------------------------------------------------------------------////

    #include "sys.h"
    #include "delay.h"
    #include "usart.h"
    #include "adc.h"
      
    
    	
    extern __IO uint32_t ADC_TripleModeConveredValue[3];
    
    extern __IO uint32_t ADC_DualModeConveredValue;
    __IO float DualModeValue1;
    __IO float DualModeValue2;
    
    extern __IO uint16_t ADC_MultiModeConveredValue[8];
    __IO float ADC_MultiModeValue[8];
    
    extern __IO uint16_t RegSimultModeConveredValue[4];
    
    extern __IO uint16_t ADC_VBATMeasureValue;
    __IO float VBAT_Value;
    
    int main(void)
    { 
    	delay_init(168);     //初始化延时函数
    	uart_init(115200);	 //初始化串口波特率为115200
     
    	printf("\n\r||-----ADC TEST-----||\n\r");
    	
    	
    	
    #if defined  (ADC_Single_Channel) //单通道采集
    
    	ADC_Single_Config();
    	ADC_Single_NVIC_Config();
    	
    	while(1);
    	
    	
    #elif defined (ADC_Multi_Channel) //多通道采集
    	
      int i;
    	
    	Multi_ADC_GPIO_Config();
    	
    	ADC_Multi_Config();
    	
    	while(1)
    	{
    		for(i=0; i<8; i++)
    		{
    		  ADC_MultiModeValue[i] = (float) ADC_MultiModeConveredValue[i]/4096*(float)3.3;
    			printf("\r\nADC Channel_%d value = %f V \r\n",i,ADC_MultiModeValue[i]);
    			if(i==8)
    				i = 0;
    		}
    
      }
    
    	
    #elif defined (ADC_DualModeInterleaved) //双重采集模式
    
    	ADC_DualModeInterleaved_Config();
    	
    	while(1)
    	{
    		
    		delay_ms(10);
    		printf("\r\n The current ADC = 0x%08x V \r\n",ADC_DualModeConveredValue);//由DMA模式2 --> 高四位为ADC2的值,低四位为ADC1的值,
    		
    		DualModeValue1 = (float)((uint16_t)ADC_DualModeConveredValue*3.3/4096);
    		DualModeValue2 = (float)((ADC_DualModeConveredValue>>16)*3.3/4096);
    
    		printf("\r\n The current ADC1 value = %f V \r\n"    ,DualModeValue1);
    		printf("\r\n The current ADC2 value = %f V \r\n\r\n",DualModeValue2);	
      }
    	
    	
    #elif defined (ADC_DualModeRegualSimult) //双ADC规则同步模式
    
    	//DualModeRegualSimult_GPIO_Config();
    	
    	ADC_DualModeRegualSimult_Config();
    	
    	while(1)
    	{
    		delay_ms(10);
    
    		printf("\r\n The current channel 10 value = %08x  \r\n"    ,RegSimultModeConveredValue[0]);//c0
    		printf("\r\n The current channel 11 value = %08x  \r\n"    ,RegSimultModeConveredValue[1]);//c1
    		printf("\r\n The current channel 12 value = %08x  \r\n"    ,RegSimultModeConveredValue[2]);//c1
    		printf("\r\n The current channel 13 value = %08x  \r\n\r\n",RegSimultModeConveredValue[3]);//c2
    		printf("\r\n The current channel 10 value = %f V \r\n"    ,(float)((uint16_t)RegSimultModeConveredValue[0]*3.3/4096));	
    		printf("\r\n The current channel 11 value = %f V \r\n"    ,(float)((uint16_t)RegSimultModeConveredValue[1]*3.3/4096));	
    		printf("\r\n The current channel 10 value = %f V \r\n"    ,(float)((uint16_t)RegSimultModeConveredValue[2]*3.3/4096));	
    		printf("\r\n The current channel 11 value = %f V \r\n\r\n",(float)((uint16_t)RegSimultModeConveredValue[3]*3.3/4096));	
    
    	}
    	
    
    #elif defined (ADC_TripleModeInterleaved) //三通道交错采集
    
    	ADC_TripleModeInterleaved_Config(); 
    	
    	while(1)
    	{
    		
    		delay_ms(10);
        printf("\r\n The current ADC1 value = %f V \r\n",(float)((uint16_t)ADC_TripleModeConveredValue[0]*3.3/4096));//三重采集模式 根据选用的DMA模式2 顺序为1,3,2
        printf("\r\n The current ADC3 value = %f V \r\n",(float)((uint16_t)ADC_TripleModeConveredValue[1]*3.3/4096));
        printf("\r\n The current ADC2 value = %f V \r\n",(float)((uint16_t)ADC_TripleModeConveredValue[2]*3.3/4096));	
      }
    	
    
    #elif defined (ADC_VBATMeasurement)   //电源电压测量
    
    	
    	ADC_VBATMeasure_Config();
    	
    	while(1)
    	{
    		delay_ms(10);
    		
    		VBAT_Value = (float)((uint16_t)ADC_VBATMeasureValue*VBATDIV*3.3/4096);
    		
    		printf("\r\n\r\n The ADC value = %08x  \r\n"  ,ADC_VBATMeasureValue);//c0
    
        printf("\r\n The VBATMeasure value = %f V\r\n",VBAT_Value);//
        
    	}
    	
    #endif
    	
    
    }
    

     

  • 以下回答由chatgpt基于相关博客总结生成:

    可以直接用C语言在keil5中编写代码。需要先了解芯片的手册,了解芯片的IO口和ADC等资源的寄存器地址。 关于设置输入的IO口,可以使用GPIO库函数进行配置。需要调用GPIO_Init函数,具体可以参考上面参考资料中的adc.c中的GPIO配置,根据自己需要进行修改。 关于初始化ADC,可以参考上述参考资料中的adc.c中的adc_init函数进行配置。 关于设置输出串口,需要先了解自己使用的芯片是否支持串口。如果支持,则需要使用USART库函数进行配置。可以调用USART_Init函数进行串口初始化,配置波特率、数据位、停止位等参数,然后使用USART_SendData函数将需要发送的数据发送出去。 需要注意的是,在使用ADC时,转换的时间不能大于采样周期,需要根据硬件环境和转换位数确定转换时间,不能突破转换时间的限制。具体可参考上述参考资料中的段落0。

先学再用。