15:HAL----ADC模数转化器

STM32C8T6有2个ADC,ADC1和ADC2

一:介绍

 1:简历

        ADC(Analog-Digital Converter)模拟-数字转换器

        ADC可以将引脚上连续变化的模拟电压转换为内存中存储的数字变量,建立模拟电路到数字电路的桥梁

        12位逐次逼近型ADC,1us转换时间

        输入电压范围:0~3.3V,转换结果范围:0~4095

        18个输入通道,可测量16个外部(GPIO)和2个内部信号源(内部温度传感器和内部参考电压)

        规则组和注入组两个转换单元

        模拟看门狗自动监测

        输入电压范围 STM32F103C8T6 ADC资源:ADC1、ADC2,10个外部输入通道

        12位逐次逼近型ADC,1us转换时间 : 

        分辨率 : 一般用多少位来表示,12位AD值,它的表示范围就是0~2^12-1,量化结果的范围是0~4095 , 位数越高,量化结果就越精细,对应分辨率就越高

        转换时间: 就是转化频率AD转换是需要花一小段时间的,这里1us就表示从AD转换开始到产生结果,需要花1us的时间。对应AD转换的频率就是1MHZ ,  这个就是STM32 ADC的最快转换频率

 规则组和注入组两个转换单元:

        普通的AD转换流程是,启动一次转换、读一次值 , 然后再启动、再读值,这样的流程 ; 

STM32的ADC就比较高级: 可以列一个组,一次性启动一个组,连续转换多个值 , 并且有两个组,一个是用于常规使用的规则组 ,一个是用于突发事件的注入组

注入组:相当于中断,可以打断规则组,用于处理紧急的事件

2:逐次逼近型ADC

         ADC0809 : 独立的8位逐次逼近型ADC芯片
        EOC是End of Convert : 转换结束信号

        START : 是开始转换,给一个输入脉冲,开始转换

        CLOCK : 是ADC时钟,因为ADC内部是一步一步进行判断的
        REF+和VREF- : DAC的参考电压

3:ADC基本结构

 4:输入通道

5:规则组的4种转换模式 

在初始化ADC时配置的参数

单次转化 : ADC 执行一次转换,然后,ADC 停止

连续转化: 与单次转换不同的是,它在一次转换结束后不会停止 ,  而是立刻开始下一轮的转换,然后一直持续下去  ,  这样就只需要最开始触发一次,之后就可以一直转换了

扫描模式 : 在组中填几个通道几个通道就有效 , 填入多个的时候应避免覆盖的问题,  使用使用DMA

非扫描模式 : 这个组就只有第一个序列1(Rank排名)的位置有效 , 这时选中一组的方式就退化为简单地选中一个的方式了。序列1(Rank排名)可以放任意的通道。

 X.ADC_ContinuousConvMode=DISABLE;//选择是连续转换还是单次转换---单X.ADC_ScanConvMode=DISABLE;//可以选择是扫描模式还是非扫描模式---非扫描模式

1:单次转化,非扫描模式

        在非扫描的模式下,这个组就只有第一个序列1的位置有效 , 这时选中一组的方式就退化为简单地选中一个的方式了

        我们可以在序列1的位置指定我们想转换的通道 , 比如通道2 , 然后,我们就可以触发转换,ADC就会对这个通道2进行模数转换 , 过一段时间转化完成  , 转换结果放在数据寄存器里,同时给EOC标志位置1----转换过程就结束了 .   我们判断这个EOC标志位,如果转换完了 ,  可以在数据寄存器里读取结果了 ,  如果我们想再启动一次转换,那就需要再触发一次 ,  转换结束,置EOC标志位,读结果

2:连续转化,非扫描模式

        首先,它还是非扫描模式,所以组列表就只用第一个  ,  与单次转换不同的是,它在一次转换结束后不会停止 ,  而是立刻开始下一轮的转换,然后一直持续下去  ,  这样就只需要最开始触发一次,之后就可以一直转换了

        优点  :  开始转换之后不需要等待一段时间的 ,  它一直都在转换,所以你就不需要手动开始转换了 , 也不用判断是否结束的 ,  想要读AD值的时候,直接从数据寄存器取就是了

3:单次转化,扫描模式

        这个模式也是单次转换,所以每触发一次 , 转换结束后,就会停下来  ,  下次转换就得再触发能开始

        扫描模式 : 会用到这个组了 , 在序列中填入通道 , 这里每个位置是通道几可以任意指定,并且也是可以重复的 ,  初始化结构体里还会有个参数,就是通道数目 (x.ADC_NbrOfChannel=)  比如这里指定通道数目为7,那它就只看前7个位置,那么x.ADC_NbrOfChannel=7, 它就会只对前7个AD通道进行转化,   转换结果都放在数据寄存器里  ,   这里为了防止数据被覆盖,就需要用DMA及时将数据挪走  ,  那7个通道转换完成之后,产生EOC信号(EOC置1),转换结束 ,  然后再触发下一次,就又开始新一轮的转换

使用DMA---避免通道数据覆盖

        因为这里只有一个规则组的数据寄存器 , 如果使用了 扫描模式在一个组中开启了7个通道,  只会有最后一个通道被保留下来,  前面的6个通道会被覆盖掉. 最后只会得到一个通道.

        使用这里使用MDA在下一个通道来之前,  把现在的数据放到了MDA中, 避免出现通道的覆盖问题

4:单次转化,扫描模式

         次转换完成后,立刻开始下一次的转换 , 也开启组

6:触发控制

下面是规则组的触发源

注入组的触发源 

7:数据对齐

ADC初始化中的配置---X.ADC_DataAlign

        我们这个ADC是12位的,它的转换结果就是一个12位的数据 ,  但是这个数据寄存器是16位的,所以就存在一个数据对齐的问题

右对齐 : 就是12位的数据向右靠 , 就是12位的数据向有靠 , 高位多出来的几位就补0 ,一般

使用右对齐,  这样读取这个16位寄存器,直接就是转换结果

左对齐 : 是12位的数据向左靠 ,  低位多出来的几位补0 ,  得到的数据会比实际的大 ,  数据左对齐实际上就是把数据左移了4次  ,数据左移一次,就等效于把这个数据乘2 , 直接读取的话相当于把数据扩大了16倍 . 

 8:转化时间

 

9:校准

        ADC有一个内置自校准模式。校准可大幅减小因内部电容器组的变化而造成的准精度误差。校准期间,在每个电容器上都会计算出一个误差修正码(数字值),这个码用于消除在随后的转换中每个电容器上产生的误差

        建议在每次上电后执行一次校准

        启动校准前, ADC必须处于关电状态超过至少两个ADC时钟周期

10:间断模式

规则组:

扫描模式下的一个细分。

  • 间断模式:区别于扫描模式连续扫描完整的一组通道,间断模式将一组通道分为多个短序列,每次外部触发事件执行一个短序列的扫描转换。
  • 必须使能扫描模式,禁止使用连续模式(为了方便我们的观察,可以禁止,手册中没有强制的要求),必须避免同时为规则和注入为间断模式。

n:一个子组中几个成员。上面为3个

每次一个信号的到来,转化一个字组。

注入组:

注入组间断模式和规则组是一样。

唯一的不同是:注入组的n=1;不能为其他的数,规定。

注入组和规则组的中断触发时机不同。

规则组:

        当完成一个子组(即n个通道)的转换后,会触发一个中断请求,进入中断回调函数。

HAL_ADC_ConvCpltCallback

注入组:

       所有的子组完成,进入中断回调函数中去。

HAL_ADCEx_InjectedConvCpltCallb()

11:ADC的硬件电路

12:温度传感器

        STM32F103C8T6内部的ADC(模拟数字转换器)的温度传感器在微控制器中起着关键作用,主要用于测量和监控芯片内部的温度。

  • 该温度传感器在-40℃至+125℃的范围内进行测量。
  • 由于是内置的简化温度传感器,其精度相对较低,大约为±1.5℃。
  • ADC的分辨率为12位,这意味着它能够提供相对较高的温度测量精度

ADC_in16和ADC_IN17是内部的通道,没有物理引脚。

接下 来我们介绍一下和温度传感器设置相关的2个地方。
                第一个地方,我们要使用STM32的内部温度传感器,必须先激活ADC的内部通道,这里 通过ADC_CR2的AWDEN位(bit23)设置。设置该位为1则启用内部温度传感器。

                第二个地方,STM32的内部温度传感器固定的连接在ADC的通道16上,所以,我们在设 置好ADC之后只要读取通道16的值,就是温度传感器返回来的电压值了。根据这个值,我们 就可以计算出当前温度。

  公式            
                          温度 = (V25-Vsense ) / Avg_Slope + 25°C

V25 是温度传感器在25°C时的输出电压。(典型值为:1.43)
Vsense 是当前温度下的温度传感器输出电压,可以通过ADC读数转换得到。
Avg_Slope 是温度传感器输出电压随温度变化的平均斜率(单位:mV/°C)。//4.3
25°C 是参考温度,即V25对应的温度。
 如电压为3v时

温度=(3.0-1.43)/4.3+25

二:HAL配置

三:案例

                                                规则组单管道

A:ADC时钟配置

ADC时钟的最大时钟源为:14MHZ,所以它的时钟源需要单独配置。

/*HSE外部高速时钟做为系统时钟*/
void sys_stm32_clock_init(uint32_t plln)
{HAL_StatusTypeDef ret = HAL_ERROR;RCC_OscInitTypeDef RCC_OscInit = {0};RCC_ClkInitTypeDef RCC_ClkInit={0};RCC_PeriphCLKInitTypeDef RCC_PeriphCLKInit={0}; //ADC时钟需要单独配置//HSE外部时钟做为PLL时钟源RCC_OscInit.OscillatorType=RCC_OSCILLATORTYPE_HSE;/*选择振荡器类型*/RCC_OscInit.HSEState=RCC_HSE_ON;                  /*选择HSL状态*/RCC_OscInit.HSEPredivValue=RCC_HSE_PREDIV_DIV1;		/*HSE的分频系数*/RCC_OscInit.PLL.PLLState=RCC_PLL_ON;RCC_OscInit.PLL.PLLSource=RCC_PLLSOURCE_HSE;RCC_OscInit.PLL.PLLMUL=plln;  //RCC_PLL_MUL9ret=HAL_RCC_OscConfig(&RCC_OscInit);if (ret !=HAL_OK){while (1);}//PLL做为系统时钟RCC_ClkInit.ClockType=RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;RCC_ClkInit.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInit.AHBCLKDivider=RCC_HCLK_DIV1;RCC_ClkInit.APB1CLKDivider=RCC_HCLK_DIV2;RCC_ClkInit.APB2CLKDivider=RCC_HCLK_DIV1;ret=HAL_RCC_ClockConfig(&RCC_ClkInit,FLASH_LATENCY_2);if (ret !=HAL_OK){while (1);}//ADC的时钟源需要单独配置:72/6=12MHZRCC_PeriphCLKInit.PeriphClockSelection=RCC_PERIPHCLK_ADC;RCC_PeriphCLKInit.AdcClockSelection=RCC_ADCPCLK2_DIV6;HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphCLKInit);}

                HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef  *PeriphClkInit)   函数在文件:stm32f1xx hal rcc_ex.c 

重要函数:

// 定义一个结构体类型 RCC_PeriphCLKInitTypeDef  
typedef struct  
{  // 选择要配置的扩展时钟  // 此参数可以是 RCCEx_Periph_Clock_Selection 枚举中的一个值  uint32_t PeriphClockSelection;        // 指定RTC时钟源  // 此参数可以是 RCC_RTC_Clock_Source 枚举中的一个值  uint32_t RTCClockSelection;           // ADC时钟源  // 此参数可以是 RCCEx_ADC_Prescaler 枚举中的一个值  uint32_t AdcClockSelection;           // 特定于STM32F103xE、STM32F103xG、STM32F105xC 和 STM32F107xC 设备的字段  
#if defined(STM32F103xE) || defined(STM32F103xG) || defined(STM32F105xC)\  || defined(STM32F107xC)  // I2S2时钟源  // 此参数可以是 RCCEx_I2S2_Clock_Source 枚举中的一个值  uint32_t I2s2ClockSelection;           // I2S3时钟源  // 此参数可以是 RCCEx_I2S3_Clock_Source 枚举中的一个值  uint32_t I2s3ClockSelection;           // 特定于STM32F105xC 和 STM32F107xC 设备的字段  
#if defined(STM32F105xC) || defined(STM32F107xC)  // 当PLLI2S被选为I2S2或I2S3的时钟源时,这个参数将用于配置PLL I2S的结构参数  RCC_PLLI2SInitTypeDef PLLI2S;    #endif /* STM32F105xC || STM32F107xC */  
#endif /* STM32F103xE || STM32F103xG || STM32F105xC || STM32F107xC */  // 特定于STM32F102x6、STM32F102xB、STM32F103x6、STM32F103xB、STM32F103xE、STM32F103xG、STM32F105xC 和 STM32F107xC 设备的字段  
#if defined(STM32F102x6) || defined(STM32F102xB) || defined(STM32F103x6)\  || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG)\  || defined(STM32F105xC) || defined(STM32F107xC)  // USB时钟源  // 此参数可以是 RCCEx_USB_Prescaler 枚举中的一个值  uint32_t UsbClockSelection;           #endif /* STM32F102x6 || STM32F102xB || STM32F103x6 || STM32F103xB || STM32F103xE || STM32F103xG || STM32F105xC || STM32F107xC */  
} RCC_PeriphCLKInitTypeDef;

B:规则组 单通道 单次转换 轮询方式


int main(void)
{HAL_Init();                         /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */delay_init(72);                     /* 延时初始化 */Uart_Init(115200);ADC1_Init();//HAL_ADC_GetValue读取常规组寄存器的数据HAL_ADC_PollForConversion(&ADC1_Handle,1000);   //轮询方式:等待ADC常规组转换完成printf("ADC1_IN0:%d \r\n",HAL_ADC_GetValue(&ADC1_Handle));   //串口1输出数字量while (1){			 }   
}
#include "stm32f1xx_hal.h"ADC_HandleTypeDef ADC1_Handle;void ADC1_Init(void)
{ADC_ChannelConfTypeDef ADC_Channel;ADC1_Handle.Instance=ADC1;ADC1_Handle.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐ADC1_Handle.Init.ScanConvMode=ADC_SCAN_DISABLE;  //扫描模式:失能ADC1_Handle.Init.ContinuousConvMode=DISABLE;     //连续模式:DISABLE(单次模式)ADC1_Handle.Init.DiscontinuousConvMode=DISABLE;   //规则组的间断模式   ADC1_Handle.Init.ExternalTrigConv=ADC_SOFTWARE_START;//触发方式:软件触发HAL_ADC_Init(&ADC1_Handle);ADC_Channel.Channel=ADC_CHANNEL_0;     //通道编号ADC_Channel.Rank=ADC_REGULAR_RANK_1;     //排名ADC_Channel.SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC1_Handle,&ADC_Channel);HAL_ADCEx_Calibration_Start(&ADC1_Handle);                   //自校准HAL_ADC_Start(&ADC1_Handle);}
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{if(hadc->Instance==ADC1){__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_ADC1_CLK_ENABLE();GPIO_InitTypeDef GPIO_InitType;//模拟输入不用设置上下拉电阻GPIO_InitType.Mode=GPIO_MODE_ANALOG;  //模拟输入GPIO_InitType.Pin=GPIO_PIN_0;HAL_GPIO_Init(GPIOA,&GPIO_InitType); }
}

采样时间:

我们配置的ADC的时钟为12MHZ

自校准

HAL_ADCEx_Calibration_Start(&ADC1_Handle);          自校准
HAL_ADC_Start(&ADC1_Handle);

所以自校准要在ADC_Start之前完成。

在stm32f1xx hal adc_ex.c里。

重要参数:

C:规则组 单通道单次or连续转换 中断方式

探索 规则组 单通道,单次中断方式和连续转换 中断方式的区别。

中断连续模式

int main(void)
{uint8_t res=0;HAL_Init();                         /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */delay_init(72);                     /* 延时初始化 */Uart_Init(115200);ADC1_Init();while (1){		}}
#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"ADC_HandleTypeDef ADC1_Handle;
void ADC1_Init(void)
{ADC_ChannelConfTypeDef ADC_Channel;ADC1_Handle.Instance=ADC1;ADC1_Handle.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐ADC1_Handle.Init.ScanConvMode=ADC_SCAN_DISABLE;  //扫描模式:失能ADC1_Handle.Init.ContinuousConvMode=ENABLE;     //连续模式:ENABLE连续模式ADC1_Handle.Init.DiscontinuousConvMode=DISABLE;   //规则组的间断模式   ADC1_Handle.Init.ExternalTrigConv=ADC_SOFTWARE_START;//触发方式:软件触发HAL_ADC_Init(&ADC1_Handle);ADC_Channel.Channel=ADC_CHANNEL_1;     //通道编号ADC_Channel.Rank=ADC_REGULAR_RANK_1;     //排名ADC_Channel.SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC1_Handle,&ADC_Channel);HAL_ADCEx_Calibration_Start(&ADC1_Handle);                   //自校准HAL_ADC_Start_IT(&ADC1_Handle);}
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{if(hadc->Instance==ADC1){__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_ADC1_CLK_ENABLE();GPIO_InitTypeDef GPIO_InitType;//模拟输入不用设置上下拉电阻GPIO_InitType.Mode=GPIO_MODE_ANALOG;  //模拟输入GPIO_InitType.Pin=GPIO_PIN_1;HAL_GPIO_Init(GPIOA,&GPIO_InitType); HAL_NVIC_SetPriority(ADC1_2_IRQn,1,0);HAL_NVIC_EnableIRQ(ADC1_2_IRQn);}
}void ADC1_2_IRQHandler()
{HAL_ADC_IRQHandler(&ADC1_Handle);
}
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{if(hadc->Instance==ADC1){printf("ADC1_IN0:%d \r\n",HAL_ADC_GetValue(&ADC1_Handle));   //串口1输出数字量delay_ms(1000);}}

单次模式:

因为单次模式执行一次就会关闭,如果在单次模式下需要达到连续模式的效果:

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{if(hadc->Instance==ADC1){printf("ADC1_IN0:%d \r\n",HAL_ADC_GetValue(&ADC1_Handle));   //串口1输出数字量HAL_ADC_Start_IT(&ADC1_Handle);delay_ms(1000);}
}

D:规则组 单通道 DMA方式 均值滤波

int main(void)
{uint8_t res=0;HAL_Init();                         /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */delay_init(72);                     /* 延时初始化 */Uart_Init(115200);ADC1_Init();while (1){		}}#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"ADC_HandleTypeDef ADC_HandleType;
DMA_HandleTypeDef DMA_Handle;uint16_t DMA_buff[10];
void ADC1_Init(void)
{ADC_ChannelConfTypeDef ADC_Channel;ADC_HandleType.Instance=ADC1;ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐ADC_HandleType.Init.ScanConvMode=ADC_SCAN_DISABLE;  //扫描模式:失能ADC_HandleType.Init.ContinuousConvMode=ENABLE;     //连续模式:ENABLE连续模式ADC_HandleType.Init.DiscontinuousConvMode=DISABLE;   //规则组的间断模式   ADC_HandleType.Init.ExternalTrigConv=ADC_SOFTWARE_START;//触发方式:软件触发HAL_ADC_Init(&ADC_HandleType);ADC_Channel.Channel=ADC_CHANNEL_2;     //通道编号ADC_Channel.Rank=ADC_REGULAR_RANK_1;     //排名ADC_Channel.SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel);HAL_ADCEx_Calibration_Start(&ADC_HandleType);                   //自校准HAL_ADC_Start_DMA(&ADC_HandleType,(uint32_t*)DMA_buff,10);  //DMA将连续读取10个ADC转换结果并存储到DMA_buff中。}
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{if(hadc->Instance==ADC1){__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_ADC1_CLK_ENABLE();__HAL_RCC_DMA1_CLK_ENABLE();GPIO_InitTypeDef GPIO_InitType;//模拟输入不用设置上下拉电阻GPIO_InitType.Mode=GPIO_MODE_ANALOG;  //模拟输入GPIO_InitType.Pin=GPIO_PIN_2;HAL_GPIO_Init(GPIOA,&GPIO_InitType); //DMA配置:方向寄存器(外设)-->数组(内存)DMA_Handle.Instance=DMA1_Channel1;DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY;  //传输方向:寄存器(外设)->数组(内存)DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE;   //寄存器(外设)是否递增加DMA_Handle.Init.MemInc=DMA_MINC_ENABLE;      //数组(内存)是否递增加DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD;    //外设数据宽度(半字=2个字节)DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_HALFWORD;      //数组(内存)数据宽度DMA_Handle.Init.Mode=DMA_CIRCULAR;                         //模式:循环DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle);   //或者下面的写法__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle);  //链接//DMA的配置HAL_DMA_Init(&DMA_Handle);HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,1,0);HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);}
}//void ADC1_2_IRQHandler()
//{
//	HAL_ADC_IRQHandler(&ADC_HandleType);
//}void DMA1_Channel1_IRQHandler()
{HAL_DMA_IRQHandler(&DMA_Handle);
}DMA将连续读取10个ADC转换结果并存储到DMA_buff中,后进入中断
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{			uint32_t num;uint8_t i;if(hadc->Instance==ADC1){num=0;for(i=0;i<10;i++){num+=DMA_buff[i];}printf("ADC1_IN0:%f V \r\n",(num/10.0)*(3.3/4096.0));   //串口1输出数字量delay_ms(1000);}}

DMA传输方向的选取

  1. DMA_PERIPH_TO_MEMORY (0x00000000U)

    • 含义:此宏表示从外设(Peripheral)到内存(Memory)的数据传输方向。
    • 选择:当您需要将数据从某个外设(如UART、SPI、GPIO等)读取到系统内存(如SRAM、SDRAM等)时,您应该选择此宏。
    • 应用:在配置DMA传输时,将此宏的值设置为DMA控制器的相关寄存器字段,以指示数据流动的方向。
  2. DMA_MEMORY_TO_PERIPH ((uint32_t)DMA_CCR_DIR)

    • 含义:此宏表示从内存(Memory)到外设(Peripheral)的数据传输方向。
    • 选择:当您需要将数据从系统内存写入某个外设时,您应该选择此宏。
    • 应用:与DMA_PERIPH_TO_MEMORY类似,将此宏的值设置为DMA控制器的相关寄存器字段。
    • 注意:这里的DMA_CCR_DIR可能是一个预定义的位掩码,用于设置DMA通道配置寄存器(CCR)中的DIR位,该位控制DMA传输的方向。
  3. DMA_MEMORY_TO_MEMORY ((uint32_t)DMA_CCR_MEM2MEM)

    • 含义:此宏表示内存到内存(Memory-to-Memory)的数据传输方向。
    • 选择:当您需要在系统内的两个内存位置之间传输数据时,您应该选择此宏。
    • 应用:将此宏的值设置为DMA控制器的相关寄存器字段。
    • 注意:这里的DMA_CCR_MEM2MEM可能是一个预定义的位掩码,用于设置DMA通道配置寄存器(CCR)中的MEM2MEM位(或其他相关位),该位(或位组合)控制DMA传输的模式为内存到内存。

E:规则组 外部触发定时器的CC事件

当外部触发信号被选为ADC规则或注入转换时,只有它的上升沿可以启动转换。

定时器1的cc事件

int main(void)
{uint8_t res=0;HAL_Init();                         /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */delay_init(72);                     /* 延时初始化 */Uart_Init(115200);ADC1_Init();      //0.2s=200ms   0.2*10=2S==DMA的时间IC_TIMX_CHX_init(2000-1,7200-1);   //T=((ARR+1)*(PSC+1)) / 72 000 000;while (1){		}}
#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"ADC_HandleTypeDef ADC_HandleType;
DMA_HandleTypeDef DMA_Handle;uint16_t DMA_buff[10];
void ADC1_Init(void)
{ADC_ChannelConfTypeDef ADC_Channel;ADC_HandleType.Instance=ADC1;ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐ADC_HandleType.Init.ScanConvMode=ADC_SCAN_DISABLE;  //扫描模式:失能ADC_HandleType.Init.ContinuousConvMode=DISABLE;     //连续模式:DISABLE(单次模式)ADC_HandleType.Init.DiscontinuousConvMode=DISABLE;   //规则组的间断模式   ADC_HandleType.Init.ExternalTrigConv=ADC_EXTERNALTRIGCONV_T1_CC1;//触发方式:TIM1的cc事件HAL_ADC_Init(&ADC_HandleType);ADC_Channel.Channel=ADC_CHANNEL_2;     //通道编号ADC_Channel.Rank=ADC_REGULAR_RANK_1;     //排名ADC_Channel.SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel);HAL_ADCEx_Calibration_Start(&ADC_HandleType);                   //自校准HAL_ADC_Start_DMA(&ADC_HandleType,(uint32_t*)DMA_buff,10);  //DMA将连续读取10个ADC转换结果并存储到DMA_buff中。
}
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{if(hadc->Instance==ADC1){__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_ADC1_CLK_ENABLE();__HAL_RCC_DMA1_CLK_ENABLE();GPIO_InitTypeDef GPIO_InitType;//模拟输入不用设置上下拉电阻GPIO_InitType.Mode=GPIO_MODE_ANALOG;  //模拟输入GPIO_InitType.Pin=GPIO_PIN_2;HAL_GPIO_Init(GPIOA,&GPIO_InitType); //DMA配置:方向寄存器(外设)-->数组(内存)DMA_Handle.Instance=DMA1_Channel1;DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY;  //传输方向:寄存器(外设)->数组(内存)DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE;   //寄存器(外设)是否递增加DMA_Handle.Init.MemInc=DMA_MINC_ENABLE;      //数组(内存)是否递增加DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD;    //外设数据宽度(半字=2个字节)DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_HALFWORD;      //数组(内存)数据宽度DMA_Handle.Init.Mode=DMA_CIRCULAR;                         //模式:循环DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle);   //或者下面的写法__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle);  //链接//DMA的配置HAL_DMA_Init(&DMA_Handle);HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,1,0);HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);}
}//void ADC1_2_IRQHandler()
//{
//	HAL_ADC_IRQHandler(&ADC_HandleType);
//}void DMA1_Channel1_IRQHandler()
{HAL_DMA_IRQHandler(&DMA_Handle);
}DMA将连续读取10个ADC转换结果并存储到DMA_buff中,后进入中断
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{			uint32_t num;uint8_t i;if(hadc->Instance==ADC1){num=0;for(i=0;i<10;i++){num+=DMA_buff[i];}printf("ADC1_IN0:%f V \r\n",(num/10.0)*(3.3/4096.0));   //串口1输出数字量}}
#include "stm32f1xx_hal.h"
#include "pwm.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
//输入捕获功能
TIM_HandleTypeDef HandleTIMXCHX;
//TIM1的CC1事件
void IC_TIMX_CHX_init(uint16_t arr,uint16_t psc)
{TIM_OC_InitTypeDef TIM_OC_Init={0};HandleTIMXCHX.Instance=TIM1;   //基地址HandleTIMXCHX.Init.Period=arr;HandleTIMXCHX.Init.Prescaler=psc;HandleTIMXCHX.Init.CounterMode=TIM_COUNTERMODE_UP;   //向上计数HandleTIMXCHX.Init.RepetitionCounter =0;                	//设置重复次数HandleTIMXCHX.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;   //设置自动重载值 预装载使能位HandleTIMXCHX.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;   //设置分频因子HAL_TIM_OC_Init(&HandleTIMXCHX);//清除跟新中断标志位__HAL_TIM_CLEAR_FLAG(&HandleTIMXCHX,TIM_FLAG_UPDATE);TIM_OC_Init.OCMode=TIM_OCMODE_PWM1;TIM_OC_Init.Pulse=100;    //比较值TIM_OC_Init.OCPolarity=TIM_OCPOLARITY_LOW;//有效值  :PWM1:CNT<CCR输出有效电平  TIM_OC_Init.OCFastMode = TIM_OCFAST_DISABLE;                     //关闭快速模式HAL_TIM_OC_ConfigChannel(&HandleTIMXCHX, &TIM_OC_Init,TIM_CHANNEL_1);HAL_TIM_OC_Start_IT(&HandleTIMXCHX,TIM_CHANNEL_1);}void HAL_TIM_OC_MspInit(TIM_HandleTypeDef *htim)
{if(htim->Instance==TIM1){__HAL_RCC_GPIOA_CLK_ENABLE() ;__HAL_RCC_TIM1_CLK_ENABLE();//来自片上的内部信号,PA8引脚输出化,随便可以开,可以不开。//PA8---TIM_CH1
//			GPIO_InitTypeDef GPIO_InitType;
//			GPIO_InitType.Mode=GPIO_MODE_AF_PP;   /*复用推完输出*/
//			GPIO_InitType.Pin=GPIO_PIN_8;
//			GPIO_InitType.Speed=GPIO_SPEED_FREQ_LOW;
//			HAL_GPIO_Init(GPIOA,&GPIO_InitType);   HAL_NVIC_SetPriority(TIM1_CC_IRQn, 1, 3);              /* 抢占1,子优先级3 */HAL_NVIC_EnableIRQ(TIM1_CC_IRQn);                      /* 开启ITMx中断 */			}
}/* 定时器1中断服务函数 */
void TIM1_CC_IRQHandler(void)
{HAL_TIM_IRQHandler(&HandleTIMXCHX);  /* 定时器HAL库共用处理函数 */}
//定时器的CC通道的输出比较
void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim)
{if(htim->Instance==TIM1){if(htim->Channel==HAL_TIM_ACTIVE_CHANNEL_1){			printf("定时器1通道1匹配成功\r\n");}		}
}

配置时候注意通道:

TIM通道的配置。我们的CC事件是通过片上定时器的内部信号触发的(所以,在定时器1中PA8为定时器1_CH1,PA8开不开都可以。)

F:规则组 外部触发 定时器3的TRGO 更新事件

int main(void)
{uint8_t res=0;HAL_Init();                         /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */delay_init(72);                     /* 延时初始化 */Uart_Init(115200);ADC1_Init();                                //0.2s=200ms   0.2*10=2S==DMA的时间IC_TIMX_CHX_init(2000-1,7200-1);   //T=((ARR+1)*(PSC+1)) / 72 000 000;while (1){		}}#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"ADC_HandleTypeDef ADC_HandleType;
DMA_HandleTypeDef DMA_Handle;uint16_t DMA_buff[10];
void ADC1_Init(void)
{ADC_ChannelConfTypeDef ADC_Channel;ADC_HandleType.Instance=ADC1;ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐ADC_HandleType.Init.ScanConvMode=ADC_SCAN_DISABLE;  //扫描模式:失能ADC_HandleType.Init.ContinuousConvMode=DISABLE;     //连续模式:DISABLE(单次模式)ADC_HandleType.Init.DiscontinuousConvMode=DISABLE;   //规则组的间断模式   ADC_HandleType.Init.ExternalTrigConv=ADC_EXTERNALTRIGCONV_T3_TRGO;//触发方式:TIM3的TRGO事件HAL_ADC_Init(&ADC_HandleType);ADC_Channel.Channel=ADC_CHANNEL_2;     //通道编号ADC_Channel.Rank=ADC_REGULAR_RANK_1;     //排名ADC_Channel.SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel);HAL_ADCEx_Calibration_Start(&ADC_HandleType);                   //自校准HAL_ADC_Start_DMA(&ADC_HandleType,(uint32_t*)DMA_buff,10);  //DMA将连续读取10个ADC转换结果并存储到DMA_buff中。
}
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{if(hadc->Instance==ADC1){__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_ADC1_CLK_ENABLE();__HAL_RCC_DMA1_CLK_ENABLE();GPIO_InitTypeDef GPIO_InitType;//模拟输入不用设置上下拉电阻GPIO_InitType.Mode=GPIO_MODE_ANALOG;  //模拟输入GPIO_InitType.Pin=GPIO_PIN_2;HAL_GPIO_Init(GPIOA,&GPIO_InitType); //DMA配置:方向寄存器(外设)-->数组(内存)DMA_Handle.Instance=DMA1_Channel1;DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY;  //传输方向:寄存器(外设)->数组(内存)DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE;   //寄存器(外设)是否递增加DMA_Handle.Init.MemInc=DMA_MINC_ENABLE;      //数组(内存)是否递增加DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD;    //外设数据宽度(半字=2个字节)DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_HALFWORD;      //数组(内存)数据宽度DMA_Handle.Init.Mode=DMA_CIRCULAR;                         //模式:循环DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle);   //或者下面的写法__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle);  //链接//DMA的配置HAL_DMA_Init(&DMA_Handle);HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,1,0);HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);}
}//void ADC1_2_IRQHandler()
//{
//	HAL_ADC_IRQHandler(&ADC_HandleType);
//}void DMA1_Channel1_IRQHandler()
{HAL_DMA_IRQHandler(&DMA_Handle);
}DMA将连续读取10个ADC转换结果并存储到DMA_buff中,后进入中断
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{			uint32_t num;uint8_t i;if(hadc->Instance==ADC1){num=0;for(i=0;i<10;i++){num+=DMA_buff[i];}printf("ADC1_IN0:%f V \r\n",(num/10.0)*(3.3/4096.0));   //串口1输出数字量}
}#include "stm32f1xx_hal.h"
#include "pwm.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
//输入捕获功能
TIM_HandleTypeDef HandleTIMXCHX;
//TIM1的CC1事件
void IC_TIMX_CHX_init(uint16_t arr,uint16_t psc)
{TIM_MasterConfigTypeDef TIM_MasterConfig={0};HandleTIMXCHX.Instance=TIM3;   //基地址HandleTIMXCHX.Init.Period=arr;HandleTIMXCHX.Init.Prescaler=psc;HandleTIMXCHX.Init.CounterMode=TIM_COUNTERMODE_UP;   //向上计数HandleTIMXCHX.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;   //设置自动重载值 预装载使能位HandleTIMXCHX.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;   //设置分频因子HAL_TIM_Base_Init(&HandleTIMXCHX);//清除跟新中断标志位__HAL_TIM_CLEAR_FLAG(&HandleTIMXCHX,TIM_FLAG_UPDATE);TIM_MasterConfig.MasterOutputTrigger=TIM_TRGO_UPDATE;TIM_MasterConfig.MasterSlaveMode=TIM_MASTERSLAVEMODE_DISABLE;  //主从模式:关闭HAL_TIMEx_MasterConfigSynchronization(&HandleTIMXCHX,&TIM_MasterConfig);HAL_TIM_Base_Start_IT(&HandleTIMXCHX);}void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim)
{if(htim->Instance==TIM3){__HAL_RCC_TIM3_CLK_ENABLE();HAL_NVIC_SetPriority(TIM3_IRQn, 1, 3);              HAL_NVIC_EnableIRQ(TIM3_IRQn);                     	}
}/* 定时器1中断服务函数 */
void TIM3_IRQHandler(void)
{HAL_TIM_IRQHandler(&HandleTIMXCHX);  /* 定时器HAL库共用处理函数 */}
//定时器的CC通道的输出比较
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{if(htim->Instance==TIM3){printf("定时器3TRGO事件\r\n");		}
}

定时器配置TRGO事件需要使用到

HAL_StatusTypeDef HAL_TIMEx_MasterConfigSynchronization(TIM_HandleTypeDef *htim,
                                                        TIM_MasterConfigTypeDef *sMasterConfig)

在stm32f1xx hal tim ex.c文件里面。

G:规则组 外部触发 定时器3的TRGO 捕获事件

        这个捕获只能发生在通道1上。   

关于复用:

         ADC1_IN6引脚在PA6上面,我们的定时器的通道6也在PA6上面,(PA6是在通道6),为了防止我们在做扫描模式的时候引脚冲突,我们在这里直接把他引脚重新定义为PB4上面;--这个实验做不做复用都一样,后面的扫描模式的使用。

int main(void)
{uint8_t res=0;HAL_Init();                         /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */delay_init(72);                     /* 延时初始化 */Uart_Init(115200);ADC1_Init();  IC_TIMX_CHX_init(0XFFFF-1,36000-1);   //T=((ARR+1)*(PSC+1)) / 72 000 000;while (1){		}}
#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"ADC_HandleTypeDef ADC_HandleType;
DMA_HandleTypeDef DMA_Handle;uint16_t DMA_buff[10];
void ADC1_Init(void)
{ADC_ChannelConfTypeDef ADC_Channel;ADC_HandleType.Instance=ADC1;ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐ADC_HandleType.Init.ScanConvMode=ADC_SCAN_DISABLE;  //扫描模式:失能ADC_HandleType.Init.ContinuousConvMode=DISABLE;     //连续模式:DISABLE(单次模式)ADC_HandleType.Init.DiscontinuousConvMode=DISABLE;   //规则组的间断模式   ADC_HandleType.Init.ExternalTrigConv=ADC_EXTERNALTRIGCONV_T3_TRGO;//触发方式:TIM3的TRGO事件HAL_ADC_Init(&ADC_HandleType);ADC_Channel.Channel=ADC_CHANNEL_2;     //通道编号ADC_Channel.Rank=ADC_REGULAR_RANK_1;     //排名ADC_Channel.SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel);HAL_ADCEx_Calibration_Start(&ADC_HandleType);                   //自校准HAL_ADC_Start_DMA(&ADC_HandleType,(uint32_t*)DMA_buff,10);  //DMA将连续读取10个ADC转换结果并存储到DMA_buff中。}
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{if(hadc->Instance==ADC1){__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_ADC1_CLK_ENABLE();__HAL_RCC_DMA1_CLK_ENABLE();GPIO_InitTypeDef GPIO_InitType;//模拟输入不用设置上下拉电阻GPIO_InitType.Mode=GPIO_MODE_ANALOG;  //模拟输入GPIO_InitType.Pin=GPIO_PIN_2;HAL_GPIO_Init(GPIOA,&GPIO_InitType); //DMA配置:方向寄存器(外设)-->数组(内存)DMA_Handle.Instance=DMA1_Channel1;DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY;  //传输方向:寄存器(外设)->数组(内存)DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE;   //寄存器(外设)是否递增加DMA_Handle.Init.MemInc=DMA_MINC_ENABLE;      //数组(内存)是否递增加DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD;    //外设数据宽度(半字=2个字节)DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_HALFWORD;      //数组(内存)数据宽度DMA_Handle.Init.Mode=DMA_CIRCULAR;                         //模式:循环DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle);   //或者下面的写法__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle);  //链接//DMA的配置HAL_DMA_Init(&DMA_Handle);HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,4,0);HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);}
}//void ADC1_2_IRQHandler()
//{
//	HAL_ADC_IRQHandler(&ADC_HandleType);//}void DMA1_Channel1_IRQHandler()
{HAL_DMA_IRQHandler(&DMA_Handle);}DMA将连续读取10个ADC转换结果并存储到DMA_buff中,后进入中断
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{			uint32_t num;uint8_t i;if(hadc->Instance==ADC1){num=0;for(i=0;i<10;i++){num+=DMA_buff[i];}printf("ADC1_IN0:%f V \r\n",(num/10.0)*(3.3/4096.0));   //串口1输出数字量}
}#include "stm32f1xx_hal.h"
#include "pwm.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
//输入捕获功能
TIM_HandleTypeDef HandleTIMXCHX;
//TIM1的CC1事件
void IC_TIMX_CHX_init(uint16_t arr,uint16_t psc)
{TIM_MasterConfigTypeDef TIM_MasterConfig={0};TIM_IC_InitTypeDef TIM_IC_Init={0};HandleTIMXCHX.Instance=TIM3;   //基地址HandleTIMXCHX.Init.Period=arr;HandleTIMXCHX.Init.Prescaler=psc;HandleTIMXCHX.Init.CounterMode=TIM_COUNTERMODE_UP;   //向上计数HandleTIMXCHX.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;   //设置自动重载值 预装载使能位HandleTIMXCHX.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;   //设置分频因子HAL_TIM_IC_Init(&HandleTIMXCHX);//清除跟新中断标志位__HAL_TIM_CLEAR_FLAG(&HandleTIMXCHX,TIM_FLAG_UPDATE);TIM_MasterConfig.MasterOutputTrigger=TIM_TRGO_OC1;             //主定时器通道1捕获时发送信号TIM_MasterConfig.MasterSlaveMode=TIM_MASTERSLAVEMODE_DISABLE;  //主从模式:关闭HAL_TIMEx_MasterConfigSynchronization(&HandleTIMXCHX,&TIM_MasterConfig);TIM_IC_Init.ICFilter=0x8;TIM_IC_Init.ICPolarity=TIM_ICPOLARITY_RISING;  //极性:上升沿TIM_IC_Init.ICSelection=TIM_ICSELECTION_DIRECTTI; //直连TIM_IC_Init.ICPrescaler=TIM_ICPSC_DIV1;HAL_TIM_IC_ConfigChannel(&HandleTIMXCHX,&TIM_IC_Init,TIM_CHANNEL_1);HAL_TIM_IC_Start_IT(&HandleTIMXCHX,TIM_CHANNEL_1);}void HAL_TIM_IC_MspInit(TIM_HandleTypeDef *htim)
{if(htim->Instance==TIM3){__HAL_RCC_GPIOB_CLK_ENABLE();                   //打开B口时钟__HAL_RCC_TIM3_CLK_ENABLE();                    //打开定时器3的时钟__HAL_RCC_AFIO_CLK_ENABLE();                    //应为要重映射,所以打开AFIO时钟__HAL_AFIO_REMAP_TIM3_PARTIAL();                //定时器3重映射__HAL_AFIO_REMAP_SWJ_NOJTAG();                  //关闭JTAG,保留SW,释放PB4//重映射CH1为PB4GPIO_InitTypeDef GPIO_InitType;GPIO_InitType.Pin = GPIO_PIN_4;                 //配置PIN4GPIO_InitType.Mode = GPIO_MODE_AF_INPUT;        //复用功能 输入方向GPIO_InitType.Pull = GPIO_PULLDOWN;             //开启IO口内部的下拉电阻HAL_GPIO_Init(GPIOB,&GPIO_InitType);            //配置PB4HAL_NVIC_SetPriority(TIM3_IRQn,3,0);            //定时器3的中断优先级HAL_NVIC_EnableIRQ(TIM3_IRQn);                  //开定时器3的中断}
}/* 定时器1中断服务函数 */
void TIM3_IRQHandler(void)
{HAL_TIM_IRQHandler(&HandleTIMXCHX);  /* 定时器HAL库共用处理函数 */
}//定时器的CC通道的输出比较
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{if(htim->Instance==TIM3){if(htim->Channel==HAL_TIM_ACTIVE_CHANNEL_1){printf("定时器3通道1上升沿捕获成功\r\n");		}}
}

H:如何一次触发信号使得DMA完成转换

        上面的都为每发生一次事件(更新事件或者为捕获事件)都会触发一次AD的转化,不过我们开启了DMA的转运,每次ADC的转化DMA会把数据拿到我们指定的内存(数组中),一共转化10次ADC,才会触发一次DMA中断。所以我们需要按下10次按键才会触发一次数据的打印。

        这个代码解决这个问题,按一次,打印一次。不过需要开启连续转化模式。

HAL_ADC_Start_DMA(&ADC_HandleType,(uint32_t*)DMA_buff,10);  

int main(void)
{uint8_t res=0;HAL_Init();                         /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */delay_init(72);                     /* 延时初始化 */Uart_Init(115200);IC_TIMX_CHX_init(0XFFFF-1,36000-1);   //T=((ARR+1)*(PSC+1)) / 72 000 000;ADC1_Init();  while (1){		}#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"
#include "TIM.h"
ADC_HandleTypeDef ADC_HandleType;
DMA_HandleTypeDef DMA_Handle;uint16_t DMA_buff[10];
void ADC1_Init(void)
{ADC_ChannelConfTypeDef ADC_Channel;ADC_HandleType.Instance=ADC1;ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐ADC_HandleType.Init.ScanConvMode=ADC_SCAN_DISABLE;  //扫描模式:失能ADC_HandleType.Init.ContinuousConvMode=ENABLE;     //连续模式:DISABLE(单次模式)  ENABLEADC_HandleType.Init.DiscontinuousConvMode=DISABLE;   //规则组的间断模式   ADC_HandleType.Init.ExternalTrigConv=ADC_EXTERNALTRIGCONV_T3_TRGO;//触发方式:TIM3的TRGO事件HAL_ADC_Init(&ADC_HandleType);ADC_Channel.Channel=ADC_CHANNEL_2;     //通道编号ADC_Channel.Rank=ADC_REGULAR_RANK_1;     //排名ADC_Channel.SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel);HAL_ADCEx_Calibration_Start(&ADC_HandleType);                   //自校准HAL_ADC_Start_DMA(&ADC_HandleType,(uint32_t*)DMA_buff,10);  //DMA将连续读取10个ADC转换结果并存储到DMA_buff中。}
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{if(hadc->Instance==ADC1){__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_ADC1_CLK_ENABLE();__HAL_RCC_DMA1_CLK_ENABLE();GPIO_InitTypeDef GPIO_InitType;//模拟输入不用设置上下拉电阻GPIO_InitType.Mode=GPIO_MODE_ANALOG;  //模拟输入GPIO_InitType.Pin=GPIO_PIN_2;HAL_GPIO_Init(GPIOA,&GPIO_InitType); //DMA配置:方向寄存器(外设)-->数组(内存)DMA_Handle.Instance=DMA1_Channel1;DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY;  //传输方向:寄存器(外设)->数组(内存)DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE;   //寄存器(外设)是否递增加DMA_Handle.Init.MemInc=DMA_MINC_ENABLE;      //数组(内存)是否递增加DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD;    //外设数据宽度(半字=2个字节)DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_HALFWORD;      //数组(内存)数据宽度DMA_Handle.Init.Mode=DMA_CIRCULAR;                         //模式:循环DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle);   //或者下面的写法__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle);  //链接//DMA的配置HAL_DMA_Init(&DMA_Handle);HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,4,0);HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);}
}//void ADC1_2_IRQHandler()
//{
//	HAL_ADC_IRQHandler(&ADC_HandleType);//}void DMA1_Channel1_IRQHandler()
{HAL_DMA_IRQHandler(&DMA_Handle);}DMA将连续读取10个ADC转换结果并存储到DMA_buff中,后进入中断
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{			uint32_t num;uint8_t i;if(hadc->Instance==ADC1){//ADC_HandleType.Instance->CR2 &=~ ADC_CR2_CONT;num=0;for(i=0;i<10;i++){num+=DMA_buff[i];}printf("ADC1_IN0:%f V \r\n",(num/10.0)*(3.3/4096.0));   //串口1输出数字量hadc->Instance->CR2 |= ADC_CR2_CONT;}
}
#include "stm32f1xx_hal.h"
#include "pwm.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "ADC.h"//输入捕获功能
TIM_HandleTypeDef HandleTIMXCHX;
//TIM1的CC1事件
void IC_TIMX_CHX_init(uint16_t arr,uint16_t psc)
{TIM_MasterConfigTypeDef TIM_MasterConfig={0};TIM_IC_InitTypeDef TIM_IC_Init={0};HandleTIMXCHX.Instance=TIM3;   //基地址HandleTIMXCHX.Init.Period=arr;HandleTIMXCHX.Init.Prescaler=psc;HandleTIMXCHX.Init.CounterMode=TIM_COUNTERMODE_UP;   //向上计数HandleTIMXCHX.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;   //设置自动重载值 预装载使能位HandleTIMXCHX.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;   //设置分频因子HAL_TIM_IC_Init(&HandleTIMXCHX);//清除跟新中断标志位__HAL_TIM_CLEAR_FLAG(&HandleTIMXCHX,TIM_FLAG_UPDATE);TIM_MasterConfig.MasterOutputTrigger=TIM_TRGO_OC1;             //主定时器通道1捕获时发送信号TIM_MasterConfig.MasterSlaveMode=TIM_MASTERSLAVEMODE_DISABLE;  //主从模式:关闭HAL_TIMEx_MasterConfigSynchronization(&HandleTIMXCHX,&TIM_MasterConfig);TIM_IC_Init.ICFilter=0x8;TIM_IC_Init.ICPolarity=TIM_ICPOLARITY_RISING;  //极性:上升沿TIM_IC_Init.ICSelection=TIM_ICSELECTION_DIRECTTI; //直连TIM_IC_Init.ICPrescaler=TIM_ICPSC_DIV1;HAL_TIM_IC_ConfigChannel(&HandleTIMXCHX,&TIM_IC_Init,TIM_CHANNEL_1);HAL_TIM_IC_Start_IT(&HandleTIMXCHX,TIM_CHANNEL_1);}void HAL_TIM_IC_MspInit(TIM_HandleTypeDef *htim)
{if(htim->Instance==TIM3){__HAL_RCC_GPIOB_CLK_ENABLE();                   //打开B口时钟__HAL_RCC_TIM3_CLK_ENABLE();                    //打开定时器3的时钟__HAL_RCC_AFIO_CLK_ENABLE();                    //应为要重映射,所以打开AFIO时钟__HAL_AFIO_REMAP_TIM3_PARTIAL();                //定时器3重映射__HAL_AFIO_REMAP_SWJ_NOJTAG();                  //关闭JTAG,保留SW,释放PB4//重映射CH1为PB4GPIO_InitTypeDef GPIO_InitType;GPIO_InitType.Pin = GPIO_PIN_4;                 //配置PIN4GPIO_InitType.Mode = GPIO_MODE_AF_INPUT;        //复用功能 输入方向GPIO_InitType.Pull = GPIO_PULLDOWN;             //开启IO口内部的下拉电阻HAL_GPIO_Init(GPIOB,&GPIO_InitType);            //配置PB4HAL_NVIC_SetPriority(TIM3_IRQn,3,0);            //定时器3的中断优先级HAL_NVIC_EnableIRQ(TIM3_IRQn);                  //开定时器3的中断}
}/* 定时器1中断服务函数 */
void TIM3_IRQHandler(void)
{HAL_TIM_IRQHandler(&HandleTIMXCHX);  /* 定时器HAL库共用处理函数 */}//定时器的CC通道的输出比较
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{if(htim->Instance==TIM3){if(htim->Channel==HAL_TIM_ACTIVE_CHANNEL_1){printf("定时器3通道1上升沿捕获成功\r\n");	ADC_HandleType.Instance->CR2 &=~ ADC_CR2_CONT;}}
}

在主函数中他TIM定时器的初始化需要在ADC初始化前面。否则会发送未知的错误。

I:规则组 外部触发 EXTI11 启动转化

int main(void)
{uint8_t res=0;HAL_Init();                         /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */delay_init(72);                     /* 延时初始化 */Uart_Init(115200);ADC1_Init();  while (1){		}}
#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"
#include "TIM.h"
ADC_HandleTypeDef ADC_HandleType;
DMA_HandleTypeDef DMA_Handle;uint16_t DMA_buff[10];
void ADC1_Init(void)
{ADC_ChannelConfTypeDef ADC_Channel;ADC_HandleType.Instance=ADC1;ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐ADC_HandleType.Init.ScanConvMode=ADC_SCAN_DISABLE;  //扫描模式:失能ADC_HandleType.Init.ContinuousConvMode=ENABLE;     //连续模式:DISABLE(单次模式)  ENABLEADC_HandleType.Init.DiscontinuousConvMode=DISABLE;   //规则组的间断模式   ADC_HandleType.Init.ExternalTrigConv=ADC_EXTERNALTRIGCONV_EXT_IT11;//触发方式:EXT_IT11HAL_ADC_Init(&ADC_HandleType);ADC_Channel.Channel=ADC_CHANNEL_2;     //通道编号ADC_Channel.Rank=ADC_REGULAR_RANK_1;     //排名ADC_Channel.SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel);HAL_ADCEx_Calibration_Start(&ADC_HandleType);                   //自校准HAL_ADC_Start_DMA(&ADC_HandleType,(uint32_t*)DMA_buff,10);  //DMA将连续读取10个ADC转换结果并存储到DMA_buff中。}
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{if(hadc->Instance==ADC1){__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_GPIOB_CLK_ENABLE();__HAL_RCC_ADC1_CLK_ENABLE();__HAL_RCC_DMA1_CLK_ENABLE();GPIO_InitTypeDef GPIO_InitType;//模拟输入不用设置上下拉电阻GPIO_InitType.Mode=GPIO_MODE_ANALOG;  //模拟输入GPIO_InitType.Pin=GPIO_PIN_2;HAL_GPIO_Init(GPIOA,&GPIO_InitType); GPIO_InitType.Mode=GPIO_MODE_IT_RISING;  //模拟输入GPIO_InitType.Pin=GPIO_PIN_11;GPIO_InitType.Pull=GPIO_PULLUP;HAL_GPIO_Init(GPIOB,&GPIO_InitType); //DMA配置:方向寄存器(外设)-->数组(内存)DMA_Handle.Instance=DMA1_Channel1;DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY;  //传输方向:寄存器(外设)->数组(内存)DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE;   //寄存器(外设)是否递增加DMA_Handle.Init.MemInc=DMA_MINC_ENABLE;      //数组(内存)是否递增加DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD;    //外设数据宽度(半字=2个字节)DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_HALFWORD;      //数组(内存)数据宽度DMA_Handle.Init.Mode=DMA_CIRCULAR;                         //模式:循环DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle);   //或者下面的写法__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle);  //链接//DMA的配置HAL_DMA_Init(&DMA_Handle);HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,4,0);HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);HAL_NVIC_SetPriority(EXTI15_10_IRQn,4,0);HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);}
}void DMA1_Channel1_IRQHandler()
{HAL_DMA_IRQHandler(&DMA_Handle);}void EXTI15_10_IRQHandler()
{HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_11);
}DMA将连续读取10个ADC转换结果并存储到DMA_buff中,后进入中断
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{			uint32_t num;uint8_t i;if(hadc->Instance==ADC1){num=0;for(i=0;i<10;i++){num+=DMA_buff[i];}printf("ADC1_IN0:%f V \r\n",(num/10.0)*(3.3/4096.0));   //串口1输出数字量hadc->Instance->CR2 |= ADC_CR2_CONT;}
}//EXT_IT11的中断回调函数
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{if(GPIO_Pin==GPIO_PIN_11){			printf("PB11产生中断\r\n");ADC_HandleType.Instance->CR2 &=~ ADC_CR2_CONT;}}

                                           

 因为ADC的触发方式配置为:

        ADC_HandleType.Init.ExternalTrigConv=ADC_EXTERNALTRIGCONV_EXT_IT11;//触发方式:EXT_IT11中断

所以在配置PB11引脚的时候,需要注意(只能在下面选):

  PB11不能使用:

GPIO_MODE_INPUT
GPIO_MODE_AF_INPUT
GPIO_MODE_ANALOG

                                        规则组 扫描模式

A:规则组10通道扫描 单次转换DMA方式

因为开启了扫描模式,在扫描模式中开启的10个通道,一个组中的10个通道全部转化完毕,中断标志位才会置位。然而我们只有一个数据寄存器(DR),会导致我们的数据出现覆盖。所以不能使用中断或者轮询

int main(void)
{uint8_t res=0;HAL_Init();                         /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */delay_init(72);                     /* 延时初始化 */Uart_Init(115200);ADC1_Init();  while (1){		}}#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"
#include "TIM.h"ADC_HandleTypeDef ADC_HandleType;
DMA_HandleTypeDef DMA_Handle;
ADC_ChannelConfTypeDef ADC_Channel[10];uint16_t DMA_buff[10];
void ADC1_Init(void)
{ADC_HandleType.Instance=ADC1;ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐ADC_HandleType.Init.ScanConvMode=ADC_SCAN_ENABLE;  //扫描模式:使能ADC_HandleType.Init.NbrOfConversion=15;            //扫描模式下规则组的数量ADC_HandleType.Init.ContinuousConvMode=DISABLE;     //连续模式:DISABLE(单次模式)  ADC_HandleType.Init.DiscontinuousConvMode=DISABLE;   //规则组的间断模式   ADC_HandleType.Init.ExternalTrigConv=ADC_SOFTWARE_START;//触发方式:EXT_IT11HAL_ADC_Init(&ADC_HandleType);ADC_Channel[0].Channel=ADC_CHANNEL_0;     //通道编号ADC_Channel[0].Rank=ADC_REGULAR_RANK_1;     //排名ADC_Channel[0].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[0]);ADC_Channel[1].Channel=ADC_CHANNEL_1;     //通道编号ADC_Channel[1].Rank=ADC_REGULAR_RANK_2;     //排名ADC_Channel[1].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[1]);ADC_Channel[2].Channel=ADC_CHANNEL_2;     //通道编号ADC_Channel[2].Rank=ADC_REGULAR_RANK_3;     //排名ADC_Channel[2].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[2]);ADC_Channel[3].Channel=ADC_CHANNEL_3;     //通道编号ADC_Channel[3].Rank=ADC_REGULAR_RANK_4;     //排名ADC_Channel[3].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&	ADC_Channel[3]);ADC_Channel[4].Channel=ADC_CHANNEL_4;     //通道编号ADC_Channel[4].Rank=ADC_REGULAR_RANK_5;     //排名ADC_Channel[4].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[4]);ADC_Channel[5].Channel=ADC_CHANNEL_5;     //通道编号ADC_Channel[5].Rank=ADC_REGULAR_RANK_6;     //排名ADC_Channel[5].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[5]);ADC_Channel[6].Channel=ADC_CHANNEL_6;     //通道编号ADC_Channel[6].Rank=ADC_REGULAR_RANK_7;     //排名ADC_Channel[6].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[6]);ADC_Channel[7].Channel=ADC_CHANNEL_7;     //通道编号ADC_Channel[7].Rank=ADC_REGULAR_RANK_8;     //排名ADC_Channel[7].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[7]);ADC_Channel[8].Channel=ADC_CHANNEL_8;     //通道编号ADC_Channel[8].Rank=ADC_REGULAR_RANK_9;     //排名ADC_Channel[8].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[8]);ADC_Channel[9].Channel=ADC_CHANNEL_9;     //通道编号ADC_Channel[9].Rank=ADC_REGULAR_RANK_10;     //排名ADC_Channel[9].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[9]);HAL_ADCEx_Calibration_Start(&ADC_HandleType);                   //自校准HAL_ADC_Start_DMA(&ADC_HandleType,(uint32_t*)DMA_buff,10);  //DMA将连续读取10个ADC转换结果并存储到DMA_buff中。}
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{if(hadc->Instance==ADC1){__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_GPIOB_CLK_ENABLE();__HAL_RCC_ADC1_CLK_ENABLE();__HAL_RCC_DMA1_CLK_ENABLE();GPIO_InitTypeDef GPIO_InitType;//模拟输入不用设置上下拉电阻GPIO_InitType.Mode=GPIO_MODE_ANALOG;  //模拟输入GPIO_InitType.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;HAL_GPIO_Init(GPIOA,&GPIO_InitType); GPIO_InitType.Mode=GPIO_MODE_ANALOG;  //模拟输入GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1;HAL_GPIO_Init(GPIOB,&GPIO_InitType); //DMA配置:方向寄存器(外设)-->数组(内存)DMA_Handle.Instance=DMA1_Channel1;DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY;  //传输方向:寄存器(外设)->数组(内存)DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE;   //寄存器(外设)是否递增加DMA_Handle.Init.MemInc=DMA_MINC_ENABLE;      //数组(内存)是否递增加DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD;    //外设数据宽度(半字=2个字节)DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_HALFWORD;      //数组(内存)数据宽度DMA_Handle.Init.Mode=DMA_NORMAL;                         //模式:普通(单次)DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle);   //或者下面的写法__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle);  //链接//DMA的配置HAL_DMA_Init(&DMA_Handle);HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,4,0);HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);}
}void DMA1_Channel1_IRQHandler()
{HAL_DMA_IRQHandler(&DMA_Handle);}DMA将连续读取10个ADC转换结果并存储到DMA_buff中,后进入中断
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{			uint8_t i;if(hadc->Instance==ADC1){for(i=0;i<10;i++){printf("ADC1_IN[%d]:%f V \r\n",i,DMA_buff[i]*(3.3/4096.0));   //串口1输出数字量	}		}
}

B:规则组10通道扫描 连续转换 DMA均值滤波

int main(void)
{uint8_t res=0;HAL_Init();                         /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */delay_init(72);                     /* 延时初始化 */Uart_Init(115200);ADC1_Init();  while (1){		}}#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"
#include "TIM.h"ADC_HandleTypeDef ADC_HandleType;
DMA_HandleTypeDef DMA_Handle;
ADC_ChannelConfTypeDef ADC_Channel[10];uint16_t DMA_buff[100];
void ADC1_Init(void)
{ADC_HandleType.Instance=ADC1;ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐ADC_HandleType.Init.ScanConvMode=ADC_SCAN_ENABLE;  //扫描模式:使能ADC_HandleType.Init.NbrOfConversion=10;            //扫描模式下规则组的数量ADC_HandleType.Init.ContinuousConvMode=ENABLE;     //连续模式:  使能ADC_HandleType.Init.DiscontinuousConvMode=DISABLE;   //规则组的间断模式   ADC_HandleType.Init.ExternalTrigConv=ADC_SOFTWARE_START;//触发方式:软件触发HAL_ADC_Init(&ADC_HandleType);ADC_Channel[0].Channel=ADC_CHANNEL_0;     //通道编号ADC_Channel[0].Rank=ADC_REGULAR_RANK_1;     //排名ADC_Channel[0].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[0]);ADC_Channel[1].Channel=ADC_CHANNEL_1;     //通道编号ADC_Channel[1].Rank=ADC_REGULAR_RANK_2;     //排名ADC_Channel[1].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[1]);ADC_Channel[2].Channel=ADC_CHANNEL_2;     //通道编号ADC_Channel[2].Rank=ADC_REGULAR_RANK_3;     //排名ADC_Channel[2].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[2]);ADC_Channel[3].Channel=ADC_CHANNEL_3;     //通道编号ADC_Channel[3].Rank=ADC_REGULAR_RANK_4;     //排名ADC_Channel[3].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&	ADC_Channel[3]);ADC_Channel[4].Channel=ADC_CHANNEL_4;     //通道编号ADC_Channel[4].Rank=ADC_REGULAR_RANK_5;     //排名ADC_Channel[4].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[4]);ADC_Channel[5].Channel=ADC_CHANNEL_5;     //通道编号ADC_Channel[5].Rank=ADC_REGULAR_RANK_6;     //排名ADC_Channel[5].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[5]);ADC_Channel[6].Channel=ADC_CHANNEL_6;     //通道编号ADC_Channel[6].Rank=ADC_REGULAR_RANK_7;     //排名ADC_Channel[6].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[6]);ADC_Channel[7].Channel=ADC_CHANNEL_7;     //通道编号ADC_Channel[7].Rank=ADC_REGULAR_RANK_8;     //排名ADC_Channel[7].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[7]);ADC_Channel[8].Channel=ADC_CHANNEL_8;     //通道编号ADC_Channel[8].Rank=ADC_REGULAR_RANK_9;     //排名ADC_Channel[8].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[8]);ADC_Channel[9].Channel=ADC_CHANNEL_9;     //通道编号ADC_Channel[9].Rank=ADC_REGULAR_RANK_10;     //排名ADC_Channel[9].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[9]);HAL_ADCEx_Calibration_Start(&ADC_HandleType);                   //自校准//DMA将连续读取100个ADC转换结果并存储到DMA_buff中,并产生DMA中断。HAL_ADC_Start_DMA(&ADC_HandleType,(uint32_t*)DMA_buff,100);  }
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{if(hadc->Instance==ADC1){__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_GPIOB_CLK_ENABLE();__HAL_RCC_ADC1_CLK_ENABLE();__HAL_RCC_DMA1_CLK_ENABLE();GPIO_InitTypeDef GPIO_InitType;//模拟输入不用设置上下拉电阻GPIO_InitType.Mode=GPIO_MODE_ANALOG;  //模拟输入GPIO_InitType.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;HAL_GPIO_Init(GPIOA,&GPIO_InitType); GPIO_InitType.Mode=GPIO_MODE_ANALOG;  //模拟输入GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1;HAL_GPIO_Init(GPIOB,&GPIO_InitType); //DMA配置:方向寄存器(外设)-->数组(内存)DMA_Handle.Instance=DMA1_Channel1;DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY;  //传输方向:寄存器(外设)->数组(内存)DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE;   //寄存器(外设)是否递增加DMA_Handle.Init.MemInc=DMA_MINC_ENABLE;      //数组(内存)是否递增加DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD;    //外设数据宽度(半字=2个字节)DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_HALFWORD;      //数组(内存)数据宽度DMA_Handle.Init.Mode=DMA_CIRCULAR;                         //模式:循环DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle);   //或者下面的写法__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle);  //链接//DMA的配置HAL_DMA_Init(&DMA_Handle);HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,4,0);HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);}
}void DMA1_Channel1_IRQHandler()
{HAL_DMA_IRQHandler(&DMA_Handle);}DMA将连续读取10个ADC转换结果并存储到DMA_buff中,后进入中断
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{			uint8_t i,j;uint32_t num;if(hadc->Instance==ADC1){for(i=0;i<10;i++){num=0;for(j=0;j<10;j++){num+=DMA_buff[j*10+i];}printf("ADC1_IN[%d]:%f V \r\n",i,(num/10.0)*(3.3/4096.0));   //串口1输出数字量	}		}
}

 C:规则组10通道扫描定时器CC事件 触发转换

一次上升沿可以触发一次扫描(组),一个组中开启的10个通道。所以10次上升沿可以触发AD转化100次。------次DMA完成中断,需要10次的周期时间 

int main(void)
{uint8_t res=0;HAL_Init();                         /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */delay_init(72);                     /* 延时初始化 */Uart_Init(115200);IC_TIMX_CHX_init(3600-1,7200-1);   //T=((ARR+1)*(PSC+1)) / 72 000 000;  t=0.36s    10t=3.6sADC1_Init();  while (1){		}}
#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"
#include "TIM.h"ADC_HandleTypeDef ADC_HandleType;
DMA_HandleTypeDef DMA_Handle;
ADC_ChannelConfTypeDef ADC_Channel[10];uint16_t DMA_buff[100];
void ADC1_Init(void)
{ADC_HandleType.Instance=ADC1;ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐ADC_HandleType.Init.ScanConvMode=ADC_SCAN_ENABLE;  //扫描模式:使能ADC_HandleType.Init.NbrOfConversion=10;            //扫描模式下规则组的数量ADC_HandleType.Init.ContinuousConvMode=DISABLE;     //连续模式:  失能ADC_HandleType.Init.DiscontinuousConvMode=DISABLE;   //规则组的间断模式   ADC_HandleType.Init.ExternalTrigConv=ADC_EXTERNALTRIGCONV_T2_CC2;//触发方式:TIM2的CC2(通道2)HAL_ADC_Init(&ADC_HandleType);ADC_Channel[0].Channel=ADC_CHANNEL_0;     //通道编号ADC_Channel[0].Rank=ADC_REGULAR_RANK_1;     //排名ADC_Channel[0].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[0]);ADC_Channel[1].Channel=ADC_CHANNEL_1;     //通道编号ADC_Channel[1].Rank=ADC_REGULAR_RANK_2;     //排名ADC_Channel[1].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[1]);ADC_Channel[2].Channel=ADC_CHANNEL_2;     //通道编号ADC_Channel[2].Rank=ADC_REGULAR_RANK_3;     //排名ADC_Channel[2].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[2]);ADC_Channel[3].Channel=ADC_CHANNEL_3;     //通道编号ADC_Channel[3].Rank=ADC_REGULAR_RANK_4;     //排名ADC_Channel[3].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&	ADC_Channel[3]);ADC_Channel[4].Channel=ADC_CHANNEL_4;     //通道编号ADC_Channel[4].Rank=ADC_REGULAR_RANK_5;     //排名ADC_Channel[4].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[4]);ADC_Channel[5].Channel=ADC_CHANNEL_5;     //通道编号ADC_Channel[5].Rank=ADC_REGULAR_RANK_6;     //排名ADC_Channel[5].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[5]);ADC_Channel[6].Channel=ADC_CHANNEL_6;     //通道编号ADC_Channel[6].Rank=ADC_REGULAR_RANK_7;     //排名ADC_Channel[6].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[6]);ADC_Channel[7].Channel=ADC_CHANNEL_7;     //通道编号ADC_Channel[7].Rank=ADC_REGULAR_RANK_8;     //排名ADC_Channel[7].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[7]);ADC_Channel[8].Channel=ADC_CHANNEL_8;     //通道编号ADC_Channel[8].Rank=ADC_REGULAR_RANK_9;     //排名ADC_Channel[8].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[8]);ADC_Channel[9].Channel=ADC_CHANNEL_9;     //通道编号ADC_Channel[9].Rank=ADC_REGULAR_RANK_10;     //排名ADC_Channel[9].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[9]);HAL_ADCEx_Calibration_Start(&ADC_HandleType);                   //自校准//DMA将连续读取100个ADC转换结果并存储到DMA_buff中,并产生DMA中断。HAL_ADC_Start_DMA(&ADC_HandleType,(uint32_t*)DMA_buff,100);  }
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{if(hadc->Instance==ADC1){__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_GPIOB_CLK_ENABLE();__HAL_RCC_ADC1_CLK_ENABLE();__HAL_RCC_DMA1_CLK_ENABLE();GPIO_InitTypeDef GPIO_InitType;//模拟输入不用设置上下拉电阻GPIO_InitType.Mode=GPIO_MODE_ANALOG;  //模拟输入GPIO_InitType.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;HAL_GPIO_Init(GPIOA,&GPIO_InitType); GPIO_InitType.Mode=GPIO_MODE_ANALOG;  //模拟输入GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1;HAL_GPIO_Init(GPIOB,&GPIO_InitType); //DMA配置:方向寄存器(外设)-->数组(内存)DMA_Handle.Instance=DMA1_Channel1;DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY;  //传输方向:寄存器(外设)->数组(内存)DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE;   //寄存器(外设)是否递增加DMA_Handle.Init.MemInc=DMA_MINC_ENABLE;      //数组(内存)是否递增加DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD;    //外设数据宽度(半字=2个字节)DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_HALFWORD;      //数组(内存)数据宽度DMA_Handle.Init.Mode=DMA_CIRCULAR;                         //模式:循环DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle);   //或者下面的写法__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle);  //链接//DMA的配置HAL_DMA_Init(&DMA_Handle);HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,4,0);HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);}
}void DMA1_Channel1_IRQHandler()
{HAL_DMA_IRQHandler(&DMA_Handle);}DMA将连续读取10个ADC转换结果并存储到DMA_buff中,后进入中断
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{			uint8_t i,j;uint32_t num;if(hadc->Instance==ADC1){for(i=0;i<10;i++){num=0;for(j=0;j<10;j++){num+=DMA_buff[j*10+i];}printf("ADC1_IN[%d]:%f V \r\n",i,(num/10.0)*(3.3/4096.0));   //串口1输出数字量	}		}
}#include "stm32f1xx_hal.h"
#include "pwm.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "ADC.h"//输入捕获功能
TIM_HandleTypeDef HandleTIMXCHX;
//TIM1的CC1事件
void IC_TIMX_CHX_init(uint16_t arr,uint16_t psc)
{TIM_OC_InitTypeDef TIM_OC_Init={0};HandleTIMXCHX.Instance=TIM2;   //基地址HandleTIMXCHX.Init.Period=arr;HandleTIMXCHX.Init.Prescaler=psc;HandleTIMXCHX.Init.CounterMode=TIM_COUNTERMODE_UP;   //向上计数HandleTIMXCHX.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;   //设置自动重载值 预装载使能位HandleTIMXCHX.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;   //设置分频因子HAL_TIM_OC_Init(&HandleTIMXCHX);//清除跟新中断标志位__HAL_TIM_CLEAR_FLAG(&HandleTIMXCHX,TIM_FLAG_UPDATE);TIM_OC_Init.OCMode=TIM_OCMODE_PWM1;TIM_OC_Init.Pulse=100;    //比较值(CCR)TIM_OC_Init.OCPolarity=TIM_OCPOLARITY_LOW;//有效值  :PWM1:CNT<CCR输出有效电平  TIM_OC_Init.OCFastMode = TIM_OCFAST_DISABLE;    HAL_TIM_OC_ConfigChannel(&HandleTIMXCHX, &TIM_OC_Init,TIM_CHANNEL_2);HAL_TIM_OC_Start_IT(&HandleTIMXCHX,TIM_CHANNEL_2);}void HAL_TIM_OC_MspInit(TIM_HandleTypeDef *htim)
{if(htim->Instance==TIM2){__HAL_RCC_TIM2_CLK_ENABLE();                    //打开定时器3的时钟//信号为内部触发所以,定时器2_CH2引脚可以使用初始化HAL_NVIC_SetPriority(TIM2_IRQn,3,0);            //定时器3的中断优先级HAL_NVIC_EnableIRQ(TIM2_IRQn);                  //开定时器3的中断}
}/* 定时器1中断服务函数 */
void TIM2_IRQHandler(void)
{HAL_TIM_IRQHandler(&HandleTIMXCHX);  /* 定时器HAL库共用处理函数 */}//定时器的CC通道的输出比较
void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim)
{if(htim->Instance==TIM2){if(htim->Channel==HAL_TIM_ACTIVE_CHANNEL_2){printf("定时器2通道2更新\r\n");	}}
}

D:规则组 10通道扫描 定时器3 TRGO更新事件 触发转换

int main(void)
{uint8_t res=0;HAL_Init();                         /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */delay_init(72);                     /* 延时初始化 */Uart_Init(115200);IC_TIMX_CHX_init(3600-1,7200-1);   //T=((ARR+1)*(PSC+1)) / 72 000 000;  t=0.36s    10t=3.6sADC1_Init();  while (1){		}}
#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"
#include "TIM.h"ADC_HandleTypeDef ADC_HandleType;
DMA_HandleTypeDef DMA_Handle;
ADC_ChannelConfTypeDef ADC_Channel[10];uint16_t DMA_buff[100];
void ADC1_Init(void)
{ADC_HandleType.Instance=ADC1;ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐ADC_HandleType.Init.ScanConvMode=ADC_SCAN_ENABLE;  //扫描模式:使能ADC_HandleType.Init.NbrOfConversion=10;            //扫描模式下规则组的数量ADC_HandleType.Init.ContinuousConvMode=DISABLE;     //连续模式:  失能ADC_HandleType.Init.DiscontinuousConvMode=DISABLE;   //规则组的间断模式   ADC_HandleType.Init.ExternalTrigConv=ADC_EXTERNALTRIGCONV_T3_TRGO;//触发方式:TIM3的TRGO事件HAL_ADC_Init(&ADC_HandleType);ADC_Channel[0].Channel=ADC_CHANNEL_0;     //通道编号ADC_Channel[0].Rank=ADC_REGULAR_RANK_1;     //排名ADC_Channel[0].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[0]);ADC_Channel[1].Channel=ADC_CHANNEL_1;     //通道编号ADC_Channel[1].Rank=ADC_REGULAR_RANK_2;     //排名ADC_Channel[1].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[1]);ADC_Channel[2].Channel=ADC_CHANNEL_2;     //通道编号ADC_Channel[2].Rank=ADC_REGULAR_RANK_3;     //排名ADC_Channel[2].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[2]);ADC_Channel[3].Channel=ADC_CHANNEL_3;     //通道编号ADC_Channel[3].Rank=ADC_REGULAR_RANK_4;     //排名ADC_Channel[3].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&	ADC_Channel[3]);ADC_Channel[4].Channel=ADC_CHANNEL_4;     //通道编号ADC_Channel[4].Rank=ADC_REGULAR_RANK_5;     //排名ADC_Channel[4].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[4]);ADC_Channel[5].Channel=ADC_CHANNEL_5;     //通道编号ADC_Channel[5].Rank=ADC_REGULAR_RANK_6;     //排名ADC_Channel[5].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[5]);ADC_Channel[6].Channel=ADC_CHANNEL_6;     //通道编号ADC_Channel[6].Rank=ADC_REGULAR_RANK_7;     //排名ADC_Channel[6].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[6]);ADC_Channel[7].Channel=ADC_CHANNEL_7;     //通道编号ADC_Channel[7].Rank=ADC_REGULAR_RANK_8;     //排名ADC_Channel[7].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[7]);ADC_Channel[8].Channel=ADC_CHANNEL_8;     //通道编号ADC_Channel[8].Rank=ADC_REGULAR_RANK_9;     //排名ADC_Channel[8].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[8]);ADC_Channel[9].Channel=ADC_CHANNEL_9;     //通道编号ADC_Channel[9].Rank=ADC_REGULAR_RANK_10;     //排名ADC_Channel[9].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[9]);HAL_ADCEx_Calibration_Start(&ADC_HandleType);                   //自校准//DMA将连续读取100个ADC转换结果并存储到DMA_buff中,并产生DMA中断。HAL_ADC_Start_DMA(&ADC_HandleType,(uint32_t*)DMA_buff,100);  }
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{if(hadc->Instance==ADC1){__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_GPIOB_CLK_ENABLE();__HAL_RCC_ADC1_CLK_ENABLE();__HAL_RCC_DMA1_CLK_ENABLE();GPIO_InitTypeDef GPIO_InitType;//模拟输入不用设置上下拉电阻GPIO_InitType.Mode=GPIO_MODE_ANALOG;  //模拟输入GPIO_InitType.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;HAL_GPIO_Init(GPIOA,&GPIO_InitType); GPIO_InitType.Mode=GPIO_MODE_ANALOG;  //模拟输入GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1;HAL_GPIO_Init(GPIOB,&GPIO_InitType); //DMA配置:方向寄存器(外设)-->数组(内存)DMA_Handle.Instance=DMA1_Channel1;DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY;  //传输方向:寄存器(外设)->数组(内存)DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE;   //寄存器(外设)是否递增加DMA_Handle.Init.MemInc=DMA_MINC_ENABLE;      //数组(内存)是否递增加DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD;    //外设数据宽度(半字=2个字节)DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_HALFWORD;      //数组(内存)数据宽度DMA_Handle.Init.Mode=DMA_CIRCULAR;                         //模式:循环DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle);   //或者下面的写法__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle);  //链接//DMA的配置HAL_DMA_Init(&DMA_Handle);HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,4,0);HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);}
}void DMA1_Channel1_IRQHandler()
{HAL_DMA_IRQHandler(&DMA_Handle);}DMA将连续读取10个ADC转换结果并存储到DMA_buff中,后进入中断
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{			uint8_t i,j;uint32_t num;if(hadc->Instance==ADC1){for(i=0;i<10;i++){num=0;for(j=0;j<10;j++){num+=DMA_buff[j*10+i];}printf("ADC1_IN[%d]:%f V \r\n",i,(num/10.0)*(3.3/4096.0));   //串口1输出数字量	}		}
}#include "stm32f1xx_hal.h"
#include "pwm.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "ADC.h"//输入捕获功能
TIM_HandleTypeDef HandleTIMXCHX;
//TIM1的CC1事件
void IC_TIMX_CHX_init(uint16_t arr,uint16_t psc)
{TIM_MasterConfigTypeDef TIM_MasterConfig={0};TIM_OC_InitTypeDef TIM_OC_Init={0};HandleTIMXCHX.Instance=TIM3;   //基地址HandleTIMXCHX.Init.Period=arr;HandleTIMXCHX.Init.Prescaler=psc;HandleTIMXCHX.Init.CounterMode=TIM_COUNTERMODE_UP;   //向上计数HandleTIMXCHX.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;   //设置自动重载值 预装载使能位HandleTIMXCHX.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;   //设置分频因子HAL_TIM_Base_Init(&HandleTIMXCHX);//清除跟新中断标志位__HAL_TIM_CLEAR_FLAG(&HandleTIMXCHX,TIM_FLAG_UPDATE);TIM_MasterConfig.MasterOutputTrigger=TIM_TRGO_UPDATE;             //主定时器通道1捕获时发送信号TIM_MasterConfig.MasterSlaveMode=TIM_MASTERSLAVEMODE_DISABLE;  //主从模式:关闭HAL_TIMEx_MasterConfigSynchronization(&HandleTIMXCHX,&TIM_MasterConfig);HAL_TIM_Base_Start_IT(&HandleTIMXCHX);}void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim)
{if(htim->Instance==TIM3){__HAL_RCC_TIM3_CLK_ENABLE();                    //打开定时器3的时钟//信号为内部触发所以,定时器2_CH2引脚可以使用初始化HAL_NVIC_SetPriority(TIM3_IRQn,3,0);            //定时器3的中断优先级HAL_NVIC_EnableIRQ(TIM3_IRQn);                  //开定时器3的中断}
}/* 定时器1中断服务函数 */
void TIM3_IRQHandler(void)
{HAL_TIM_IRQHandler(&HandleTIMXCHX);  /* 定时器HAL库共用处理函数 */}//定时器的CC通道的输出比较
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{if(htim->Instance==TIM3){printf("定时器3更新事件\r\n");	}
}

E:规则组 10通道扫描 定时器3 TRGO捕获事件 触发转换

int main(void)
{uint8_t res=0;HAL_Init();                         /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */delay_init(72);                     /* 延时初始化 */Uart_Init(115200);IC_TIMX_CHX_init(3600-1,7200-1);   //T=((ARR+1)*(PSC+1)) / 72 000 000;  t=0.36s    10t=3.6sADC1_Init();  while (1){		}}
#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"
#include "TIM.h"ADC_HandleTypeDef ADC_HandleType;
DMA_HandleTypeDef DMA_Handle;
ADC_ChannelConfTypeDef ADC_Channel[10];uint16_t DMA_buff[100];
void ADC1_Init(void)
{//DISABLE     ENABLEADC_HandleType.Instance=ADC1;ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐ADC_HandleType.Init.ScanConvMode=ADC_SCAN_ENABLE;  //扫描模式:使能ADC_HandleType.Init.NbrOfConversion=10;            //扫描模式下规则组的数量ADC_HandleType.Init.ContinuousConvMode=ENABLE;     //连续模式:  使能ADC_HandleType.Init.DiscontinuousConvMode=DISABLE;   //规则组的间断模式   ADC_HandleType.Init.ExternalTrigConv=ADC_EXTERNALTRIGCONV_T3_TRGO;//触发方式:TIM3的TRGO事件HAL_ADC_Init(&ADC_HandleType);ADC_Channel[0].Channel=ADC_CHANNEL_0;     //通道编号ADC_Channel[0].Rank=ADC_REGULAR_RANK_1;     //排名ADC_Channel[0].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[0]);ADC_Channel[1].Channel=ADC_CHANNEL_1;     //通道编号ADC_Channel[1].Rank=ADC_REGULAR_RANK_2;     //排名ADC_Channel[1].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[1]);ADC_Channel[2].Channel=ADC_CHANNEL_2;     //通道编号ADC_Channel[2].Rank=ADC_REGULAR_RANK_3;     //排名ADC_Channel[2].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[2]);ADC_Channel[3].Channel=ADC_CHANNEL_3;     //通道编号ADC_Channel[3].Rank=ADC_REGULAR_RANK_4;     //排名ADC_Channel[3].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&	ADC_Channel[3]);ADC_Channel[4].Channel=ADC_CHANNEL_4;     //通道编号ADC_Channel[4].Rank=ADC_REGULAR_RANK_5;     //排名ADC_Channel[4].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[4]);ADC_Channel[5].Channel=ADC_CHANNEL_5;     //通道编号ADC_Channel[5].Rank=ADC_REGULAR_RANK_6;     //排名ADC_Channel[5].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[5]);ADC_Channel[6].Channel=ADC_CHANNEL_6;     //通道编号ADC_Channel[6].Rank=ADC_REGULAR_RANK_7;     //排名ADC_Channel[6].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[6]);ADC_Channel[7].Channel=ADC_CHANNEL_7;     //通道编号ADC_Channel[7].Rank=ADC_REGULAR_RANK_8;     //排名ADC_Channel[7].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[7]);ADC_Channel[8].Channel=ADC_CHANNEL_8;     //通道编号ADC_Channel[8].Rank=ADC_REGULAR_RANK_9;     //排名ADC_Channel[8].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[8]);ADC_Channel[9].Channel=ADC_CHANNEL_9;     //通道编号ADC_Channel[9].Rank=ADC_REGULAR_RANK_10;     //排名ADC_Channel[9].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[9]);HAL_ADCEx_Calibration_Start(&ADC_HandleType);                   //自校准//DMA将连续读取100个ADC转换结果并存储到DMA_buff中,并产生DMA中断。HAL_ADC_Start_DMA(&ADC_HandleType,(uint32_t*)DMA_buff,100);  }
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{if(hadc->Instance==ADC1){__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_GPIOB_CLK_ENABLE();__HAL_RCC_ADC1_CLK_ENABLE();__HAL_RCC_DMA1_CLK_ENABLE();GPIO_InitTypeDef GPIO_InitType;//模拟输入不用设置上下拉电阻GPIO_InitType.Mode=GPIO_MODE_ANALOG;  //模拟输入GPIO_InitType.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;HAL_GPIO_Init(GPIOA,&GPIO_InitType); GPIO_InitType.Mode=GPIO_MODE_ANALOG;  //模拟输入GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1;HAL_GPIO_Init(GPIOB,&GPIO_InitType); //DMA配置:方向寄存器(外设)-->数组(内存)DMA_Handle.Instance=DMA1_Channel1;DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY;  //传输方向:寄存器(外设)->数组(内存)DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE;   //寄存器(外设)是否递增加DMA_Handle.Init.MemInc=DMA_MINC_ENABLE;      //数组(内存)是否递增加DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD;    //外设数据宽度(半字=2个字节)DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_HALFWORD;      //数组(内存)数据宽度DMA_Handle.Init.Mode=DMA_CIRCULAR;                         //模式:循环DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle);   //或者下面的写法__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle);  //链接//DMA的配置HAL_DMA_Init(&DMA_Handle);HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,4,0);HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);}
}void DMA1_Channel1_IRQHandler()
{HAL_DMA_IRQHandler(&DMA_Handle);}//DMA将连续读取10个ADC转换结果并存储到DMA_buff中,后进入中断
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{			uint32_t num,i,j;if(hadc->Instance==ADC1){ADC_HandleType.Instance->CR2 &=~ ADC_CR2_CONT;for(i=0;i<10;i++){num=0;for(j=0;j<10;j++){num+=DMA_buff[j*10+i];}printf("ADC1_IN[%d]:%f V \r\n",i,(num/10.0)*(3.3/4096.0));   //串口1输出数字量	}	hadc->Instance->CR2 |= ADC_CR2_CONT;}
}#include "stm32f1xx_hal.h"
#include "pwm.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
//输入捕获功能
TIM_HandleTypeDef HandleTIMXCHX;
//TIM1的CC1事件
void IC_TIMX_CHX_init(uint16_t arr,uint16_t psc)
{TIM_MasterConfigTypeDef TIM_MasterConfig={0};TIM_IC_InitTypeDef TIM_IC_Init={0};HandleTIMXCHX.Instance=TIM3;   //基地址HandleTIMXCHX.Init.Period=arr;HandleTIMXCHX.Init.Prescaler=psc;HandleTIMXCHX.Init.CounterMode=TIM_COUNTERMODE_UP;   //向上计数HandleTIMXCHX.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;   //设置自动重载值 预装载使能位HandleTIMXCHX.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;   //设置分频因子HAL_TIM_IC_Init(&HandleTIMXCHX);//清除跟新中断标志位__HAL_TIM_CLEAR_FLAG(&HandleTIMXCHX,TIM_FLAG_UPDATE);TIM_MasterConfig.MasterOutputTrigger=TIM_TRGO_OC1;             //主定时器通道1捕获时发送信号//TIM_MasterConfig.MasterSlaveMode=TIM_MASTERSLAVEMODE_DISABLE;  //主从模式:关闭HAL_TIMEx_MasterConfigSynchronization(&HandleTIMXCHX,&TIM_MasterConfig);TIM_IC_Init.ICFilter=0x8;TIM_IC_Init.ICPolarity=TIM_ICPOLARITY_RISING;  //极性:上升沿TIM_IC_Init.ICSelection=TIM_ICSELECTION_DIRECTTI; //直连TIM_IC_Init.ICPrescaler=TIM_ICPSC_DIV1;HAL_TIM_IC_ConfigChannel(&HandleTIMXCHX,&TIM_IC_Init,TIM_CHANNEL_1);HAL_TIM_IC_Start_IT(&HandleTIMXCHX,TIM_CHANNEL_1);}void HAL_TIM_IC_MspInit(TIM_HandleTypeDef *htim)
{if(htim->Instance==TIM3){__HAL_RCC_GPIOB_CLK_ENABLE();                   //打开B口时钟__HAL_RCC_TIM3_CLK_ENABLE();                    //打开定时器3的时钟__HAL_RCC_AFIO_CLK_ENABLE();                    //应为要重映射,所以打开AFIO时钟__HAL_AFIO_REMAP_TIM3_PARTIAL();                //定时器3重映射__HAL_AFIO_REMAP_SWJ_NOJTAG();                  //关闭JTAG,保留SW,释放PB4//重映射CH1为PB4GPIO_InitTypeDef GPIO_InitType;GPIO_InitType.Pin = GPIO_PIN_4;                 //配置PIN4GPIO_InitType.Mode = GPIO_MODE_AF_INPUT;        //复用功能 输入方向GPIO_InitType.Pull = GPIO_PULLDOWN;             //开启IO口内部的下拉电阻HAL_GPIO_Init(GPIOB,&GPIO_InitType);            //配置PB4HAL_NVIC_SetPriority(TIM3_IRQn,3,0);            //定时器3的中断优先级HAL_NVIC_EnableIRQ(TIM3_IRQn);                  //开定时器3的中断}
}/* 定时器1中断服务函数 */
void TIM3_IRQHandler(void)
{HAL_TIM_IRQHandler(&HandleTIMXCHX);  /* 定时器HAL库共用处理函数 */
}//定时器的CC通道的输出比较
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{if(htim->Instance==TIM3){if(htim->Channel==HAL_TIM_ACTIVE_CHANNEL_1){printf("定时器3通道1上升沿捕获成功\r\n");		}}
}

注意:不管哪个TRGO事件的比较脉冲(输入捕获),使用哪个定时器,必须走通道1

F:规则组 10通道扫描 EXIT11事件 触发转换

int main(void)
{uint8_t res=0;HAL_Init();                         /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */delay_init(72);                     /* 延时初始化 */Uart_Init(115200);ADC1_Init();  while (1){		}}#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"
#include "TIM.h"ADC_HandleTypeDef ADC_HandleType;
DMA_HandleTypeDef DMA_Handle;
ADC_ChannelConfTypeDef ADC_Channel[10];uint16_t DMA_buff[100];
void ADC1_Init(void)
{//DISABLE     ENABLEADC_HandleType.Instance=ADC1;ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐ADC_HandleType.Init.ScanConvMode=ADC_SCAN_ENABLE;  //扫描模式:使能ADC_HandleType.Init.NbrOfConversion=10;            //扫描模式下规则组的数量ADC_HandleType.Init.ContinuousConvMode=ENABLE;     //连续模式:  使能ADC_HandleType.Init.DiscontinuousConvMode=DISABLE;   //规则组的间断模式   ADC_HandleType.Init.ExternalTrigConv=ADC_EXTERNALTRIGCONV_EXT_IT11;//触发方式:EXT_IT11中断HAL_ADC_Init(&ADC_HandleType);ADC_Channel[0].Channel=ADC_CHANNEL_0;     //通道编号ADC_Channel[0].Rank=ADC_REGULAR_RANK_1;     //排名ADC_Channel[0].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[0]);ADC_Channel[1].Channel=ADC_CHANNEL_1;     //通道编号ADC_Channel[1].Rank=ADC_REGULAR_RANK_2;     //排名ADC_Channel[1].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[1]);ADC_Channel[2].Channel=ADC_CHANNEL_2;     //通道编号ADC_Channel[2].Rank=ADC_REGULAR_RANK_3;     //排名ADC_Channel[2].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[2]);ADC_Channel[3].Channel=ADC_CHANNEL_3;     //通道编号ADC_Channel[3].Rank=ADC_REGULAR_RANK_4;     //排名ADC_Channel[3].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&	ADC_Channel[3]);ADC_Channel[4].Channel=ADC_CHANNEL_4;     //通道编号ADC_Channel[4].Rank=ADC_REGULAR_RANK_5;     //排名ADC_Channel[4].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[4]);ADC_Channel[5].Channel=ADC_CHANNEL_5;     //通道编号ADC_Channel[5].Rank=ADC_REGULAR_RANK_6;     //排名ADC_Channel[5].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[5]);ADC_Channel[6].Channel=ADC_CHANNEL_6;     //通道编号ADC_Channel[6].Rank=ADC_REGULAR_RANK_7;     //排名ADC_Channel[6].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[6]);ADC_Channel[7].Channel=ADC_CHANNEL_7;     //通道编号ADC_Channel[7].Rank=ADC_REGULAR_RANK_8;     //排名ADC_Channel[7].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[7]);ADC_Channel[8].Channel=ADC_CHANNEL_8;     //通道编号ADC_Channel[8].Rank=ADC_REGULAR_RANK_9;     //排名ADC_Channel[8].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[8]);ADC_Channel[9].Channel=ADC_CHANNEL_9;     //通道编号ADC_Channel[9].Rank=ADC_REGULAR_RANK_10;     //排名ADC_Channel[9].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[9]);HAL_ADCEx_Calibration_Start(&ADC_HandleType);                   //自校准//DMA将连续读取100个ADC转换结果并存储到DMA_buff中,并产生DMA中断。HAL_ADC_Start_DMA(&ADC_HandleType,(uint32_t*)DMA_buff,100);  }
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{if(hadc->Instance==ADC1){__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_GPIOB_CLK_ENABLE();__HAL_RCC_ADC1_CLK_ENABLE();__HAL_RCC_DMA1_CLK_ENABLE();GPIO_InitTypeDef GPIO_InitType;//模拟输入不用设置上下拉电阻GPIO_InitType.Mode=GPIO_MODE_ANALOG;  //模拟输入GPIO_InitType.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;HAL_GPIO_Init(GPIOA,&GPIO_InitType); GPIO_InitType.Mode=GPIO_MODE_ANALOG;  //模拟输入GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1;HAL_GPIO_Init(GPIOB,&GPIO_InitType); GPIO_InitType.Mode=GPIO_MODE_IT_RISING;  //模拟输入GPIO_InitType.Pin=GPIO_PIN_11;GPIO_InitType.Pull=GPIO_PULLUP;HAL_GPIO_Init(GPIOB,&GPIO_InitType); //DMA配置:方向寄存器(外设)-->数组(内存)DMA_Handle.Instance=DMA1_Channel1;DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY;  //传输方向:寄存器(外设)->数组(内存)DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE;   //寄存器(外设)是否递增加DMA_Handle.Init.MemInc=DMA_MINC_ENABLE;      //数组(内存)是否递增加DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD;    //外设数据宽度(半字=2个字节)DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_HALFWORD;      //数组(内存)数据宽度DMA_Handle.Init.Mode=DMA_CIRCULAR;                         //模式:循环DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle);   //或者下面的写法__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle);  //链接//DMA的配置HAL_DMA_Init(&DMA_Handle);HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,4,0);HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);}
}void DMA1_Channel1_IRQHandler()
{HAL_DMA_IRQHandler(&DMA_Handle);}//DMA将连续读取10个ADC转换结果并存储到DMA_buff中,后进入中断
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{			uint32_t num,i,j;if(hadc->Instance==ADC1){ADC_HandleType.Instance->CR2 &=~ ADC_CR2_CONT;for(i=0;i<10;i++){num=0;for(j=0;j<10;j++){num+=DMA_buff[j*10+i];}printf("ADC1_IN[%d]:%f V \r\n",i,(num/10.0)*(3.3/4096.0));   //串口1输出数字量	}	hadc->Instance->CR2 |= ADC_CR2_CONT;}
}

因为ADC的触发方式配置为:

        ADC_HandleType.Init.ExternalTrigConv=ADC_EXTERNALTRIGCONV_EXT_IT11;//触发方式:EXT_IT11中断

所以在配置PB11引脚的时候,需要注意(只能在下面选):

        PB11不能使用:

GPIO_MODE_INPUT
GPIO_MODE_AF_INPUT
GPIO_MODE_ANALOG

                                         间断模式

A:规则组扫描 间断模式 EXIT11事件 触发转换

int main(void)
{uint8_t res=0;HAL_Init();                         /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */delay_init(72);                     /* 延时初始化 */Uart_Init(115200);//IC_TIMX_CHX_init(3600-1,7200-1);   //T=((ARR+1)*(PSC+1)) / 72 000 000;  t=0.36s    10t=3.6sADC1_Init();  while (1){		}}
#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"
#include "TIM.h"ADC_HandleTypeDef ADC_HandleType;
DMA_HandleTypeDef DMA_Handle;
ADC_ChannelConfTypeDef ADC_Channel[10];
uint16_t count;
uint16_t DMA_buff[2];
void ADC1_Init(void)
{//DISABLE     ENABLEADC_HandleType.Instance=ADC1;ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐ADC_HandleType.Init.ScanConvMode=ADC_SCAN_ENABLE;  //扫描模式:使能ADC_HandleType.Init.NbrOfConversion=10;            //扫描模式下规则组的数量ADC_HandleType.Init.ContinuousConvMode=DISABLE;     //连续模式:  失能ADC_HandleType.Init.DiscontinuousConvMode=ENABLE;   //规则组的间断模式   ADC_HandleType.Init.NbrOfDiscConversion=2;            //规则组的间断模式子组的成员数量ADC_HandleType.Init.ExternalTrigConv=ADC_EXTERNALTRIGCONV_EXT_IT11;//触发方式:EXT_IT11中断HAL_ADC_Init(&ADC_HandleType);ADC_Channel[0].Channel=ADC_CHANNEL_0;     //通道编号ADC_Channel[0].Rank=ADC_REGULAR_RANK_1;     //排名ADC_Channel[0].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[0]);ADC_Channel[1].Channel=ADC_CHANNEL_1;     //通道编号ADC_Channel[1].Rank=ADC_REGULAR_RANK_2;     //排名ADC_Channel[1].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[1]);ADC_Channel[2].Channel=ADC_CHANNEL_2;     //通道编号ADC_Channel[2].Rank=ADC_REGULAR_RANK_3;     //排名ADC_Channel[2].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[2]);ADC_Channel[3].Channel=ADC_CHANNEL_3;     //通道编号ADC_Channel[3].Rank=ADC_REGULAR_RANK_4;     //排名ADC_Channel[3].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&	ADC_Channel[3]);ADC_Channel[4].Channel=ADC_CHANNEL_4;     //通道编号ADC_Channel[4].Rank=ADC_REGULAR_RANK_5;     //排名ADC_Channel[4].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[4]);ADC_Channel[5].Channel=ADC_CHANNEL_5;     //通道编号ADC_Channel[5].Rank=ADC_REGULAR_RANK_6;     //排名ADC_Channel[5].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[5]);ADC_Channel[6].Channel=ADC_CHANNEL_6;     //通道编号ADC_Channel[6].Rank=ADC_REGULAR_RANK_7;     //排名ADC_Channel[6].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[6]);ADC_Channel[7].Channel=ADC_CHANNEL_7;     //通道编号ADC_Channel[7].Rank=ADC_REGULAR_RANK_8;     //排名ADC_Channel[7].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[7]);ADC_Channel[8].Channel=ADC_CHANNEL_8;     //通道编号ADC_Channel[8].Rank=ADC_REGULAR_RANK_9;     //排名ADC_Channel[8].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[8]);ADC_Channel[9].Channel=ADC_CHANNEL_9;     //通道编号ADC_Channel[9].Rank=ADC_REGULAR_RANK_10;     //排名ADC_Channel[9].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[9]);HAL_ADCEx_Calibration_Start(&ADC_HandleType);                   //自校准//DMA将连续读取100个ADC转换结果并存储到DMA_buff中,并产生DMA中断。HAL_ADC_Start_DMA(&ADC_HandleType,(uint32_t*)DMA_buff,2);  }
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{if(hadc->Instance==ADC1){__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_GPIOB_CLK_ENABLE();__HAL_RCC_ADC1_CLK_ENABLE();__HAL_RCC_DMA1_CLK_ENABLE();GPIO_InitTypeDef GPIO_InitType;//模拟输入不用设置上下拉电阻GPIO_InitType.Mode=GPIO_MODE_ANALOG;  //模拟输入GPIO_InitType.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;HAL_GPIO_Init(GPIOA,&GPIO_InitType); GPIO_InitType.Mode=GPIO_MODE_ANALOG;  //模拟输入GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1;HAL_GPIO_Init(GPIOB,&GPIO_InitType); GPIO_InitType.Mode=GPIO_MODE_IT_RISING;  //模拟输入GPIO_InitType.Pin=GPIO_PIN_11;GPIO_InitType.Pull=GPIO_PULLUP;HAL_GPIO_Init(GPIOB,&GPIO_InitType); //DMA配置:方向寄存器(外设)-->数组(内存)DMA_Handle.Instance=DMA1_Channel1;DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY;  //传输方向:寄存器(外设)->数组(内存)DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE;   //寄存器(外设)是否递增加DMA_Handle.Init.MemInc=DMA_MINC_ENABLE;      //数组(内存)是否递增加DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD;    //外设数据宽度(半字=2个字节)DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_HALFWORD;      //数组(内存)数据宽度DMA_Handle.Init.Mode=DMA_CIRCULAR;                         //模式:循环DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle);   //或者下面的写法__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle);  //链接//DMA的配置HAL_DMA_Init(&DMA_Handle);HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,4,0);HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);}
}void DMA1_Channel1_IRQHandler()
{HAL_DMA_IRQHandler(&DMA_Handle);}//DMA将连续读取10个ADC转换结果并存储到DMA_buff中,后进入中断
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{			if(hadc->Instance==ADC1){//取余取的是被除数的余,不是除数的余。printf("ADC1_IN[%d]:%f V \r\n",(count%5)*2, DMA_buff[0]*(3.3/4096.0));   //串口1输出数字量	printf("ADC1_IN[%d]:%f V \r\n\r\n",(count%5)*2+1, DMA_buff[1]*(3.3/4096.0));   //串口1输出数字量	count++;}
}

一共开启了10个通道:0~9

ADC_HandleType.Init.NbrOfDiscConversion=2;            //规则组的间断模式子组的成员数量

每个子组2个通道,所以一共5个子组。

第1子组:通道0,1

第2子组:通道2,3

第3子组:通道4,5

第4子组:通道6,7

第5子组:通道8,9

每按下一次转化一个子组,按下第6次,转化第一子组。以此类推,,,,,

按下一次进入一次中断回调函数。

                                               注入组

A:规则组 6通道扫描+注入组4通道 自动注入方式

自动注入必须使用软件触发

int main(void)
{uint8_t res=0;HAL_Init();                         /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */delay_init(72);                     /* 延时初始化 */Uart_Init(115200);ADC1_Init();  while (1){		}}#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"
#include "TIM.h"
ADC_InjectionConfTypeDef ADC_Injection;  //注入组句柄
ADC_HandleTypeDef ADC_HandleType;
DMA_HandleTypeDef DMA_Handle;                 //DMA句柄
ADC_ChannelConfTypeDef ADC_Channel[10];      //规则组通道uint16_t DMA_buff[6];            //储存DMA数据的内存地址
void ADC1_Init(void)
{//规则组的配置ADC_HandleType.Instance=ADC1;ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐ADC_HandleType.Init.ScanConvMode=ADC_SCAN_ENABLE;  //扫描模式:使能ADC_HandleType.Init.NbrOfConversion=6;            //扫描模式下规则组的数量ADC_HandleType.Init.ContinuousConvMode=ENABLE;     //连续模式:  使能ADC_HandleType.Init.DiscontinuousConvMode=DISABLE;   //规则组的间断模式   //ADC_HandleType.Init.NbrOfDiscConversion=2;            //规则组的间断模式子组的成员数量ADC_HandleType.Init.ExternalTrigConv=ADC_SOFTWARE_START;//触发方式:软件触发HAL_ADC_Init(&ADC_HandleType);ADC_Channel[0].Channel=ADC_CHANNEL_0;     //通道编号ADC_Channel[0].Rank=ADC_REGULAR_RANK_1;     //排名ADC_Channel[0].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[0]);ADC_Channel[1].Channel=ADC_CHANNEL_1;     //通道编号ADC_Channel[1].Rank=ADC_REGULAR_RANK_2;     //排名ADC_Channel[1].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[1]);ADC_Channel[2].Channel=ADC_CHANNEL_2;     //通道编号ADC_Channel[2].Rank=ADC_REGULAR_RANK_3;     //排名ADC_Channel[2].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[2]);ADC_Channel[3].Channel=ADC_CHANNEL_3;     //通道编号ADC_Channel[3].Rank=ADC_REGULAR_RANK_4;     //排名ADC_Channel[3].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&	ADC_Channel[3]);ADC_Channel[4].Channel=ADC_CHANNEL_4;     //通道编号ADC_Channel[4].Rank=ADC_REGULAR_RANK_5;     //排名ADC_Channel[4].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[4]);ADC_Channel[5].Channel=ADC_CHANNEL_5;     //通道编号ADC_Channel[5].Rank=ADC_REGULAR_RANK_6;     //排名ADC_Channel[5].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[5]);//注入组配置---配置为自动注入ADC_Injection.InjectedChannel=ADC_CHANNEL_6;               //需要配置的通道ADC_Injection.InjectedRank=ADC_INJECTED_RANK_1;             //注入组的排名ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC_Injection.InjectedOffset=0;                             //偏移量ADC_Injection.InjectedNbrOfConversion=4;                        	//注入组的转化通道:max=4  ADC_Injection.InjectedDiscontinuousConvMode=DISABLE;          //租入组间断模式;不可能同时使用自动注入和间断模式ADC_Injection.AutoInjectedConv=ENABLE;                        //自动注入ADC_Injection.ExternalTrigInjecConv=ADC_INJECTED_SOFTWARE_START;   //触发方式:软件,自动注入下必须禁止注入通道的外部触发HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);//注入组配置ADC_Injection.InjectedChannel=ADC_CHANNEL_7;               //需要配置的通道ADC_Injection.InjectedRank=ADC_INJECTED_RANK_2;             //注入组的排名ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC_Injection.InjectedOffset=0;                           //偏移量HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);//注入组配置ADC_Injection.InjectedChannel=ADC_CHANNEL_8;               //需要配置的通道ADC_Injection.InjectedRank=ADC_INJECTED_RANK_3;             //注入组的排名ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC_Injection.InjectedOffset=0;                           //偏移量HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);//注入组配置ADC_Injection.InjectedChannel=ADC_CHANNEL_9;               //需要配置的通道ADC_Injection.InjectedRank=ADC_INJECTED_RANK_4;             //注入组的排名ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC_Injection.InjectedOffset=0;                           //偏移量HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);HAL_ADCEx_Calibration_Start(&ADC_HandleType);                   //自校准HAL_ADCEx_InjectedStart_IT(&ADC_HandleType);      //中断方式开启注入组//DMA将连续读取100个ADC转换结果并存储到DMA_buff中,并产生DMA中断。HAL_ADC_Start_DMA(&ADC_HandleType,(uint32_t*)DMA_buff,6);  }
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{if(hadc->Instance==ADC1){__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_GPIOB_CLK_ENABLE();__HAL_RCC_ADC1_CLK_ENABLE();__HAL_RCC_DMA1_CLK_ENABLE();GPIO_InitTypeDef GPIO_InitType;//模拟输入不用设置上下拉电阻GPIO_InitType.Mode=GPIO_MODE_ANALOG;  //模拟输入GPIO_InitType.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;HAL_GPIO_Init(GPIOA,&GPIO_InitType); GPIO_InitType.Mode=GPIO_MODE_ANALOG;  //模拟输入GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1;HAL_GPIO_Init(GPIOB,&GPIO_InitType); //DMA配置:方向寄存器(外设)-->数组(内存)DMA_Handle.Instance=DMA1_Channel1;DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY;  //传输方向:寄存器(外设)->数组(内存)DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE;   //寄存器(外设)是否递增加DMA_Handle.Init.MemInc=DMA_MINC_ENABLE;      //数组(内存)是否递增加DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD;    //外设数据宽度(半字=2个字节)DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_HALFWORD;      //数组(内存)数据宽度DMA_Handle.Init.Mode=DMA_CIRCULAR;                         //模式:循环DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle);   //或者下面的写法__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle);  //链接//DMA的配置HAL_DMA_Init(&DMA_Handle);HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,3,0);HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);HAL_NVIC_SetPriority(ADC1_2_IRQn,3,0);      //ADC的中断优先级HAL_NVIC_EnableIRQ(ADC1_2_IRQn);            //开ADC的中断}
}void DMA1_Channel1_IRQHandler()
{HAL_DMA_IRQHandler(&DMA_Handle);}//注入组是以ADC中断执行的
void ADC1_2_IRQHandler()
{HAL_ADC_IRQHandler(&ADC_HandleType);}//DMA将连续读取10个ADC转换结果并存储到DMA_buff中,后进入中断
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{			if(hadc->Instance==ADC1){printf("DMA完成中断\r\n");for(uint16_t i=0;i<6;i++){printf("ADC1_IN[%d]:%f V \r\n",i,DMA_buff[i]*(3.3/4096.0));   //串口1输出数字量	}}
}//注入租中断回调函数			
void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef* hadc)
{if(hadc->Instance==ADC1){printf("注入组完成中断\r\n");printf("ADC1_IN[6]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_1)*(3.3/4096.0));   printf("ADC1_IN[7]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_2)*(3.3/4096.0));   printf("ADC1_IN[8]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_3)*(3.3/4096.0));   printf("ADC1_IN[8]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_4)*(3.3/4096.0));   __HAL_ADC_ENABLE_IT(hadc, ADC_IT_JEOC);	//HAL_ADC_IRQHandler函数中会关闭我们的注入组的中断标志为所以我们需要自己在打开一下}}

关于能不能使用中断或者轮询

规则组:

        规则组只有一个DR寄存器,因为开启了扫描模式,在扫描模式中开启的6个通道,一个组中的6个通道全部转化完毕,中断标志位才会置位。然而我们只有一个数据寄存器(DR),会导致我们的数据出现覆盖。所以不能使用中断或者轮询 

注入组:

        注入组一共有4个通道,每个对应一个寄存器,所以可以使用中断和轮询方式,不会出现数据的覆盖问题。

中断问题

注入组使用的是我们ADC的中断方式所以,需要打开中断和NVIC.

ADC中断函数会关闭我们注入组的中断标志位,所以我们需要自己在注入组的回调函数中自己在开一遍

void HAL_ADC_IRQHandler(ADC_HandleTypeDef* hadc)/* Determine whether any further conversion upcoming on group injected  *//* by external trigger, scan sequence on going or by automatic injected *//* conversion from group regular (same conditions as group regular      *//* interruption disabling above).                                       *//* Note: On STM32F1 devices, in case of sequencer enabled               *//*       (several ranks selected), end of conversion flag is raised     *//*       at the end of the sequence.                                    */if(ADC_IS_SOFTWARE_START_INJECTED(hadc) 判断注入组是否开启了软件触发                  || (HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO) 判断是否清除的自动注入&&     (ADC_IS_SOFTWARE_START_REGULAR(hadc)  是否开启的规则组的软件触发      &&(hadc->Init.ContinuousConvMode == DISABLE)规则组是否开启了连续转换位   )        )   ){/* Disable ADC end of conversion interrupt on group injected */__HAL_ADC_DISABLE_IT(hadc, ADC_IT_JEOC);/* Set ADC state */CLEAR_BIT(hadc->State, HAL_ADC_STATE_INJ_BUSY);   if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_REG_BUSY)){ SET_BIT(hadc->State, HAL_ADC_STATE_READY);}}/* Conversion complete callback */ 
#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)hadc->InjectedConvCpltCallback(hadc);
#elseHAL_ADCEx_InjectedConvCpltCallback(hadc);  注入组中断回调函数
#endif /* USE_HAL_ADC_REGISTER_CALLBACKS *//* Clear injected group conversion flag */__HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_JSTRT | ADC_FLAG_JEOC));}}

中断优先级

			HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,4,0);HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);HAL_NVIC_SetPriority(ADC1_2_IRQn,4,0);      //ADC的中断优先级HAL_NVIC_EnableIRQ(ADC1_2_IRQn);            //开ADC的中断

2个优先级必须一样 。 自动注入的工作方式:如果设置了JAUTO位(打开自动注入),在规则组通道之后,注入组通道被自动转换。


优先级:DMA(规则组)>ADC(注入组):一直转化规则组的,注入组无法转化。

优先级:DMA(规则组)<ADC(注入组):一直转化注入组的,规则组无法转化。

注入组函数参数配置:

B:规则组 外部触发 6通道扫描+注入组4通道 自动注入方式

int main(void)
{uint8_t res=0;HAL_Init();                         /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */delay_init(72);                     /* 延时初始化 */Uart_Init(115200);//IC_TIMX_CHX_init(3600-1,7200-1);   //T=((ARR+1)*(PSC+1)) / 72 000 000;  t=0.36s    10t=3.6sADC1_Init();  while (1){		}}
#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"
#include "TIM.h"
ADC_InjectionConfTypeDef ADC_Injection;  //注入组句柄
ADC_HandleTypeDef ADC_HandleType;
DMA_HandleTypeDef DMA_Handle;                 //DMA句柄
ADC_ChannelConfTypeDef ADC_Channel[10];      //规则组通道uint16_t DMA_buff[6];            //储存DMA数据的内存地址
void ADC1_Init(void)
{//规则组的配置ADC_HandleType.Instance=ADC1;ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐ADC_HandleType.Init.ScanConvMode=ADC_SCAN_ENABLE;  //扫描模式:使能ADC_HandleType.Init.NbrOfConversion=6;            //扫描模式下规则组的数量ADC_HandleType.Init.ContinuousConvMode=DISABLE;     //连续模式:  失能ADC_HandleType.Init.DiscontinuousConvMode=DISABLE;   //规则组的间断模式   //ADC_HandleType.Init.NbrOfDiscConversion=2;            //规则组的间断模式子组的成员数量ADC_HandleType.Init.ExternalTrigConv=ADC_EXTERNALTRIGCONV_EXT_IT11;//触发方式:EXT_IT11触发HAL_ADC_Init(&ADC_HandleType);ADC_Channel[0].Channel=ADC_CHANNEL_0;     //通道编号ADC_Channel[0].Rank=ADC_REGULAR_RANK_1;     //排名ADC_Channel[0].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[0]);ADC_Channel[1].Channel=ADC_CHANNEL_1;     //通道编号ADC_Channel[1].Rank=ADC_REGULAR_RANK_2;     //排名ADC_Channel[1].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[1]);ADC_Channel[2].Channel=ADC_CHANNEL_2;     //通道编号ADC_Channel[2].Rank=ADC_REGULAR_RANK_3;     //排名ADC_Channel[2].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[2]);ADC_Channel[3].Channel=ADC_CHANNEL_3;     //通道编号ADC_Channel[3].Rank=ADC_REGULAR_RANK_4;     //排名ADC_Channel[3].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&	ADC_Channel[3]);ADC_Channel[4].Channel=ADC_CHANNEL_4;     //通道编号ADC_Channel[4].Rank=ADC_REGULAR_RANK_5;     //排名ADC_Channel[4].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[4]);ADC_Channel[5].Channel=ADC_CHANNEL_5;     //通道编号ADC_Channel[5].Rank=ADC_REGULAR_RANK_6;     //排名ADC_Channel[5].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[5]);//注入组配置---配置为自动注入ADC_Injection.InjectedChannel=ADC_CHANNEL_6;               //需要配置的通道ADC_Injection.InjectedRank=ADC_INJECTED_RANK_1;             //注入组的排名ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC_Injection.InjectedOffset=0;                             //偏移量ADC_Injection.InjectedNbrOfConversion=4;                        	//注入组的转化通道:max=4  ADC_Injection.InjectedDiscontinuousConvMode=DISABLE;          //租入组间断模式;不可能同时使用自动注入和间断模式ADC_Injection.AutoInjectedConv=ENABLE;                        //自动注入ADC_Injection.ExternalTrigInjecConv=ADC_INJECTED_SOFTWARE_START;   //触发方式:软件,自动注入下必须禁止注入通道的外部触发HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);//注入组配置ADC_Injection.InjectedChannel=ADC_CHANNEL_7;               //需要配置的通道ADC_Injection.InjectedRank=ADC_INJECTED_RANK_2;             //注入组的排名ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC_Injection.InjectedOffset=0;                           //偏移量HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);//注入组配置ADC_Injection.InjectedChannel=ADC_CHANNEL_8;               //需要配置的通道ADC_Injection.InjectedRank=ADC_INJECTED_RANK_3;             //注入组的排名ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC_Injection.InjectedOffset=0;                           //偏移量HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);//注入组配置ADC_Injection.InjectedChannel=ADC_CHANNEL_9;               //需要配置的通道ADC_Injection.InjectedRank=ADC_INJECTED_RANK_4;             //注入组的排名ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC_Injection.InjectedOffset=0;                           //偏移量HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);HAL_ADCEx_Calibration_Start(&ADC_HandleType);                   //自校准HAL_ADCEx_InjectedStart_IT(&ADC_HandleType);      //中断方式开启注入组//DMA将连续读取100个ADC转换结果并存储到DMA_buff中,并产生DMA中断。HAL_ADC_Start_DMA(&ADC_HandleType,(uint32_t*)DMA_buff,6);  }
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{if(hadc->Instance==ADC1){__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_GPIOB_CLK_ENABLE();__HAL_RCC_ADC1_CLK_ENABLE();__HAL_RCC_DMA1_CLK_ENABLE();GPIO_InitTypeDef GPIO_InitType;//模拟输入不用设置上下拉电阻GPIO_InitType.Mode=GPIO_MODE_ANALOG;  //模拟输入GPIO_InitType.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;HAL_GPIO_Init(GPIOA,&GPIO_InitType); GPIO_InitType.Mode=GPIO_MODE_ANALOG;  //模拟输入GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1;HAL_GPIO_Init(GPIOB,&GPIO_InitType); GPIO_InitType.Mode=GPIO_MODE_IT_RISING; GPIO_InitType.Pull=GPIO_PULLUP;GPIO_InitType.Pin=GPIO_PIN_11;HAL_GPIO_Init(GPIOB,&GPIO_InitType); //DMA配置:方向寄存器(外设)-->数组(内存)DMA_Handle.Instance=DMA1_Channel1;DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY;  //传输方向:寄存器(外设)->数组(内存)DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE;   //寄存器(外设)是否递增加DMA_Handle.Init.MemInc=DMA_MINC_ENABLE;      //数组(内存)是否递增加DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD;    //外设数据宽度(半字=2个字节)DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_HALFWORD;      //数组(内存)数据宽度DMA_Handle.Init.Mode=DMA_CIRCULAR;                         //模式:循环DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle);   //或者下面的写法__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle);  //链接//DMA的配置HAL_DMA_Init(&DMA_Handle);HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,3,0);HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);HAL_NVIC_SetPriority(ADC1_2_IRQn,3,0);      //ADC的中断优先级HAL_NVIC_EnableIRQ(ADC1_2_IRQn);            //开ADC的中断}
}void DMA1_Channel1_IRQHandler()
{HAL_DMA_IRQHandler(&DMA_Handle);}//注入组是以ADC中断执行的
void ADC1_2_IRQHandler()
{HAL_ADC_IRQHandler(&ADC_HandleType);}//DMA将连续读取10个ADC转换结果并存储到DMA_buff中,后进入中断
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{			if(hadc->Instance==ADC1){printf("DMA完成中断\r\n");for(uint16_t i=0;i<6;i++){printf("ADC1_IN[%d]:%f V \r\n",i,DMA_buff[i]*(3.3/4096.0));   //串口1输出数字量	}}
}//注入租中断回调函数			
void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef* hadc)
{if(hadc->Instance==ADC1){printf("注入组完成中断\r\n");printf("ADC1_IN[6]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_1)*(3.3/4096.0));   printf("ADC1_IN[7]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_2)*(3.3/4096.0));   printf("ADC1_IN[8]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_3)*(3.3/4096.0));   printf("ADC1_IN[8]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_4)*(3.3/4096.0));   __HAL_ADC_ENABLE_IT(hadc, ADC_IT_JEOC);	//HAL_ADC_IRQHandler函数中会关闭我们的注入组的中断标志为所以我们需要自己在打开一下}}

C:注入组 偏移值 效果测试

int main(void)
{uint8_t res=0;HAL_Init();                         /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */delay_init(72);                     /* 延时初始化 */Uart_Init(115200);//IC_TIMX_CHX_init(3600-1,7200-1);   //T=((ARR+1)*(PSC+1)) / 72 000 000;  t=0.36s    10t=3.6sADC1_Init();  while (1){		}}#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"
#include "TIM.h"
ADC_InjectionConfTypeDef ADC_Injection;  //注入组句柄
ADC_HandleTypeDef ADC_HandleType;
DMA_HandleTypeDef DMA_Handle;                 //DMA句柄
ADC_ChannelConfTypeDef ADC_Channel[10];      //规则组通道uint16_t DMA_buff[6];            //储存DMA数据的内存地址
void ADC1_Init(void)
{//规则组的配置ADC_HandleType.Instance=ADC1;ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐ADC_HandleType.Init.ScanConvMode=ADC_SCAN_ENABLE;  //扫描模式:使能ADC_HandleType.Init.NbrOfConversion=6;            //扫描模式下规则组的数量ADC_HandleType.Init.ContinuousConvMode=DISABLE;     //连续模式:  失能ADC_HandleType.Init.DiscontinuousConvMode=DISABLE;   //规则组的间断模式   //ADC_HandleType.Init.NbrOfDiscConversion=2;            //规则组的间断模式子组的成员数量ADC_HandleType.Init.ExternalTrigConv=ADC_EXTERNALTRIGCONV_EXT_IT11;//触发方式:EXT_IT11触发HAL_ADC_Init(&ADC_HandleType);ADC_Channel[0].Channel=ADC_CHANNEL_0;     //通道编号ADC_Channel[0].Rank=ADC_REGULAR_RANK_1;     //排名ADC_Channel[0].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[0]);ADC_Channel[1].Channel=ADC_CHANNEL_1;     //通道编号ADC_Channel[1].Rank=ADC_REGULAR_RANK_2;     //排名ADC_Channel[1].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[1]);ADC_Channel[2].Channel=ADC_CHANNEL_2;     //通道编号ADC_Channel[2].Rank=ADC_REGULAR_RANK_3;     //排名ADC_Channel[2].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[2]);ADC_Channel[3].Channel=ADC_CHANNEL_3;     //通道编号ADC_Channel[3].Rank=ADC_REGULAR_RANK_4;     //排名ADC_Channel[3].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&	ADC_Channel[3]);ADC_Channel[4].Channel=ADC_CHANNEL_4;     //通道编号ADC_Channel[4].Rank=ADC_REGULAR_RANK_5;     //排名ADC_Channel[4].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[4]);ADC_Channel[5].Channel=ADC_CHANNEL_5;     //通道编号ADC_Channel[5].Rank=ADC_REGULAR_RANK_6;     //排名ADC_Channel[5].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[5]);//注入组配置---配置为自动注入ADC_Injection.InjectedChannel=ADC_CHANNEL_6;               //需要配置的通道ADC_Injection.InjectedRank=ADC_INJECTED_RANK_1;             //注入组的排名ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC_Injection.InjectedOffset=3000;                             //偏移量ADC_Injection.InjectedNbrOfConversion=4;                        	//注入组的转化通道:max=4  ADC_Injection.InjectedDiscontinuousConvMode=DISABLE;          //租入组间断模式;不可能同时使用自动注入和间断模式ADC_Injection.AutoInjectedConv=ENABLE;                        //自动注入ADC_Injection.ExternalTrigInjecConv=ADC_INJECTED_SOFTWARE_START;   //触发方式:软件,自动注入下必须禁止注入通道的外部触发HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);//注入组配置ADC_Injection.InjectedChannel=ADC_CHANNEL_7;               //需要配置的通道ADC_Injection.InjectedRank=ADC_INJECTED_RANK_2;             //注入组的排名ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC_Injection.InjectedOffset=20;                           //偏移量HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);//注入组配置ADC_Injection.InjectedChannel=ADC_CHANNEL_8;               //需要配置的通道ADC_Injection.InjectedRank=ADC_INJECTED_RANK_3;             //注入组的排名ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC_Injection.InjectedOffset=100;                           //偏移量HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);//注入组配置ADC_Injection.InjectedChannel=ADC_CHANNEL_9;               //需要配置的通道ADC_Injection.InjectedRank=ADC_INJECTED_RANK_4;             //注入组的排名ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC_Injection.InjectedOffset=2000;                           //偏移量HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);HAL_ADCEx_Calibration_Start(&ADC_HandleType);                   //自校准HAL_ADCEx_InjectedStart_IT(&ADC_HandleType);      //中断方式开启注入组//DMA将连续读取100个ADC转换结果并存储到DMA_buff中,并产生DMA中断。HAL_ADC_Start_DMA(&ADC_HandleType,(uint32_t*)DMA_buff,6);  }
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{if(hadc->Instance==ADC1){__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_GPIOB_CLK_ENABLE();__HAL_RCC_ADC1_CLK_ENABLE();__HAL_RCC_DMA1_CLK_ENABLE();GPIO_InitTypeDef GPIO_InitType;//模拟输入不用设置上下拉电阻GPIO_InitType.Mode=GPIO_MODE_ANALOG;  //模拟输入GPIO_InitType.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;HAL_GPIO_Init(GPIOA,&GPIO_InitType); GPIO_InitType.Mode=GPIO_MODE_ANALOG;  //模拟输入GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1;HAL_GPIO_Init(GPIOB,&GPIO_InitType); GPIO_InitType.Mode=GPIO_MODE_IT_RISING; GPIO_InitType.Pull=GPIO_PULLUP;GPIO_InitType.Pin=GPIO_PIN_11;HAL_GPIO_Init(GPIOB,&GPIO_InitType); //DMA配置:方向寄存器(外设)-->数组(内存)DMA_Handle.Instance=DMA1_Channel1;DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY;  //传输方向:寄存器(外设)->数组(内存)DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE;   //寄存器(外设)是否递增加DMA_Handle.Init.MemInc=DMA_MINC_ENABLE;      //数组(内存)是否递增加DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD;    //外设数据宽度(半字=2个字节)DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_HALFWORD;      //数组(内存)数据宽度DMA_Handle.Init.Mode=DMA_CIRCULAR;                         //模式:循环DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle);   //或者下面的写法__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle);  //链接//DMA的配置HAL_DMA_Init(&DMA_Handle);HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,3,0);HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);HAL_NVIC_SetPriority(ADC1_2_IRQn,3,0);      //ADC的中断优先级HAL_NVIC_EnableIRQ(ADC1_2_IRQn);            //开ADC的中断}
}void DMA1_Channel1_IRQHandler()
{HAL_DMA_IRQHandler(&DMA_Handle);}//注入组是以ADC中断执行的
void ADC1_2_IRQHandler()
{HAL_ADC_IRQHandler(&ADC_HandleType);}//DMA将连续读取10个ADC转换结果并存储到DMA_buff中,后进入中断
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{			if(hadc->Instance==ADC1){printf("DMA完成中断\r\n");for(uint16_t i=0;i<6;i++){printf("ADC1_IN[%d]:%f V \r\n",i,DMA_buff[i]*(3.3/4096.0));   //串口1输出数字量	}}
}//注入租中断回调函数			
void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef* hadc)
{if(hadc->Instance==ADC1){printf("注入组完成中断\r\n");printf("ADC1_IN[6]:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_1));   printf("ADC1_IN[7]:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_2));   printf("ADC1_IN[8]:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_3));   printf("ADC1_IN[9]:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_4));   __HAL_ADC_ENABLE_IT(hadc, ADC_IT_JEOC);	//HAL_ADC_IRQHandler函数中会关闭我们的注入组的中断标志为所以我们需要自己在打开一下//JOFFSETx[11:0]:注入通道x的数据偏移 (Data offset for injected channel x) 位11:0//为16位,所以int16_t;不使用32位的//			printf("注入组完成中断\r\n");
//			printf("ADC1_IN[6]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_1)*(3.3/4096.0));   
//			printf("ADC1_IN[7]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_2)*(3.3/4096.0));   
//			printf("ADC1_IN[8]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_3)*(3.3/4096.0));   
//			printf("ADC1_IN[8]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_4)*(3.3/4096.0));   
//			__HAL_ADC_ENABLE_IT(hadc, ADC_IT_JEOC);	
//			//HAL_ADC_IRQHandler函数中会关闭我们的注入组的中断标志为所以我们需要自己在打开一下}}

D:规则组6通道扫描 注入组定时器CC事件 触发转换

int main(void)
{uint8_t res=0;HAL_Init();                         /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */delay_init(72);                     /* 延时初始化 */Uart_Init(115200);IC_TIMX_CHX_init(3600-1,7200-1);   //T=((ARR+1)*(PSC+1)) / 72 000 000;  t=0.36s    10t=3.6sADC1_Init();  while (1){		}}
#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"
#include "TIM.h"
ADC_InjectionConfTypeDef ADC_Injection;  //注入组句柄
ADC_HandleTypeDef ADC_HandleType;
DMA_HandleTypeDef DMA_Handle;                 //DMA句柄
ADC_ChannelConfTypeDef ADC_Channel[10];      //规则组通道uint16_t DMA_buff[6];            //储存DMA数据的内存地址
void ADC1_Init(void)
{//规则组的配置ADC_HandleType.Instance=ADC1;ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐ADC_HandleType.Init.ScanConvMode=ADC_SCAN_ENABLE;  //扫描模式:使能ADC_HandleType.Init.NbrOfConversion=6;            //扫描模式下规则组的数量ADC_HandleType.Init.ContinuousConvMode=ENABLE;     //连续模式:  使能ADC_HandleType.Init.DiscontinuousConvMode=DISABLE;   //规则组的间断模式   //ADC_HandleType.Init.NbrOfDiscConversion=2;            //规则组的间断模式子组的成员数量ADC_HandleType.Init.ExternalTrigConv=ADC_SOFTWARE_START;//触发方式:软件触发HAL_ADC_Init(&ADC_HandleType);ADC_Channel[0].Channel=ADC_CHANNEL_0;     //通道编号ADC_Channel[0].Rank=ADC_REGULAR_RANK_1;     //排名ADC_Channel[0].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[0]);ADC_Channel[1].Channel=ADC_CHANNEL_1;     //通道编号ADC_Channel[1].Rank=ADC_REGULAR_RANK_2;     //排名ADC_Channel[1].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[1]);ADC_Channel[2].Channel=ADC_CHANNEL_2;     //通道编号ADC_Channel[2].Rank=ADC_REGULAR_RANK_3;     //排名ADC_Channel[2].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[2]);ADC_Channel[3].Channel=ADC_CHANNEL_3;     //通道编号ADC_Channel[3].Rank=ADC_REGULAR_RANK_4;     //排名ADC_Channel[3].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&	ADC_Channel[3]);ADC_Channel[4].Channel=ADC_CHANNEL_4;     //通道编号ADC_Channel[4].Rank=ADC_REGULAR_RANK_5;     //排名ADC_Channel[4].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[4]);ADC_Channel[5].Channel=ADC_CHANNEL_5;     //通道编号ADC_Channel[5].Rank=ADC_REGULAR_RANK_6;     //排名ADC_Channel[5].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[5]);//注入组配置---配置为自动注入//自动注入和外部触发不可能共存ADC_Injection.InjectedChannel=ADC_CHANNEL_6;               //需要配置的通道ADC_Injection.InjectedRank=ADC_INJECTED_RANK_1;             //注入组的排名ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC_Injection.InjectedOffset=0;                             //偏移量ADC_Injection.InjectedNbrOfConversion=4;                        	//注入组的转化通道:max=4  ADC_Injection.InjectedDiscontinuousConvMode=DISABLE;          //注入组间断模式;不可能同时使用自动注入和间断模式ADC_Injection.AutoInjectedConv=DISABLE;                        //自动注入ADC_Injection.ExternalTrigInjecConv=ADC_EXTERNALTRIGINJECCONV_T1_CC4;   //触发方式:TIM1的通道4HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);//注入组配置ADC_Injection.InjectedChannel=ADC_CHANNEL_7;               //需要配置的通道ADC_Injection.InjectedRank=ADC_INJECTED_RANK_2;             //注入组的排名ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC_Injection.InjectedOffset=0;                           //偏移量HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);//注入组配置ADC_Injection.InjectedChannel=ADC_CHANNEL_8;               //需要配置的通道ADC_Injection.InjectedRank=ADC_INJECTED_RANK_3;             //注入组的排名ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC_Injection.InjectedOffset=0;                           //偏移量HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);//注入组配置ADC_Injection.InjectedChannel=ADC_CHANNEL_9;               //需要配置的通道ADC_Injection.InjectedRank=ADC_INJECTED_RANK_4;             //注入组的排名ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC_Injection.InjectedOffset=0;                           //偏移量HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);HAL_ADCEx_Calibration_Start(&ADC_HandleType);                   //自校准HAL_ADCEx_InjectedStart_IT(&ADC_HandleType);      //中断方式开启注入组//DMA将连续读取100个ADC转换结果并存储到DMA_buff中,并产生DMA中断。HAL_ADC_Start_DMA(&ADC_HandleType,(uint32_t*)DMA_buff,6);  }
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{if(hadc->Instance==ADC1){__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_GPIOB_CLK_ENABLE();__HAL_RCC_ADC1_CLK_ENABLE();__HAL_RCC_DMA1_CLK_ENABLE();GPIO_InitTypeDef GPIO_InitType;//模拟输入不用设置上下拉电阻GPIO_InitType.Mode=GPIO_MODE_ANALOG;  //模拟输入GPIO_InitType.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;HAL_GPIO_Init(GPIOA,&GPIO_InitType); GPIO_InitType.Mode=GPIO_MODE_ANALOG;  //模拟输入GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1;HAL_GPIO_Init(GPIOB,&GPIO_InitType); //DMA配置:方向寄存器(外设)-->数组(内存)DMA_Handle.Instance=DMA1_Channel1;DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY;  //传输方向:寄存器(外设)->数组(内存)DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE;   //寄存器(外设)是否递增加DMA_Handle.Init.MemInc=DMA_MINC_ENABLE;      //数组(内存)是否递增加DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD;    //外设数据宽度(半字=2个字节)DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_HALFWORD;      //数组(内存)数据宽度DMA_Handle.Init.Mode=DMA_CIRCULAR;                         //模式:循环DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle);   //或者下面的写法__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle);  //链接//DMA的配置HAL_DMA_Init(&DMA_Handle);HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,3,0);HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);HAL_NVIC_SetPriority(ADC1_2_IRQn,2,0);      //ADC的中断优先级HAL_NVIC_EnableIRQ(ADC1_2_IRQn);            //开ADC的中断}
}void DMA1_Channel1_IRQHandler()
{HAL_DMA_IRQHandler(&DMA_Handle);}//注入组是以ADC中断执行的
void ADC1_2_IRQHandler()
{HAL_ADC_IRQHandler(&ADC_HandleType);}//DMA将连续读取10个ADC转换结果并存储到DMA_buff中,后进入中断
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{			if(hadc->Instance==ADC1){printf("DMA完成中断\r\n");for(uint16_t i=0;i<6;i++){printf("ADC1_IN[%d]:%f V \r\n",i,DMA_buff[i]*(3.3/4096.0));   //串口1输出数字量	}}
}//注入租中断回调函数			
void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef* hadc)
{if(hadc->Instance==ADC1){printf("----------------------------------------注入组完成中断\r\n");printf("DMA剩余没有转换的通道量:%d\r\n",__HAL_DMA_GET_COUNTER(&DMA_Handle));printf("ADC1_IN[6]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_1)*(3.3/4096.0));   printf("ADC1_IN[7]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_2)*(3.3/4096.0));   printf("ADC1_IN[8]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_3)*(3.3/4096.0));   printf("ADC1_IN[9]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_4)*(3.3/4096.0));   }}#include "stm32f1xx_hal.h"
#include "pwm.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"//输入捕获功能
TIM_HandleTypeDef HandleTIMXCHX;
//TIM1的CC1事件
void IC_TIMX_CHX_init(uint16_t arr,uint16_t psc)
{TIM_OC_InitTypeDef TIM_OC_Init={0};HandleTIMXCHX.Instance=TIM1;   //基地址HandleTIMXCHX.Init.Period=arr;HandleTIMXCHX.Init.Prescaler=psc;HandleTIMXCHX.Init.CounterMode=TIM_COUNTERMODE_UP;   //向上计数HandleTIMXCHX.Init.RepetitionCounter = 0;                	//设置重复次数HandleTIMXCHX.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;   //设置自动重载值 预装载使能位HandleTIMXCHX.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;   //设置分频因子HAL_TIM_OC_Init(&HandleTIMXCHX);//清除跟新中断标志位__HAL_TIM_CLEAR_FLAG(&HandleTIMXCHX,TIM_FLAG_UPDATE);TIM_OC_Init.OCMode=TIM_OCMODE_PWM1;TIM_OC_Init.Pulse=100;    //比较值(CCR)TIM_OC_Init.OCPolarity=TIM_OCPOLARITY_LOW;//有效值  :PWM1:CNT<CCR输出有效电平  TIM_OC_Init.OCFastMode = TIM_OCFAST_DISABLE;    HAL_TIM_OC_ConfigChannel(&HandleTIMXCHX,&TIM_OC_Init,TIM_CHANNEL_4);HAL_TIM_OC_Start(&HandleTIMXCHX,TIM_CHANNEL_4);}void HAL_TIM_OC_MspInit(TIM_HandleTypeDef *htim)
{if(htim->Instance==TIM1){__HAL_RCC_TIM1_CLK_ENABLE();                    //打开定时器1的时钟//		HAL_NVIC_SetPriority(TIM1_CC_IRQn,1,0);            //定时器3的中断优先级
//		HAL_NVIC_EnableIRQ(TIM1_CC_IRQn);                  //开定时器3的中断}
}

注入组可以打断规则组。

注入组:自动注入和外部触发不能共存在。自动注入相当于放弃了优先级。外部触发可以打断规则组。

关于要不要在注入回调函数中再一次打开中断:判断它有没有关闭。(这里没有关闭,所以我们不要再次打开。)

void HAL_ADC_IRQHandler(ADC_HandleTypeDef* hadc)/* Determine whether any further conversion upcoming on group injected  *//* by external trigger, scan sequence on going or by automatic injected *//* conversion from group regular (same conditions as group regular      *//* interruption disabling above).                                       *//* Note: On STM32F1 devices, in case of sequencer enabled               *//*       (several ranks selected), end of conversion flag is raised     *//*       at the end of the sequence.                                    */if(ADC_IS_SOFTWARE_START_INJECTED(hadc) 判断注入组是否开启了软件触发                  || (HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO) 判断是否清除的自动注入&&     (ADC_IS_SOFTWARE_START_REGULAR(hadc)  是否开启的规则组的软件触发      &&(hadc->Init.ContinuousConvMode == DISABLE)规则组是否开启了连续转换位   )        )   ){/* Disable ADC end of conversion interrupt on group injected */__HAL_ADC_DISABLE_IT(hadc, ADC_IT_JEOC);/* Set ADC state */CLEAR_BIT(hadc->State, HAL_ADC_STATE_INJ_BUSY);   if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_REG_BUSY)){ SET_BIT(hadc->State, HAL_ADC_STATE_READY);}}/* Conversion complete callback */ 
#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)hadc->InjectedConvCpltCallback(hadc);
#elseHAL_ADCEx_InjectedConvCpltCallback(hadc);  注入组中断回调函数
#endif /* USE_HAL_ADC_REGISTER_CALLBACKS *//* Clear injected group conversion flag */__HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_JSTRT | ADC_FLAG_JEOC));}}

E:注入组 定时器TRGO之下 更新事件 触发转换

int main(void)
{uint8_t res=0;HAL_Init();                         /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */delay_init(72);                     /* 延时初始化 */Uart_Init(115200);IC_TIMX_CHX_init(3600-1,7200-1);   //T=((ARR+1)*(PSC+1)) / 72 000 000;  t=0.36s    10t=3.6sADC1_Init();  while (1){		}}
#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"
#include "TIM.h"
ADC_InjectionConfTypeDef ADC_Injection;  //注入组句柄
ADC_HandleTypeDef ADC_HandleType;
DMA_HandleTypeDef DMA_Handle;                 //DMA句柄
ADC_ChannelConfTypeDef ADC_Channel[10];      //规则组通道uint16_t DMA_buff[6];            //储存DMA数据的内存地址
void ADC1_Init(void)
{//规则组的配置ADC_HandleType.Instance=ADC1;ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐ADC_HandleType.Init.ScanConvMode=ADC_SCAN_ENABLE;  //扫描模式:使能ADC_HandleType.Init.NbrOfConversion=6;            //扫描模式下规则组的数量ADC_HandleType.Init.ContinuousConvMode=ENABLE;     //连续模式:  使能ADC_HandleType.Init.DiscontinuousConvMode=DISABLE;   //规则组的间断模式   //ADC_HandleType.Init.NbrOfDiscConversion=2;            //规则组的间断模式子组的成员数量ADC_HandleType.Init.ExternalTrigConv=ADC_SOFTWARE_START;//触发方式:软件触发HAL_ADC_Init(&ADC_HandleType);ADC_Channel[0].Channel=ADC_CHANNEL_0;     //通道编号ADC_Channel[0].Rank=ADC_REGULAR_RANK_1;     //排名ADC_Channel[0].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[0]);ADC_Channel[1].Channel=ADC_CHANNEL_1;     //通道编号ADC_Channel[1].Rank=ADC_REGULAR_RANK_2;     //排名ADC_Channel[1].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[1]);ADC_Channel[2].Channel=ADC_CHANNEL_2;     //通道编号ADC_Channel[2].Rank=ADC_REGULAR_RANK_3;     //排名ADC_Channel[2].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[2]);ADC_Channel[3].Channel=ADC_CHANNEL_3;     //通道编号ADC_Channel[3].Rank=ADC_REGULAR_RANK_4;     //排名ADC_Channel[3].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&	ADC_Channel[3]);ADC_Channel[4].Channel=ADC_CHANNEL_4;     //通道编号ADC_Channel[4].Rank=ADC_REGULAR_RANK_5;     //排名ADC_Channel[4].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[4]);ADC_Channel[5].Channel=ADC_CHANNEL_5;     //通道编号ADC_Channel[5].Rank=ADC_REGULAR_RANK_6;     //排名ADC_Channel[5].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[5]);//注入组配置---配置为自动注入//自动注入和外部触发不可能共存ADC_Injection.InjectedChannel=ADC_CHANNEL_6;               //需要配置的通道ADC_Injection.InjectedRank=ADC_INJECTED_RANK_1;             //注入组的排名ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC_Injection.InjectedOffset=0;                             //偏移量ADC_Injection.InjectedNbrOfConversion=4;                        	//注入组的转化通道:max=4  ADC_Injection.InjectedDiscontinuousConvMode=DISABLE;          //注入组间断模式;不可能同时使用自动注入和间断模式ADC_Injection.AutoInjectedConv=DISABLE;                        //自动注入ADC_Injection.ExternalTrigInjecConv=ADC_EXTERNALTRIGINJECCONV_T1_TRGO;   //触发方式:TIM1的通道TRGO事件HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);//注入组配置ADC_Injection.InjectedChannel=ADC_CHANNEL_7;               //需要配置的通道ADC_Injection.InjectedRank=ADC_INJECTED_RANK_2;             //注入组的排名ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC_Injection.InjectedOffset=0;                           //偏移量HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);//注入组配置ADC_Injection.InjectedChannel=ADC_CHANNEL_8;               //需要配置的通道ADC_Injection.InjectedRank=ADC_INJECTED_RANK_3;             //注入组的排名ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC_Injection.InjectedOffset=0;                           //偏移量HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);//注入组配置ADC_Injection.InjectedChannel=ADC_CHANNEL_9;               //需要配置的通道ADC_Injection.InjectedRank=ADC_INJECTED_RANK_4;             //注入组的排名ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC_Injection.InjectedOffset=0;                           //偏移量HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);HAL_ADCEx_Calibration_Start(&ADC_HandleType);                   //自校准HAL_ADCEx_InjectedStart_IT(&ADC_HandleType);      //中断方式开启注入组//DMA将连续读取100个ADC转换结果并存储到DMA_buff中,并产生DMA中断。HAL_ADC_Start_DMA(&ADC_HandleType,(uint32_t*)DMA_buff,6);  }
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{if(hadc->Instance==ADC1){__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_GPIOB_CLK_ENABLE();__HAL_RCC_ADC1_CLK_ENABLE();__HAL_RCC_DMA1_CLK_ENABLE();GPIO_InitTypeDef GPIO_InitType;//模拟输入不用设置上下拉电阻GPIO_InitType.Mode=GPIO_MODE_ANALOG;  //模拟输入GPIO_InitType.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;HAL_GPIO_Init(GPIOA,&GPIO_InitType); GPIO_InitType.Mode=GPIO_MODE_ANALOG;  //模拟输入GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1;HAL_GPIO_Init(GPIOB,&GPIO_InitType); //DMA配置:方向寄存器(外设)-->数组(内存)DMA_Handle.Instance=DMA1_Channel1;DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY;  //传输方向:寄存器(外设)->数组(内存)DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE;   //寄存器(外设)是否递增加DMA_Handle.Init.MemInc=DMA_MINC_ENABLE;      //数组(内存)是否递增加DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD;    //外设数据宽度(半字=2个字节)DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_HALFWORD;      //数组(内存)数据宽度DMA_Handle.Init.Mode=DMA_CIRCULAR;                         //模式:循环DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle);   //或者下面的写法__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle);  //链接//DMA的配置HAL_DMA_Init(&DMA_Handle);HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,3,0);HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);HAL_NVIC_SetPriority(ADC1_2_IRQn,2,0);      //ADC的中断优先级HAL_NVIC_EnableIRQ(ADC1_2_IRQn);            //开ADC的中断}
}void DMA1_Channel1_IRQHandler()
{HAL_DMA_IRQHandler(&DMA_Handle);}//注入组是以ADC中断执行的
void ADC1_2_IRQHandler()
{HAL_ADC_IRQHandler(&ADC_HandleType);}//DMA将连续读取10个ADC转换结果并存储到DMA_buff中,后进入中断
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{			if(hadc->Instance==ADC1){printf("DMA完成中断\r\n");for(uint16_t i=0;i<6;i++){printf("ADC1_IN[%d]:%f V \r\n",i,DMA_buff[i]*(3.3/4096.0));   //串口1输出数字量	}}
}//注入租中断回调函数			
void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef* hadc)
{if(hadc->Instance==ADC1){printf("----------------------------------------注入组完成中断\r\n");printf("DMA剩余没有转换的通道量:%d\r\n",__HAL_DMA_GET_COUNTER(&DMA_Handle));printf("ADC1_IN[6]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_1)*(3.3/4096.0));   printf("ADC1_IN[7]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_2)*(3.3/4096.0));   printf("ADC1_IN[8]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_3)*(3.3/4096.0));   printf("ADC1_IN[9]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_4)*(3.3/4096.0));   }}#include "stm32f1xx_hal.h"
#include "pwm.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"//输入捕获功能
TIM_HandleTypeDef HandleTIMXCHX;
//TIM1的CC1事件
void IC_TIMX_CHX_init(uint16_t arr,uint16_t psc)
{TIM_MasterConfigTypeDef TIM_MasterConfig={0};TIM_OC_InitTypeDef TIM_OC_Init={0};HandleTIMXCHX.Instance=TIM1;   //基地址HandleTIMXCHX.Init.Period=arr;HandleTIMXCHX.Init.Prescaler=psc;HandleTIMXCHX.Init.CounterMode=TIM_COUNTERMODE_UP;   //向上计数HandleTIMXCHX.Init.RepetitionCounter = 0;                	//设置重复次数HandleTIMXCHX.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;   //设置自动重载值 预装载使能位HandleTIMXCHX.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;   //设置分频因子HAL_TIM_Base_Init(&HandleTIMXCHX);//清除跟新中断标志位__HAL_TIM_CLEAR_FLAG(&HandleTIMXCHX,TIM_FLAG_UPDATE);//	TIM_OC_Init.OCMode=TIM_OCMODE_PWM1;
//	TIM_OC_Init.Pulse=100;    //比较值(CCR)
//	TIM_OC_Init.OCPolarity=TIM_OCPOLARITY_LOW;//有效值  :PWM1:CNT<CCR输出有效电平  
//	TIM_OC_Init.OCFastMode = TIM_OCFAST_DISABLE;    
//	HAL_TIM_OC_ConfigChannel(&HandleTIMXCHX,&TIM_OC_Init,TIM_CHANNEL_4);TIM_MasterConfig.MasterOutputTrigger=TIM_TRGO_UPDATE;             //主定时器通道1捕获时发送信号TIM_MasterConfig.MasterSlaveMode=TIM_MASTERSLAVEMODE_DISABLE;  //主从模式:关闭HAL_TIMEx_MasterConfigSynchronization(&HandleTIMXCHX,&TIM_MasterConfig);HAL_TIM_Base_Start(&HandleTIMXCHX);}void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim)
{if(htim->Instance==TIM1){__HAL_RCC_TIM1_CLK_ENABLE();                    //打开定时器1的时钟//		HAL_NVIC_SetPriority(TIM1_CC_IRQn,1,0);            //定时器3的中断优先级
//		HAL_NVIC_EnableIRQ(TIM1_CC_IRQn);                  //开定时器3的中断}
}

F:注入组 定时器TRGO之下 输入捕获事件 触发转换

注意:不管哪个TRGO事件的比较脉冲(输入捕获),使用哪个定时器,必须走通道1

int main(void)
{uint8_t res=0;HAL_Init();                         /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */delay_init(72);                     /* 延时初始化 */Uart_Init(115200);IC_TIMX_CHX_init(0xFFFF,36000-1);    ADC1_Init();  while (1){		}}#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"
#include "TIM.h"
ADC_InjectionConfTypeDef ADC_Injection;  //注入组句柄
ADC_HandleTypeDef ADC_HandleType;
DMA_HandleTypeDef DMA_Handle;                 //DMA句柄
ADC_ChannelConfTypeDef ADC_Channel[10];      //规则组通道uint16_t DMA_buff[6];            //储存DMA数据的内存地址
void ADC1_Init(void)
{//规则组的配置ADC_HandleType.Instance=ADC1;ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐ADC_HandleType.Init.ScanConvMode=ADC_SCAN_ENABLE;  //扫描模式:使能ADC_HandleType.Init.NbrOfConversion=6;            //扫描模式下规则组的数量ADC_HandleType.Init.ContinuousConvMode=ENABLE;     //连续模式:  使能ADC_HandleType.Init.DiscontinuousConvMode=DISABLE;   //规则组的间断模式   //ADC_HandleType.Init.NbrOfDiscConversion=2;            //规则组的间断模式子组的成员数量ADC_HandleType.Init.ExternalTrigConv=ADC_SOFTWARE_START;//触发方式:软件触发HAL_ADC_Init(&ADC_HandleType);ADC_Channel[0].Channel=ADC_CHANNEL_0;     //通道编号ADC_Channel[0].Rank=ADC_REGULAR_RANK_1;     //排名ADC_Channel[0].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[0]);ADC_Channel[1].Channel=ADC_CHANNEL_1;     //通道编号ADC_Channel[1].Rank=ADC_REGULAR_RANK_2;     //排名ADC_Channel[1].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[1]);ADC_Channel[2].Channel=ADC_CHANNEL_2;     //通道编号ADC_Channel[2].Rank=ADC_REGULAR_RANK_3;     //排名ADC_Channel[2].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[2]);ADC_Channel[3].Channel=ADC_CHANNEL_3;     //通道编号ADC_Channel[3].Rank=ADC_REGULAR_RANK_4;     //排名ADC_Channel[3].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&	ADC_Channel[3]);ADC_Channel[4].Channel=ADC_CHANNEL_4;     //通道编号ADC_Channel[4].Rank=ADC_REGULAR_RANK_5;     //排名ADC_Channel[4].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[4]);ADC_Channel[5].Channel=ADC_CHANNEL_5;     //通道编号ADC_Channel[5].Rank=ADC_REGULAR_RANK_6;     //排名ADC_Channel[5].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[5]);//注入组配置---配置为自动注入//自动注入和外部触发不可能共存ADC_Injection.InjectedChannel=ADC_CHANNEL_6;               //需要配置的通道ADC_Injection.InjectedRank=ADC_INJECTED_RANK_1;             //注入组的排名ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC_Injection.InjectedOffset=0;                             //偏移量ADC_Injection.InjectedNbrOfConversion=4;                        	//注入组的转化通道:max=4  ADC_Injection.InjectedDiscontinuousConvMode=DISABLE;          //注入组间断模式;不可能同时使用自动注入和间断模式ADC_Injection.AutoInjectedConv=DISABLE;                        //自动注入ADC_Injection.ExternalTrigInjecConv=ADC_EXTERNALTRIGINJECCONV_T1_TRGO;   //触发方式:TIM1的通道TRGO事件HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);//注入组配置ADC_Injection.InjectedChannel=ADC_CHANNEL_7;               //需要配置的通道ADC_Injection.InjectedRank=ADC_INJECTED_RANK_2;             //注入组的排名ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC_Injection.InjectedOffset=0;                           //偏移量HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);//注入组配置ADC_Injection.InjectedChannel=ADC_CHANNEL_8;               //需要配置的通道ADC_Injection.InjectedRank=ADC_INJECTED_RANK_3;             //注入组的排名ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC_Injection.InjectedOffset=0;                           //偏移量HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);//注入组配置ADC_Injection.InjectedChannel=ADC_CHANNEL_9;               //需要配置的通道ADC_Injection.InjectedRank=ADC_INJECTED_RANK_4;             //注入组的排名ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC_Injection.InjectedOffset=0;                           //偏移量HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);HAL_ADCEx_Calibration_Start(&ADC_HandleType);                   //自校准HAL_ADCEx_InjectedStart_IT(&ADC_HandleType);      //中断方式开启注入组//DMA将连续读取100个ADC转换结果并存储到DMA_buff中,并产生DMA中断。HAL_ADC_Start_DMA(&ADC_HandleType,(uint32_t*)DMA_buff,6);  }
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{if(hadc->Instance==ADC1){__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_GPIOB_CLK_ENABLE();__HAL_RCC_ADC1_CLK_ENABLE();__HAL_RCC_DMA1_CLK_ENABLE();GPIO_InitTypeDef GPIO_InitType;//模拟输入不用设置上下拉电阻GPIO_InitType.Mode=GPIO_MODE_ANALOG;  //模拟输入GPIO_InitType.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;HAL_GPIO_Init(GPIOA,&GPIO_InitType); GPIO_InitType.Mode=GPIO_MODE_ANALOG;  //模拟输入GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1;HAL_GPIO_Init(GPIOB,&GPIO_InitType); //DMA配置:方向寄存器(外设)-->数组(内存)DMA_Handle.Instance=DMA1_Channel1;DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY;  //传输方向:寄存器(外设)->数组(内存)DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE;   //寄存器(外设)是否递增加DMA_Handle.Init.MemInc=DMA_MINC_ENABLE;      //数组(内存)是否递增加DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD;    //外设数据宽度(半字=2个字节)DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_HALFWORD;      //数组(内存)数据宽度DMA_Handle.Init.Mode=DMA_CIRCULAR;                         //模式:循环DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle);   //或者下面的写法__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle);  //链接//DMA的配置HAL_DMA_Init(&DMA_Handle);HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,3,0);HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);HAL_NVIC_SetPriority(ADC1_2_IRQn,3,0);      //ADC的中断优先级HAL_NVIC_EnableIRQ(ADC1_2_IRQn);            //开ADC的中断}
}void DMA1_Channel1_IRQHandler()
{HAL_DMA_IRQHandler(&DMA_Handle);}//注入组是以ADC中断执行的
void ADC1_2_IRQHandler()
{HAL_ADC_IRQHandler(&ADC_HandleType);}//DMA将连续读取10个ADC转换结果并存储到DMA_buff中,后进入中断
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{			if(hadc->Instance==ADC1){printf("DMA完成中断\r\n");for(uint16_t i=0;i<6;i++){printf("ADC1_IN[%d]:%f V \r\n",i,DMA_buff[i]*(3.3/4096.0));   //串口1输出数字量	}}
}//注入租中断回调函数			
void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef* hadc)
{if(hadc->Instance==ADC1){printf("----------------------------------------注入组完成中断\r\n");printf("DMA剩余没有转换的通道量:%d\r\n",__HAL_DMA_GET_COUNTER(&DMA_Handle));printf("ADC1_IN[6]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_1)*(3.3/4096.0));   printf("ADC1_IN[7]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_2)*(3.3/4096.0));   printf("ADC1_IN[8]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_3)*(3.3/4096.0));   printf("ADC1_IN[9]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_4)*(3.3/4096.0));   }}#include "stm32f1xx_hal.h"
#include "pwm.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"//输入捕获功能
TIM_HandleTypeDef HandleTIMXCHX;
//TIM1的CC1事件
void IC_TIMX_CHX_init(uint16_t arr,uint16_t psc)
{TIM_MasterConfigTypeDef TIM_MasterConfig={0};TIM_IC_InitTypeDef TIM_IC_Init={0};HandleTIMXCHX.Instance=TIM1;   //基地址HandleTIMXCHX.Init.Period=arr;HandleTIMXCHX.Init.Prescaler=psc;HandleTIMXCHX.Init.CounterMode=TIM_COUNTERMODE_UP;   //向上计数HandleTIMXCHX.Init.RepetitionCounter = 0;                	//设置重复次数HandleTIMXCHX.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;   //设置自动重载值 预装载使能位HandleTIMXCHX.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;   //设置分频因子HAL_TIM_IC_Init(&HandleTIMXCHX);//清除跟新中断标志位__HAL_TIM_CLEAR_FLAG(&HandleTIMXCHX,TIM_FLAG_UPDATE);TIM_IC_Init.ICFilter=0x8;TIM_IC_Init.ICPolarity=TIM_ICPOLARITY_RISING;  //极性:上升沿TIM_IC_Init.ICSelection=TIM_ICSELECTION_DIRECTTI; //直连TIM_IC_Init.ICPrescaler=TIM_ICPSC_DIV1;TIM_MasterConfig.MasterOutputTrigger=TIM_TRGO_OC1;             //主定时器通道1捕获时发送信号TIM_MasterConfig.MasterSlaveMode=TIM_MASTERSLAVEMODE_DISABLE;  //主从模式:关闭HAL_TIMEx_MasterConfigSynchronization(&HandleTIMXCHX,&TIM_MasterConfig);HAL_TIM_IC_ConfigChannel(&HandleTIMXCHX,&TIM_IC_Init,TIM_CHANNEL_1);HAL_TIM_IC_Start(&HandleTIMXCHX,TIM_CHANNEL_1);}void HAL_TIM_IC_MspInit(TIM_HandleTypeDef *htim)
{if(htim->Instance==TIM1){__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_TIM1_CLK_ENABLE();                    //打开定时器1的时钟GPIO_InitTypeDef GPIO_InitType;//TIM1——CH1--PA8GPIO_InitType.Mode=GPIO_MODE_AF_INPUT;  GPIO_InitType.Pin=GPIO_PIN_8;GPIO_InitType.Pull=GPIO_PULLDOWN;HAL_GPIO_Init(GPIOA,&GPIO_InitType); }
}

G:注入组 EXIT15线事件 触发转换

int main(void)
{uint8_t res=0;HAL_Init();                         /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */delay_init(72);                     /* 延时初始化 */Uart_Init(115200);//IC_TIMX_CHX_init(0xFFFF,36000-1);    ADC1_Init();  while (1){		}}#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"
#include "TIM.h"
ADC_InjectionConfTypeDef ADC_Injection;  //注入组句柄
ADC_HandleTypeDef ADC_HandleType;
DMA_HandleTypeDef DMA_Handle;                 //DMA句柄
ADC_ChannelConfTypeDef ADC_Channel[10];      //规则组通道uint16_t DMA_buff[6];            //储存DMA数据的内存地址
void ADC1_Init(void)
{//规则组的配置ADC_HandleType.Instance=ADC1;ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐ADC_HandleType.Init.ScanConvMode=ADC_SCAN_ENABLE;  //扫描模式:使能ADC_HandleType.Init.NbrOfConversion=6;            //扫描模式下规则组的数量ADC_HandleType.Init.ContinuousConvMode=ENABLE;     //连续模式:  使能ADC_HandleType.Init.DiscontinuousConvMode=DISABLE;   //规则组的间断模式   //ADC_HandleType.Init.NbrOfDiscConversion=2;            //规则组的间断模式子组的成员数量ADC_HandleType.Init.ExternalTrigConv=ADC_SOFTWARE_START;//触发方式:软件触发HAL_ADC_Init(&ADC_HandleType);ADC_Channel[0].Channel=ADC_CHANNEL_0;     //通道编号ADC_Channel[0].Rank=ADC_REGULAR_RANK_1;     //排名ADC_Channel[0].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[0]);ADC_Channel[1].Channel=ADC_CHANNEL_1;     //通道编号ADC_Channel[1].Rank=ADC_REGULAR_RANK_2;     //排名ADC_Channel[1].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[1]);ADC_Channel[2].Channel=ADC_CHANNEL_2;     //通道编号ADC_Channel[2].Rank=ADC_REGULAR_RANK_3;     //排名ADC_Channel[2].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[2]);ADC_Channel[3].Channel=ADC_CHANNEL_3;     //通道编号ADC_Channel[3].Rank=ADC_REGULAR_RANK_4;     //排名ADC_Channel[3].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&	ADC_Channel[3]);ADC_Channel[4].Channel=ADC_CHANNEL_4;     //通道编号ADC_Channel[4].Rank=ADC_REGULAR_RANK_5;     //排名ADC_Channel[4].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[4]);ADC_Channel[5].Channel=ADC_CHANNEL_5;     //通道编号ADC_Channel[5].Rank=ADC_REGULAR_RANK_6;     //排名ADC_Channel[5].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[5]);//注入组配置---配置为自动注入//自动注入和外部触发不可能共存ADC_Injection.InjectedChannel=ADC_CHANNEL_6;               //需要配置的通道ADC_Injection.InjectedRank=ADC_INJECTED_RANK_1;             //注入组的排名ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC_Injection.InjectedOffset=0;                             //偏移量ADC_Injection.InjectedNbrOfConversion=4;                        	//注入组的转化通道:max=4  ADC_Injection.InjectedDiscontinuousConvMode=DISABLE;          //注入组间断模式;不可能同时使用自动注入和间断模式ADC_Injection.AutoInjectedConv=DISABLE;                        //自动注入ADC_Injection.ExternalTrigInjecConv=ADC_EXTERNALTRIGINJECCONV_EXT_IT15;   //触发方式:EXT_IT15HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);//注入组配置ADC_Injection.InjectedChannel=ADC_CHANNEL_7;               //需要配置的通道ADC_Injection.InjectedRank=ADC_INJECTED_RANK_2;             //注入组的排名ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC_Injection.InjectedOffset=0;                           //偏移量HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);//注入组配置ADC_Injection.InjectedChannel=ADC_CHANNEL_8;               //需要配置的通道ADC_Injection.InjectedRank=ADC_INJECTED_RANK_3;             //注入组的排名ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC_Injection.InjectedOffset=0;                           //偏移量HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);//注入组配置ADC_Injection.InjectedChannel=ADC_CHANNEL_9;               //需要配置的通道ADC_Injection.InjectedRank=ADC_INJECTED_RANK_4;             //注入组的排名ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC_Injection.InjectedOffset=0;                           //偏移量HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);HAL_ADCEx_Calibration_Start(&ADC_HandleType);                   //自校准HAL_ADCEx_InjectedStart_IT(&ADC_HandleType);      //中断方式开启注入组//DMA将连续读取100个ADC转换结果并存储到DMA_buff中,并产生DMA中断。HAL_ADC_Start_DMA(&ADC_HandleType,(uint32_t*)DMA_buff,6);  }
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{if(hadc->Instance==ADC1){__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_GPIOB_CLK_ENABLE();__HAL_RCC_ADC1_CLK_ENABLE();__HAL_RCC_DMA1_CLK_ENABLE();GPIO_InitTypeDef GPIO_InitType;//模拟输入不用设置上下拉电阻GPIO_InitType.Mode=GPIO_MODE_ANALOG;  //模拟输入GPIO_InitType.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;HAL_GPIO_Init(GPIOA,&GPIO_InitType); GPIO_InitType.Mode=GPIO_MODE_ANALOG;  //模拟输入GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1;HAL_GPIO_Init(GPIOB,&GPIO_InitType); GPIO_InitType.Mode=GPIO_MODE_IT_RISING;  GPIO_InitType.Pull=GPIO_PULLDOWN;GPIO_InitType.Pin=GPIO_PIN_15;HAL_GPIO_Init(GPIOB,&GPIO_InitType); //DMA配置:方向寄存器(外设)-->数组(内存)DMA_Handle.Instance=DMA1_Channel1;DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY;  //传输方向:寄存器(外设)->数组(内存)DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE;   //寄存器(外设)是否递增加DMA_Handle.Init.MemInc=DMA_MINC_ENABLE;      //数组(内存)是否递增加DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD;    //外设数据宽度(半字=2个字节)DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_HALFWORD;      //数组(内存)数据宽度DMA_Handle.Init.Mode=DMA_CIRCULAR;                         //模式:循环DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle);   //或者下面的写法__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle);  //链接//DMA的配置HAL_DMA_Init(&DMA_Handle);HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,3,0);HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);HAL_NVIC_SetPriority(ADC1_2_IRQn,3,0);      //ADC的中断优先级HAL_NVIC_EnableIRQ(ADC1_2_IRQn);            //开ADC的中断}
}void DMA1_Channel1_IRQHandler()
{HAL_DMA_IRQHandler(&DMA_Handle);}//注入组是以ADC中断执行的
void ADC1_2_IRQHandler()
{HAL_ADC_IRQHandler(&ADC_HandleType);}//DMA将连续读取10个ADC转换结果并存储到DMA_buff中,后进入中断
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{			if(hadc->Instance==ADC1){printf("DMA完成中断\r\n");for(uint16_t i=0;i<6;i++){printf("ADC1_IN[%d]:%f V \r\n",i,DMA_buff[i]*(3.3/4096.0));   //串口1输出数字量	}}
}//注入租中断回调函数			
void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef* hadc)
{if(hadc->Instance==ADC1){printf("----------------------------------------注入组完成中断\r\n");printf("DMA剩余没有转换的通道量:%d\r\n",__HAL_DMA_GET_COUNTER(&DMA_Handle));printf("ADC1_IN[6]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_1)*(3.3/4096.0));   printf("ADC1_IN[7]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_2)*(3.3/4096.0));   printf("ADC1_IN[8]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_3)*(3.3/4096.0));   printf("ADC1_IN[9]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_4)*(3.3/4096.0));   }}

H:注入组 间断模式 触发转换


 

int main(void)
{uint8_t res=0;HAL_Init();                         /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */delay_init(72);                     /* 延时初始化 */Uart_Init(115200);//IC_TIMX_CHX_init(0xFFFF,36000-1);    ADC1_Init();  while (1){		}}#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"
#include "TIM.h"
ADC_InjectionConfTypeDef ADC_Injection;  //注入组句柄
ADC_HandleTypeDef ADC_HandleType;
DMA_HandleTypeDef DMA_Handle;                 //DMA句柄
ADC_ChannelConfTypeDef ADC_Channel[10];      //规则组通道uint16_t DMA_buff[6];            //储存DMA数据的内存地址
void ADC1_Init(void)
{//规则组的配置ADC_HandleType.Instance=ADC1;ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐ADC_HandleType.Init.ScanConvMode=ADC_SCAN_ENABLE;  //扫描模式:使能ADC_HandleType.Init.NbrOfConversion=6;            //扫描模式下规则组的数量ADC_HandleType.Init.ContinuousConvMode=ENABLE;     //连续模式:  使能ADC_HandleType.Init.DiscontinuousConvMode=DISABLE;   //规则组的间断模式   //ADC_HandleType.Init.NbrOfDiscConversion=2;            //规则组的间断模式子组的成员数量ADC_HandleType.Init.ExternalTrigConv=ADC_SOFTWARE_START;//触发方式:软件触发HAL_ADC_Init(&ADC_HandleType);ADC_Channel[0].Channel=ADC_CHANNEL_0;     //通道编号ADC_Channel[0].Rank=ADC_REGULAR_RANK_1;     //排名ADC_Channel[0].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[0]);ADC_Channel[1].Channel=ADC_CHANNEL_1;     //通道编号ADC_Channel[1].Rank=ADC_REGULAR_RANK_2;     //排名ADC_Channel[1].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[1]);ADC_Channel[2].Channel=ADC_CHANNEL_2;     //通道编号ADC_Channel[2].Rank=ADC_REGULAR_RANK_3;     //排名ADC_Channel[2].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[2]);ADC_Channel[3].Channel=ADC_CHANNEL_3;     //通道编号ADC_Channel[3].Rank=ADC_REGULAR_RANK_4;     //排名ADC_Channel[3].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&	ADC_Channel[3]);ADC_Channel[4].Channel=ADC_CHANNEL_4;     //通道编号ADC_Channel[4].Rank=ADC_REGULAR_RANK_5;     //排名ADC_Channel[4].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[4]);ADC_Channel[5].Channel=ADC_CHANNEL_5;     //通道编号ADC_Channel[5].Rank=ADC_REGULAR_RANK_6;     //排名ADC_Channel[5].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[5]);//注入组配置---配置为自动注入//自动注入和外部触发不可能共存ADC_Injection.InjectedChannel=ADC_CHANNEL_6;               //需要配置的通道ADC_Injection.InjectedRank=ADC_INJECTED_RANK_1;             //注入组的排名ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC_Injection.InjectedOffset=0;                             //偏移量ADC_Injection.InjectedNbrOfConversion=4;                        	//注入组的转化通道:max=4  ADC_Injection.InjectedDiscontinuousConvMode=ENABLE;          //注入组间断模式;不可能同时使用自动注入和间断模式ADC_Injection.AutoInjectedConv=DISABLE;                        //自动注入ADC_Injection.ExternalTrigInjecConv=ADC_EXTERNALTRIGINJECCONV_EXT_IT15;   //触发方式:EXT_IT15HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);//注入组配置ADC_Injection.InjectedChannel=ADC_CHANNEL_7;               //需要配置的通道ADC_Injection.InjectedRank=ADC_INJECTED_RANK_2;             //注入组的排名ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC_Injection.InjectedOffset=0;                           //偏移量HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);//注入组配置ADC_Injection.InjectedChannel=ADC_CHANNEL_8;               //需要配置的通道ADC_Injection.InjectedRank=ADC_INJECTED_RANK_3;             //注入组的排名ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC_Injection.InjectedOffset=0;                           //偏移量HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);//注入组配置ADC_Injection.InjectedChannel=ADC_CHANNEL_9;               //需要配置的通道ADC_Injection.InjectedRank=ADC_INJECTED_RANK_4;             //注入组的排名ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC_Injection.InjectedOffset=0;                           //偏移量HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);HAL_ADCEx_Calibration_Start(&ADC_HandleType);                   //自校准HAL_ADCEx_InjectedStart_IT(&ADC_HandleType);      //中断方式开启注入组//DMA将连续读取100个ADC转换结果并存储到DMA_buff中,并产生DMA中断。HAL_ADC_Start_DMA(&ADC_HandleType,(uint32_t*)DMA_buff,6);  }
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{if(hadc->Instance==ADC1){__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_GPIOB_CLK_ENABLE();__HAL_RCC_ADC1_CLK_ENABLE();__HAL_RCC_DMA1_CLK_ENABLE();GPIO_InitTypeDef GPIO_InitType;//模拟输入不用设置上下拉电阻GPIO_InitType.Mode=GPIO_MODE_ANALOG;  //模拟输入GPIO_InitType.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;HAL_GPIO_Init(GPIOA,&GPIO_InitType); GPIO_InitType.Mode=GPIO_MODE_ANALOG;  //模拟输入GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1;HAL_GPIO_Init(GPIOB,&GPIO_InitType); GPIO_InitType.Mode=GPIO_MODE_IT_RISING;  GPIO_InitType.Pull=GPIO_PULLDOWN;GPIO_InitType.Pin=GPIO_PIN_15;HAL_GPIO_Init(GPIOB,&GPIO_InitType); //DMA配置:方向寄存器(外设)-->数组(内存)DMA_Handle.Instance=DMA1_Channel1;DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY;  //传输方向:寄存器(外设)->数组(内存)DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE;   //寄存器(外设)是否递增加DMA_Handle.Init.MemInc=DMA_MINC_ENABLE;      //数组(内存)是否递增加DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD;    //外设数据宽度(半字=2个字节)DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_HALFWORD;      //数组(内存)数据宽度DMA_Handle.Init.Mode=DMA_CIRCULAR;                         //模式:循环DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle);   //或者下面的写法__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle);  //链接//DMA的配置HAL_DMA_Init(&DMA_Handle);HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,3,0);HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);HAL_NVIC_SetPriority(ADC1_2_IRQn,3,0);      //ADC的中断优先级HAL_NVIC_EnableIRQ(ADC1_2_IRQn);            //开ADC的中断}
}void DMA1_Channel1_IRQHandler()
{HAL_DMA_IRQHandler(&DMA_Handle);}//注入组是以ADC中断执行的
void ADC1_2_IRQHandler()
{HAL_ADC_IRQHandler(&ADC_HandleType);}//DMA将连续读取10个ADC转换结果并存储到DMA_buff中,后进入中断
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{			
//		if(hadc->Instance==ADC1)
//		{
//			printf("DMA完成中断\r\n");
//			for(uint16_t i=0;i<6;i++)
//			{
//				printf("ADC1_IN[%d]:%f V \r\n",i,DMA_buff[i]*(3.3/4096.0));   //串口1输出数字量	
//			}
//				
//		}
}//注入租中断回调函数			
void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef* hadc)
{if(hadc->Instance==ADC1){printf("----------------------------------------注入组完成中断\r\n");printf("DMA剩余没有转换的通道量:%d\r\n",__HAL_DMA_GET_COUNTER(&DMA_Handle));printf("ADC1_IN[6]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_1)*(3.3/4096.0));   printf("ADC1_IN[7]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_2)*(3.3/4096.0));   printf("ADC1_IN[8]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_3)*(3.3/4096.0));   printf("ADC1_IN[9]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_4)*(3.3/4096.0));   }}

        我们开启了注入组的间断模式,一共使用了4个通道,因为n固定为1,所以每按下一次转化一个子组,等组(4个子组)全部转化完毕,才可以进去中断回调函数中去。也就是说我们需要按下4次才会进入中断回调函数。

HAL_ADCEx_InjectedConvCpltCallback()

                                            模拟看门狗

可以参考我写的:

CSDNicon-default.png?t=N7T8https://mp.csdn.net/mp_blog/creation/editor/136916809

 我们的ADC是12位的,也就是说取值范围为:0X000----0XFFF

        我们选取一个上限制和一个下限制,当我们的值在这个范围内属于正常值。一但高于或者低于就属于异常值,会触发模拟看门狗中断。

int main(void)
{uint8_t res=0;HAL_Init();                         /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */delay_init(72);                     /* 延时初始化 */Uart_Init(115200);//IC_TIMX_CHX_init(0xFFFF,36000-1);    ADC1_Init();  while (1){		}}
#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"
#include "TIM.h"
ADC_InjectionConfTypeDef ADC_Injection;  //注入组句柄
ADC_HandleTypeDef ADC_HandleType;
DMA_HandleTypeDef DMA_Handle;                 //DMA句柄
ADC_AnalogWDGConfTypeDef   adc1_dog;   //ADC1的模拟看门狗的结构体
ADC_ChannelConfTypeDef ADC_Channel[10];      //规则组通道uint16_t DMA_buff[6];            //储存DMA数据的内存地址
void ADC1_Init(void)
{//规则组的配置ADC_HandleType.Instance=ADC1;ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐ADC_HandleType.Init.ScanConvMode=ADC_SCAN_ENABLE;  //扫描模式:使能ADC_HandleType.Init.NbrOfConversion=6;            //扫描模式下规则组的数量ADC_HandleType.Init.ContinuousConvMode=ENABLE;     //连续模式:  使能ADC_HandleType.Init.DiscontinuousConvMode=DISABLE;   //规则组的间断模式   //ADC_HandleType.Init.NbrOfDiscConversion=2;            //规则组的间断模式子组的成员数量ADC_HandleType.Init.ExternalTrigConv=ADC_SOFTWARE_START;//触发方式:软件触发HAL_ADC_Init(&ADC_HandleType);ADC_Channel[0].Channel=ADC_CHANNEL_0;     //通道编号ADC_Channel[0].Rank=ADC_REGULAR_RANK_1;     //排名ADC_Channel[0].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[0]);ADC_Channel[1].Channel=ADC_CHANNEL_1;     //通道编号ADC_Channel[1].Rank=ADC_REGULAR_RANK_2;     //排名ADC_Channel[1].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[1]);ADC_Channel[2].Channel=ADC_CHANNEL_2;     //通道编号ADC_Channel[2].Rank=ADC_REGULAR_RANK_3;     //排名ADC_Channel[2].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[2]);ADC_Channel[3].Channel=ADC_CHANNEL_3;     //通道编号ADC_Channel[3].Rank=ADC_REGULAR_RANK_4;     //排名ADC_Channel[3].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&	ADC_Channel[3]);ADC_Channel[4].Channel=ADC_CHANNEL_4;     //通道编号ADC_Channel[4].Rank=ADC_REGULAR_RANK_5;     //排名ADC_Channel[4].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[4]);ADC_Channel[5].Channel=ADC_CHANNEL_5;     //通道编号ADC_Channel[5].Rank=ADC_REGULAR_RANK_6;     //排名ADC_Channel[5].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[5]);//注入组配置---配置为自动注入//自动注入和外部触发不可能共存ADC_Injection.InjectedChannel=ADC_CHANNEL_4;               //需要配置的通道ADC_Injection.InjectedRank=ADC_INJECTED_RANK_1;             //注入组的排名ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC_Injection.InjectedOffset=0;                             //偏移量ADC_Injection.InjectedNbrOfConversion=4;                        	//注入组的转化通道:max=4  ADC_Injection.InjectedDiscontinuousConvMode=DISABLE;         //注入组间断模式;不可能同时使用自动注入和间断模式ADC_Injection.AutoInjectedConv=ENABLE;                        //自动注入ADC_Injection.ExternalTrigInjecConv=ADC_INJECTED_SOFTWARE_START;   //触发方式:软件HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);//注入组配置ADC_Injection.InjectedChannel=ADC_CHANNEL_5;               //需要配置的通道ADC_Injection.InjectedRank=ADC_INJECTED_RANK_2;             //注入组的排名ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC_Injection.InjectedOffset=0;                           //偏移量HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);//注入组配置ADC_Injection.InjectedChannel=ADC_CHANNEL_6;               //需要配置的通道ADC_Injection.InjectedRank=ADC_INJECTED_RANK_3;             //注入组的排名ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC_Injection.InjectedOffset=0;                           //偏移量HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);//注入组配置ADC_Injection.InjectedChannel=ADC_CHANNEL_7;               //需要配置的通道ADC_Injection.InjectedRank=ADC_INJECTED_RANK_4;             //注入组的排名ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC_Injection.InjectedOffset=0;                           //偏移量HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);HAL_ADCEx_Calibration_Start(&ADC_HandleType);                   //自校准adc1_dog.WatchdogMode = ADC_ANALOGWATCHDOG_SINGLE_REG;           //工作模式adc1_dog.Channel = ADC_CHANNEL_2;                             //设置单一模式下,监控的通道adc1_dog.ITMode = ENABLE;                                     //使用中断模式adc1_dog.HighThreshold = 0xFFF;                               //设置高阈值adc1_dog.LowThreshold = 0x3FF;                                //设置低阈值HAL_ADC_AnalogWDGConfig(&ADC_HandleType,&adc1_dog);                     //这是模拟看门狗HAL_ADCEx_InjectedStart_IT(&ADC_HandleType);      //中断方式开启注入组//DMA将连续读取100个ADC转换结果并存储到DMA_buff中,并产生DMA中断。HAL_ADC_Start_DMA(&ADC_HandleType,(uint32_t*)DMA_buff,6);  }
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{if(hadc->Instance==ADC1){__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_GPIOB_CLK_ENABLE();__HAL_RCC_ADC1_CLK_ENABLE();__HAL_RCC_DMA1_CLK_ENABLE();GPIO_InitTypeDef GPIO_InitType;//模拟输入不用设置上下拉电阻GPIO_InitType.Mode=GPIO_MODE_ANALOG;  //模拟输入GPIO_InitType.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;HAL_GPIO_Init(GPIOA,&GPIO_InitType); GPIO_InitType.Mode=GPIO_MODE_ANALOG;  //模拟输入GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1;HAL_GPIO_Init(GPIOB,&GPIO_InitType); GPIO_InitType.Mode=GPIO_MODE_IT_RISING;  GPIO_InitType.Pull=GPIO_PULLDOWN;GPIO_InitType.Pin=GPIO_PIN_15;HAL_GPIO_Init(GPIOB,&GPIO_InitType); //DMA配置:方向寄存器(外设)-->数组(内存)DMA_Handle.Instance=DMA1_Channel1;DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY;  //传输方向:寄存器(外设)->数组(内存)DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE;   //寄存器(外设)是否递增加DMA_Handle.Init.MemInc=DMA_MINC_ENABLE;      //数组(内存)是否递增加DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD;    //外设数据宽度(半字=2个字节)DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_HALFWORD;      //数组(内存)数据宽度DMA_Handle.Init.Mode=DMA_CIRCULAR;                         //模式:循环DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle);   //或者下面的写法__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle);  //链接//DMA的配置HAL_DMA_Init(&DMA_Handle);HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,3,0);HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);HAL_NVIC_SetPriority(ADC1_2_IRQn,3,0);      //ADC的中断优先级HAL_NVIC_EnableIRQ(ADC1_2_IRQn);            //开ADC的中断}
}void DMA1_Channel1_IRQHandler()
{HAL_DMA_IRQHandler(&DMA_Handle);}//注入组是以ADC中断执行的
void ADC1_2_IRQHandler()
{HAL_ADC_IRQHandler(&ADC_HandleType);}//DMA将连续读取10个ADC转换结果并存储到DMA_buff中,后进入中断
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{			
//		if(hadc->Instance==ADC1)
//		{
//			printf("DMA完成中断\r\n");
//			for(uint16_t i=0;i<6;i++)
//			{
//				printf("ADC1_IN[%d]:%f V \r\n",i,DMA_buff[i]*(3.3/4096.0));   //串口1输出数字量	
//			}
//				
//		}
}//注入租中断回调函数			
void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef* hadc)
{if(hadc->Instance==ADC1){printf("----------------------------------------注入组完成中断\r\n");printf("DMA剩余没有转换的通道量:%d\r\n",__HAL_DMA_GET_COUNTER(&DMA_Handle));printf("ADC1_IN[6]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_1)*(3.3/4096.0));   printf("ADC1_IN[7]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_2)*(3.3/4096.0));   printf("ADC1_IN[8]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_3)*(3.3/4096.0));   printf("ADC1_IN[9]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_4)*(3.3/4096.0));   }}//模拟看门狗的中断回调
void HAL_ADC_LevelOutOfWindowCallback(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance == ADC1){ printf("模拟看门狗的中断回调\r\n");	}	
}

                                          双ADC模式

A:双ADC模式 软件触发 ADC1 ADC2同步规则模式

有软件触发

int main(void)
{uint8_t res=0;HAL_Init();                         /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */delay_init(72);                     /* 延时初始化 */Uart_Init(115200);ADC1_Init();  ADC2_Init();while (1){		}}#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"
#include "TIM.h"ADC_HandleTypeDef ADC_HandleType;   //ADC1为主模式
ADC_HandleTypeDef ADC2_HandleType;   //ADC2为从模式ADC_ChannelConfTypeDef ADC_Channel[10];  //ADC1为主模式的通道
ADC_ChannelConfTypeDef ADC2_Channel[10];  //ADC2为从模式的通道uint32_t DMA_buff[10];DMA_HandleTypeDef DMA_Handle;
void ADC1_Init(void)
{ADC_HandleType.Instance=ADC1;ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐ADC_HandleType.Init.ScanConvMode=ADC_SCAN_ENABLE;  //扫描模式:使能ADC_HandleType.Init.NbrOfConversion=10;            //扫描模式下规则组的数量ADC_HandleType.Init.ContinuousConvMode=ENABLE;     //连续模式:  使能ADC_HandleType.Init.DiscontinuousConvMode=DISABLE;   //规则组的间断模式   ADC_HandleType.Init.ExternalTrigConv=ADC_SOFTWARE_START;//触发方式:软件触发HAL_ADC_Init(&ADC_HandleType);ADC_Channel[0].Channel=ADC_CHANNEL_0;     //通道编号ADC_Channel[0].Rank=ADC_REGULAR_RANK_1;     //排名ADC_Channel[0].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[0]);ADC_Channel[1].Channel=ADC_CHANNEL_1;     //通道编号ADC_Channel[1].Rank=ADC_REGULAR_RANK_2;     //排名ADC_Channel[1].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[1]);ADC_Channel[2].Channel=ADC_CHANNEL_2;     //通道编号ADC_Channel[2].Rank=ADC_REGULAR_RANK_3;     //排名ADC_Channel[2].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[2]);ADC_Channel[3].Channel=ADC_CHANNEL_3;     //通道编号ADC_Channel[3].Rank=ADC_REGULAR_RANK_4;     //排名ADC_Channel[3].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&	ADC_Channel[3]);ADC_Channel[4].Channel=ADC_CHANNEL_4;     //通道编号ADC_Channel[4].Rank=ADC_REGULAR_RANK_5;     //排名ADC_Channel[4].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[4]);ADC_Channel[5].Channel=ADC_CHANNEL_5;     //通道编号ADC_Channel[5].Rank=ADC_REGULAR_RANK_6;     //排名ADC_Channel[5].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[5]);ADC_Channel[6].Channel=ADC_CHANNEL_6;     //通道编号ADC_Channel[6].Rank=ADC_REGULAR_RANK_7;     //排名ADC_Channel[6].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[6]);ADC_Channel[7].Channel=ADC_CHANNEL_7;     //通道编号ADC_Channel[7].Rank=ADC_REGULAR_RANK_8;     //排名ADC_Channel[7].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[7]);ADC_Channel[8].Channel=ADC_CHANNEL_8;     //通道编号ADC_Channel[8].Rank=ADC_REGULAR_RANK_9;     //排名ADC_Channel[8].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[8]);ADC_Channel[9].Channel=ADC_CHANNEL_9;     //通道编号ADC_Channel[9].Rank=ADC_REGULAR_RANK_10;     //排名ADC_Channel[9].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[9]);}void ADC2_Init(void)
{ADC2_HandleType.Instance=ADC2;ADC2_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐ADC2_HandleType.Init.ScanConvMode=ADC_SCAN_ENABLE;  //扫描模式:使能ADC2_HandleType.Init.NbrOfConversion=10;            //扫描模式下规则组的数量ADC2_HandleType.Init.ContinuousConvMode=ENABLE;     //连续模式:  使能ADC2_HandleType.Init.DiscontinuousConvMode=DISABLE;   //规则组的间断模式   ADC2_HandleType.Init.ExternalTrigConv=ADC_SOFTWARE_START;//触发方式:软件触发HAL_ADC_Init(&ADC2_HandleType);ADC_MultiModeTypeDef ADC_MultiMode={0};ADC2_Channel[0].Channel=ADC_CHANNEL_0;     //通道编号ADC2_Channel[0].Rank=ADC_REGULAR_RANK_10;     //排名ADC2_Channel[0].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[0]);ADC2_Channel[1].Channel=ADC_CHANNEL_1;     //通道编号ADC2_Channel[1].Rank=ADC_REGULAR_RANK_9;     //排名ADC2_Channel[1].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[1]);ADC2_Channel[2].Channel=ADC_CHANNEL_2;     //通道编号ADC2_Channel[2].Rank=ADC_REGULAR_RANK_8;     //排名ADC2_Channel[2].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[2]);ADC2_Channel[3].Channel=ADC_CHANNEL_3;     //通道编号ADC2_Channel[3].Rank=ADC_REGULAR_RANK_7;     //排名ADC2_Channel[3].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC2_HandleType,&	ADC2_Channel[3]);ADC2_Channel[4].Channel=ADC_CHANNEL_4;     //通道编号ADC2_Channel[4].Rank=ADC_REGULAR_RANK_6;     //排名ADC2_Channel[4].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[4]);ADC2_Channel[5].Channel=ADC_CHANNEL_5;     //通道编号ADC2_Channel[5].Rank=ADC_REGULAR_RANK_5;     //排名ADC2_Channel[5].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[5]);ADC2_Channel[6].Channel=ADC_CHANNEL_6;     //通道编号ADC2_Channel[6].Rank=ADC_REGULAR_RANK_4;     //排名ADC2_Channel[6].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[6]);ADC2_Channel[7].Channel=ADC_CHANNEL_7;     //通道编号ADC2_Channel[7].Rank=ADC_REGULAR_RANK_3;     //排名ADC2_Channel[7].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[7]);ADC2_Channel[8].Channel=ADC_CHANNEL_8;     //通道编号ADC2_Channel[8].Rank=ADC_REGULAR_RANK_2;     //排名ADC2_Channel[8].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[8]);ADC2_Channel[9].Channel=ADC_CHANNEL_9;     //通道编号ADC2_Channel[9].Rank=ADC_REGULAR_RANK_1;     //排名ADC2_Channel[9].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[9]);//配置ADC双模式:同步规则模式ADC_MultiMode.Mode=ADC_DUALMODE_REGSIMULT;HAL_ADCEx_MultiModeConfigChannel(&ADC_HandleType,&ADC_MultiMode);HAL_ADCEx_Calibration_Start(&ADC2_HandleType);   //自校准HAL_ADCEx_Calibration_Start(&ADC_HandleType);    //自校准HAL_ADC_Start(&ADC2_HandleType);HAL_ADCEx_MultiModeStart_DMA(&ADC_HandleType,DMA_buff,10);//双adc下使用这个API配置主adc}
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{if(hadc->Instance==ADC1){__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_GPIOB_CLK_ENABLE();__HAL_RCC_ADC1_CLK_ENABLE();__HAL_RCC_DMA1_CLK_ENABLE();GPIO_InitTypeDef GPIO_InitType;//模拟输入不用设置上下拉电阻GPIO_InitType.Mode=GPIO_MODE_ANALOG;  //模拟输入GPIO_InitType.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;HAL_GPIO_Init(GPIOA,&GPIO_InitType); GPIO_InitType.Mode=GPIO_MODE_ANALOG;  //模拟输入GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1;HAL_GPIO_Init(GPIOB,&GPIO_InitType); //DMA配置:方向寄存器(外设)-->数组(内存)DMA_Handle.Instance=DMA1_Channel1;DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY;  //传输方向:寄存器(外设)->数组(内存)DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE;   //寄存器(外设)是否递增加DMA_Handle.Init.MemInc=DMA_MINC_ENABLE;      //数组(内存)是否递增加DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_WORD;    //外设数据宽度(半字=2个字节)DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_WORD;      //数组(内存)数据宽度DMA_Handle.Init.Mode=DMA_CIRCULAR;                         //模式:循环DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle);   //或者下面的写法__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle);  //链接//DMA的配置HAL_DMA_Init(&DMA_Handle);HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,4,0);HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);}else if (hadc->Instance==ADC2){__HAL_RCC_ADC2_CLK_ENABLE();}
}void DMA1_Channel1_IRQHandler()
{HAL_DMA_IRQHandler(&DMA_Handle);}DMA将连续读取10个ADC转换结果并存储到DMA_buff中,后进入中断
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{			if(hadc->Instance==ADC1){printf("DMA完成中断\r\n");printf("ADC1_IN0:%d\r\n",DMA_buff[0]&0x0000FFFF);   //串口1输出电压值printf("ADC1_IN1:%d\r\n",DMA_buff[1]&0x0000FFFF);   //串口1输出电压值printf("ADC1_IN2:%d\r\n",DMA_buff[2]&0x0000FFFF);   //串口1输出电压值printf("ADC1_IN3:%d\r\n",DMA_buff[3]&0x0000FFFF);   //串口1输出电压值printf("ADC1_IN4:%d\r\n",DMA_buff[4]&0x0000FFFF);   //串口1输出电压值printf("ADC1_IN5:%d\r\n",DMA_buff[5]&0x0000FFFF);   //串口1输出电压值printf("ADC1_IN6:%d\r\n",DMA_buff[6]&0x0000FFFF);   //串口1输出电压值printf("ADC1_IN7:%d\r\n",DMA_buff[7]&0x0000FFFF);   //串口1输出电压值printf("ADC1_IN8:%d\r\n",DMA_buff[8]&0x0000FFFF);   //串口1输出电压值printf("ADC1_IN9:%d\r\n",DMA_buff[9]&0x0000FFFF);   //串口1输出电压值printf("----------------------------------------\r\n");printf("ADC2_IN9:%d\r\n",(DMA_buff[0]&0xFFFF0000)>>16);   //串口1输出电压值printf("ADC2_IN8:%d\r\n",(DMA_buff[1]&0xFFFF0000)>>16);   //串口1输出电压值printf("ADC2_IN7:%d\r\n",(DMA_buff[2]&0xFFFF0000)>>16);   //串口1输出电压值printf("ADC2_IN6:%d\r\n",(DMA_buff[3]&0xFFFF0000)>>16);   //串口1输出电压值printf("ADC2_IN5:%d\r\n",(DMA_buff[4]&0xFFFF0000)>>16);   //串口1输出电压值printf("ADC2_IN4:%d\r\n",(DMA_buff[5]&0xFFFF0000)>>16);   //串口1输出电压值printf("ADC2_IN3:%d\r\n",(DMA_buff[6]&0xFFFF0000)>>16);   //串口1输出电压值printf("ADC2_IN2:%d\r\n",(DMA_buff[7]&0xFFFF0000)>>16);   //串口1输出电压值printf("ADC2_IN1:%d\r\n",(DMA_buff[8]&0xFFFF0000)>>16);   //串口1输出电压值printf("ADC2_IN0:%d\r\n",(DMA_buff[9]&0xFFFF0000)>>16);   //串口1输出电压值}
}

 

关于ADC1_Init ()和ADC2_Init

我们在主函数中首先初始化的是ADC1,在初始化ADC2。所以基本上开启什么的通道都放在了ADC2上面。

 在同步规则模式中,必须转换具有相同时间长度的序列(软件触发)

ADC1和ADC2的通道数必须相同。

B:双ADC 外部信号触发 ADC1 ADC2同步规则模式

int main(void)
{uint8_t res=0;HAL_Init();                         /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */delay_init(72);                     /* 延时初始化 */Uart_Init(115200);IC_TIMX_CHX_init(10000-1,7200-1);   //T=((ARR+1)*(PSC+1)) / 1SADC1_Init();  ADC2_Init();while (1){		}}#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"
#include "TIM.h"ADC_HandleTypeDef ADC_HandleType;   //ADC1为主模式
ADC_HandleTypeDef ADC2_HandleType;   //ADC2为从模式ADC_ChannelConfTypeDef ADC_Channel[10];  //ADC1为主模式的通道
ADC_ChannelConfTypeDef ADC2_Channel[10];  //ADC2为从模式的通道uint32_t DMA_buff[10];DMA_HandleTypeDef DMA_Handle;
void ADC1_Init(void)
{ADC_HandleType.Instance=ADC1;ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐ADC_HandleType.Init.ScanConvMode=ADC_SCAN_ENABLE;  //扫描模式:使能ADC_HandleType.Init.NbrOfConversion=10;            //扫描模式下规则组的数量ADC_HandleType.Init.ContinuousConvMode=DISABLE;     //连续模式:  失能ADC_HandleType.Init.DiscontinuousConvMode=DISABLE;   //规则组的间断模式   ADC_HandleType.Init.ExternalTrigConv=ADC_EXTERNALTRIGCONV_T1_CC1;//触发方式:TIM1的通道1HAL_ADC_Init(&ADC_HandleType);ADC_Channel[0].Channel=ADC_CHANNEL_0;     //通道编号ADC_Channel[0].Rank=ADC_REGULAR_RANK_1;     //排名ADC_Channel[0].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[0]);ADC_Channel[1].Channel=ADC_CHANNEL_1;     //通道编号ADC_Channel[1].Rank=ADC_REGULAR_RANK_2;     //排名ADC_Channel[1].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[1]);ADC_Channel[2].Channel=ADC_CHANNEL_2;     //通道编号ADC_Channel[2].Rank=ADC_REGULAR_RANK_3;     //排名ADC_Channel[2].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[2]);ADC_Channel[3].Channel=ADC_CHANNEL_3;     //通道编号ADC_Channel[3].Rank=ADC_REGULAR_RANK_4;     //排名ADC_Channel[3].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&	ADC_Channel[3]);ADC_Channel[4].Channel=ADC_CHANNEL_4;     //通道编号ADC_Channel[4].Rank=ADC_REGULAR_RANK_5;     //排名ADC_Channel[4].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[4]);ADC_Channel[5].Channel=ADC_CHANNEL_5;     //通道编号ADC_Channel[5].Rank=ADC_REGULAR_RANK_6;     //排名ADC_Channel[5].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[5]);ADC_Channel[6].Channel=ADC_CHANNEL_6;     //通道编号ADC_Channel[6].Rank=ADC_REGULAR_RANK_7;     //排名ADC_Channel[6].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[6]);ADC_Channel[7].Channel=ADC_CHANNEL_7;     //通道编号ADC_Channel[7].Rank=ADC_REGULAR_RANK_8;     //排名ADC_Channel[7].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[7]);ADC_Channel[8].Channel=ADC_CHANNEL_8;     //通道编号ADC_Channel[8].Rank=ADC_REGULAR_RANK_9;     //排名ADC_Channel[8].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[8]);ADC_Channel[9].Channel=ADC_CHANNEL_9;     //通道编号ADC_Channel[9].Rank=ADC_REGULAR_RANK_10;     //排名ADC_Channel[9].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[9]);}void ADC2_Init(void)
{ADC2_HandleType.Instance=ADC2;ADC2_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐ADC2_HandleType.Init.ScanConvMode=ADC_SCAN_ENABLE;  //扫描模式:使能ADC2_HandleType.Init.NbrOfConversion=8;            //扫描模式下规则组的数量ADC2_HandleType.Init.ContinuousConvMode=DISABLE;     //连续模式:失能ADC2_HandleType.Init.DiscontinuousConvMode=DISABLE;   //规则组的间断模式   ADC2_HandleType.Init.ExternalTrigConv=ADC_SOFTWARE_START;//触发方式:软件触发HAL_ADC_Init(&ADC2_HandleType);ADC_MultiModeTypeDef ADC_MultiMode={0};ADC2_Channel[2].Channel=ADC_CHANNEL_2;     //通道编号ADC2_Channel[2].Rank=ADC_REGULAR_RANK_8;     //排名ADC2_Channel[2].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[2]);ADC2_Channel[3].Channel=ADC_CHANNEL_3;     //通道编号ADC2_Channel[3].Rank=ADC_REGULAR_RANK_7;     //排名ADC2_Channel[3].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC2_HandleType,&	ADC2_Channel[3]);ADC2_Channel[4].Channel=ADC_CHANNEL_4;     //通道编号ADC2_Channel[4].Rank=ADC_REGULAR_RANK_6;     //排名ADC2_Channel[4].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[4]);ADC2_Channel[5].Channel=ADC_CHANNEL_5;     //通道编号ADC2_Channel[5].Rank=ADC_REGULAR_RANK_5;     //排名ADC2_Channel[5].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[5]);ADC2_Channel[6].Channel=ADC_CHANNEL_6;     //通道编号ADC2_Channel[6].Rank=ADC_REGULAR_RANK_4;     //排名ADC2_Channel[6].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[6]);ADC2_Channel[7].Channel=ADC_CHANNEL_7;     //通道编号ADC2_Channel[7].Rank=ADC_REGULAR_RANK_3;     //排名ADC2_Channel[7].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[7]);ADC2_Channel[8].Channel=ADC_CHANNEL_8;     //通道编号ADC2_Channel[8].Rank=ADC_REGULAR_RANK_2;     //排名ADC2_Channel[8].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[8]);ADC2_Channel[9].Channel=ADC_CHANNEL_9;     //通道编号ADC2_Channel[9].Rank=ADC_REGULAR_RANK_1;     //排名ADC2_Channel[9].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[9]);//配置ADC双模式:同步规则模式ADC_MultiMode.Mode=ADC_DUALMODE_REGSIMULT;HAL_ADCEx_MultiModeConfigChannel(&ADC_HandleType,&ADC_MultiMode);HAL_ADCEx_Calibration_Start(&ADC2_HandleType);   //自校准HAL_ADCEx_Calibration_Start(&ADC_HandleType);    //自校准HAL_ADC_Start(&ADC2_HandleType);HAL_ADCEx_MultiModeStart_DMA(&ADC_HandleType,DMA_buff,10);//双adc下使用这个API配置主adc}
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{if(hadc->Instance==ADC1){__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_GPIOB_CLK_ENABLE();__HAL_RCC_ADC1_CLK_ENABLE();__HAL_RCC_DMA1_CLK_ENABLE();GPIO_InitTypeDef GPIO_InitType;//模拟输入不用设置上下拉电阻GPIO_InitType.Mode=GPIO_MODE_ANALOG;  //模拟输入GPIO_InitType.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;HAL_GPIO_Init(GPIOA,&GPIO_InitType); GPIO_InitType.Mode=GPIO_MODE_ANALOG;  //模拟输入GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1;HAL_GPIO_Init(GPIOB,&GPIO_InitType); //DMA配置:方向寄存器(外设)-->数组(内存)DMA_Handle.Instance=DMA1_Channel1;DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY;  //传输方向:寄存器(外设)->数组(内存)DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE;   //寄存器(外设)是否递增加DMA_Handle.Init.MemInc=DMA_MINC_ENABLE;      //数组(内存)是否递增加DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_WORD;    //外设数据宽度(半字=2个字节)DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_WORD;      //数组(内存)数据宽度DMA_Handle.Init.Mode=DMA_CIRCULAR;                         //模式:循环DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle);   //或者下面的写法__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle);  //链接//DMA的配置HAL_DMA_Init(&DMA_Handle);HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,4,0);HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);}else if (hadc->Instance==ADC2){__HAL_RCC_ADC2_CLK_ENABLE();}
}void DMA1_Channel1_IRQHandler()
{HAL_DMA_IRQHandler(&DMA_Handle);}DMA将连续读取10个ADC转换结果并存储到DMA_buff中,后进入中断
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{			if(hadc->Instance==ADC1){printf("DMA完成中断\r\n");printf("ADC1_IN0:%d\r\n",DMA_buff[0]&0x0000FFFF);   //串口1输出电压值printf("ADC1_IN1:%d\r\n",DMA_buff[1]&0x0000FFFF);   //串口1输出电压值printf("ADC1_IN2:%d\r\n",DMA_buff[2]&0x0000FFFF);   //串口1输出电压值printf("ADC1_IN3:%d\r\n",DMA_buff[3]&0x0000FFFF);   //串口1输出电压值printf("ADC1_IN4:%d\r\n",DMA_buff[4]&0x0000FFFF);   //串口1输出电压值printf("ADC1_IN5:%d\r\n",DMA_buff[5]&0x0000FFFF);   //串口1输出电压值printf("ADC1_IN6:%d\r\n",DMA_buff[6]&0x0000FFFF);   //串口1输出电压值printf("ADC1_IN7:%d\r\n",DMA_buff[7]&0x0000FFFF);   //串口1输出电压值printf("ADC1_IN8:%d\r\n",DMA_buff[8]&0x0000FFFF);   //串口1输出电压值printf("ADC1_IN9:%d\r\n",DMA_buff[9]&0x0000FFFF);   //串口1输出电压值printf("----------------------------------------\r\n");printf("ADC2_IN9:%d\r\n",(DMA_buff[0]&0xFFFF0000)>>16);   //串口1输出电压值printf("ADC2_IN8:%d\r\n",(DMA_buff[1]&0xFFFF0000)>>16);   //串口1输出电压值printf("ADC2_IN7:%d\r\n",(DMA_buff[2]&0xFFFF0000)>>16);   //串口1输出电压值printf("ADC2_IN6:%d\r\n",(DMA_buff[3]&0xFFFF0000)>>16);   //串口1输出电压值printf("ADC2_IN5:%d\r\n",(DMA_buff[4]&0xFFFF0000)>>16);   //串口1输出电压值printf("ADC2_IN4:%d\r\n",(DMA_buff[5]&0xFFFF0000)>>16);   //串口1输出电压值printf("ADC2_IN3:%d\r\n",(DMA_buff[6]&0xFFFF0000)>>16);   //串口1输出电压值printf("ADC2_IN2:%d\r\n",(DMA_buff[7]&0xFFFF0000)>>16);   //串口1输出电压值}
}#include "stm32f1xx_hal.h"
#include "pwm.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "ADC.h"//输入捕获功能
TIM_HandleTypeDef HandleTIMXCHX;
//TIM1的CC1事件
void IC_TIMX_CHX_init(uint16_t arr,uint16_t psc)
{TIM_OC_InitTypeDef TIM_OC_Init={0};HandleTIMXCHX.Instance=TIM1;   //基地址HandleTIMXCHX.Init.Period=arr;HandleTIMXCHX.Init.Prescaler=psc;HandleTIMXCHX.Init.CounterMode=TIM_COUNTERMODE_UP;   //向上计数HandleTIMXCHX.Init.RepetitionCounter = 0;                	//设置重复次数HandleTIMXCHX.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;   //设置自动重载值 预装载使能位HandleTIMXCHX.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;   //设置分频因子HAL_TIM_OC_Init(&HandleTIMXCHX);//清除跟新中断标志位__HAL_TIM_CLEAR_FLAG(&HandleTIMXCHX,TIM_FLAG_UPDATE);TIM_OC_Init.OCMode=TIM_OCMODE_PWM1;TIM_OC_Init.Pulse=100;    //比较值(CCR)TIM_OC_Init.OCPolarity=TIM_OCPOLARITY_LOW;//有效值  :PWM1:CNT<CCR输出有效电平  TIM_OC_Init.OCFastMode = TIM_OCFAST_DISABLE;    HAL_TIM_OC_ConfigChannel(&HandleTIMXCHX,&TIM_OC_Init,TIM_CHANNEL_1);HAL_TIM_OC_Start(&HandleTIMXCHX,TIM_CHANNEL_1);}

或保证触发的间隔比2个序列中较长的 序列长(外部触发)
ADC1使用了10个通道,ADC2使用了8个通道。
我们的定时器设置的触发周期为1S,远远满足了。

C:双ADC 外部信号触发 ADC1 ADC2同步注入模式

在注入组的模式中,我们只能使用外部触发的模式,没有软件触发的模式

int main(void)
{uint8_t res=0;HAL_Init();                         /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */delay_init(72);                     /* 延时初始化 */Uart_Init(115200);IC_TIMX_CHX_init(10000-1,7200-1);   //T=((ARR+1)*(PSC+1)) / 1SADC1_Init();  ADC2_Init();while (1){		}}
#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"
#include "TIM.h"ADC_HandleTypeDef ADC_HandleType;   //ADC1为主模式
ADC_HandleTypeDef ADC2_HandleType;   //ADC2为从模式ADC_ChannelConfTypeDef ADC_Channel[10];  //ADC1为主模式的通道
ADC_ChannelConfTypeDef ADC2_Channel[10];  //ADC2为从模式的通道ADC_InjectionConfTypeDef ADC_Injection;     //ADC1主模式的注入组
ADC_InjectionConfTypeDef ADC2_Injection;     //ADC1从模式的注入组
uint32_t DMA_buff[10];DMA_HandleTypeDef DMA_Handle;
void ADC1_Init(void)
{ADC_HandleType.Instance=ADC1;ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐ADC_HandleType.Init.ScanConvMode=ADC_SCAN_ENABLE;  //扫描模式:使能ADC_HandleType.Init.NbrOfConversion=10;            //扫描模式下规则组的数量ADC_HandleType.Init.ContinuousConvMode=ENABLE;     //连续模式:  使能ADC_HandleType.Init.DiscontinuousConvMode=DISABLE;   //规则组的间断模式   ADC_HandleType.Init.ExternalTrigConv=ADC_SOFTWARE_START;//触发方式HAL_ADC_Init(&ADC_HandleType);ADC_Channel[0].Channel=ADC_CHANNEL_0;     //通道编号ADC_Channel[0].Rank=ADC_REGULAR_RANK_1;     //排名ADC_Channel[0].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[0]);ADC_Channel[1].Channel=ADC_CHANNEL_1;     //通道编号ADC_Channel[1].Rank=ADC_REGULAR_RANK_2;     //排名ADC_Channel[1].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[1]);ADC_Channel[2].Channel=ADC_CHANNEL_2;     //通道编号ADC_Channel[2].Rank=ADC_REGULAR_RANK_3;     //排名ADC_Channel[2].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[2]);ADC_Channel[3].Channel=ADC_CHANNEL_3;     //通道编号ADC_Channel[3].Rank=ADC_REGULAR_RANK_4;     //排名ADC_Channel[3].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&	ADC_Channel[3]);ADC_Channel[4].Channel=ADC_CHANNEL_4;     //通道编号ADC_Channel[4].Rank=ADC_REGULAR_RANK_5;     //排名ADC_Channel[4].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[4]);ADC_Channel[5].Channel=ADC_CHANNEL_5;     //通道编号ADC_Channel[5].Rank=ADC_REGULAR_RANK_6;     //排名ADC_Channel[5].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[5]);ADC_Channel[6].Channel=ADC_CHANNEL_6;     //通道编号ADC_Channel[6].Rank=ADC_REGULAR_RANK_7;     //排名ADC_Channel[6].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[6]);ADC_Channel[7].Channel=ADC_CHANNEL_7;     //通道编号ADC_Channel[7].Rank=ADC_REGULAR_RANK_8;     //排名ADC_Channel[7].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[7]);ADC_Channel[8].Channel=ADC_CHANNEL_8;     //通道编号ADC_Channel[8].Rank=ADC_REGULAR_RANK_9;     //排名ADC_Channel[8].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[8]);ADC_Channel[9].Channel=ADC_CHANNEL_9;     //通道编号ADC_Channel[9].Rank=ADC_REGULAR_RANK_10;     //排名ADC_Channel[9].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[9]);//注入组配置---配置为自动注入//自动注入和外部触发不可能共存ADC_Injection.InjectedChannel=ADC_CHANNEL_6;               //需要配置的通道ADC_Injection.InjectedRank=ADC_INJECTED_RANK_1;             //注入组的排名ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC_Injection.InjectedOffset=0;                             //偏移量ADC_Injection.InjectedNbrOfConversion=4;                        	//注入组的转化通道:max=4  ADC_Injection.InjectedDiscontinuousConvMode=DISABLE;          //注入组间断模式;不可能同时使用自动注入和间断模式ADC_Injection.AutoInjectedConv=DISABLE;                        //自动注入ADC_Injection.ExternalTrigInjecConv=ADC_EXTERNALTRIGINJECCONV_T4_TRGO;   //触发方式:EXT_IT15HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);//注入组配置ADC_Injection.InjectedChannel=ADC_CHANNEL_7;               //需要配置的通道ADC_Injection.InjectedRank=ADC_INJECTED_RANK_2;             //注入组的排名ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC_Injection.InjectedOffset=0;                           //偏移量HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);//注入组配置ADC_Injection.InjectedChannel=ADC_CHANNEL_8;               //需要配置的通道ADC_Injection.InjectedRank=ADC_INJECTED_RANK_3;             //注入组的排名ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC_Injection.InjectedOffset=0;                           //偏移量HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);//注入组配置ADC_Injection.InjectedChannel=ADC_CHANNEL_9;               //需要配置的通道ADC_Injection.InjectedRank=ADC_INJECTED_RANK_4;             //注入组的排名ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC_Injection.InjectedOffset=0;                           //偏移量HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);}void ADC2_Init(void)
{ADC2_HandleType.Instance=ADC2;ADC2_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐ADC2_HandleType.Init.ScanConvMode=ADC_SCAN_ENABLE;  //扫描模式:使能ADC2_HandleType.Init.NbrOfConversion=10;            //扫描模式下规则组的数量ADC2_HandleType.Init.ContinuousConvMode=DISABLE;     //连续模式:  使能ADC2_HandleType.Init.DiscontinuousConvMode=DISABLE;   //规则组的间断模式   ADC2_HandleType.Init.ExternalTrigConv=ADC_SOFTWARE_START;//触发方式HAL_ADC_Init(&ADC2_HandleType);ADC_MultiModeTypeDef ADC_MultiMode={0};//注入组配置---配置为自动注入//自动注入和外部触发不可能共存ADC2_Injection.InjectedChannel=ADC_CHANNEL_6;               //需要配置的通道ADC2_Injection.InjectedRank=ADC_INJECTED_RANK_4;             //注入组的排名ADC2_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC2_Injection.InjectedOffset=0;                             //偏移量ADC2_Injection.InjectedNbrOfConversion=4;                        	//注入组的转化通道:max=4  ADC2_Injection.InjectedDiscontinuousConvMode=DISABLE;          //注入组间断模式;不可能同时使用自动注入和间断模式ADC2_Injection.AutoInjectedConv=DISABLE;                        //自动注入ADC2_Injection.ExternalTrigInjecConv=ADC_INJECTED_SOFTWARE_START;   //触发方式HAL_ADCEx_InjectedConfigChannel(&ADC2_HandleType,&ADC2_Injection);//注入组配置ADC2_Injection.InjectedChannel=ADC_CHANNEL_7;               //需要配置的通道ADC2_Injection.InjectedRank=ADC_INJECTED_RANK_3;             //注入组的排名ADC2_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC2_Injection.InjectedOffset=0;                           //偏移量HAL_ADCEx_InjectedConfigChannel(&ADC2_HandleType,&ADC2_Injection);//注入组配置ADC2_Injection.InjectedChannel=ADC_CHANNEL_8;               //需要配置的通道ADC2_Injection.InjectedRank=ADC_INJECTED_RANK_2;             //注入组的排名ADC2_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC2_Injection.InjectedOffset=0;                           //偏移量HAL_ADCEx_InjectedConfigChannel(&ADC2_HandleType,&ADC2_Injection);//注入组配置ADC2_Injection.InjectedChannel=ADC_CHANNEL_9;               //需要配置的通道ADC2_Injection.InjectedRank=ADC_INJECTED_RANK_1;             //注入组的排名ADC2_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC2_Injection.InjectedOffset=0;                           //偏移量HAL_ADCEx_InjectedConfigChannel(&ADC2_HandleType,&ADC2_Injection);//配置ADC双模式:同步规则模式ADC_MultiMode.Mode=ADC_DUALMODE_INJECSIMULT;HAL_ADCEx_MultiModeConfigChannel(&ADC_HandleType,&ADC_MultiMode);HAL_ADCEx_Calibration_Start(&ADC2_HandleType);   //自校准HAL_ADCEx_Calibration_Start(&ADC_HandleType);    //自校准HAL_ADCEx_InjectedStart_IT(&ADC_HandleType);      //中断方式开启注入组ADC1主模式HAL_ADCEx_InjectedStart(&ADC2_HandleType);      //开启注入组ADC2从模式HAL_ADCEx_MultiModeStart_DMA(&ADC_HandleType,DMA_buff,10);//双adc下使用这个API配置主adc}
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{if(hadc->Instance==ADC1){__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_GPIOB_CLK_ENABLE();__HAL_RCC_ADC1_CLK_ENABLE();__HAL_RCC_DMA1_CLK_ENABLE();GPIO_InitTypeDef GPIO_InitType;//模拟输入不用设置上下拉电阻GPIO_InitType.Mode=GPIO_MODE_ANALOG;  //模拟输入GPIO_InitType.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;HAL_GPIO_Init(GPIOA,&GPIO_InitType); GPIO_InitType.Mode=GPIO_MODE_ANALOG;  //模拟输入GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1;HAL_GPIO_Init(GPIOB,&GPIO_InitType); HAL_NVIC_SetPriority(ADC1_2_IRQn,4,0);          //ADC的中断优先级HAL_NVIC_EnableIRQ(ADC1_2_IRQn);                //开ADC的中断//DMA配置:方向寄存器(外设)-->数组(内存)DMA_Handle.Instance=DMA1_Channel1;DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY;  //传输方向:寄存器(外设)->数组(内存)DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE;   //寄存器(外设)是否递增加DMA_Handle.Init.MemInc=DMA_MINC_ENABLE;      //数组(内存)是否递增加DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_WORD;    //外设数据宽度(半字=2个字节)DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_WORD;      //数组(内存)数据宽度DMA_Handle.Init.Mode=DMA_CIRCULAR;                         //模式:循环DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle);   //或者下面的写法__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle);  //链接//DMA的配置HAL_DMA_Init(&DMA_Handle);HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,4,0);HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);}else if (hadc->Instance==ADC2){__HAL_RCC_ADC2_CLK_ENABLE();HAL_NVIC_SetPriority(ADC1_2_IRQn,4,0);          //ADC的中断优先级HAL_NVIC_EnableIRQ(ADC1_2_IRQn);                //开ADC的中断}
}void DMA1_Channel1_IRQHandler()
{HAL_DMA_IRQHandler(&DMA_Handle);}void ADC1_2_IRQHandler(void)
{HAL_ADC_IRQHandler(&ADC_HandleType);
}DMA将连续读取10个ADC转换结果并存储到DMA_buff中,后进入中断
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{			if(hadc->Instance==ADC1){
//		printf("DMA完成中断\r\n");
//		printf("ADC1_IN0:%d\r\n",DMA_buff[0]&0x0000FFFF);   //串口1输出电压值
//		printf("ADC1_IN1:%d\r\n",DMA_buff[1]&0x0000FFFF);   //串口1输出电压值
//		printf("ADC1_IN2:%d\r\n",DMA_buff[2]&0x0000FFFF);   //串口1输出电压值
//		printf("ADC1_IN3:%d\r\n",DMA_buff[3]&0x0000FFFF);   //串口1输出电压值
//		printf("ADC1_IN4:%d\r\n",DMA_buff[4]&0x0000FFFF);   //串口1输出电压值
//		printf("ADC1_IN5:%d\r\n",DMA_buff[5]&0x0000FFFF);   //串口1输出电压值
//		printf("ADC1_IN6:%d\r\n",DMA_buff[6]&0x0000FFFF);   //串口1输出电压值
//		printf("ADC1_IN7:%d\r\n",DMA_buff[7]&0x0000FFFF);   //串口1输出电压值
//		printf("ADC1_IN8:%d\r\n",DMA_buff[8]&0x0000FFFF);   //串口1输出电压值
//		printf("ADC1_IN9:%d\r\n",DMA_buff[9]&0x0000FFFF);   //串口1输出电压值
//		printf("----------------------------------------\r\n");
//		printf("ADC2_IN9:%d\r\n",(DMA_buff[0]&0xFFFF0000)>>16);   //串口1输出电压值
//		printf("ADC2_IN8:%d\r\n",(DMA_buff[1]&0xFFFF0000)>>16);   //串口1输出电压值
//		printf("ADC2_IN7:%d\r\n",(DMA_buff[2]&0xFFFF0000)>>16);   //串口1输出电压值
//		printf("ADC2_IN6:%d\r\n",(DMA_buff[3]&0xFFFF0000)>>16);   //串口1输出电压值
//		printf("ADC2_IN5:%d\r\n",(DMA_buff[4]&0xFFFF0000)>>16);   //串口1输出电压值
//		printf("ADC2_IN4:%d\r\n",(DMA_buff[5]&0xFFFF0000)>>16);   //串口1输出电压值
//		printf("ADC2_IN3:%d\r\n",(DMA_buff[6]&0xFFFF0000)>>16);   //串口1输出电压值
//		printf("ADC2_IN2:%d\r\n",(DMA_buff[7]&0xFFFF0000)>>16);   //串口1输出电压值}
}//注入组完成中断
void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef* hadc)
{if(hadc->Instance == ADC1){ printf("---------------------------------------------ADC1注入组完成\r\n");printf("ADC1_IN6:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC_HandleType,ADC_INJECTED_RANK_1));   //串口1输出电压值printf("ADC1_IN7:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC_HandleType,ADC_INJECTED_RANK_2));   //串口1输出电压值printf("ADC1_IN8:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC_HandleType,ADC_INJECTED_RANK_3));   //串口1输出电压值printf("ADC1_IN9:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC_HandleType,ADC_INJECTED_RANK_4));   //串口1输出电压值	printf("---------------------------------------------ADC2注入组完成\r\n");printf("ADC2_IN9:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC2_HandleType,ADC_INJECTED_RANK_1));   //串口1输出电压值printf("ADC2_IN8:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC2_HandleType,ADC_INJECTED_RANK_2));   //串口1输出电压值printf("ADC2_IN7:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC2_HandleType,ADC_INJECTED_RANK_3));   //串口1输出电压值printf("ADC2_IN6:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC2_HandleType,ADC_INJECTED_RANK_4));   //串口1输出电压值//__HAL_ADC_ENABLE_IT(hadc, ADC_IT_JEOC);}}#include "stm32f1xx_hal.h"
#include "pwm.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
//输入捕获功能
TIM_HandleTypeDef HandleTIMXCHX;
//TIM1的CC1事件
void IC_TIMX_CHX_init(uint16_t arr,uint16_t psc)
{TIM_MasterConfigTypeDef TIM_MasterConfig={0};TIM_IC_InitTypeDef TIM_IC_Init={0};HandleTIMXCHX.Instance=TIM4;   //基地址HandleTIMXCHX.Init.Period=arr;HandleTIMXCHX.Init.Prescaler=psc;HandleTIMXCHX.Init.CounterMode=TIM_COUNTERMODE_UP;   //向上计数HandleTIMXCHX.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;   //设置自动重载值 预装载使能位HandleTIMXCHX.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;   //设置分频因子HAL_TIM_IC_Init(&HandleTIMXCHX);//清除跟新中断标志位__HAL_TIM_CLEAR_FLAG(&HandleTIMXCHX,TIM_FLAG_UPDATE);TIM_MasterConfig.MasterOutputTrigger=TIM_TRGO_OC1;             //主定时器通道1捕获时发送信号//TIM_MasterConfig.MasterSlaveMode=TIM_MASTERSLAVEMODE_DISABLE;  //主从模式:关闭HAL_TIMEx_MasterConfigSynchronization(&HandleTIMXCHX,&TIM_MasterConfig);TIM_IC_Init.ICFilter=0x8;TIM_IC_Init.ICPolarity=TIM_ICPOLARITY_RISING;  //极性:上升沿TIM_IC_Init.ICSelection=TIM_ICSELECTION_DIRECTTI; //直连TIM_IC_Init.ICPrescaler=TIM_ICPSC_DIV1;HAL_TIM_IC_ConfigChannel(&HandleTIMXCHX,&TIM_IC_Init,TIM_CHANNEL_1);HAL_TIM_IC_Start(&HandleTIMXCHX,TIM_CHANNEL_1);}void HAL_TIM_IC_MspInit(TIM_HandleTypeDef *htim)
{if(htim->Instance==TIM4){__HAL_RCC_GPIOB_CLK_ENABLE();                   //打开B口时钟__HAL_RCC_TIM4_CLK_ENABLE();                    //打开定时器3的时钟GPIO_InitTypeDef GPIO_InitType;GPIO_InitType.Pin = GPIO_PIN_6;                 //配置PIN4GPIO_InitType.Mode = GPIO_MODE_AF_INPUT;        //复用功能 输入方向GPIO_InitType.Pull = GPIO_PULLDOWN;             //开启IO口内部的下拉电阻HAL_GPIO_Init(GPIOB,&GPIO_InitType);            //配置PB4}
}

当所有ADC1/ADC2注入通道都被转换时,产生JEOC中断(若任一ADC接口开放了中断)

关于中断:打开任意一个就ok了。

打开主模式(ADC1)的中断,在注入组中断回调函数中不需要再使能注入组的中断。(中断不会被关闭)

打开从模式(ADC2)的中断,需要再注入组的中断回调函数中再次打开注入组中断。(中断被关闭)

void HAL_ADC_IRQHandler(ADC_HandleTypeDef* hadc)/* Determine whether any further conversion upcoming on group injected  *//* by external trigger, scan sequence on going or by automatic injected *//* conversion from group regular (same conditions as group regular      *//* interruption disabling above).                                       *//* Note: On STM32F1 devices, in case of sequencer enabled               *//*       (several ranks selected), end of conversion flag is raised     *//*       at the end of the sequence.                                    */if(ADC_IS_SOFTWARE_START_INJECTED(hadc) 判断注入组是否开启了软件触发                  || (HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO) 判断是否清除的自动注入&&     (ADC_IS_SOFTWARE_START_REGULAR(hadc)  是否开启的规则组的软件触发      &&(hadc->Init.ContinuousConvMode == DISABLE)规则组是否开启了连续转换位   )        )   ){/* Disable ADC end of conversion interrupt on group injected */__HAL_ADC_DISABLE_IT(hadc, ADC_IT_JEOC);/* Set ADC state */CLEAR_BIT(hadc->State, HAL_ADC_STATE_INJ_BUSY);   if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_REG_BUSY)){ SET_BIT(hadc->State, HAL_ADC_STATE_READY);}}/* Conversion complete callback */ 
#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)hadc->InjectedConvCpltCallback(hadc);
#elseHAL_ADCEx_InjectedConvCpltCallback(hadc);  注入组中断回调函数
#endif /* USE_HAL_ADC_REGISTER_CALLBACKS *//* Clear injected group conversion flag */__HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_JSTRT | ADC_FLAG_JEOC));}}

D:双ADC 外部信号触发 ADC1 ADC2交替触发模式

没有软件触发,只有外部触发

int main(void)
{uint8_t res=0;HAL_Init();                         /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */delay_init(72);                     /* 延时初始化 */Uart_Init(115200);IC_TIMX_CHX_init(10000-1,7200-1);   //T=((ARR+1)*(PSC+1)) / 1SADC1_Init();  ADC2_Init();while (1){		}}
#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"
#include "TIM.h"ADC_HandleTypeDef ADC_HandleType;   //ADC1为主模式
ADC_HandleTypeDef ADC2_HandleType;   //ADC2为从模式ADC_ChannelConfTypeDef ADC_Channel[10];  //ADC1为主模式的通道
ADC_ChannelConfTypeDef ADC2_Channel[10];  //ADC2为从模式的通道ADC_InjectionConfTypeDef ADC_Injection;     //ADC1主模式的注入组
ADC_InjectionConfTypeDef ADC2_Injection;     //ADC1从模式的注入组
uint32_t DMA_buff[10];DMA_HandleTypeDef DMA_Handle;
void ADC1_Init(void)
{ADC_HandleType.Instance=ADC1;ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐ADC_HandleType.Init.ScanConvMode=ADC_SCAN_ENABLE;  //扫描模式:使能ADC_HandleType.Init.NbrOfConversion=10;            //扫描模式下规则组的数量ADC_HandleType.Init.ContinuousConvMode=ENABLE;     //连续模式:  使能ADC_HandleType.Init.DiscontinuousConvMode=DISABLE;   //规则组的间断模式   ADC_HandleType.Init.ExternalTrigConv=ADC_SOFTWARE_START;//触发方式HAL_ADC_Init(&ADC_HandleType);ADC_Channel[0].Channel=ADC_CHANNEL_0;     //通道编号ADC_Channel[0].Rank=ADC_REGULAR_RANK_1;     //排名ADC_Channel[0].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[0]);ADC_Channel[1].Channel=ADC_CHANNEL_1;     //通道编号ADC_Channel[1].Rank=ADC_REGULAR_RANK_2;     //排名ADC_Channel[1].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[1]);ADC_Channel[2].Channel=ADC_CHANNEL_2;     //通道编号ADC_Channel[2].Rank=ADC_REGULAR_RANK_3;     //排名ADC_Channel[2].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[2]);ADC_Channel[3].Channel=ADC_CHANNEL_3;     //通道编号ADC_Channel[3].Rank=ADC_REGULAR_RANK_4;     //排名ADC_Channel[3].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&	ADC_Channel[3]);ADC_Channel[4].Channel=ADC_CHANNEL_4;     //通道编号ADC_Channel[4].Rank=ADC_REGULAR_RANK_5;     //排名ADC_Channel[4].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[4]);ADC_Channel[5].Channel=ADC_CHANNEL_5;     //通道编号ADC_Channel[5].Rank=ADC_REGULAR_RANK_6;     //排名ADC_Channel[5].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[5]);ADC_Channel[6].Channel=ADC_CHANNEL_6;     //通道编号ADC_Channel[6].Rank=ADC_REGULAR_RANK_7;     //排名ADC_Channel[6].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[6]);ADC_Channel[7].Channel=ADC_CHANNEL_7;     //通道编号ADC_Channel[7].Rank=ADC_REGULAR_RANK_8;     //排名ADC_Channel[7].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[7]);ADC_Channel[8].Channel=ADC_CHANNEL_8;     //通道编号ADC_Channel[8].Rank=ADC_REGULAR_RANK_9;     //排名ADC_Channel[8].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[8]);ADC_Channel[9].Channel=ADC_CHANNEL_9;     //通道编号ADC_Channel[9].Rank=ADC_REGULAR_RANK_10;     //排名ADC_Channel[9].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[9]);//注入组配置---配置为自动注入//自动注入和外部触发不可能共存ADC_Injection.InjectedChannel=ADC_CHANNEL_6;               //需要配置的通道ADC_Injection.InjectedRank=ADC_INJECTED_RANK_1;             //注入组的排名ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC_Injection.InjectedOffset=0;                             //偏移量ADC_Injection.InjectedNbrOfConversion=4;                        	//注入组的转化通道:max=4  ADC_Injection.InjectedDiscontinuousConvMode=DISABLE;          //注入组间断模式;不可能同时使用自动注入和间断模式ADC_Injection.AutoInjectedConv=DISABLE;                        //自动注入ADC_Injection.ExternalTrigInjecConv=ADC_EXTERNALTRIGINJECCONV_T2_CC1;   //触发方式:TIM2的CC1(通道1)HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);//注入组配置ADC_Injection.InjectedChannel=ADC_CHANNEL_7;               //需要配置的通道ADC_Injection.InjectedRank=ADC_INJECTED_RANK_2;             //注入组的排名ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC_Injection.InjectedOffset=0;                           //偏移量HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);//注入组配置ADC_Injection.InjectedChannel=ADC_CHANNEL_8;               //需要配置的通道ADC_Injection.InjectedRank=ADC_INJECTED_RANK_3;             //注入组的排名ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC_Injection.InjectedOffset=0;                           //偏移量HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);//注入组配置ADC_Injection.InjectedChannel=ADC_CHANNEL_9;               //需要配置的通道ADC_Injection.InjectedRank=ADC_INJECTED_RANK_4;             //注入组的排名ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC_Injection.InjectedOffset=0;                           //偏移量HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);}void ADC2_Init(void)
{ADC2_HandleType.Instance=ADC2;ADC2_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐ADC2_HandleType.Init.ScanConvMode=ADC_SCAN_ENABLE;  //扫描模式:使能ADC2_HandleType.Init.NbrOfConversion=0;            //扫描模式下规则组的数量ADC2_HandleType.Init.ContinuousConvMode=DISABLE;     //连续模式:  使能ADC2_HandleType.Init.DiscontinuousConvMode=DISABLE;   //规则组的间断模式   ADC2_HandleType.Init.ExternalTrigConv=ADC_SOFTWARE_START;//触发方式HAL_ADC_Init(&ADC2_HandleType);ADC_MultiModeTypeDef ADC_MultiMode={0};//注入组配置---配置为自动注入//自动注入和外部触发不可能共存ADC2_Injection.InjectedChannel=ADC_CHANNEL_6;               //需要配置的通道ADC2_Injection.InjectedRank=ADC_INJECTED_RANK_4;             //注入组的排名ADC2_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC2_Injection.InjectedOffset=0;                             //偏移量ADC2_Injection.InjectedNbrOfConversion=4;                        	//注入组的转化通道:max=4  ADC2_Injection.InjectedDiscontinuousConvMode=DISABLE;          //注入组间断模式;不可能同时使用自动注入和间断模式ADC2_Injection.AutoInjectedConv=DISABLE;                        //自动注入ADC2_Injection.ExternalTrigInjecConv=ADC_INJECTED_SOFTWARE_START;   //触发方式HAL_ADCEx_InjectedConfigChannel(&ADC2_HandleType,&ADC2_Injection);//注入组配置ADC2_Injection.InjectedChannel=ADC_CHANNEL_7;               //需要配置的通道ADC2_Injection.InjectedRank=ADC_INJECTED_RANK_3;             //注入组的排名ADC2_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC2_Injection.InjectedOffset=0;                           //偏移量HAL_ADCEx_InjectedConfigChannel(&ADC2_HandleType,&ADC2_Injection);//注入组配置ADC2_Injection.InjectedChannel=ADC_CHANNEL_8;               //需要配置的通道ADC2_Injection.InjectedRank=ADC_INJECTED_RANK_2;             //注入组的排名ADC2_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC2_Injection.InjectedOffset=0;                           //偏移量HAL_ADCEx_InjectedConfigChannel(&ADC2_HandleType,&ADC2_Injection);//注入组配置ADC2_Injection.InjectedChannel=ADC_CHANNEL_9;               //需要配置的通道ADC2_Injection.InjectedRank=ADC_INJECTED_RANK_1;             //注入组的排名ADC2_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC2_Injection.InjectedOffset=0;                           //偏移量HAL_ADCEx_InjectedConfigChannel(&ADC2_HandleType,&ADC2_Injection);//配置ADC双模式:交替触发模式ADC_MultiMode.Mode=ADC_DUALMODE_ALTERTRIG;HAL_ADCEx_MultiModeConfigChannel(&ADC_HandleType,&ADC_MultiMode);HAL_ADCEx_Calibration_Start(&ADC2_HandleType);   //自校准HAL_ADCEx_Calibration_Start(&ADC_HandleType);    //自校准HAL_ADCEx_InjectedStart_IT(&ADC_HandleType);      //中断方式开启注入组ADC1主模式HAL_ADCEx_InjectedStart_IT(&ADC2_HandleType);      //中断方式开启注入组ADC2从模式//配置规则组HAL_ADCEx_MultiModeStart_DMA(&ADC_HandleType,DMA_buff,10);//双adc下使用这个API配置主adc}
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{if(hadc->Instance==ADC1){__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_GPIOB_CLK_ENABLE();__HAL_RCC_ADC1_CLK_ENABLE();__HAL_RCC_DMA1_CLK_ENABLE();GPIO_InitTypeDef GPIO_InitType;//模拟输入不用设置上下拉电阻GPIO_InitType.Mode=GPIO_MODE_ANALOG;  //模拟输入GPIO_InitType.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;HAL_GPIO_Init(GPIOA,&GPIO_InitType); GPIO_InitType.Mode=GPIO_MODE_ANALOG;  //模拟输入GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1;HAL_GPIO_Init(GPIOB,&GPIO_InitType); HAL_NVIC_SetPriority(ADC1_2_IRQn,4,0);          //ADC的中断优先级HAL_NVIC_EnableIRQ(ADC1_2_IRQn);                //开ADC的中断//DMA配置:方向寄存器(外设)-->数组(内存)DMA_Handle.Instance=DMA1_Channel1;DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY;  //传输方向:寄存器(外设)->数组(内存)DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE;   //寄存器(外设)是否递增加DMA_Handle.Init.MemInc=DMA_MINC_ENABLE;      //数组(内存)是否递增加DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_WORD;    //外设数据宽度(半字=2个字节)DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_WORD;      //数组(内存)数据宽度DMA_Handle.Init.Mode=DMA_CIRCULAR;                         //模式:循环DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle);   //或者下面的写法__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle);  //链接//DMA的配置HAL_DMA_Init(&DMA_Handle);HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,4,0);HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);}else if (hadc->Instance==ADC2){__HAL_RCC_ADC2_CLK_ENABLE();HAL_NVIC_SetPriority(ADC1_2_IRQn,4,0);          //ADC的中断优先级HAL_NVIC_EnableIRQ(ADC1_2_IRQn);                //开ADC的中断}
}void DMA1_Channel1_IRQHandler()
{HAL_DMA_IRQHandler(&DMA_Handle);}void ADC1_2_IRQHandler(void)
{HAL_ADC_IRQHandler(&ADC_HandleType);HAL_ADC_IRQHandler(&ADC2_HandleType);
}DMA将连续读取10个ADC转换结果并存储到DMA_buff中,后进入中断
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{			if(hadc->Instance==ADC1){
//		printf("DMA完成中断\r\n");
//		printf("ADC1_IN0:%d\r\n",DMA_buff[0]&0x0000FFFF);   //串口1输出电压值
//		printf("ADC1_IN1:%d\r\n",DMA_buff[1]&0x0000FFFF);   //串口1输出电压值
//		printf("ADC1_IN2:%d\r\n",DMA_buff[2]&0x0000FFFF);   //串口1输出电压值
//		printf("ADC1_IN3:%d\r\n",DMA_buff[3]&0x0000FFFF);   //串口1输出电压值
//		printf("ADC1_IN4:%d\r\n",DMA_buff[4]&0x0000FFFF);   //串口1输出电压值
//		printf("ADC1_IN5:%d\r\n",DMA_buff[5]&0x0000FFFF);   //串口1输出电压值
//		printf("ADC1_IN6:%d\r\n",DMA_buff[6]&0x0000FFFF);   //串口1输出电压值
//		printf("ADC1_IN7:%d\r\n",DMA_buff[7]&0x0000FFFF);   //串口1输出电压值
//		printf("ADC1_IN8:%d\r\n",DMA_buff[8]&0x0000FFFF);   //串口1输出电压值
//		printf("ADC1_IN9:%d\r\n",DMA_buff[9]&0x0000FFFF);   //串口1输出电压值
//		printf("----------------------------------------\r\n");
//		printf("ADC2_IN9:%d\r\n",(DMA_buff[0]&0xFFFF0000)>>16);   //串口1输出电压值
//		printf("ADC2_IN8:%d\r\n",(DMA_buff[1]&0xFFFF0000)>>16);   //串口1输出电压值
//		printf("ADC2_IN7:%d\r\n",(DMA_buff[2]&0xFFFF0000)>>16);   //串口1输出电压值
//		printf("ADC2_IN6:%d\r\n",(DMA_buff[3]&0xFFFF0000)>>16);   //串口1输出电压值
//		printf("ADC2_IN5:%d\r\n",(DMA_buff[4]&0xFFFF0000)>>16);   //串口1输出电压值
//		printf("ADC2_IN4:%d\r\n",(DMA_buff[5]&0xFFFF0000)>>16);   //串口1输出电压值
//		printf("ADC2_IN3:%d\r\n",(DMA_buff[6]&0xFFFF0000)>>16);   //串口1输出电压值
//		printf("ADC2_IN2:%d\r\n",(DMA_buff[7]&0xFFFF0000)>>16);   //串口1输出电压值}
}//注入组完成中断
void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef* hadc)
{if(hadc->Instance == ADC1){ printf("---------------------------------------------ADC1注入组完成\r\n");printf("ADC1_IN6:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC_HandleType,ADC_INJECTED_RANK_1));   //串口1输出电压值printf("ADC1_IN7:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC_HandleType,ADC_INJECTED_RANK_2));   //串口1输出电压值printf("ADC1_IN8:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC_HandleType,ADC_INJECTED_RANK_3));   //串口1输出电压值printf("ADC1_IN9:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC_HandleType,ADC_INJECTED_RANK_4));   //串口1输出电压值	//__HAL_ADC_ENABLE_IT(hadc, ADC_IT_JEOC);}else if(hadc->Instance == ADC2){ printf("---------------------------------------------ADC2注入组完成\r\n");printf("ADC2_IN9:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC2_HandleType,ADC_INJECTED_RANK_1));   //串口1输出电压值printf("ADC2_IN8:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC2_HandleType,ADC_INJECTED_RANK_2));   //串口1输出电压值printf("ADC2_IN7:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC2_HandleType,ADC_INJECTED_RANK_3));   //串口1输出电压值printf("ADC2_IN6:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC2_HandleType,ADC_INJECTED_RANK_4));   //串口1输出电压值__HAL_ADC_ENABLE_IT(hadc, ADC_IT_JEOC);}}#include "stm32f1xx_hal.h"
#include "pwm.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "ADC.h"//输入捕获功能
TIM_HandleTypeDef HandleTIMXCHX;
//TIM1的CC1事件
void IC_TIMX_CHX_init(uint16_t arr,uint16_t psc)
{TIM_OC_InitTypeDef TIM_OC_Init={0};HandleTIMXCHX.Instance=TIM2;   //基地址HandleTIMXCHX.Init.Period=arr;HandleTIMXCHX.Init.Prescaler=psc;HandleTIMXCHX.Init.CounterMode=TIM_COUNTERMODE_UP;   //向上计数HandleTIMXCHX.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;   //设置自动重载值 预装载使能位HandleTIMXCHX.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;   //设置分频因子HAL_TIM_OC_Init(&HandleTIMXCHX);//清除跟新中断标志位__HAL_TIM_CLEAR_FLAG(&HandleTIMXCHX,TIM_FLAG_UPDATE);TIM_OC_Init.OCMode=TIM_OCMODE_PWM1;TIM_OC_Init.Pulse=100;    //比较值(CCR)TIM_OC_Init.OCPolarity=TIM_OCPOLARITY_LOW;//有效值  :PWM1:CNT<CCR输出有效电平  TIM_OC_Init.OCFastMode = TIM_OCFAST_DISABLE;    HAL_TIM_OC_ConfigChannel(&HandleTIMXCHX, &TIM_OC_Init,TIM_CHANNEL_1);HAL_TIM_OC_Start(&HandleTIMXCHX,TIM_CHANNEL_1);}void HAL_TIM_OC_MspInit(TIM_HandleTypeDef *htim)
{if(htim->Instance==TIM2){__HAL_RCC_TIM2_CLK_ENABLE();                    //打开定时器3的时钟//信号为内部触发所以,定时器2_CH2引脚可以使用初始化HAL_NVIC_SetPriority(TIM2_IRQn,3,0);            //定时器3的中断优先级HAL_NVIC_EnableIRQ(TIM2_IRQn);                  //开定时器3的中断}
}

E:双ADC 外部信号触发 ADC1 ADC2交替触发模式+间断模式 

没有软件触发,只有外部触发

所有的东西和D一样,不过就是开启了ADC1和ADC2的注入模式。 

ADC_Injection.InjectedDiscontinuousConvMode=ENABLE;          //注入组间断模式;不可能同时使用自动注入和间断模式

F:双ADC 外部信号触发 ADC1 ADC2快速交叉模式

没有软件触发,只有外部触发

int main(void)
{uint8_t res=0;HAL_Init();                         /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */delay_init(72);                     /* 延时初始化 */Uart_Init(115200);IC_TIMX_CHX_init(5000-1,3600-1);   //T=((ARR+1)*(PSC+1)) / 0.25s   0.25*10=2.5s因为DMA转运10次进入一次DMA中断ADC1_Init();  ADC2_Init();while (1){		}}
#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"
#include "TIM.h"ADC_HandleTypeDef ADC_HandleType;   //ADC1为主模式
ADC_HandleTypeDef ADC2_HandleType;   //ADC2为从模式ADC_ChannelConfTypeDef ADC_Channel[10];  //ADC1为主模式的通道
ADC_ChannelConfTypeDef ADC2_Channel[10];  //ADC2为从模式的通道ADC_InjectionConfTypeDef ADC_Injection;     //ADC1主模式的注入组
ADC_InjectionConfTypeDef ADC2_Injection;     //ADC1从模式的注入组
uint32_t DMA_buff[10];DMA_HandleTypeDef DMA_Handle;
void ADC1_Init(void)
{ADC_HandleType.Instance=ADC1;ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐ADC_HandleType.Init.ScanConvMode=ADC_SCAN_DISABLE;  //扫描模式:失能//ADC_HandleType.Init.NbrOfConversion=1;            //扫描模式下规则组的数量ADC_HandleType.Init.ContinuousConvMode=DISABLE;     //连续模式:  使能ADC_HandleType.Init.DiscontinuousConvMode=DISABLE;   //规则组的间断模式   ADC_HandleType.Init.ExternalTrigConv=ADC_EXTERNALTRIGCONV_T2_CC2;//触发方式HAL_ADC_Init(&ADC_HandleType);ADC_Channel[0].Channel=ADC_CHANNEL_3;     //通道编号ADC_Channel[0].Rank=ADC_REGULAR_RANK_1;     //排名ADC_Channel[0].SamplingTime=ADC_SAMPLETIME_1CYCLE_5;   //周期://配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[0]);}void ADC2_Init(void)
{ADC2_HandleType.Instance=ADC2;ADC2_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐ADC2_HandleType.Init.ScanConvMode=ADC_SCAN_DISABLE;  //扫描模式:失能//ADC2_HandleType.Init.NbrOfConversion=1;            //扫描模式下规则组的数量ADC2_HandleType.Init.ContinuousConvMode=DISABLE;     //连续模式:  使能ADC2_HandleType.Init.DiscontinuousConvMode=DISABLE;   //规则组的间断模式   ADC2_HandleType.Init.ExternalTrigConv=ADC_SOFTWARE_START;//触发方式HAL_ADC_Init(&ADC2_HandleType);ADC_MultiModeTypeDef ADC_MultiMode={0};ADC2_Channel[0].Channel=ADC_CHANNEL_3;     //通道编号ADC2_Channel[0].Rank=ADC_REGULAR_RANK_1;     //排名ADC2_Channel[0].SamplingTime=ADC_SAMPLETIME_1CYCLE_5;   //周期://配置规则组通道HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[0]);//配置ADC双模式:快速交叉模式ADC_MultiMode.Mode=ADC_DUALMODE_INTERLFAST;HAL_ADCEx_MultiModeConfigChannel(&ADC_HandleType,&ADC_MultiMode);HAL_ADCEx_Calibration_Start(&ADC_HandleType);    //自校准HAL_ADCEx_Calibration_Start(&ADC2_HandleType);   //自校准HAL_ADC_Start(&ADC2_HandleType);//配置规则组HAL_ADCEx_MultiModeStart_DMA(&ADC_HandleType,DMA_buff,10);//双adc下使用这个API配置主adc}
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{if(hadc->Instance==ADC1){__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_GPIOB_CLK_ENABLE();__HAL_RCC_ADC1_CLK_ENABLE();__HAL_RCC_DMA1_CLK_ENABLE();GPIO_InitTypeDef GPIO_InitType;//模拟输入不用设置上下拉电阻GPIO_InitType.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_InitType.Mode = GPIO_MODE_ANALOG;       //ADC功能HAL_GPIO_Init(GPIOA,&GPIO_InitType);         //配置PA0 1 2 3 4 5 6 7	GPIO_InitType.Pin = GPIO_PIN_0|GPIO_PIN_1;   //配置PIN0 1         GPIO_InitType.Mode = GPIO_MODE_ANALOG;       //ADC功能HAL_GPIO_Init(GPIOB,&GPIO_InitType);         //配置PB0 1//DMA配置:方向寄存器(外设)-->数组(内存)DMA_Handle.Instance=DMA1_Channel1;DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY;  //传输方向:寄存器(外设)->数组(内存)DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE;   //寄存器(外设)是否递增加DMA_Handle.Init.MemInc=DMA_MINC_ENABLE;      //数组(内存)是否递增加DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_WORD;    //外设数据宽度(半字=2个字节)DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_WORD;      //数组(内存)数据宽度DMA_Handle.Init.Mode=DMA_CIRCULAR;                         //模式:循环DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle);   //或者下面的写法__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle);  //链接//DMA的配置HAL_DMA_Init(&DMA_Handle);HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,3,0);   //DMA通道1的中断优先级HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);         //开DMA通道1的中断	}else if (hadc->Instance==ADC2){__HAL_RCC_ADC2_CLK_ENABLE();}
}void DMA1_Channel1_IRQHandler()
{HAL_DMA_IRQHandler(&DMA_Handle);}DMA将连续读取10个ADC转换结果并存储到DMA_buff中,后进入中断
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{			uint32_t i,sum;if(hadc->Instance==ADC1){sum = 0;for(i=0;i<10;i++){sum += DMA_buff[i];}printf("DMA完成中断\r\n");printf("ADC1_IN3:%f\r\n",((sum&0x0000FFFF)/10.0)*(3.3/4096.0));   //串口1输出电压值printf("ADC2_IN3:%f\r\n",(((sum&0xFFFF0000)>>16)/10.0)*(3.3/4096.0));   //串口1输出电压值}
}#include "stm32f1xx_hal.h"
#include "pwm.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "ADC.h"//输入捕获功能
TIM_HandleTypeDef HandleTIMXCHX;
//TIM1的CC1事件
void IC_TIMX_CHX_init(uint16_t arr,uint16_t psc)
{TIM_OC_InitTypeDef TIM_OC_Init={0};HandleTIMXCHX.Instance=TIM2;   //基地址HandleTIMXCHX.Init.Period=arr;HandleTIMXCHX.Init.Prescaler=psc;HandleTIMXCHX.Init.CounterMode=TIM_COUNTERMODE_UP;   //向上计数HandleTIMXCHX.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;   //设置自动重载值 预装载使能位HandleTIMXCHX.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;   //设置分频因子HAL_TIM_OC_Init(&HandleTIMXCHX);//清除跟新中断标志位__HAL_TIM_CLEAR_FLAG(&HandleTIMXCHX,TIM_FLAG_UPDATE);TIM_OC_Init.OCMode=TIM_OCMODE_PWM1;TIM_OC_Init.Pulse=100;    //比较值(CCR)TIM_OC_Init.OCPolarity=TIM_OCPOLARITY_LOW;//有效值  :PWM1:CNT<CCR输出有效电平  TIM_OC_Init.OCFastMode = TIM_OCFAST_DISABLE;    HAL_TIM_OC_ConfigChannel(&HandleTIMXCHX, &TIM_OC_Init,TIM_CHANNEL_2);HAL_TIM_OC_Start(&HandleTIMXCHX,TIM_CHANNEL_2);}void HAL_TIM_OC_MspInit(TIM_HandleTypeDef *htim)
{if(htim->Instance==TIM2){__HAL_RCC_TIM2_CLK_ENABLE();                    //打开定时器3的时钟//信号为内部触发所以,定时器2_CH2引脚可以使用初始化}
}

G:双ADC 外部信号触发 ADC1 ADC2慢速交叉模式

没有软件触发,只有外部触发

int main(void)
{uint8_t res=0;HAL_Init();                         /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */delay_init(72);                     /* 延时初始化 */Uart_Init(115200);IC_TIMX_CHX_init(50000-1,7200-1);   //T=((ARR+1)*(PSC+1)) / 5s   5*10=50s因为DMA转运10次进入一次DMA中断ADC1_Init();  ADC2_Init();while (1){		}}
#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"
#include "TIM.h"ADC_HandleTypeDef ADC_HandleType;   //ADC1为主模式
ADC_HandleTypeDef ADC2_HandleType;   //ADC2为从模式ADC_ChannelConfTypeDef ADC_Channel[10];  //ADC1为主模式的通道
ADC_ChannelConfTypeDef ADC2_Channel[10];  //ADC2为从模式的通道ADC_InjectionConfTypeDef ADC_Injection;     //ADC1主模式的注入组
ADC_InjectionConfTypeDef ADC2_Injection;     //ADC1从模式的注入组
uint32_t DMA_buff[10];DMA_HandleTypeDef DMA_Handle;
void ADC1_Init(void)
{ADC_HandleType.Instance=ADC1;ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐ADC_HandleType.Init.ScanConvMode=ADC_SCAN_DISABLE;  //扫描模式:失能//ADC_HandleType.Init.NbrOfConversion=1;            //扫描模式下规则组的数量ADC_HandleType.Init.ContinuousConvMode=DISABLE;     //连续模式:  使能ADC_HandleType.Init.DiscontinuousConvMode=DISABLE;   //规则组的间断模式   ADC_HandleType.Init.ExternalTrigConv=ADC_EXTERNALTRIGCONV_T2_CC2;//触发方式HAL_ADC_Init(&ADC_HandleType);ADC_Channel[0].Channel=ADC_CHANNEL_3;     //通道编号ADC_Channel[0].Rank=ADC_REGULAR_RANK_1;     //排名ADC_Channel[0].SamplingTime=ADC_SAMPLETIME_1CYCLE_5;   //周期://配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[0]);}void ADC2_Init(void)
{ADC2_HandleType.Instance=ADC2;ADC2_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐ADC2_HandleType.Init.ScanConvMode=ADC_SCAN_DISABLE;  //扫描模式:失能//ADC2_HandleType.Init.NbrOfConversion=1;            //扫描模式下规则组的数量ADC2_HandleType.Init.ContinuousConvMode=DISABLE;     //连续模式:  使能ADC2_HandleType.Init.DiscontinuousConvMode=DISABLE;   //规则组的间断模式   ADC2_HandleType.Init.ExternalTrigConv=ADC_SOFTWARE_START;//触发方式HAL_ADC_Init(&ADC2_HandleType);ADC_MultiModeTypeDef ADC_MultiMode={0};ADC2_Channel[0].Channel=ADC_CHANNEL_3;     //通道编号ADC2_Channel[0].Rank=ADC_REGULAR_RANK_1;     //排名ADC2_Channel[0].SamplingTime=ADC_SAMPLETIME_1CYCLE_5;   //周期://配置规则组通道HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[0]);//配置ADC双模式:慢交叉模式ADC_MultiMode.Mode=ADC_DUALMODE_INTERLSLOW;HAL_ADCEx_MultiModeConfigChannel(&ADC_HandleType,&ADC_MultiMode);HAL_ADCEx_Calibration_Start(&ADC_HandleType);    //自校准HAL_ADCEx_Calibration_Start(&ADC2_HandleType);   //自校准HAL_ADC_Start(&ADC2_HandleType);//配置规则组HAL_ADCEx_MultiModeStart_DMA(&ADC_HandleType,DMA_buff,10);//双adc下使用这个API配置主adc}
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{if(hadc->Instance==ADC1){__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_GPIOB_CLK_ENABLE();__HAL_RCC_ADC1_CLK_ENABLE();__HAL_RCC_DMA1_CLK_ENABLE();GPIO_InitTypeDef GPIO_InitType;//模拟输入不用设置上下拉电阻GPIO_InitType.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_InitType.Mode = GPIO_MODE_ANALOG;       //ADC功能HAL_GPIO_Init(GPIOA,&GPIO_InitType);         //配置PA0 1 2 3 4 5 6 7	GPIO_InitType.Pin = GPIO_PIN_0|GPIO_PIN_1;   //配置PIN0 1         GPIO_InitType.Mode = GPIO_MODE_ANALOG;       //ADC功能HAL_GPIO_Init(GPIOB,&GPIO_InitType);         //配置PB0 1//DMA配置:方向寄存器(外设)-->数组(内存)DMA_Handle.Instance=DMA1_Channel1;DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY;  //传输方向:寄存器(外设)->数组(内存)DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE;   //寄存器(外设)是否递增加DMA_Handle.Init.MemInc=DMA_MINC_ENABLE;      //数组(内存)是否递增加DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_WORD;    //外设数据宽度(半字=2个字节)DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_WORD;      //数组(内存)数据宽度DMA_Handle.Init.Mode=DMA_CIRCULAR;                         //模式:循环DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle);   //或者下面的写法__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle);  //链接//DMA的配置HAL_DMA_Init(&DMA_Handle);HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,3,0);   //DMA通道1的中断优先级HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);         //开DMA通道1的中断	}else if (hadc->Instance==ADC2){__HAL_RCC_ADC2_CLK_ENABLE();}
}void DMA1_Channel1_IRQHandler()
{HAL_DMA_IRQHandler(&DMA_Handle);}DMA将连续读取10个ADC转换结果并存储到DMA_buff中,后进入中断
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{			uint32_t i,sum;if(hadc->Instance==ADC1){sum = 0;for(i=0;i<10;i++){sum += DMA_buff[i];}printf("DMA完成中断\r\n");printf("ADC1_IN3:%f\r\n",((sum&0x0000FFFF)/10.0)*(3.3/4096.0));   //串口1输出电压值printf("ADC2_IN3:%f\r\n",(((sum&0xFFFF0000)>>16)/10.0)*(3.3/4096.0));   //串口1输出电压值}
}#include "stm32f1xx_hal.h"
#include "pwm.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "ADC.h"//输入捕获功能
TIM_HandleTypeDef HandleTIMXCHX;
//TIM1的CC1事件
void IC_TIMX_CHX_init(uint16_t arr,uint16_t psc)
{TIM_OC_InitTypeDef TIM_OC_Init={0};HandleTIMXCHX.Instance=TIM2;   //基地址HandleTIMXCHX.Init.Period=arr;HandleTIMXCHX.Init.Prescaler=psc;HandleTIMXCHX.Init.CounterMode=TIM_COUNTERMODE_UP;   //向上计数HandleTIMXCHX.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;   //设置自动重载值 预装载使能位HandleTIMXCHX.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;   //设置分频因子HAL_TIM_OC_Init(&HandleTIMXCHX);//清除跟新中断标志位__HAL_TIM_CLEAR_FLAG(&HandleTIMXCHX,TIM_FLAG_UPDATE);TIM_OC_Init.OCMode=TIM_OCMODE_PWM1;TIM_OC_Init.Pulse=100;    //比较值(CCR)TIM_OC_Init.OCPolarity=TIM_OCPOLARITY_LOW;//有效值  :PWM1:CNT<CCR输出有效电平  TIM_OC_Init.OCFastMode = TIM_OCFAST_DISABLE;    HAL_TIM_OC_ConfigChannel(&HandleTIMXCHX, &TIM_OC_Init,TIM_CHANNEL_2);HAL_TIM_OC_Start(&HandleTIMXCHX,TIM_CHANNEL_2);}void HAL_TIM_OC_MspInit(TIM_HandleTypeDef *htim)
{if(htim->Instance==TIM2){__HAL_RCC_TIM2_CLK_ENABLE();                    //打开定时器3的时钟//信号为内部触发所以,定时器2_CH2引脚可以使用初始化}
}

ADC2 立即启动并且
ADC1 在延迟 14 ADC 时钟周期后启动
● 在延迟第二次 14 ADC 周期后 ADC2 再次启动,如此循环。
在慢速交叉模式下只有开始的信号是受控制的,第二次将以14个 ADC 周期后 再次启动,如此循环。

H:双ADC混合模式 ADC1 ADC2同步规则+同步注入模式


int main(void)
{uint8_t res=0;HAL_Init();                         /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */delay_init(72);                     /* 延时初始化 */Uart_Init(115200);ADC1_Init();  ADC2_Init();while (1){		}}#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"
#include "TIM.h"ADC_HandleTypeDef ADC_HandleType;   //ADC1为主模式
ADC_HandleTypeDef ADC2_HandleType;   //ADC2为从模式ADC_ChannelConfTypeDef ADC_Channel[10];  //ADC1为主模式的通道
ADC_ChannelConfTypeDef ADC2_Channel[10];  //ADC2为从模式的通道ADC_InjectionConfTypeDef ADC_Injection;     //ADC1主模式的注入组
ADC_InjectionConfTypeDef ADC2_Injection;     //ADC1从模式的注入组
uint32_t DMA_buff[10];DMA_HandleTypeDef DMA_Handle;
void ADC1_Init(void)
{ADC_HandleType.Instance=ADC1;ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐ADC_HandleType.Init.ScanConvMode=ADC_SCAN_ENABLE;  //扫描模式:使能ADC_HandleType.Init.NbrOfConversion=10;            //扫描模式下规则组的数量ADC_HandleType.Init.ContinuousConvMode=ENABLE;     //连续模式:  使能ADC_HandleType.Init.DiscontinuousConvMode=DISABLE;   //规则组的间断模式   ADC_HandleType.Init.ExternalTrigConv=ADC_SOFTWARE_START;//触发方式HAL_ADC_Init(&ADC_HandleType);ADC_Channel[0].Channel=ADC_CHANNEL_0;     //通道编号ADC_Channel[0].Rank=ADC_REGULAR_RANK_1;     //排名ADC_Channel[0].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[0]);ADC_Channel[1].Channel=ADC_CHANNEL_1;     //通道编号ADC_Channel[1].Rank=ADC_REGULAR_RANK_2;     //排名ADC_Channel[1].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[1]);ADC_Channel[2].Channel=ADC_CHANNEL_2;     //通道编号ADC_Channel[2].Rank=ADC_REGULAR_RANK_3;     //排名ADC_Channel[2].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[2]);ADC_Channel[3].Channel=ADC_CHANNEL_3;     //通道编号ADC_Channel[3].Rank=ADC_REGULAR_RANK_4;     //排名ADC_Channel[3].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&	ADC_Channel[3]);ADC_Channel[4].Channel=ADC_CHANNEL_4;     //通道编号ADC_Channel[4].Rank=ADC_REGULAR_RANK_5;     //排名ADC_Channel[4].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[4]);ADC_Channel[5].Channel=ADC_CHANNEL_5;     //通道编号ADC_Channel[5].Rank=ADC_REGULAR_RANK_6;     //排名ADC_Channel[5].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[5]);ADC_Channel[6].Channel=ADC_CHANNEL_6;     //通道编号ADC_Channel[6].Rank=ADC_REGULAR_RANK_7;     //排名ADC_Channel[6].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[6]);ADC_Channel[7].Channel=ADC_CHANNEL_7;     //通道编号ADC_Channel[7].Rank=ADC_REGULAR_RANK_8;     //排名ADC_Channel[7].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[7]);ADC_Channel[8].Channel=ADC_CHANNEL_8;     //通道编号ADC_Channel[8].Rank=ADC_REGULAR_RANK_9;     //排名ADC_Channel[8].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[8]);ADC_Channel[9].Channel=ADC_CHANNEL_9;     //通道编号ADC_Channel[9].Rank=ADC_REGULAR_RANK_10;     //排名ADC_Channel[9].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[9]);//注入组配置---配置为自动注入//自动注入和外部触发不可能共存ADC_Injection.InjectedChannel=ADC_CHANNEL_6;               //需要配置的通道ADC_Injection.InjectedRank=ADC_INJECTED_RANK_1;             //注入组的排名ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC_Injection.InjectedOffset=0;                             //偏移量ADC_Injection.InjectedNbrOfConversion=4;                        	//注入组的转化通道:max=4  ADC_Injection.InjectedDiscontinuousConvMode=DISABLE;          //注入组间断模式;不可能同时使用自动注入和间断模式ADC_Injection.AutoInjectedConv=DISABLE;                        //自动注入ADC_Injection.ExternalTrigInjecConv=ADC_EXTERNALTRIGINJECCONV_EXT_IT15;   //触发方式:_EXT_IT15HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);//注入组配置ADC_Injection.InjectedChannel=ADC_CHANNEL_7;               //需要配置的通道ADC_Injection.InjectedRank=ADC_INJECTED_RANK_2;             //注入组的排名ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC_Injection.InjectedOffset=0;                           //偏移量HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);//注入组配置ADC_Injection.InjectedChannel=ADC_CHANNEL_8;               //需要配置的通道ADC_Injection.InjectedRank=ADC_INJECTED_RANK_3;             //注入组的排名ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC_Injection.InjectedOffset=0;                           //偏移量HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);//注入组配置ADC_Injection.InjectedChannel=ADC_CHANNEL_9;               //需要配置的通道ADC_Injection.InjectedRank=ADC_INJECTED_RANK_4;             //注入组的排名ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC_Injection.InjectedOffset=0;                           //偏移量HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);}void ADC2_Init(void)
{ADC2_HandleType.Instance=ADC2;ADC2_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐ADC2_HandleType.Init.ScanConvMode=ADC_SCAN_ENABLE;  //扫描模式:使能ADC2_HandleType.Init.NbrOfConversion=10;            //扫描模式下规则组的数量ADC2_HandleType.Init.ContinuousConvMode=ENABLE;     //连续模式:  使能ADC2_HandleType.Init.DiscontinuousConvMode=DISABLE;   //规则组的间断模式   ADC2_HandleType.Init.ExternalTrigConv=ADC_SOFTWARE_START;//触发方式HAL_ADC_Init(&ADC2_HandleType);ADC_MultiModeTypeDef ADC_MultiMode={0};ADC2_Channel[0].Channel=ADC_CHANNEL_0;     //通道编号ADC2_Channel[0].Rank=ADC_REGULAR_RANK_10;     //排名ADC2_Channel[0].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[0]);ADC2_Channel[1].Channel=ADC_CHANNEL_1;     //通道编号ADC2_Channel[1].Rank=ADC_REGULAR_RANK_9;     //排名ADC2_Channel[1].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[1]);ADC2_Channel[2].Channel=ADC_CHANNEL_2;     //通道编号ADC2_Channel[2].Rank=ADC_REGULAR_RANK_8;     //排名ADC2_Channel[2].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[2]);ADC2_Channel[3].Channel=ADC_CHANNEL_3;     //通道编号ADC2_Channel[3].Rank=ADC_REGULAR_RANK_7;     //排名ADC2_Channel[3].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC2_HandleType,&	ADC2_Channel[3]);ADC2_Channel[4].Channel=ADC_CHANNEL_4;     //通道编号ADC2_Channel[4].Rank=ADC_REGULAR_RANK_6;     //排名ADC2_Channel[4].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[4]);ADC2_Channel[5].Channel=ADC_CHANNEL_5;     //通道编号ADC2_Channel[5].Rank=ADC_REGULAR_RANK_5;     //排名ADC2_Channel[5].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[5]);ADC2_Channel[6].Channel=ADC_CHANNEL_6;     //通道编号ADC2_Channel[6].Rank=ADC_REGULAR_RANK_4;     //排名ADC2_Channel[6].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[6]);ADC2_Channel[7].Channel=ADC_CHANNEL_7;     //通道编号ADC2_Channel[7].Rank=ADC_REGULAR_RANK_3;     //排名ADC2_Channel[7].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[7]);ADC2_Channel[8].Channel=ADC_CHANNEL_8;     //通道编号ADC2_Channel[8].Rank=ADC_REGULAR_RANK_2;     //排名ADC2_Channel[8].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[8]);ADC2_Channel[9].Channel=ADC_CHANNEL_9;     //通道编号ADC2_Channel[9].Rank=ADC_REGULAR_RANK_1;     //排名ADC2_Channel[9].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[9]);//注入组配置---配置为自动注入//自动注入和外部触发不可能共存ADC2_Injection.InjectedChannel=ADC_CHANNEL_6;               //需要配置的通道ADC2_Injection.InjectedRank=ADC_INJECTED_RANK_4;             //注入组的排名ADC2_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC2_Injection.InjectedOffset=0;                             //偏移量ADC2_Injection.InjectedNbrOfConversion=4;                        	//注入组的转化通道:max=4  ADC2_Injection.InjectedDiscontinuousConvMode=DISABLE;          //注入组间断模式;不可能同时使用自动注入和间断模式ADC2_Injection.AutoInjectedConv=DISABLE;                        //自动注入ADC2_Injection.ExternalTrigInjecConv=ADC_INJECTED_SOFTWARE_START;   //触发方式HAL_ADCEx_InjectedConfigChannel(&ADC2_HandleType,&ADC2_Injection);//注入组配置ADC2_Injection.InjectedChannel=ADC_CHANNEL_7;               //需要配置的通道ADC2_Injection.InjectedRank=ADC_INJECTED_RANK_3;             //注入组的排名ADC2_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC2_Injection.InjectedOffset=0;                           //偏移量HAL_ADCEx_InjectedConfigChannel(&ADC2_HandleType,&ADC2_Injection);//注入组配置ADC2_Injection.InjectedChannel=ADC_CHANNEL_8;               //需要配置的通道ADC2_Injection.InjectedRank=ADC_INJECTED_RANK_2;             //注入组的排名ADC2_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC2_Injection.InjectedOffset=0;                           //偏移量HAL_ADCEx_InjectedConfigChannel(&ADC2_HandleType,&ADC2_Injection);//注入组配置ADC2_Injection.InjectedChannel=ADC_CHANNEL_9;               //需要配置的通道ADC2_Injection.InjectedRank=ADC_INJECTED_RANK_1;             //注入组的排名ADC2_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC2_Injection.InjectedOffset=0;                           //偏移量HAL_ADCEx_InjectedConfigChannel(&ADC2_HandleType,&ADC2_Injection);//配置ADC双模式:交替触发模式ADC_MultiMode.Mode=ADC_DUALMODE_REGSIMULT_INJECSIMULT;HAL_ADCEx_MultiModeConfigChannel(&ADC_HandleType,&ADC_MultiMode);HAL_ADCEx_Calibration_Start(&ADC2_HandleType);   //自校准HAL_ADCEx_Calibration_Start(&ADC_HandleType);    //自校准HAL_ADCEx_InjectedStart_IT(&ADC_HandleType);      //中断方式开启注入组ADC1主模式HAL_ADCEx_InjectedStart(&ADC2_HandleType);      //中断方式开启注入组ADC2从模式HAL_ADC_Start(&ADC2_HandleType);//配置规则组HAL_ADCEx_MultiModeStart_DMA(&ADC_HandleType,DMA_buff,10);//双adc下使用这个API配置主adc}
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{if(hadc->Instance==ADC1){__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_GPIOB_CLK_ENABLE();__HAL_RCC_ADC1_CLK_ENABLE();__HAL_RCC_DMA1_CLK_ENABLE();GPIO_InitTypeDef GPIO_InitType;//模拟输入不用设置上下拉电阻GPIO_InitType.Mode=GPIO_MODE_ANALOG;  //模拟输入GPIO_InitType.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;HAL_GPIO_Init(GPIOA,&GPIO_InitType); GPIO_InitType.Mode=GPIO_MODE_ANALOG;  //模拟输入GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1;HAL_GPIO_Init(GPIOB,&GPIO_InitType); GPIO_InitType.Mode=GPIO_MODE_IT_RISING;  //模拟输入GPIO_InitType.Pull=GPIO_PULLDOWN;GPIO_InitType.Pin=GPIO_PIN_15;HAL_GPIO_Init(GPIOB,&GPIO_InitType);HAL_NVIC_SetPriority(ADC1_2_IRQn,4,0);          //ADC的中断优先级HAL_NVIC_EnableIRQ(ADC1_2_IRQn);                //开ADC的中断//DMA配置:方向寄存器(外设)-->数组(内存)DMA_Handle.Instance=DMA1_Channel1;DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY;  //传输方向:寄存器(外设)->数组(内存)DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE;   //寄存器(外设)是否递增加DMA_Handle.Init.MemInc=DMA_MINC_ENABLE;      //数组(内存)是否递增加DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_WORD;    //外设数据宽度(半字=2个字节)DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_WORD;      //数组(内存)数据宽度DMA_Handle.Init.Mode=DMA_CIRCULAR;                         //模式:循环DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle);   //或者下面的写法__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle);  //链接//DMA的配置HAL_DMA_Init(&DMA_Handle);HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,4,0);HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);}else if (hadc->Instance==ADC2){__HAL_RCC_ADC2_CLK_ENABLE();HAL_NVIC_SetPriority(ADC1_2_IRQn,4,0);          //ADC的中断优先级HAL_NVIC_EnableIRQ(ADC1_2_IRQn);                //开ADC的中断}
}void DMA1_Channel1_IRQHandler()
{HAL_DMA_IRQHandler(&DMA_Handle);}void ADC1_2_IRQHandler(void)
{HAL_ADC_IRQHandler(&ADC_HandleType);
}//ADC的DMA的完成中断回调
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{if(hadc->Instance == ADC1){                                        //判断是不是ADC1进入的中断回调printf("DMA完成中断\r\n");printf("ADC1_IN0:%d\r\n",DMA_buff[0]&0x0000FFFF);   //串口1输出电压值printf("ADC1_IN1:%d\r\n",DMA_buff[1]&0x0000FFFF);   //串口1输出电压值printf("ADC1_IN2:%d\r\n",DMA_buff[2]&0x0000FFFF);   //串口1输出电压值printf("ADC1_IN3:%d\r\n",DMA_buff[3]&0x0000FFFF);   //串口1输出电压值printf("ADC1_IN4:%d\r\n",DMA_buff[4]&0x0000FFFF);   //串口1输出电压值printf("ADC1_IN5:%d\r\n",DMA_buff[5]&0x0000FFFF);   //串口1输出电压值printf("ADC1_IN6:%d\r\n",DMA_buff[6]&0x0000FFFF);   //串口1输出电压值printf("ADC1_IN7:%d\r\n",DMA_buff[7]&0x0000FFFF);   //串口1输出电压值printf("ADC1_IN8:%d\r\n",DMA_buff[8]&0x0000FFFF);   //串口1输出电压值printf("ADC1_IN9:%d\r\n",DMA_buff[9]&0x0000FFFF);   //串口1输出电压值printf("----------------------------------------\r\n");printf("ADC2_IN9:%d\r\n",(DMA_buff[0]&0xFFFF0000)>>16);   //串口1输出电压值printf("ADC2_IN8:%d\r\n",(DMA_buff[1]&0xFFFF0000)>>16);   //串口1输出电压值printf("ADC2_IN7:%d\r\n",(DMA_buff[2]&0xFFFF0000)>>16);   //串口1输出电压值printf("ADC2_IN6:%d\r\n",(DMA_buff[3]&0xFFFF0000)>>16);   //串口1输出电压值printf("ADC2_IN5:%d\r\n",(DMA_buff[4]&0xFFFF0000)>>16);   //串口1输出电压值printf("ADC2_IN4:%d\r\n",(DMA_buff[5]&0xFFFF0000)>>16);   //串口1输出电压值printf("ADC2_IN3:%d\r\n",(DMA_buff[6]&0xFFFF0000)>>16);   //串口1输出电压值printf("ADC2_IN2:%d\r\n",(DMA_buff[7]&0xFFFF0000)>>16);   //串口1输出电压值printf("ADC2_IN1:%d\r\n",(DMA_buff[8]&0xFFFF0000)>>16);   //串口1输出电压值printf("ADC2_IN0:%d\r\n",(DMA_buff[9]&0xFFFF0000)>>16);   //串口1输出电压值}
}//注入组完成中断
void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef* hadc)
{if(hadc->Instance == ADC1){ printf("---------------------------------------------ADC1注入组完成\r\n");printf("ADC1_IN4:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC_HandleType,ADC_INJECTED_RANK_1));   //串口1输出电压值printf("ADC1_IN5:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC_HandleType,ADC_INJECTED_RANK_2));   //串口1输出电压值printf("ADC1_IN6:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC_HandleType,ADC_INJECTED_RANK_3));   //串口1输出电压值printf("ADC1_IN7:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC_HandleType,ADC_INJECTED_RANK_4));   //串口1输出电压值	printf("---------------------------------------------ADC2注入组完成\r\n");printf("ADC2_IN7:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC2_HandleType,ADC_INJECTED_RANK_1));   //串口1输出电压值printf("ADC2_IN6:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC2_HandleType,ADC_INJECTED_RANK_2));   //串口1输出电压值printf("ADC2_IN5:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC2_HandleType,ADC_INJECTED_RANK_3));   //串口1输出电压值printf("ADC2_IN4:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC2_HandleType,ADC_INJECTED_RANK_4));   //串口1输出电压值//__HAL_ADC_ENABLE_IT(hadc, ADC_IT_JEOC);}}

I:双ADC混合模式 ADC1 ADC2同步规则+交替注入模式

int main(void)
{uint8_t res=0;HAL_Init();                         /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */delay_init(72);                     /* 延时初始化 */Uart_Init(115200);ADC1_Init();  ADC2_Init();while (1){		}}#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"
#include "TIM.h"ADC_HandleTypeDef ADC_HandleType;   //ADC1为主模式
ADC_HandleTypeDef ADC2_HandleType;   //ADC2为从模式ADC_ChannelConfTypeDef ADC_Channel[10];  //ADC1为主模式的通道
ADC_ChannelConfTypeDef ADC2_Channel[10];  //ADC2为从模式的通道ADC_InjectionConfTypeDef ADC_Injection;     //ADC1主模式的注入组
ADC_InjectionConfTypeDef ADC2_Injection;     //ADC1从模式的注入组
uint32_t DMA_buff[10];DMA_HandleTypeDef DMA_Handle;
void ADC1_Init(void)
{ADC_HandleType.Instance=ADC1;ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐ADC_HandleType.Init.ScanConvMode=ADC_SCAN_ENABLE;  //扫描模式:使能ADC_HandleType.Init.NbrOfConversion=10;            //扫描模式下规则组的数量ADC_HandleType.Init.ContinuousConvMode=ENABLE;     //连续模式:  使能ADC_HandleType.Init.DiscontinuousConvMode=DISABLE;   //规则组的间断模式   ADC_HandleType.Init.ExternalTrigConv=ADC_SOFTWARE_START;//触发方式HAL_ADC_Init(&ADC_HandleType);ADC_Channel[0].Channel=ADC_CHANNEL_0;     //通道编号ADC_Channel[0].Rank=ADC_REGULAR_RANK_1;     //排名ADC_Channel[0].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[0]);ADC_Channel[1].Channel=ADC_CHANNEL_1;     //通道编号ADC_Channel[1].Rank=ADC_REGULAR_RANK_2;     //排名ADC_Channel[1].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[1]);ADC_Channel[2].Channel=ADC_CHANNEL_2;     //通道编号ADC_Channel[2].Rank=ADC_REGULAR_RANK_3;     //排名ADC_Channel[2].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[2]);ADC_Channel[3].Channel=ADC_CHANNEL_3;     //通道编号ADC_Channel[3].Rank=ADC_REGULAR_RANK_4;     //排名ADC_Channel[3].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&	ADC_Channel[3]);ADC_Channel[4].Channel=ADC_CHANNEL_4;     //通道编号ADC_Channel[4].Rank=ADC_REGULAR_RANK_5;     //排名ADC_Channel[4].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[4]);ADC_Channel[5].Channel=ADC_CHANNEL_5;     //通道编号ADC_Channel[5].Rank=ADC_REGULAR_RANK_6;     //排名ADC_Channel[5].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[5]);ADC_Channel[6].Channel=ADC_CHANNEL_6;     //通道编号ADC_Channel[6].Rank=ADC_REGULAR_RANK_7;     //排名ADC_Channel[6].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[6]);ADC_Channel[7].Channel=ADC_CHANNEL_7;     //通道编号ADC_Channel[7].Rank=ADC_REGULAR_RANK_8;     //排名ADC_Channel[7].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[7]);ADC_Channel[8].Channel=ADC_CHANNEL_8;     //通道编号ADC_Channel[8].Rank=ADC_REGULAR_RANK_9;     //排名ADC_Channel[8].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[8]);ADC_Channel[9].Channel=ADC_CHANNEL_9;     //通道编号ADC_Channel[9].Rank=ADC_REGULAR_RANK_10;     //排名ADC_Channel[9].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[9]);//注入组配置---配置为自动注入//自动注入和外部触发不可能共存ADC_Injection.InjectedChannel=ADC_CHANNEL_6;               //需要配置的通道ADC_Injection.InjectedRank=ADC_INJECTED_RANK_1;             //注入组的排名ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC_Injection.InjectedOffset=0;                             //偏移量ADC_Injection.InjectedNbrOfConversion=4;                        	//注入组的转化通道:max=4  ADC_Injection.InjectedDiscontinuousConvMode=DISABLE;          //注入组间断模式;不可能同时使用自动注入和间断模式ADC_Injection.AutoInjectedConv=DISABLE;                        //自动注入ADC_Injection.ExternalTrigInjecConv=ADC_EXTERNALTRIGINJECCONV_EXT_IT15;   //触发方式:_EXT_IT15HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);//注入组配置ADC_Injection.InjectedChannel=ADC_CHANNEL_7;               //需要配置的通道ADC_Injection.InjectedRank=ADC_INJECTED_RANK_2;             //注入组的排名ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC_Injection.InjectedOffset=0;                           //偏移量HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);//注入组配置ADC_Injection.InjectedChannel=ADC_CHANNEL_8;               //需要配置的通道ADC_Injection.InjectedRank=ADC_INJECTED_RANK_3;             //注入组的排名ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC_Injection.InjectedOffset=0;                           //偏移量HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);//注入组配置ADC_Injection.InjectedChannel=ADC_CHANNEL_9;               //需要配置的通道ADC_Injection.InjectedRank=ADC_INJECTED_RANK_4;             //注入组的排名ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC_Injection.InjectedOffset=0;                           //偏移量HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);}void ADC2_Init(void)
{ADC2_HandleType.Instance=ADC2;ADC2_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐ADC2_HandleType.Init.ScanConvMode=ADC_SCAN_ENABLE;  //扫描模式:使能ADC2_HandleType.Init.NbrOfConversion=10;            //扫描模式下规则组的数量ADC2_HandleType.Init.ContinuousConvMode=ENABLE;     //连续模式:  使能ADC2_HandleType.Init.DiscontinuousConvMode=DISABLE;   //规则组的间断模式   ADC2_HandleType.Init.ExternalTrigConv=ADC_SOFTWARE_START;//触发方式HAL_ADC_Init(&ADC2_HandleType);ADC_MultiModeTypeDef ADC_MultiMode={0};ADC2_Channel[0].Channel=ADC_CHANNEL_0;     //通道编号ADC2_Channel[0].Rank=ADC_REGULAR_RANK_10;     //排名ADC2_Channel[0].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[0]);ADC2_Channel[1].Channel=ADC_CHANNEL_1;     //通道编号ADC2_Channel[1].Rank=ADC_REGULAR_RANK_9;     //排名ADC2_Channel[1].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[1]);ADC2_Channel[2].Channel=ADC_CHANNEL_2;     //通道编号ADC2_Channel[2].Rank=ADC_REGULAR_RANK_8;     //排名ADC2_Channel[2].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[2]);ADC2_Channel[3].Channel=ADC_CHANNEL_3;     //通道编号ADC2_Channel[3].Rank=ADC_REGULAR_RANK_7;     //排名ADC2_Channel[3].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC2_HandleType,&	ADC2_Channel[3]);ADC2_Channel[4].Channel=ADC_CHANNEL_4;     //通道编号ADC2_Channel[4].Rank=ADC_REGULAR_RANK_6;     //排名ADC2_Channel[4].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[4]);ADC2_Channel[5].Channel=ADC_CHANNEL_5;     //通道编号ADC2_Channel[5].Rank=ADC_REGULAR_RANK_5;     //排名ADC2_Channel[5].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[5]);ADC2_Channel[6].Channel=ADC_CHANNEL_6;     //通道编号ADC2_Channel[6].Rank=ADC_REGULAR_RANK_4;     //排名ADC2_Channel[6].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[6]);ADC2_Channel[7].Channel=ADC_CHANNEL_7;     //通道编号ADC2_Channel[7].Rank=ADC_REGULAR_RANK_3;     //排名ADC2_Channel[7].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[7]);ADC2_Channel[8].Channel=ADC_CHANNEL_8;     //通道编号ADC2_Channel[8].Rank=ADC_REGULAR_RANK_2;     //排名ADC2_Channel[8].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[8]);ADC2_Channel[9].Channel=ADC_CHANNEL_9;     //通道编号ADC2_Channel[9].Rank=ADC_REGULAR_RANK_1;     //排名ADC2_Channel[9].SamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[9]);//注入组配置---配置为自动注入//自动注入和外部触发不可能共存ADC2_Injection.InjectedChannel=ADC_CHANNEL_6;               //需要配置的通道ADC2_Injection.InjectedRank=ADC_INJECTED_RANK_4;             //注入组的排名ADC2_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC2_Injection.InjectedOffset=0;                             //偏移量ADC2_Injection.InjectedNbrOfConversion=4;                        	//注入组的转化通道:max=4  ADC2_Injection.InjectedDiscontinuousConvMode=DISABLE;          //注入组间断模式;不可能同时使用自动注入和间断模式ADC2_Injection.AutoInjectedConv=DISABLE;                        //自动注入ADC2_Injection.ExternalTrigInjecConv=ADC_INJECTED_SOFTWARE_START;   //触发方式HAL_ADCEx_InjectedConfigChannel(&ADC2_HandleType,&ADC2_Injection);//注入组配置ADC2_Injection.InjectedChannel=ADC_CHANNEL_7;               //需要配置的通道ADC2_Injection.InjectedRank=ADC_INJECTED_RANK_3;             //注入组的排名ADC2_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC2_Injection.InjectedOffset=0;                           //偏移量HAL_ADCEx_InjectedConfigChannel(&ADC2_HandleType,&ADC2_Injection);//注入组配置ADC2_Injection.InjectedChannel=ADC_CHANNEL_8;               //需要配置的通道ADC2_Injection.InjectedRank=ADC_INJECTED_RANK_2;             //注入组的排名ADC2_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC2_Injection.InjectedOffset=0;                           //偏移量HAL_ADCEx_InjectedConfigChannel(&ADC2_HandleType,&ADC2_Injection);//注入组配置ADC2_Injection.InjectedChannel=ADC_CHANNEL_9;               //需要配置的通道ADC2_Injection.InjectedRank=ADC_INJECTED_RANK_1;             //注入组的排名ADC2_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC2_Injection.InjectedOffset=0;                           //偏移量HAL_ADCEx_InjectedConfigChannel(&ADC2_HandleType,&ADC2_Injection);//配置ADC双模式:混合的同步规则+交替触发模式ADC_MultiMode.Mode=ADC_DUALMODE_REGSIMULT_ALTERTRIG;HAL_ADCEx_MultiModeConfigChannel(&ADC_HandleType,&ADC_MultiMode);HAL_ADCEx_Calibration_Start(&ADC2_HandleType);   //自校准HAL_ADCEx_Calibration_Start(&ADC_HandleType);    //自校准HAL_ADCEx_InjectedStart_IT(&ADC_HandleType);      //中断方式开启注入组ADC1主模式HAL_ADCEx_InjectedStart_IT(&ADC2_HandleType);      //中断方式开启注入组ADC2从模式HAL_ADC_Start(&ADC2_HandleType);//配置规则组HAL_ADCEx_MultiModeStart_DMA(&ADC_HandleType,DMA_buff,10);//双adc下使用这个API配置主adc}
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{if(hadc->Instance==ADC1){__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_GPIOB_CLK_ENABLE();__HAL_RCC_ADC1_CLK_ENABLE();__HAL_RCC_DMA1_CLK_ENABLE();GPIO_InitTypeDef GPIO_InitType;//模拟输入不用设置上下拉电阻GPIO_InitType.Mode=GPIO_MODE_ANALOG;  //模拟输入GPIO_InitType.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;HAL_GPIO_Init(GPIOA,&GPIO_InitType); GPIO_InitType.Mode=GPIO_MODE_ANALOG;  //模拟输入GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1;HAL_GPIO_Init(GPIOB,&GPIO_InitType); GPIO_InitType.Mode=GPIO_MODE_IT_RISING;  //模拟输入GPIO_InitType.Pull=GPIO_PULLDOWN;GPIO_InitType.Pin=GPIO_PIN_15;HAL_GPIO_Init(GPIOB,&GPIO_InitType);HAL_NVIC_SetPriority(ADC1_2_IRQn,4,0);          //ADC的中断优先级HAL_NVIC_EnableIRQ(ADC1_2_IRQn);                //开ADC的中断//DMA配置:方向寄存器(外设)-->数组(内存)DMA_Handle.Instance=DMA1_Channel1;DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY;  //传输方向:寄存器(外设)->数组(内存)DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE;   //寄存器(外设)是否递增加DMA_Handle.Init.MemInc=DMA_MINC_ENABLE;      //数组(内存)是否递增加DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_WORD;    //外设数据宽度(半字=2个字节)DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_WORD;      //数组(内存)数据宽度DMA_Handle.Init.Mode=DMA_CIRCULAR;                         //模式:循环DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle);   //或者下面的写法__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle);  //链接//DMA的配置HAL_DMA_Init(&DMA_Handle);HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,4,0);HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);}else if (hadc->Instance==ADC2){__HAL_RCC_ADC2_CLK_ENABLE();HAL_NVIC_SetPriority(ADC1_2_IRQn,4,0);          //ADC的中断优先级HAL_NVIC_EnableIRQ(ADC1_2_IRQn);                //开ADC的中断}
}void DMA1_Channel1_IRQHandler()
{HAL_DMA_IRQHandler(&DMA_Handle);}void ADC1_2_IRQHandler(void)
{HAL_ADC_IRQHandler(&ADC_HandleType);HAL_ADC_IRQHandler(&ADC2_HandleType);
}//ADC的DMA的完成中断回调
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{if(hadc->Instance == ADC1){                                        //判断是不是ADC1进入的中断回调printf("DMA完成中断\r\n");printf("ADC1_IN0:%d\r\n",DMA_buff[0]&0x0000FFFF);   //串口1输出电压值printf("ADC1_IN1:%d\r\n",DMA_buff[1]&0x0000FFFF);   //串口1输出电压值printf("ADC1_IN2:%d\r\n",DMA_buff[2]&0x0000FFFF);   //串口1输出电压值printf("ADC1_IN3:%d\r\n",DMA_buff[3]&0x0000FFFF);   //串口1输出电压值printf("ADC1_IN4:%d\r\n",DMA_buff[4]&0x0000FFFF);   //串口1输出电压值printf("ADC1_IN5:%d\r\n",DMA_buff[5]&0x0000FFFF);   //串口1输出电压值printf("ADC1_IN6:%d\r\n",DMA_buff[6]&0x0000FFFF);   //串口1输出电压值printf("ADC1_IN7:%d\r\n",DMA_buff[7]&0x0000FFFF);   //串口1输出电压值printf("ADC1_IN8:%d\r\n",DMA_buff[8]&0x0000FFFF);   //串口1输出电压值printf("ADC1_IN9:%d\r\n",DMA_buff[9]&0x0000FFFF);   //串口1输出电压值printf("----------------------------------------\r\n");printf("ADC2_IN9:%d\r\n",(DMA_buff[0]&0xFFFF0000)>>16);   //串口1输出电压值printf("ADC2_IN8:%d\r\n",(DMA_buff[1]&0xFFFF0000)>>16);   //串口1输出电压值printf("ADC2_IN7:%d\r\n",(DMA_buff[2]&0xFFFF0000)>>16);   //串口1输出电压值printf("ADC2_IN6:%d\r\n",(DMA_buff[3]&0xFFFF0000)>>16);   //串口1输出电压值printf("ADC2_IN5:%d\r\n",(DMA_buff[4]&0xFFFF0000)>>16);   //串口1输出电压值printf("ADC2_IN4:%d\r\n",(DMA_buff[5]&0xFFFF0000)>>16);   //串口1输出电压值printf("ADC2_IN3:%d\r\n",(DMA_buff[6]&0xFFFF0000)>>16);   //串口1输出电压值printf("ADC2_IN2:%d\r\n",(DMA_buff[7]&0xFFFF0000)>>16);   //串口1输出电压值printf("ADC2_IN1:%d\r\n",(DMA_buff[8]&0xFFFF0000)>>16);   //串口1输出电压值printf("ADC2_IN0:%d\r\n",(DMA_buff[9]&0xFFFF0000)>>16);   //串口1输出电压值}
}//注入组完成中断
void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef* hadc)
{if(hadc->Instance == ADC1){ printf("---------------------------------------------ADC1注入组完成\r\n");printf("ADC1_IN4:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC_HandleType,ADC_INJECTED_RANK_1));   //串口1输出电压值printf("ADC1_IN5:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC_HandleType,ADC_INJECTED_RANK_2));   //串口1输出电压值printf("ADC1_IN6:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC_HandleType,ADC_INJECTED_RANK_3));   //串口1输出电压值printf("ADC1_IN7:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC_HandleType,ADC_INJECTED_RANK_4));   //串口1输出电压值	//__HAL_ADC_ENABLE_IT(hadc, ADC_IT_JEOC);}else if(hadc->Instance == ADC2){printf("---------------------------------------------ADC2注入组完成\r\n");printf("ADC2_IN7:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC2_HandleType,ADC_INJECTED_RANK_1));   //串口1输出电压值printf("ADC2_IN6:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC2_HandleType,ADC_INJECTED_RANK_2));   //串口1输出电压值printf("ADC2_IN5:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC2_HandleType,ADC_INJECTED_RANK_3));   //串口1输出电压值printf("ADC2_IN4:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC2_HandleType,ADC_INJECTED_RANK_4));   //串口1输出电压值__HAL_ADC_ENABLE_IT(hadc, ADC_IT_JEOC);}}

 

H:双ADC混合模式 ADC1 ADC2同步注入+交叉模式

int main(void)
{uint8_t res=0;HAL_Init();                         /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */delay_init(72);                     /* 延时初始化 */Uart_Init(115200);IC_TIMX_CHX_init(2000-1,7200-1);   //T=((ARR+1)*(PSC+1)) / T=0.2S     0.2*10=2SADC1_Init();  ADC2_Init();while (1){		}}
#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"
#include "TIM.h"ADC_HandleTypeDef ADC_HandleType;   //ADC1为主模式
ADC_HandleTypeDef ADC2_HandleType;   //ADC2为从模式ADC_ChannelConfTypeDef ADC_Channel[10];  //ADC1为主模式的通道
ADC_ChannelConfTypeDef ADC2_Channel[10];  //ADC2为从模式的通道ADC_InjectionConfTypeDef ADC_Injection;     //ADC1主模式的注入组
ADC_InjectionConfTypeDef ADC2_Injection;     //ADC1从模式的注入组
uint32_t DMA_buff[10];DMA_HandleTypeDef DMA_Handle;
void ADC1_Init(void)
{ADC_HandleType.Instance=ADC1;ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐ADC_HandleType.Init.ScanConvMode=ADC_SCAN_ENABLE;  //扫描模式:使能ADC_HandleType.Init.NbrOfConversion=1;            //扫描模式下规则组的数量ADC_HandleType.Init.ContinuousConvMode=DISABLE;     //连续模式:  使能ADC_HandleType.Init.DiscontinuousConvMode=DISABLE;   //规则组的间断模式   ADC_HandleType.Init.ExternalTrigConv=ADC_EXTERNALTRIGCONV_T2_CC2;//触发方式HAL_ADC_Init(&ADC_HandleType);ADC_Channel[0].Channel=ADC_CHANNEL_2;     //通道编号ADC_Channel[0].Rank=ADC_REGULAR_RANK_1;     //排名ADC_Channel[0].SamplingTime=ADC_SAMPLETIME_1CYCLE_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[0]);//注入组配置---配置为自动注入//自动注入和外部触发不可能共存ADC_Injection.InjectedChannel=ADC_CHANNEL_6;               //需要配置的通道ADC_Injection.InjectedRank=ADC_INJECTED_RANK_1;             //注入组的排名ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC_Injection.InjectedOffset=0;                             //偏移量ADC_Injection.InjectedNbrOfConversion=4;                        	//注入组的转化通道:max=4  ADC_Injection.InjectedDiscontinuousConvMode=DISABLE;          //注入组间断模式;不可能同时使用自动注入和间断模式ADC_Injection.AutoInjectedConv=DISABLE;                        //自动注入ADC_Injection.ExternalTrigInjecConv=ADC_EXTERNALTRIGINJECCONV_EXT_IT15;   //触发方式:_EXT_IT15HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);//注入组配置ADC_Injection.InjectedChannel=ADC_CHANNEL_7;               //需要配置的通道ADC_Injection.InjectedRank=ADC_INJECTED_RANK_2;             //注入组的排名ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC_Injection.InjectedOffset=0;                           //偏移量HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);//注入组配置ADC_Injection.InjectedChannel=ADC_CHANNEL_8;               //需要配置的通道ADC_Injection.InjectedRank=ADC_INJECTED_RANK_3;             //注入组的排名ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC_Injection.InjectedOffset=0;                           //偏移量HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);//注入组配置ADC_Injection.InjectedChannel=ADC_CHANNEL_9;               //需要配置的通道ADC_Injection.InjectedRank=ADC_INJECTED_RANK_4;             //注入组的排名ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC_Injection.InjectedOffset=0;                           //偏移量HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);}void ADC2_Init(void)
{ADC2_HandleType.Instance=ADC2;ADC2_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐ADC2_HandleType.Init.ScanConvMode=ADC_SCAN_ENABLE;  //扫描模式:使能ADC2_HandleType.Init.NbrOfConversion=1;            //扫描模式下规则组的数量ADC2_HandleType.Init.ContinuousConvMode=DISABLE;     //连续模式:  使能ADC2_HandleType.Init.DiscontinuousConvMode=DISABLE;   //规则组的间断模式   ADC2_HandleType.Init.ExternalTrigConv=ADC_SOFTWARE_START;//触发方式HAL_ADC_Init(&ADC2_HandleType);ADC_MultiModeTypeDef ADC_MultiMode={0};ADC2_Channel[0].Channel=ADC_CHANNEL_2;     //通道编号ADC2_Channel[0].Rank=ADC_REGULAR_RANK_1;     //排名ADC2_Channel[0].SamplingTime=ADC_SAMPLETIME_1CYCLE_5;   //周期:41.5个  41.5+12.5=54个//配置规则组通道HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[0]);//注入组配置---配置为自动注入//自动注入和外部触发不可能共存ADC2_Injection.InjectedChannel=ADC_CHANNEL_6;               //需要配置的通道ADC2_Injection.InjectedRank=ADC_INJECTED_RANK_4;             //注入组的排名ADC2_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC2_Injection.InjectedOffset=0;                             //偏移量ADC2_Injection.InjectedNbrOfConversion=4;                        	//注入组的转化通道:max=4  ADC2_Injection.InjectedDiscontinuousConvMode=DISABLE;          //注入组间断模式;不可能同时使用自动注入和间断模式ADC2_Injection.AutoInjectedConv=DISABLE;                        //自动注入ADC2_Injection.ExternalTrigInjecConv=ADC_INJECTED_SOFTWARE_START;   //触发方式HAL_ADCEx_InjectedConfigChannel(&ADC2_HandleType,&ADC2_Injection);//注入组配置ADC2_Injection.InjectedChannel=ADC_CHANNEL_7;               //需要配置的通道ADC2_Injection.InjectedRank=ADC_INJECTED_RANK_3;             //注入组的排名ADC2_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC2_Injection.InjectedOffset=0;                           //偏移量HAL_ADCEx_InjectedConfigChannel(&ADC2_HandleType,&ADC2_Injection);//注入组配置ADC2_Injection.InjectedChannel=ADC_CHANNEL_8;               //需要配置的通道ADC2_Injection.InjectedRank=ADC_INJECTED_RANK_2;             //注入组的排名ADC2_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC2_Injection.InjectedOffset=0;                           //偏移量HAL_ADCEx_InjectedConfigChannel(&ADC2_HandleType,&ADC2_Injection);//注入组配置ADC2_Injection.InjectedChannel=ADC_CHANNEL_9;               //需要配置的通道ADC2_Injection.InjectedRank=ADC_INJECTED_RANK_1;             //注入组的排名ADC2_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5;   //采用周期ADC2_Injection.InjectedOffset=0;                           //偏移量HAL_ADCEx_InjectedConfigChannel(&ADC2_HandleType,&ADC2_Injection);//配置ADC双模式:同步注入+规则组快速交叉ADC_MultiMode.Mode=ADC_DUALMODE_INJECSIMULT_INTERLFAST;HAL_ADCEx_MultiModeConfigChannel(&ADC_HandleType,&ADC_MultiMode);HAL_ADCEx_Calibration_Start(&ADC2_HandleType);   //自校准HAL_ADCEx_Calibration_Start(&ADC_HandleType);    //自校准HAL_ADCEx_InjectedStart_IT(&ADC_HandleType);      //中断方式开启注入组ADC1主模式HAL_ADCEx_InjectedStart(&ADC2_HandleType);      //中断方式开启注入组ADC2从模式HAL_ADC_Start(&ADC2_HandleType);//配置规则组HAL_ADCEx_MultiModeStart_DMA(&ADC_HandleType,DMA_buff,10);//双adc下使用这个API配置主adc}
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{if(hadc->Instance==ADC1){__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_GPIOB_CLK_ENABLE();__HAL_RCC_ADC1_CLK_ENABLE();__HAL_RCC_DMA1_CLK_ENABLE();GPIO_InitTypeDef GPIO_InitType;//模拟输入不用设置上下拉电阻GPIO_InitType.Mode=GPIO_MODE_ANALOG;  //模拟输入GPIO_InitType.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;HAL_GPIO_Init(GPIOA,&GPIO_InitType); GPIO_InitType.Mode=GPIO_MODE_ANALOG;  //模拟输入GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1;HAL_GPIO_Init(GPIOB,&GPIO_InitType); GPIO_InitType.Mode=GPIO_MODE_IT_RISING;  //模拟输入GPIO_InitType.Pull=GPIO_PULLDOWN;GPIO_InitType.Pin=GPIO_PIN_15;HAL_GPIO_Init(GPIOB,&GPIO_InitType);HAL_NVIC_SetPriority(ADC1_2_IRQn,4,0);          //ADC的中断优先级HAL_NVIC_EnableIRQ(ADC1_2_IRQn);                //开ADC的中断//DMA配置:方向寄存器(外设)-->数组(内存)DMA_Handle.Instance=DMA1_Channel1;DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY;  //传输方向:寄存器(外设)->数组(内存)DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE;   //寄存器(外设)是否递增加DMA_Handle.Init.MemInc=DMA_MINC_ENABLE;      //数组(内存)是否递增加DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_WORD;    //外设数据宽度(半字=2个字节)DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_WORD;      //数组(内存)数据宽度DMA_Handle.Init.Mode=DMA_CIRCULAR;                         //模式:循环DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle);   //或者下面的写法__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle);  //链接//DMA的配置HAL_DMA_Init(&DMA_Handle);HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,4,0);HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);}else if (hadc->Instance==ADC2){__HAL_RCC_ADC2_CLK_ENABLE();HAL_NVIC_SetPriority(ADC1_2_IRQn,4,0);          //ADC的中断优先级HAL_NVIC_EnableIRQ(ADC1_2_IRQn);                //开ADC的中断}
}void DMA1_Channel1_IRQHandler()
{HAL_DMA_IRQHandler(&DMA_Handle);}void ADC1_2_IRQHandler(void)
{HAL_ADC_IRQHandler(&ADC_HandleType);
}//ADC的DMA的完成中断回调
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{uint32_t sum,i;if(hadc->Instance == ADC1){                                        //判断是不是ADC1进入的中断回调sum=0;for(i=0;i<10;i++){sum+=DMA_buff[i];}printf("DMA完成中断\r\n");printf("ADC1_IN2:%f\r\n",((sum&0x0000FFFF)/10.0)*(3.3/4096));   //串口1输出电压值printf("----------------------------------------\r\n");printf("ADC2_IN2:%f\r\n",(((sum&0xFFFF0000)>>16)/10.0)*(3.3/4096));   //串口1输出电压值}
}//注入组完成中断
void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef* hadc)
{if(hadc->Instance == ADC1){ printf("---------------------------------------------ADC1注入组完成\r\n");printf("ADC1_IN4:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC_HandleType,ADC_INJECTED_RANK_1));   //串口1输出电压值printf("ADC1_IN5:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC_HandleType,ADC_INJECTED_RANK_2));   //串口1输出电压值printf("ADC1_IN6:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC_HandleType,ADC_INJECTED_RANK_3));   //串口1输出电压值printf("ADC1_IN7:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC_HandleType,ADC_INJECTED_RANK_4));   //串口1输出电压值	printf("---------------------------------------------ADC2注入组完成\r\n");printf("ADC2_IN7:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC2_HandleType,ADC_INJECTED_RANK_1));   //串口1输出电压值printf("ADC2_IN6:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC2_HandleType,ADC_INJECTED_RANK_2));   //串口1输出电压值printf("ADC2_IN5:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC2_HandleType,ADC_INJECTED_RANK_3));   //串口1输出电压值printf("ADC2_IN4:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC2_HandleType,ADC_INJECTED_RANK_4));   //串口1输出电压值//__HAL_ADC_ENABLE_IT(hadc, ADC_IT_JEOC);}}#include "stm32f1xx_hal.h"
#include "pwm.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "ADC.h"//输入捕获功能
TIM_HandleTypeDef HandleTIMXCHX;
//TIM1的CC1事件
void IC_TIMX_CHX_init(uint16_t arr,uint16_t psc)
{TIM_OC_InitTypeDef TIM_OC_Init={0};HandleTIMXCHX.Instance=TIM2;   //基地址HandleTIMXCHX.Init.Period=arr;HandleTIMXCHX.Init.Prescaler=psc;HandleTIMXCHX.Init.CounterMode=TIM_COUNTERMODE_UP;   //向上计数HandleTIMXCHX.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;   //设置自动重载值 预装载使能位HandleTIMXCHX.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;   //设置分频因子HAL_TIM_OC_Init(&HandleTIMXCHX);//清除跟新中断标志位__HAL_TIM_CLEAR_FLAG(&HandleTIMXCHX,TIM_FLAG_UPDATE);TIM_OC_Init.OCMode=TIM_OCMODE_PWM1;TIM_OC_Init.Pulse=100;    //比较值(CCR)TIM_OC_Init.OCPolarity=TIM_OCPOLARITY_LOW;//有效值  :PWM1:CNT<CCR输出有效电平  TIM_OC_Init.OCFastMode = TIM_OCFAST_DISABLE;    HAL_TIM_OC_ConfigChannel(&HandleTIMXCHX, &TIM_OC_Init,TIM_CHANNEL_2);HAL_TIM_OC_Start(&HandleTIMXCHX,TIM_CHANNEL_2);}void HAL_TIM_OC_MspInit(TIM_HandleTypeDef *htim)
{if(htim->Instance==TIM2){__HAL_RCC_TIM2_CLK_ENABLE();                    //打开定时器3的时钟//信号为内部触发所以,定时器2_CH2引脚可以使用初始化HAL_NVIC_SetPriority(TIM2_IRQn,3,0);            //定时器3的中断优先级HAL_NVIC_EnableIRQ(TIM2_IRQn);                  //开定时器3的中断}
}

因为扫描模式是对于规则组和注入组共有的,注入组开启了4个通道,所有必须开启扫描模式。 

                                        

                                              温度传感器 

int main(void)
{uint8_t res=0;HAL_Init();                         /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */delay_init(72);                     /* 延时初始化 */Uart_Init(115200);//IC_TIMX_CHX_init(0xFFFF,36000-1);    ADC1_Init();  while (1){		}}
#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"
#include "TIM.h"
ADC_InjectionConfTypeDef ADC_Injection;  //注入组句柄
ADC_HandleTypeDef ADC_HandleType;
DMA_HandleTypeDef DMA_Handle;                 //DMA句柄
ADC_ChannelConfTypeDef ADC_Channel[10];      //规则组通道uint16_t DMA_buff[10];            //储存DMA数据的内存地址
void ADC1_Init(void)
{//规则组的配置ADC_HandleType.Instance=ADC1;ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐ADC_HandleType.Init.ScanConvMode=ADC_SCAN_DISABLE;  //扫描模式:使能ADC_HandleType.Init.NbrOfConversion=0;            //扫描模式下规则组的数量ADC_HandleType.Init.ContinuousConvMode=ENABLE;     //连续模式:  使能ADC_HandleType.Init.DiscontinuousConvMode=DISABLE;   //规则组的间断模式   //ADC_HandleType.Init.NbrOfDiscConversion=2;            //规则组的间断模式子组的成员数量ADC_HandleType.Init.ExternalTrigConv=ADC_SOFTWARE_START;//触发方式:软件触发HAL_ADC_Init(&ADC_HandleType);ADC_Channel[0].Channel=ADC_CHANNEL_16;     //通道编号ADC_Channel[0].Rank=ADC_REGULAR_RANK_1;     //排名ADC_Channel[0].SamplingTime=ADC_SAMPLETIME_239CYCLES_5;   //周期:41.5个  71.5+12.5=84个//配置规则组通道HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[0]);HAL_ADCEx_Calibration_Start(&ADC_HandleType);                   //自校准//DMA将连续读取100个ADC转换结果并存储到DMA_buff中,并产生DMA中断。HAL_ADC_Start_DMA(&ADC_HandleType,(uint32_t*)DMA_buff,10);  }
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{if(hadc->Instance==ADC1){__HAL_RCC_ADC1_CLK_ENABLE();__HAL_RCC_DMA1_CLK_ENABLE();//DMA配置:方向寄存器(外设)-->数组(内存)DMA_Handle.Instance=DMA1_Channel1;DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY;  //传输方向:寄存器(外设)->数组(内存)DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE;   //寄存器(外设)是否递增加DMA_Handle.Init.MemInc=DMA_MINC_ENABLE;      //数组(内存)是否递增加DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD;    //外设数据宽度(半字=2个字节)DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_HALFWORD;      //数组(内存)数据宽度DMA_Handle.Init.Mode=DMA_CIRCULAR;                         //模式:循环DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle);   //或者下面的写法__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle);  //链接//DMA的配置HAL_DMA_Init(&DMA_Handle);HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,3,0);HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);}
}void DMA1_Channel1_IRQHandler()
{HAL_DMA_IRQHandler(&DMA_Handle);}//DMA将连续读取10个ADC转换结果并存储到DMA_buff中,后进入中断
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{			uint32_t sum,i;float temperature;if(hadc->Instance==ADC1){sum=0;for(i=0;i<10;i++){sum+=DMA_buff[i];}printf("DMA完成中断\r\n");printf("ADC1_IN6的电压为:%f V \r\n",((sum/10.0)*(3.3/4096.0)));   //串口1输出数字量	printf("温度为:%f  \r\n",(1.43-((sum/10.0)*(3.3/4096.0)))/4.3+25.0);   //串口1输出数字量	}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/26345.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java从放弃到继续放弃

并发编程 为什么需要多线程&#xff1f; 由于硬件的发展&#xff0c;CPU的核数增多&#xff0c;如果仍然使用单线程对CPU资源会造成浪费。同时&#xff0c;单线程也会出现阻塞的问题。所以&#xff0c;选择向多线程转变。 多线程的使用使得程序能够并行计算&#xff0c;提高计…

python学习—合并多个Excel工作簿表格文件

系列文章目录 python学习—合并TXT文本文件 python学习—统计嵌套文件夹内的文件数量并建立索引表格 python学习—查找指定目录下的指定类型文件 python学习—年会不能停&#xff0c;游戏抽签抽奖 python学习—循环语句-控制流 文章目录 系列文章目录功能说明1 准备工作&#…

服务器数据恢复—EMC Isilon存储中被误删的虚拟机数据恢复案例

服务器存储数据恢复环境&#xff1a; EMC Isilon S200集群存储&#xff0c;共三个节点&#xff0c;每节点配置12块SATA硬盘。 服务器存储故障&#xff1a; 工作人员误操作删除虚拟机&#xff0c;虚拟机中数据包括数据库、MP4、AS、TS类型的视频文件等。需要恢复数据的虚拟机通…

芯片环氧胶可以提供一定的耐盐雾耐腐蚀效果!

芯片环氧胶&#xff08;或称为环氧树脂胶&#xff09;在电子封装和保护应用中确实能提供一定的耐盐雾和耐腐蚀效果。 环氧树脂因为其出色的粘接性能、机械强度以及良好的化学稳定性&#xff0c;被广泛用于电子封装领域&#xff0c;尤其是芯片固定和保护。在面对盐雾腐蚀或恶劣…

使用RV1126交叉编译工具链交叉编译opencv,c++代码直接调用VideoCapture 读取摄像头数据

使用RV1126交叉编译工具链交叉编译opencv&#xff0c;rv1126直接调用VideoCapture 读取摄像头数据 前言环境一、ubantu安装二、交叉编译工具安装三、cmake升级四、ffmpeg安装五、opencv安装六、c代码测试&#xff08;上板运行&#xff09; 前言 交叉编译是一种将软件在操作系统…

关于docker无法正常下载镜像的问题

文章目录 之前还可以正常下载镜像&#xff0c;但是一段时间之后就无法下载了&#xff0c;猜测可能是政治原因&#xff0c;无法连接到国外服务器&#xff0c;所以我设置了阿里云的镜像加速器。 配置方法如下&#xff1a; 前往阿里云&#xff08;https://help.aliyun.com/zh/acr/…

ATA-3040C功率放大器的正确使用方法

功率放大器是一种用于增强电信号功率的重要设备。正确使用功率放大器可以确保信号的稳定放大&#xff0c;并避免设备损坏。下面将介绍功率放大器的正确使用方法。 确定输入信号的功率范围&#xff1a;在使用功率放大器之前&#xff0c;需要确定输入信号的功率范围。过大的输入功…

Python 最强的5个高级函数,你会几个?

Python是一门灵活而强大的编程语言&#xff0c;具有丰富的内置函数和库。今天&#xff0c;我们将深入探讨五个非常有用的Python高级函数。这些函数不仅能够简化代码&#xff0c;还能提高代码的可读性和可维护性。 首先&#xff0c;了解下什么是高级函数&#xff1f; 高级函数…

【Unity】如何做一个很平滑的行人动画,且可以根据行人速度动态调整动画速度?

首先我们定一下不同速度对应的行人动作状态&#xff0c;设计为四种状态&#xff1a; 静止站立Stand&#xff1a;0~maxStandSpeed走路Walk&#xff1a;minWalkSpeed~maxWalkSpeed慢跑Jog&#xff1a;minJogSpeed~maxJogSpeed快跑Run&#xff1a;大于MinRunSpeed 我们可以使用A…

FISCO BCOS x GitLink,为国产开源技术生态注入新活力

作为中国领先的区块链底层平台之一&#xff0c;FISCO BCOS 自成立以来始终致力于推动国产开源区块链技术的应用和普及。近期&#xff0c;FISCO BCOS 将开源代码托管到CCF官方代码托管平台 GitLink &#xff08;确实开源&#xff09;&#xff0c;为国产开源技术生态注入新活力。…

刚实习的大学生如何避免招聘骗局?

大学生在求职过程中&#xff0c;常常成为招聘骗局的受害者。为了避免这种情况&#xff0c;大学生需要提高警惕&#xff0c;采取一系列措施来防范招聘骗局。以下是一些建议&#xff1a; 首先&#xff0c;大学生应当保持警惕&#xff0c;不轻信招聘信息。在求职时&#xff0c;务…

使用 Elasticsearch 设计大规模向量搜索

作者&#xff1a;Jim Ferenczi 第 1 部分&#xff1a;高保真密集向量搜索 简介 在设计向量搜索体验时&#xff0c;可用选项的数量之多可能会让人感到不知所措。最初&#xff0c;管理少量向量很简单&#xff0c;但随着应用程序的扩展&#xff0c;这很快就会成为瓶颈。 在本系列…

ip地址公和内有什么区别

在数字化世界中&#xff0c;IP地址扮演着至关重要的角色。它不仅是网络设备的身份标识&#xff0c;更是信息传输的桥梁。然而&#xff0c;并非所有IP地址都拥有相同的属性和功能。公有IP地址和私有IP地址&#xff0c;作为IP地址的两大类别&#xff0c;它们存在着显著的差异。虎…

成都百洲文化传媒有限公司电商服务的领航者

在当今数字化浪潮席卷全球的时代&#xff0c;电商行业以其独特的魅力和无穷的潜力&#xff0c;正成为推动经济发展的重要引擎。在这一领域&#xff0c;成都百洲文化传媒有限公司以其专业的电商服务和创新的营销理念&#xff0c;成为了行业的佼佼者&#xff0c;引领着电商服务的…

芯片后端对于芯片设计公司的重要性

在芯片设计流程中&#xff0c;后端设计是一个至关重要的环节&#xff0c;它直接关系到芯片从设计到实际生产的转化&#xff0c;以及最终产品的性能、可靠性、成本和上市时间。 以下是为什么芯片后端非常重要的几个关键原因&#xff1a; 物理实现&#xff1a;后端设计是芯片从逻…

CAP理论

CAP理论 在分布式系统的世界中&#xff0c;CAP理论是一个绕不开的话题。CAP&#xff0c;即Consistency&#xff08;一致性&#xff09;、Availability&#xff08;可用性&#xff09;和Partition tolerance&#xff08;分区容错性&#xff09;&#xff0c;这三个属性在分布式系…

Vxe UI vxe-table custom 实现自定义列服务端保存,服务端恢复状态,实现用户个性化列信息保存

Vxe UI vue vxe-table custom 实现自定义列服务端保存&#xff0c;服务端恢复状态&#xff0c;实现用户个性化列信息保存 支持将自定义列状态信息&#xff0c;列宽、冻结列、列排序、列显示隐藏 等状态信息保存到本地或服务端 代码 实现自定义列状态保存功能&#xff0c;只需…

在气膜建筑中运动,我们会感觉到不舒服吗—轻空间

气膜建筑是一种以膜材为主要结构&#xff0c;通过空气压力支撑的新型建筑形式&#xff0c;广泛应用于体育场馆、游泳馆和多功能运动场等领域。然而&#xff0c;人们常常担心在这种建筑中运动是否会感到不适。本文将探讨气膜建筑中运动的舒适度问题&#xff0c;并结合相关的技术…

GaN VCSEL:工艺革新引领精准波长控制新纪元

日本工程师们凭借精湛的技艺&#xff0c;开创了一种革命性的生产工艺&#xff0c;让VCSEL的制造达到了前所未有的高效与精准。这一成果由名城大学与国家先进工业科学技术研究所的精英们联手铸就&#xff0c;将氮化镓基VCSELs的商业化进程推向了新的高峰。它们将有望成为自适应前…

Spring Cloud 之 GateWay

前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家&#xff1a;https://www.captainbed.cn/z ChatGPT体验地址 文章目录 前言前言1、通过API网关访问服务2、Spring Cloud GateWay 最主要的功能就是路由…