STM32G474的ADC(寄存器开发)

11 篇文章 4 订阅

个人笔记,自己看的,写的很随意。

最后更新时间:2022.07.06
添加 注入触发通道 的说明

正文

  • 规则 和 注入 是两类通道,不是模式。

ADC时钟

在这里插入图片描述
如果只用规则通道而不用注入通道,则ADC时钟与AHB没有约束关系。

上图可以看到,ADC的时钟输入有两个时钟源:adc_hclkadc_ker_ck
adc_hclk 被认为是 同步时钟。
adc_ker_ck 被认为是 异步时钟,他也有两个输入时钟,可以通过 RCC_CCIPR 寄存器配置选择使用 SYSCLK 还是 PCLK

1. ADC的启动

1.1 退出深度掉电模式和ADC稳压器的开启

  • 使用ADC的第一步就是退出“深度掉电模式”,即ADC->CR中的DEEPPWD = 0;
  • 然后使能稳压器,即ADC->CR中的ADVREGEN = 1;
  • 等待稳压器启动,具体启动时间参见数据手册。(G474数据手册写的是20us )数据手册第146页 DM00431551_ENV3

在这里插入图片描述

	ADC1->CR &= ~ADC_CR_DEEPPWD;//退出掉电模式
	ADC1->CR |= ADC_CR_ADVREGEN;//使能稳压器
	for (i = 0; i < 0xffff; i++)//延时等待稳压器稳定
	{
		/* code */
	}

1.2 选择输入模式

ADC->DIFSEL 模式选择寄存器 中选择 差分输入或者单端输入模式。

	ADC1->DIFSEL = (ADC1->DIFSEL & 0xfff80000)//模式选择寄存器
	// |ADC_DIFSEL_DIFSEL_18		//bit18:【0|单端输入模式】【1|差分输入模式】
	// |ADC_DIFSEL_DIFSEL_17
	// |ADC_DIFSEL_DIFSEL_16
	// |ADC_DIFSEL_DIFSEL_15
	// |ADC_DIFSEL_DIFSEL_14
	// |ADC_DIFSEL_DIFSEL_13
	// |ADC_DIFSEL_DIFSEL_12
	// |ADC_DIFSEL_DIFSEL_11
	// |ADC_DIFSEL_DIFSEL_10
	// |ADC_DIFSEL_DIFSEL_9
	// |ADC_DIFSEL_DIFSEL_8
	// |ADC_DIFSEL_DIFSEL_7
	// |ADC_DIFSEL_DIFSEL_6
	// |ADC_DIFSEL_DIFSEL_5
	// |ADC_DIFSEL_DIFSEL_4
	// |ADC_DIFSEL_DIFSEL_3
	// |ADC_DIFSEL_DIFSEL_2
	// |ADC_DIFSEL_DIFSEL_1
	// |ADC_DIFSEL_DIFSEL_0
	;
	

1.3 校准

校准分为单端校准和差分校准

在这里插入图片描述

  1. 确定DEEPPWD=0(退出深度掉电模式),ADVREGEN=1(稳压器开启),并且已经等待了稳压器的启动时间。
  2. 确定ADEN=0。
  3. 配置ADC->CR寄存器中的ADCALDIF标志位,选择输入模式(ADCALDIF=0 单端输入 / ADCALDIF=1 差分输入)。
  4. ADC->CR寄存器的ADCAL标志位置位,即开启校准(ADCALDIF配置为什么模式就校准什么模式)。
  5. 等待ADC->CR寄存器的ADCAL硬件清除,即ADCAL=0,代表校准结束。
  6. 在ADC->CALFACT寄存器中读取校准系数。

下面以单端输入校准为例:

	ADC1->CR &= ~ADC_CR_ADCALDIF;//单端输入模式 步骤2
	ADC1->CR &= ~ADC_CR_ADEN;	//禁止ADC 步骤3
	ADC1->CR |= ADC_CR_ADCAL;	//校准ADC 步骤4
	i = 0xffff;
	while((ADC1->CR & ADC_CR_ADCAL) && (i--));//等待校准结束。步骤5
	if(i == 0)//超时判断
	{
		return FAILED;
	}

如果通道中又有差分输入还有单端输入,则需要将两个系数都进行校准。

1.4 转换队列设置

1.5 采样时间设置

在这里插入图片描述

每个通道都可以用不同的采样时间进行采样,采样时间由ADC->SMPR1寄存器中的SMP位进行编程。因此,可以在以下采样时间值中进行选择:
• SMP = 000: 2.5 ADC clock cycles
• SMP = 001: 6.5 ADC clock cycles
• SMP = 010: 12.5 ADC clock cycles
• SMP = 011: 24.5 ADC clock cycles
• SMP = 100: 47.5 ADC clock cycles
• SMP = 101: 92.5 ADC clock cycles
• SMP = 110: 247.5 ADC clock cycles
• SMP = 111: 640.5 ADC clock cycles
总转换时间计算如下:TCONV = SMP + 12.5 ADC时钟周期(12-bit)
例如:
Fadc_ker_ck = 30MHz,并且SMP=0 即2.5 ADC时钟周期
TCONV = (2.5 + 12.5)个 ADC 时钟周期,即 15 / 30 us = 500ns
采样结束后,ADC_ISR_EOSMP置位,代表采样结束(仅在规则转换中有效)

器与分辨率的转换时间如下表:
在这里插入图片描述

注意:
在这里插入图片描述

每个通道的采样时间必须遵循数据手册的最小采样时间。(数据手册第146页 DM00431551_ENV3)

在这里插入图片描述

SMPPLUS control bit

在ADC->SMPR1寄存器中有这么个标志位,其作用是为了方便 交错模式 对称。

2 ADC采样模式

2.1 Bulb sampling mode(灯泡模式?)

启动该采样模式,则在第二个ADC空闲时间进行采样,如下图
在这里插入图片描述

  • 该采样方式有最大采样时间限制,参考数据手册。
  • 该采样方式不适用连续采样和注入采样。
  • 如果该模式启动(ADC->CFGR2中的BULB=1),则不准置位ADC->CFGR2中的SMPTRIG。

2.2 Sampling time control trigger mode(采样时间控制触发模式)

当SMPTRIG置位时(在ADC->CFGR2寄存器中),通过SMPx位(在ADC->SMPRx寄存器中)编程的采样时间是无效的。采样时间由触发信号边缘控制。

该模式分为软件控制和硬件控制:

  • 硬件触发
    当选择硬件触发器时,触发信号的每个上升沿开始采样周期。下降沿结束采样周期并开始转换。EXTEN(外部触发极性选择,在ADC->CFGR寄存器中)必须设置为01(上升沿有效)。 Hardware triggers with not defined rising and falling edges (one pulse event) cannot be used in Bulb mode.
  • 软件触发
    当选择软件触发器时,软件触发器不是ADC->CR中的ADSTART位,而是ADC->CFGR2寄存器中的SWTRIG位。置位SWTRIG位开始采样周期,清除SWTRIG位结束采样周期同时开始转换。EXTEN(外部触发极性选择,在ADC->CFGR寄存器中)必须设置为00(禁止外部触发)。

3. 转换模式

3.1 单次转换模式(CONT=0)

当ADC_CFGR_CONT=0,代表配置为单次转换模式。

  • 规则模式:置位ADSTART(ADC->CR寄存器)或者外部触发
  • 注入模式:置位JADSTART(ADC->CR寄存器)或者外部触发

在规则序列中,每次转换完成后

  • 转换后的数据存储到16位ADC_DR寄存器
  • 置位ADC_ISR_EOC(结束常规转换)标志(读取或者写1 清零)
  • 如果设置了ADC_IER_EOCIE位,就会产生一个中断

在注入序列中,每次转换完成后

  • 转换后的数据存储到16位ADC_JDRy寄存器
  • 置位ADC_ISR_JEOC(结束常规转换)标志(读取或者写1 清零)
  • 如果设置了ADC_IER_JEOCIE位,就会产生一个中断

在规则序列完成后

  • ADC_ISR_EOSEOS标志位置位(写1清零)
  • 如果ADC_IER_EOSIE置位,则会产生一个中断

在注入序列完成后

  • ADC_ISR_JEOS标志位置位(写1清零)
  • 如果ADC_IER_JEOSIE置位,则会产生一个中断

提示:如果想转换单个通道请将 L(队列转换长度,在ADC1->SQR1寄存器中)设置为0(0代表转换1次也就是1个通道)。

3.2 连续转换模式(CONT=1)

当ADC_CFGR_CONT=1,代表配置为连续转换模式。
只有规则通道有连续转换模式。

在规则序列中,每次转换完成后

  • 转换后的数据存储到16位ADC_DR寄存器
  • 置位ADC_ISR_EOC(结束常规转换)标志(读取或者写1 清零)
  • 如果设置了ADC_IER_EOCIE位,就会产生一个中断

在规则序列完成后

  • ADC_ISR_EOSEOS标志位置位(写1清零)
  • 如果ADC_IER_EOSIE置位,则会产生一个中断

然后,一个新的序列立即重启,ADC连续重复转换序列。
禁止同时置位 ADC_CFGR_DISCEN 和 ADC_CFGR_CONT。
注入通道要想连续转换,需要设置自动注入。

连续转换模式下,ADSTART不会被硬件清除。
不能同时使能ADC_CFGR_DISCEN和ADC_CFGR_CONT。

3.3 不连续模式

ADC_CFGR_DISCEN=1,开启不连续模式,每次触发都只转换ADC_CFGR_DISCNUM个通道数量,每次转换都会置位EOC标志位,直到转换完ADC->SQR里面的通道(总个数为ADC->SQR1中的L),最后置位EOS标志位。

ADC_CFGR_DISCEN=0,关闭不连续模式,一次触发转换ADC_SQR1_L个通道,每次转换都会置位EOC标志位,最后置位EOS标志位。

不能同时使能ADC_CFGR_DISCEN和ADC_CFGR_CONT。

4. 触发模式

ADSTART

  • 当EXTEN[1:0] == 0,ADSTART=1立即触发转换
  • 当EXTEN[1:0] != 0,ADSTART=1得等待下个有效硬件触发才进行转换

JADSTART

  • 当JEXTEN[1:0] == 0,JADSTART=1立即触发转换
  • 当JEXTEN[1:0] != 0,JADSTART=1得等待下个有效硬件触发才进行转换

外部触发

当注入队列使能(ADC_CFGR_JQDIS=0),软件不能触发注入通道。
转换过程中,触发会被忽略。

触发极性

在这里插入图片描述
在这里插入图片描述

触发源

在这里插入图片描述
具体触发源见手册的第627页(DM00355726_ENV4)

5. 使用方法

5.1 注入模式

5.1.1 描述

注入模式 的优点就是相比 规则转换模式队列模式 有更好的灵活性,它可以在ADC使能运行的情况下,修改 触发源采样队列。对于经常变换 通道采样 或者 触发源 的工况下,这种模式更适合应用。

5.1.1 触发注入模式

在选择触发注入模式时,JAUTO 控制位(自动注入) 必须清除

  1. 通过外部触发或通过设置 ADC_CR 寄存器中的 ADSTART 位来启动一组常规通道的转换
  2. 如果发生外部注入触发,或者在常规通道组转换期间设置了 ADC_CR 寄存器中的 JADSTART 位,则当前执行的规则转换复位,然后启动注入转换序列(所有注入通道转换一次)
  3. 然后,恢复上次中断的常规转换
  4. 如果在注入转换期间发生常规事件,则注入转换不会中断,而是在注入序列结束时执行常规序列

配置 触发注入 模式的方法如下:

  1. 退出 睡眠模式(清除ADC_CR寄存器中的位DEEPPWD
  2. 使能 ADC电压调节器(置位ADC_CR寄存器中的位ADVREGEN),延时等待电压调节器稳定
  3. 配置校准的模式(差分 和 单端 ,ADC_CR寄存器中的位ADCALDIF
  4. 使能校准(ADC_CR寄存器中的位ADCAL),等待ADCAL清除,代表校准完毕
    如果需要存储校准值可以读取CALFACT寄存器获取校准值,下次上电直接写入该寄存器
  5. 配置 ADC12_CCR 寄存器,选择单独工作还是同步工作、时钟配置、传感器使能采样延时等参数
  6. 配置ADC_CFGR寄存器,清除位JQDIS,允许注入模式,DMA、采样模式等参数
  7. 配置ADC_SMPR寄存器,来确定采样时间
  8. 配置ADC_IER寄存器,使能需要的中断
  9. 使能ADC(ADC_CR寄存器中的位ADEN),等待ADC就绪(等待ADC_ISR中的位** ADRDY**置位)
  10. 允许注入触发(ADC_CR寄存器中的位JADSTART
  • 可以在任意处配置ADC_JSQR寄存器,选择触发源和采样序列。

下面是

  • ADC12同步注入模式
  • ADC1、2 触发模式,每次触发序列为2次转换
  • 触发源为 TIM1的TIGRO2

转换序列为

  • ADC1 第一次转换通道3 第二次转换同道4
  • ADC2 第一次转换通道2 第二次转换同道15
void ADC1_2_Function_Init(void)
{
	volatile uint32_t j;			// 避免延时函数被编译器优化

	//============================================基本初始化开始
	// 步骤1 退出 睡眠模式
	ADC1->CR &= ~ADC_CR_DEEPPWD;    //退出掉电模式 
	ADC2->CR &= ~ADC_CR_DEEPPWD;    //退出掉电模式


	// 步骤2 使能 ADC电压调节器
	ADC1->CR |= ADC_CR_ADVREGEN;
	ADC2->CR |= ADC_CR_ADVREGEN;
	for(j=0;j<430000;j++);		//延时,等待voltage regulator启动


	// 步骤3 配置校准的模式
	ADC1->CR &= ~ADC_CR_ADCALDIF;//【0|单端输入】【1|差分输入】
	ADC2->CR &= ~ADC_CR_ADCALDIF;//当前为单端校准


	// 步骤4 使能校准
	ADC1->CR |= ADC_CR_ADCAL;
	ADC2->CR |= ADC_CR_ADCAL;
	//等待ADC校准结束
	while((ADC1->CR & ADC_CR_ADCAL) != 0);
	while((ADC2->CR & ADC_CR_ADCAL) != 0);
	//============================================基本初始化结束


	// 步骤5 配置 ADC12_CCR 寄存器
	ADC12_COMMON->CCR = 0x00000000
						// |ADC_CCR_VBATSEL
						// |ADC_CCR_VSENSESEL
						// |ADC_CCR_VREFEN
						|(0 << ADC_CCR_PRESC_Pos)	// 时钟配置(详细见手册 DM00355726_ENV4手册718页)
						|(3 << ADC_CCR_CKMODE_Pos)	// ADC 时钟配置(详细见手册 DM00355726_ENV4手册719页)
						|(0 << ADC_CCR_MDMA_Pos)	// DMA 数据分辨率配置
						// |ADC_CCR_DMACFG			// DMA 循环模式配置
						|(10 << ADC_CCR_DELAY_Pos)	// 延时采样时间配置(详细见手册 DM00355726_ENV4手册720页)
						|(5 << ADC_CCR_DUAL_Pos)	// 选择 仅同步注入模式(详细见手册 DM00355726_ENV4手册720页)
						;


	// 步骤6 配置ADC_CFGR寄存器
	ADC1->CFGR = 0x00000000
				// |ADC_CFGR_JQDIS						// 禁止注入(默认为1) 【0|允许注入】【1|禁止注入】
				|(0 << ADC_CFGR_AWD1CH_Pos)			// AWTD1 通道选择
				// |ADC_CFGR_JAUTO						// 自动注入组转换(当启用双模式时,从ADC的位JAUTO不再可写,其内容等于主ADC的位JAUTO。)
				// |ADC_CFGR_JAWD1EN					// JAWTD1 使能注入通道
				// |ADC_CFGR_AWD1EN					// AWTD1 使能规则通道
				// |ADC_CFGR_AWD1SGL					// 【0|AWTD1使能所有通道】【1|AWTD1使能 AWD1CH 通道】
				// |ADC_CFGR_JQM						// 注入队列模式。【0|一次序列后,保持队列参数】【1|一次序列后,队列不保存,清除,续重新配置才能再次触发,这段没有配置的时间不响应触发】
				// |ADC_CFGR_JDISCEN					// 注入通道上的不连续模式。【0|禁止不连续模式】【1|使能连续模式】(不能同时使用 自动注入 和 不连续模式)(当启用双模式时,从ADC该bit无效)
				|(0 << ADC_CFGR_DISCNUM_Pos)		// 不连续通道数
				// |ADC_CFGR_DISCEN					// 规则通道上的不连续模式【0|禁止不连续模式】【1|使能连续模式】(不能同时使用 自动注入 和 不连续模式)(当启用双模式时,从ADC该bit无效)
				// |ADC_CFGR_ALIGN						// 数据左对齐【0|数据右对齐】【1|数据左对齐】
				// |ADC_CFGR_AUTDLY					// 延时转换模式开启 (当启用双模式时,从ADC该bit无效)
				// |ADC_CFGR_CONT						// 单独/连续 转换模式规则转换【0|单独转换模式】【1|连续转换模式(只有规则通道有该模式)】 (当启用双模式时,从ADC该bit无效)
				|ADC_CFGR_OVRMOD					// 【0|溢出后保留老数据】【1|溢出后覆盖老数据】
				|(0 << ADC_CFGR_EXTEN_Pos)			// 规则通道 触发方式选择
														//【0|禁止】
														//【1|上升沿触发】
														//【2|下降沿触发】
														//【3|上升和下降沿触发】
				|(0 << ADC_CFGR_EXTSEL_Pos)			// 规则通道 外部触发源选择
				|(0 << ADC_CFGR_RES_Pos)			// 数据分辨率 【00|12-bit】【01|10-bit】【10|8-bit】【11|6-bit】
				// |ADC_CFGR_DMACFG					// DMA 配置
				// |ADC_CFGR_DMAEN						// DMA 请求使能
				;

	ADC2->CFGR = 0x00000000
				// |ADC_CFGR_JQDIS						// 禁止注入(默认为1) 【0|允许注入】【1|禁止注入】
				|(0 << ADC_CFGR_AWD1CH_Pos)			// AWTD1 通道选择
				// |ADC_CFGR_JAUTO						// 自动注入组转换(当启用双模式时,从ADC的位JAUTO不再可写,其内容等于主ADC的位JAUTO。)
				// |ADC_CFGR_JAWD1EN					// JAWTD1 使能注入通道
				// |ADC_CFGR_AWD1EN					// AWTD1 使能规则通道
				// |ADC_CFGR_AWD1SGL					// 【0|AWTD1使能所有通道】【1|AWTD1使能 AWD1CH 通道】
				// |ADC_CFGR_JQM						// 注入队列模式。【0|一次序列后,保持队列参数】【1|一次序列后,队列不保存,清除,续重新配置才能再次触发,这段没有配置的时间不响应触发】
				// |ADC_CFGR_JDISCEN					// 注入通道上的不连续模式。【0|禁止不连续模式】【1|使能连续模式】(不能同时使用 自动注入 和 不连续模式)(当启用双模式时,从ADC该bit无效)
				|(0 << ADC_CFGR_DISCNUM_Pos)		// 不连续通道数
				// |ADC_CFGR_DISCEN					// 规则通道上的不连续模式【0|禁止不连续模式】【1|使能连续模式】(不能同时使用 自动注入 和 不连续模式)(当启用双模式时,从ADC该bit无效)
				// |ADC_CFGR_ALIGN						// 数据左对齐【0|数据右对齐】【1|数据左对齐】
				// |ADC_CFGR_AUTDLY					// 延时转换模式开启 (当启用双模式时,从ADC该bit无效)
				// |ADC_CFGR_CONT						// 单独/连续 转换模式规则转换【0|单独转换模式】【1|连续转换模式(只有规则通道有该模式)】 (当启用双模式时,从ADC该bit无效)
				|ADC_CFGR_OVRMOD					// 【0|溢出后保留老数据】【1|溢出后覆盖老数据】
				|(0 << ADC_CFGR_EXTEN_Pos)			// 规则通道 触发方式选择
														//【0|禁止】
														//【1|上升沿触发】
														//【2|下降沿触发】
														//【3|上升和下降沿触发】
				|(0 << ADC_CFGR_EXTSEL_Pos)			// 规则通道 外部触发源选择
				|(0 << ADC_CFGR_RES_Pos)			// 数据分辨率 【00|12-bit】【01|10-bit】【10|8-bit】【11|6-bit】
				// |ADC_CFGR_DMACFG					// DMA 配置
				// |ADC_CFGR_DMAEN						// DMA 请求使能
				;


	// 配置 ADC 看门狗, 如果不需要就不用配置
	ADC1->TR1 = (3548 << ADC_TR1_HT1_Pos)	//2048+1500 = 3548
				|(548 << ADC_TR1_LT1_Pos)	//2048-1500 = 548
				|(1 << ADC_TR1_AWDFILT_Pos)	//达到阈值次数
				;
	ADC2->TR1 = (3548 << ADC_TR1_HT1_Pos)	//2048+1500 = 3548
				|(548 << ADC_TR1_LT1_Pos)	//2048-1500 = 548
				|(1 << ADC_TR1_AWDFILT_Pos)	//达到阈值次数
				;


	// 步骤7 配置ADC_SMPR寄存器
	ADC1->SMPR1 = (ADC1->SMPR1 & 0x40000007)
				// |(5 << ADC_SMPR1_SMP9_Pos)	//bit[29-27]:  通道x采样时间选择
				// |(0 << ADC_SMPR1_SMP8_Pos)	//bit[26-24]: 【000|2.5 ADC clock cycles】  0
				// |(5 << ADC_SMPR1_SMP7_Pos)	//bit[23-21]: 【001|6.5 ADC clock cycles】  1
				// |(0 << ADC_SMPR1_SMP6_Pos)	//bit[20-18]: 【010|12.5 ADC clock cycles】 2
				// |(5 << ADC_SMPR1_SMP5_Pos)	//bit[17-15]: 【011|24.5 ADC clock cycles】 3
				|(3 << ADC_SMPR1_SMP4_Pos)	//bit[14-12]: 【100|47.5 ADC clock cycles】 4
				|(3 << ADC_SMPR1_SMP3_Pos)	//bit[11-09]: 【101|92.5 ADC clock cycles】 5
				// |(0 << ADC_SMPR1_SMP2_Pos)	//bit[08-06]: 【110|247.5 ADC clock cycles】6
				// |(0 << ADC_SMPR1_SMP1_Pos)	//bit[05-03]: 【111|640.5 ADC clock cycles】7
				;
	ADC1->SMPR2 = (ADC1->SMPR2 & 0xf8000000)
				// |(0 << ADC_SMPR2_SMP18_Pos)	//bit[26-24]:  通道x采样时间选择
				// |(5 << ADC_SMPR2_SMP17_Pos)	//bit[23-21]: 【000|2.5 ADC clock cycles】  0
				// |(0 << ADC_SMPR2_SMP16_Pos)	//bit[20-18]: 【001|6.5 ADC clock cycles】  1
				// |(0 << ADC_SMPR2_SMP15_Pos)	//bit[17-15]: 【010|12.5 ADC clock cycles】 2
				// |(0 << ADC_SMPR2_SMP14_Pos)	//bit[14-12]: 【011|24.5 ADC clock cycles】 3
				// |(5 << ADC_SMPR2_SMP13_Pos)	//bit[11-09]: 【100|47.5 ADC clock cycles】 4
				// |(0 << ADC_SMPR2_SMP12_Pos)	//bit[08-06]: 【101|92.5 ADC clock cycles】 5
				// |(5 << ADC_SMPR2_SMP11_Pos)	//bit[05-03]: 【110|247.5 ADC clock cycles】6
				// |(0 << ADC_SMPR2_SMP10_Pos)	//bit[02-00]: 【111|640.5 ADC clock cycles】7
				;
	ADC2->SMPR1 = (ADC2->SMPR1 & 0x40000007)
				// |(5 << ADC_SMPR1_SMP9_Pos)	//bit[29-27]:  通道x采样时间选择
				// |(0 << ADC_SMPR1_SMP8_Pos)	//bit[26-24]: 【000|2.5 ADC clock cycles】  0
				// |(5 << ADC_SMPR1_SMP7_Pos)	//bit[23-21]: 【001|6.5 ADC clock cycles】  1
				// |(0 << ADC_SMPR1_SMP6_Pos)	//bit[20-18]: 【010|12.5 ADC clock cycles】 2
				// |(5 << ADC_SMPR1_SMP5_Pos)	//bit[17-15]: 【011|24.5 ADC clock cycles】 3
				// |(0 << ADC_SMPR1_SMP4_Pos)	//bit[14-12]: 【100|47.5 ADC clock cycles】 4
				// |(0 << ADC_SMPR1_SMP3_Pos)	//bit[11-09]: 【101|92.5 ADC clock cycles】 5
				|(3 << ADC_SMPR1_SMP2_Pos)	//bit[08-06]: 【110|247.5 ADC clock cycles】6
				// |(0 << ADC_SMPR1_SMP1_Pos)	//bit[05-03]: 【111|640.5 ADC clock cycles】7
				;
	ADC2->SMPR2 = (ADC2->SMPR2 & 0xf8000000)
				// |(0 << ADC_SMPR2_SMP18_Pos)	//bit[26-24]:  通道x采样时间选择
				// |(5 << ADC_SMPR2_SMP17_Pos)	//bit[23-21]: 【000|2.5 ADC clock cycles】  0
				// |(0 << ADC_SMPR2_SMP16_Pos)	//bit[20-18]: 【001|6.5 ADC clock cycles】  1
				|(3 << ADC_SMPR2_SMP15_Pos)	//bit[17-15]: 【010|12.5 ADC clock cycles】 2
				// |(0 << ADC_SMPR2_SMP14_Pos)	//bit[14-12]: 【011|24.5 ADC clock cycles】 3
				// |(5 << ADC_SMPR2_SMP13_Pos)	//bit[11-09]: 【100|47.5 ADC clock cycles】 4
				// |(0 << ADC_SMPR2_SMP12_Pos)	//bit[08-06]: 【101|92.5 ADC clock cycles】 5
				// |(5 << ADC_SMPR2_SMP11_Pos)	//bit[05-03]: 【110|247.5 ADC clock cycles】6
				// |(0 << ADC_SMPR2_SMP10_Pos)	//bit[02-00]: 【111|640.5 ADC clock cycles】7
				;


	// 步骤8 配置ADC_IER寄存器,配置中断
	ADC1->IER = 0x00000000
				// |ADC_IER_JQOVFIE
				// |ADC_IER_AWD3IE
				// |ADC_IER_AWD2IE
				// |ADC_IER_AWD1IE
				// |ADC_IER_JEOSIE
				|ADC_IER_JEOCIE
				// |ADC_IER_OVRIE
				// |ADC_IER_EOSIE
				// |ADC_IER_EOCIE
				// |ADC_IER_EOSMPIE
				// |ADC_IER_ADRDYIE
				;


	// 步骤9 使能ADC
	ADC1->CR |= ADC_CR_ADEN;
	ADC2->CR |= ADC_CR_ADEN;
	//等待ADC 就绪
	while(!(ADC1->ISR & ADC_ISR_ADRDY));
	while(!(ADC2->ISR & ADC_ISR_ADRDY));
	

	// 步骤10 允许注入触发
	ADC1->CR |= ADC_CR_JADSTART;
	ADC2->CR |= ADC_CR_JADSTART;
	

	// 配置注入队列
	ADC1->JSQR = 0x00000000
				|(0 << ADC_JSQR_JSQ4_Pos)			// 0~18
				|(0 << ADC_JSQR_JSQ3_Pos)			// 0~18
				|(4 << ADC_JSQR_JSQ2_Pos)			// 0~18
				|(3 << ADC_JSQR_JSQ1_Pos)			// 0~18
				|(1 << ADC_JSQR_JEXTEN_Pos)			// 外部触发极性选择。
														//【0|如果 JQDIS=0 ,禁止硬件和软件触发。如果 JQDIS=1 ,禁止硬件触发】
														//【1|上升沿触发】
														//【2|下降沿触发】
														//【3|上升和下降沿触发】
				|(0x08 << ADC_JSQR_JEXTSEL_Pos)		// 外部触发源选择
				|(1 << ADC_JSQR_JL_Pos)				// 注入通道长度 n-1
				;

	ADC2->JSQR = 0x00000000
				|(0 << ADC_JSQR_JSQ4_Pos)			// 0~18
				|(0 << ADC_JSQR_JSQ3_Pos)			// 0~18
				|(15 << ADC_JSQR_JSQ2_Pos)			// 0~18
				|(2 << ADC_JSQR_JSQ1_Pos)			// 0~18
				|(1 << ADC_JSQR_JEXTEN_Pos)			// 外部触发极性选择。
														//【0|如果 JQDIS=0 ,禁止硬件和软件触发。如果 JQDIS=1 ,禁止硬件触发】
														//【1|上升沿触发】
														//【2|下降沿触发】
														//【3|上升和下降沿触发】
				|(0x08 << ADC_JSQR_JEXTSEL_Pos)		// 外部触发源选择
				|(1 << ADC_JSQR_JL_Pos)				// 注入通道长度 n-1
				;
}

下面是触发注入模式,在ADC运行过程中,修改 采样队列 的时序图。
在这里插入图片描述

5.1.2 自动注入模式
5.1.3

DMA请求

双ADC模式

当ADC_CCR_DUAL不等于0的时候,ADC进入双ADC模式,双ADC模式下,从ADC的配置位和主模式的配置位共享(CFGR寄存器),只需在主ADC中配置触发源、触发方式、触发极性、注入触发源、注入触发极性就可以,从ADC不用配置。

附录

寄存器表

	ADC1->CR = (ADC1->CR & 0x2fffffc0)//default:0x2000 0000
	// |ADC_CR_ADCAL				//bit31: ADC校准
	// |ADC_CR_ADCALDIF			//bit30: 校准模式【0|单端输入模式】【1|差分输入模式】
	// |ADC_CR_DEEPPWD				//bit29: 深度掉电使能【1|深度掉电模式】
	// |ADC_CR_ADVREGEN			//bit28: ADC稳压器使能【1|使能稳压器】
	// |ADC_CR_JADSTP				//bit05: 停止注入转换指令
	// |ADC_CR_ADSTP				//bit04: 停止规则转换指令
	// |ADC_CR_JADSTART			//bit03: 开始注入转换指令
	// |ADC_CR_ADSTART				//bit02: 开始规则转换指令
	// |ADC_CR_ADDIS				//bit01: ADC停止指令
	// |ADC_CR_ADEN				//bit00: ADC使能
	;
	ADC1->DIFSEL = (ADC1->DIFSEL & 0xfff80000)//模式选择寄存器
	// |ADC_DIFSEL_DIFSEL_18		//bit18:【0|单端输入模式】【1|差分输入模式】
	// |ADC_DIFSEL_DIFSEL_17
	// |ADC_DIFSEL_DIFSEL_16
	// |ADC_DIFSEL_DIFSEL_15
	// |ADC_DIFSEL_DIFSEL_14
	// |ADC_DIFSEL_DIFSEL_13
	// |ADC_DIFSEL_DIFSEL_12
	// |ADC_DIFSEL_DIFSEL_11
	// |ADC_DIFSEL_DIFSEL_10
	// |ADC_DIFSEL_DIFSEL_9
	// |ADC_DIFSEL_DIFSEL_8
	// |ADC_DIFSEL_DIFSEL_7
	// |ADC_DIFSEL_DIFSEL_6
	// |ADC_DIFSEL_DIFSEL_5
	// |ADC_DIFSEL_DIFSEL_4
	// |ADC_DIFSEL_DIFSEL_3
	// |ADC_DIFSEL_DIFSEL_2
	// |ADC_DIFSEL_DIFSEL_1
	// |ADC_DIFSEL_DIFSEL_0
	;
	

	ADC1->SQR1 = (ADC1->SQR1 & 0xe0820830)
	// |(0 << ADC_SQR1_SQ4_Pos)	//bit[28-24]: 4th 规则队列(5-bit 0~18)
	// |(0 << ADC_SQR1_SQ3_Pos)	//bit[22-18]: 3rd 规则队列(5-bit 0~18)
	// |(0 << ADC_SQR1_SQ2_Pos)	//bit[16-12]: 2nd 规则队列(5-bit 0~18)
	// |(0 << ADC_SQR1_SQ1_Pos)	//bit[10-06]: 1st 规则队列(5-bit 0~18)
	// |(0 << ADC_SQR1_L_Pos)		//bit[03-00]: 规则通道队列长度
	;
	ADC1->SQR2 = (ADC1->SQR2 & 0xe0820820)
	// |(0 << ADC_SQR2_SQ9_Pos)	//bit[28-24]: 9th 规则队列(5-bit 0~18)
	// |(0 << ADC_SQR2_SQ8_Pos)	//bit[22-18]: 8th 规则队列(5-bit 0~18)
	// |(0 << ADC_SQR2_SQ7_Pos)	//bit[16-12]: 7th 规则队列(5-bit 0~18)
	// |(0 << ADC_SQR2_SQ6_Pos)	//bit[10-06]: 6th 规则队列(5-bit 0~18)
	// |(0 << ADC_SQR2_SQ5_Pos)	//bit[04-00]: 5th 规则队列(5-bit 0~18)
	;
	ADC1->SQR3 = (ADC1->SQR3 & 0xe0820820)
	// |(0 << ADC_SQR3_SQ14_Pos)	//bit[28-24]: 14th 规则队列(5-bit 0~18)
	// |(0 << ADC_SQR3_SQ13_Pos)	//bit[22-18]: 13th 规则队列(5-bit 0~18)
	// |(0 << ADC_SQR3_SQ12_Pos)	//bit[16-12]: 12th 规则队列(5-bit 0~18)
	// |(0 << ADC_SQR3_SQ11_Pos)	//bit[10-06]: 11th 规则队列(5-bit 0~18)
	// |(0 << ADC_SQR3_SQ10_Pos)	//bit[04-00]: 10th 规则队列(5-bit 0~18)
	;
	ADC1->SQR4 = (ADC1->SQR4 & 0xfffff820)
	// |(0 << ADC_SQR4_SQ16_Pos)	//bit[10-06]: 16th 规则队列(5-bit 0~18)
	// |(0 << ADC_SQR4_SQ15_Pos)	//bit[04-00]: 15th 规则队列(5-bit 0~18)
	;
	
	// ADC1->ISR  只读
	// |ADC_ISR_JQOVF				//bit10: 注入队列溢出
	// |ADC_ISR_AWD3				//bit09: 模拟看门狗3 标志位
	// |ADC_ISR_AWD2				//bit08: 模拟看门狗2 标志位
	// |ADC_ISR_AWD1				//bit07: 模拟看门狗1 标志位
    // |ADC_ISR_JEOS				//bit06: 注入通道队列转换结束标志(写1清零)
	// |ADC_ISR_JEOC				//bit05: 注入通道转换结束标志(读取清零)
	// |ADC_ISR_OVR				//bit04: ADC溢出(数据被覆盖)
	// |ADC_ISR_EOS				//bit03: 规则转换队列结束
	// |ADC_ISR_EOC				//bit02: 规则转换结束
	// |ADC_ISR_EOSMP				//bit01: 采样结束标志
	// |ADC_ISR_ADRDY				//bit00: ADC准备就绪

	ADC1->IER = (ADC1->IER & 0xfffff800)
	// |ADC_IER_JQOVFIE			//bit10: 注入队列溢出 中断使能
	// |ADC_IER_AWD3IE				//bit09: 模拟看门狗3 中断使能
	// |ADC_IER_AWD2IE				//bit08: 模拟看门狗2 中断使能
	// |ADC_IER_AWD1IE				//bit07: 模拟看门狗1 中断使能
	// |ADC_IER_JEOSIE				//bit06: 注入通道队列转换结束 中断使能
	// |ADC_IER_JEOCIE				//bit05: 注入通道转换结束 中断使能
	// |ADC_IER_OVRIE				//bit04: ADC溢出 中断使能
	// |ADC_IER_EOSIE				//bit03: 规则转换队列结束 中断使能
	// |ADC_IER_EOCIE				//bit02: 规则转换结束 中断使能
	// |ADC_IER_EOSMPIE			//bit01: 采样结束 中断使能
	// |ADC_IER_ADRDYIE			//bit00: ADC就绪 中断使能
	;

	
	ADC1->CFGR = (ADC1->CFGR & 0x80000000)
	// |ADC_CFGR_JQDIS				//bit31: 注入队列禁止使能【1|禁止注入队列】
	// |(0 << ADC_CFGR_AWD1CH_Pos)	//bit[30-26]: 模拟量看门狗1 通道选择
	// |ADC_CFGR_JAUTO				//bit25: 自动注入通道【1|自动注入组转换使能】
	// |ADC_CFGR_JAWD1EN			//bit24: 注入通道 模拟量看门狗1 使能
	// |ADC_CFGR_AWD1EN			//bit23: 规则通道 模拟量看门狗1 使能
	// |ADC_CFGR_AWD1SGL			//bit22: 【1|模拟量看门狗1 使能在单独通道上】
	// |ADC_CFGR_JQM				//bit21: JSQR队列模式
	// |ADC_CFGR_JDISCEN			//bit20: 注入通道上的不连续模式
	// |(0 << ADC_CFGR_DISCNUM_Pos)//bit[19-17]: 不连续模式通道计数
	// |ADC_CFGR_DISCEN			//bit16: 规则通道上的不连续模式
	// |ADC_CFGR_ALIGN				//bit15: 数据左对齐【1|数据左对齐】
	// |ADC_CFGR_AUTDLY			//bit14: 延时转换模式开启
	// |ADC_CFGR_CONT				//bit13: 单独/连续 转换模式规则转换【0|单独转换模式】【1|连续转换模式】
	// |ADC_CFGR_OVRMOD			//bit12: 【0|溢出后保留老数据】【1|溢出后覆盖老数据】
	// |ADC_CFGR_EXTEN_1			//bit[11-10]: 外部触发极性选择
	// |ADC_CFGR_EXTEN_0			//    【00|禁止外部触发】【01|上升沿】【10|下降沿】【11|上下都有效】
	// |(0 << ADC_CFGR_EXTSEL_Pos)	//bit[09-05]: 外部触发源选择
	// |ADC_CFGR_RES_1				//bit[04-03]: 数据分辨率
	// |ADC_CFGR_RES_0				//    【00|12-bit】【01|10-bit】【10|8-bit】【11|6-bit】
	// |ADC_CFGR_DMACFG			//bit01: 【0|单次模式】【1|循环模式】
	// |ADC_CFGR_DMAEN				//bit00: 【0|禁止DMA请求】【1|使能DMA请求】
	;
	ADC1->CFGR2 = (ADC1->CFGR2 & 0xf1fef800)
	// |ADC_CFGR2_SMPTRIG			//bit27: 采样时间控制触发模式,通过SWTRIG位控制采样时间和转换时间
	// |ADC_CFGR2_BULB				//bit26: 【1|两次采样间隔的空闲进行下次采样】
	// |ADC_CFGR2_SWTRIG			//bit25: 采样时间控制触发模式的软件触发位
	// |ADC_CFGR2_GCOMP			//bit16: 增益补偿模式【1|所有通道增益补偿】
	// |ADC_CFGR2_ROVSM			//bit10: 规则过采样模式【0|继续采样】【1|整个序列重新从头采样】
	// |ADC_CFGR2_TROVS			//bit09: 触发常规过采样
	// |(0 << ADC_CFGR2_OVSS_Pos)	//bit[08-05]: 过采样移位
	// |(0 << ADC_CFGR2_OVSR_Pos)	//bit[04-02]: 过采样比率
	// |ADC_CFGR2_JOVSE			//bit01: 注入过采样使能
	// |ADC_CFGR2_ROVSE			//bit00: 规则过采样使能
	;

	ADC1->SMPR1 = (ADC1->SMPR1 & 0x40000000)
	// |ADC_SMPR1_SMPPLUS			//bit31: 【1|2.5-ADCCLK】【0|3.5-ADCCLK】为了使整个周期成为偶数,方便交错模式
	// |(0 << ADC_SMPR1_SMP9_Pos)	//bit[29-27]:  通道x采样时间选择
	// |(0 << ADC_SMPR1_SMP8_Pos)	//bit[26-24]: 【000|2.5 ADC clock cycles】  0
	// |(0 << ADC_SMPR1_SMP7_Pos)	//bit[23-21]: 【001|6.5 ADC clock cycles】  1
	// |(0 << ADC_SMPR1_SMP6_Pos)	//bit[20-18]: 【010|12.5 ADC clock cycles】 2
	// |(0 << ADC_SMPR1_SMP5_Pos)	//bit[17-15]: 【011|24.5 ADC clock cycles】 3
	// |(0 << ADC_SMPR1_SMP4_Pos)	//bit[14-12]: 【100|47.5 ADC clock cycles】 4
	// |(0 << ADC_SMPR1_SMP3_Pos)	//bit[11-09]: 【101|92.5 ADC clock cycles】 5
	// |(0 << ADC_SMPR1_SMP2_Pos)	//bit[08-06]: 【110|247.5 ADC clock cycles】6
	// |(0 << ADC_SMPR1_SMP1_Pos)	//bit[05-03]: 【111|640.5 ADC clock cycles】7
	// |(0 << ADC_SMPR1_SMP0_Pos)	//bit[02-00]: 
	;
	ADC1->SMPR2 = (ADC1->SMPR2 & 0xf8000000)
	// |(0 << ADC_SMPR2_SMP18_Pos)	//bit[26-24]:  通道x采样时间选择
	// |(0 << ADC_SMPR2_SMP17_Pos)	//bit[23-21]: 【000|2.5 ADC clock cycles】  0
	// |(0 << ADC_SMPR2_SMP16_Pos)	//bit[20-18]: 【001|6.5 ADC clock cycles】  1
	// |(0 << ADC_SMPR2_SMP15_Pos)	//bit[17-15]: 【010|12.5 ADC clock cycles】 2
	// |(0 << ADC_SMPR2_SMP14_Pos)	//bit[14-12]: 【011|24.5 ADC clock cycles】 3
	// |(0 << ADC_SMPR2_SMP13_Pos)	//bit[11-09]: 【100|47.5 ADC clock cycles】 4
	// |(0 << ADC_SMPR2_SMP12_Pos)	//bit[08-06]: 【101|92.5 ADC clock cycles】 5
	// |(0 << ADC_SMPR2_SMP11_Pos)	//bit[05-03]: 【110|247.5 ADC clock cycles】6
	// |(0 << ADC_SMPR2_SMP10_Pos)	//bit[02-00]: 【111|640.5 ADC clock cycles】7
	;

	ADC1->TR1 = (ADC1->TR1 & 0xf0008000)
	// |(0x0000 << ADC_TR1_HT1_Pos)//bit[27-16]: 模拟看门狗1 高阈值(12-bit)
	// |(0 << ADC_TR1_AWDFILT_Pos)	//bit[14-12]: 模拟看门狗滤波参数 连续出现x+1(x!=0)次越限 才被视为有效【0|无滤波】
	// |(0x0000 << ADC_TR1_LT1_Pos)//bit[11-00]: 模拟看门狗1 低阈值(12-bit)
	;
	ADC1->TR2 = (ADC1->TR2 & 0xff00ff00)
	// |(0x0000 << ADC_TR1_HT2_Pos)//bit[23-16]: 模拟看门狗2 高阈值(8-bit)
	// |(0x0000 << ADC_TR1_LT2_Pos)//bit[07-00]: 模拟看门狗2 低阈值(8-bit)
	;
	ADC1->TR3 = (ADC1->TR3 & 0xff00ff00)
	// |(0x0000 << ADC_TR1_HT3_Pos)//bit[23-16]: 模拟看门狗3 高阈值(8-bit)
	// |(0x0000 << ADC_TR1_LT3_Pos)//bit[07-00]: 模拟看门狗3 低阈值(8-bit)
	;


	// ADC1->DR 只读(共32-bit,16-bit有效) ADC规则数据寄存器
	// ADC1->JSQR = (ADC1->JSQR & 0x04104000);
	// ADC1->OFR1//偏移
	// ADC1->JDR1//注入采样 数据
	// ADC1->AWD2CR
	// ADC1->AWD3CR


	// ADC1->CALFACT = (ADC1->CALFACT & 0xff80ff80)
	// |(0 << ADC_CALFACT_CALFACT_D_Pos)//bit[22-16]: 差分校准系数
	// |(0 << ADC_CALFACT_CALFACT_S_Pos)//bit[06-00]: 单端校准系数
	// ;

	// ADC1->GCOMP = (ADC1->GCOMP & 0xffffc000)
	// |0x0000						//bit[13-00]: 增益(14-bit]
	// ;

	// ADC12_COMMON->CSR 只读
	// ADC_CSR_JQOVF_SLV		//bit26: 从 ADC注入溢出
	// ADC_CSR_AWD3_SLV			//bit25: 从 模拟看门狗3
	// ADC_CSR_AWD2_SLV			//bit24: 从 模拟看门狗2 标志位
	// ADC_CSR_AWD1_SLV			//bit23: 从 模拟看门狗1 标志位
	// ADC_CSR_JEOS_SLV			//bit22: 从 注入通道队列转换结束标志(写1清零)
	// ADC_CSR_JEOC_SLV			//bit21: 从 注入通道转换结束标志(读取清零)
	// ADC_CSR_OVR_SLV			//bit20: 从 ADC溢出(数据被覆盖)
	// ADC_CSR_EOS_SLV			//bit19: 从 规则转换队列结束
	// ADC_CSR_EOC_SLV			//bit18: 从 规则转换结束
	// ADC_CSR_EOSMP_SLV		//bit17: 从 采样结束标志
	// ADC_CSR_ADRDY_SLV		//bit16: 从 ADC准备就绪
	// ADC_CSR_JQOVF_MST		//bit10: 主 ADC注入溢出
	// ADC_CSR_AWD3_MST			//bit09: 主 模拟看门狗3
	// ADC_CSR_AWD2_MST			//bit08: 主 模拟看门狗2 标志位
	// ADC_CSR_AWD1_MST			//bit07: 主 模拟看门狗1 标志位
	// ADC_CSR_JEOS_MST			//bit06: 主 注入通道队列转换结束标志(写1清零)
	// ADC_CSR_JEOC_MST			//bit05: 主 注入通道转换结束标志(读取清零)
	// ADC_CSR_OVR_MST			//bit04: 主 ADC溢出(数据被覆盖)
	// ADC_CSR_EOS_MST			//bit03: 主 规则转换队列结束
	// ADC_CSR_EOC_MST			//bit02: 主 规则转换结束
	// ADC_CSR_EOSMP_MST		//bit01: 主 采样结束标志
	// ADC_CSR_ADRDY_MST		//bit00: 主 ADC准备就绪

	ADC12_COMMON->CCR = (ADC12_COMMON->CCR & 0xfe0010e0)
	// |ADC_CCR_VBATSEL			//bit24: VBAT选择【0|VBAT禁止】【1|VBAT使能】
	// |ADC_CCR_VSENSESEL			//bit23: VTS选择【0|VTS温度传感器通道禁止】【1|VTS温度传感器通道使能】
	// |(0 << ADC_CCR_PRESC_Pos)	//bit[22-18]: ADC 预分频 【0|输入ADC时钟不分频】【1|输入ADC时钟2分频】【2~11|4/6/8/10/12/16/32/64/128/256】
	// |(0 << ADC_CCR_CKMODE_Pos)	//bit[17-16]: ADC 时钟模式【0|异步模式adc_ker_ck RCC中选择】【1| adc_hclk/1】【2| adc_hclk/2】【3| adc_hclk/4】
	// |(0 << ADC_CCR_MDMA_Pos)	//bit[15-14]: 双AD模式下的DMA模式【0|禁用DMA】【1|保留】【2|12-bit或者10-bit模式】【3|8-bit或者6-bit模式】
	// |ADC_CCR_DMACFG				//bit13: 双ADC模式下的DMA配置【0|单次模式】【1|循环模式】
	// |(0 << ADC_CCR_DELAY_Pos)	//bit[11-08]: 双交错模式下的两次采样间隔
	// |(0 << ADC_CCR_DUAL_Pos)	//bit[04-00]: 双ADC模式选择【720page】
	;
	// ADC12_COMMON->CDR 只读
	// // ADC_CDR_RDATA_SLV
	// // ADC_CDR_RDATA_MST
  • 9
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值