[STM32] オンチップ ADC の予備使用

stm32f103シリーズ準拠
「STM32F103を死角ゼロで遊ぶガイド」準拠

ADC の概要

stm32f103 の ADC

数量:3
精度:12bit(4096)
通道: ADC1 と ADC2 は両方とも 16 チャネル、ADC3 は 8 チャネルあります。
功能変換
  終了時、注入変換終了時、およびアナログ ウォッチドッグ イベントの発生時に割り込みが生成されます。
  単一および連続変換モード
  チャネル 0 からチャネル n までの自動スキャン モード
  自己
  校正 埋め込まれたデータの一貫性によるデータ アラインメント   サンプリング間隔は   チャネル 2 またはそれ以上の ADC デバイスによって   個別に
  プログラム可能)



ここに画像の説明を挿入します

入力電圧範囲

ここに画像の説明を挿入します

入力チャンネル

マニュアルに従って入力チャンネルを選択してください
ここに画像の説明を挿入します

変換順序

ルールの順序

ルール シーケンスは小さいものから大きいものに変換されます。

ここに画像の説明を挿入します
SQR3、SQR2、およびSQR1レジスタを設定します。SQR3のSQ1、SQ2からSQR1のSQ16の順

注入シーケンス

注入シーケンスは、大から小、または小から大のチャネル数に基づいています。

  注入シーケンス レジスタ JSQR は 1 つだけあり、最大 4 チャネルをサポートします。具体的な番号はJSQRのJL[2:0]で決まります。JL の値が 4 未満の場合、変換順序を決定する JSQR と SQR の設定が異なります。最初の変換は JSQR1[4:0] ではなく、JCQRx[4:0]、x = (4-JL) )、SQR のちょうど逆です。JL=00(1変換)の場合、JSQR1[4:0]からではなく、JSQR4[4:0]から変換が開始されますので、プログラミングの際は注意してください。JL が 4 の場合、SQR と同じになります。
ここに画像の説明を挿入します

トリガーソース

1. CR レジスタの CONbit ビットが有効になり、変換が開始されます
2. トリガ スタート:多くの
    内部タイマ トリガと外部 IO トリガ
ソースがあり、特定のトリガ ソースは ADC 制御レジスタによって選択されます 2: ADC_CR2 の EXTSEL[2 :0] および JEXTSEL[2:0] ビットを制御します。EXTSEL[2:0]は通常チャンネルのトリガーソースの選択に使用され、JEXTSEL[2:0]はインジェクションチャンネルのトリガーソースの選択に使用されます。トリガソースを選択した後、トリガソースを活性化するかどうかは、ADC 制御レジスタ 2:ADC_CR2 の 2 ビット EXTTRIG と JEXTTRIG によって活性化されます。ADC3 の通常変換およびインジェクション変換のトリガソースは ADC1/2 とは異なります。

EXTSEL[2:0] および JEXTSEL2:0] 制御ビットを使用すると、アプリケーションは、ルールをトリガーしてグループ サンプリングを挿入できる 8 つの可能なイベントのうち 1 つを選択できます。
ここに画像の説明を挿入します
ここに画像の説明を挿入します

変換時間

ADCクロック

ADC 入力クロック ADC_CLK は、分周後に PCLK2 によって生成されます。最大は 14M です。分周係数は、RCC クロック コンフィギュレーション レジスタ RCC_CFGR のビット 15:14 ADCPRE[1:0] によって設定されます。2/4 で分周できます。 /6/8. 注 ここには 1 による除算はありません。通常、PCLK2=HCLK=72M に設定します。

サンプリング時間

ADC は複数の ADC_CLK サイクルを使用して入力電圧をサンプリングします。サンプリング サイクル数は、ADC サンプリング時間レジスタ ADC_SMPR1 および ADC_SMPR2 の SMP[2:0] ビットで設定できます。ADC_SMPR2 はチャネル 0 ~ 9 を制御し、ADC_SMPR1 はチャネルを制御します10〜17。各チャンネルは異なる時間にサンプリングできます。最小サンプリング周期は 1.5、つまり最速のサンプリングを実現したい場合は、サンプリング周期を 1.5 周期に設定する必要があります (ここで言う周期は 1/ADC_CLK)。

ADC 変換時間は ADC 入力クロックとサンプリング時間に関係し、式は次のようになります: Tconv = サンプリング時間 + 12.5 サイクル。ADCLK = 14MHZ (最高) の場合、サンプリング時間は 1.5 サイクル (最速) に設定され、合計変換時間 (最短) Tconv = 1.5 サイクル + 12.5 サイクル = 14 サイクル = 1us となります。

通常、PCLK2=72M に設定します。ADC プリスケーラで分周できる最大クロックは 12M までです。サンプリング周期は 1.5 サイクルに設定します。最短変換時間は 1.17us と計算され、これが最も一般的に使用されます。 。

データレジスタ ADC→DR

ADC で変換されるデータは変換グループに応じて異なり、ルールグループのデータは ADC_DR レジスタに、インジェクショングループのデータは JDRx に配置されます。

ルールデータレジスタ ADC_DR レジスタ

ADC ルール グループ データ レジスタ ADC_DR は 1 つだけあり、これは 32 ビット レジスタです。下位 16 ビットはシングル ADC で使用されます。上位 16 ビットは、デュアル モードの ADC2 によって変換されたルール データを保存するために ADC1 で使用されます。モードは、ADC1 と ADC2 が同時に使用されることを意味します。

通常チャネルは最大16個ありますが、通常データレジスタは1つしかありません マルチチャネル変換を使用すると、変換されたすべてのデータがDRに密集します 前回の時点で変換されたチャネルデータが変換されますその時点で別のチャネルで変換されたデータは上書きされるため、チャネル変換が完了したらデータを取り出すか、DMA モードを ON にしてメモリにデータを転送する必要があります。データは上書きされます。最も一般的な方法は、DMA 転送を有効にすることです。

インジェクトデータレジスタ JDRxレジスタ

ADC インジェクション グループには最大 4 チャネルがあり、インジェクション データ レジスタも 4 つあり、各チャネルは独自のレジスタに対応しているため、通常のレジスタのようなデータ カバレッジの問題は発生しません。ADC_JDRx は 32 ビットで、下位 16 ビットが有効、上位 16 ビットが予約であり、データも左詰めと右詰めに分かれており、具体的な格納方法は ADC_CR2 の 11 ビット ALIGN で設定されます。

割り込み

変換終了割り込み

データ変換完了後に割り込みを発生させることができ、割り込みには通常チャネル変換終了割り込み、インジェクション変換チャネル変換終了割り込み、アナログウォッチドッグ割り込みの3種類があります。

ウォッチドッグ割り込みをシミュレートする

ADC によって変換されたアナログ電圧が下限しきい値より低いか、上限しきい値より高い場合、アナログ ウォッチドッグ割り込みを有効にすると、割り込みが生成されます。下限しきい値と上限しきい値は ADC_LTR および ADC_HTR によって設定されます。たとえば、高しきい値を 2.5V に設定すると、アナログ電圧が 2.5V を超えるとアナログ ウォッチドッグ割り込みが発生し、低しきい値の場合はその逆になります。

DMA リクエスト

ルールと注入チャネルの変換が完了した後、割り込みを生成するだけでなく、変換されたデータをメモリに直接保存するための DMA リクエストも生成できます。DMA リクエストを生成できるのは ADC1 と ADC3 だけであることに注意してください。

プログラミングの必需品

独立したシングルチャンネル

ADC GPIO の初期化

 static void ADCx_GPIO_Config(void)
 {
    
    
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2,ENABLE)
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;//模拟输入
	GPIO_Init(GPIOC, &GPIO_InitStructure);
 }

ADC動作モード構成

// ADC 编号选择
// 可以是 ADC1/2,如果使用 ADC3,中断相关的要改成 ADC3 的
#define ADC_APBxClock_FUN RCC_APB2PeriphClockCmd
#define ADCx ADC2
#define ADC_CLK RCC_APB2Periph_ADC2

// ADC GPIO 宏定义
// 注意:用作 ADC 采集的 IO 必须没有复用,否则采集电压会有影响
#define ADC_GPIO_APBxClock_FUN RCC_APB2PeriphClockCmd
#define ADC_GPIO_CLK RCC_APB2Periph_GPIOC
#define ADC_PORT GPIOC
#define ADC_PIN GPIO_Pin_1
// ADC 通道宏定义
#define ADC_CHANNEL ADC_Channel_11
 
// ADC 中断相关宏定义
#define ADC_IRQ ADC1_2_IRQn
#define ADC_IRQHandler ADC1_2_IRQHandler


static void ADCx_Mode_Config(void)
{
    
    
	ADC_InitTypeDef ADC_InitStructure;

	// 打开 ADC 时钟
	ADC_APBxClock_FUN ( ADC_CLK, ENABLE );

	// ADC 模式配置
	// 只使用一个 ADC,属于独立模式
	 ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
 
	 // 禁止扫描模式,多通道才要,单通道不需要
	 ADC_InitStructure.ADC_ScanConvMode = DISABLE ;
 
	 // 连续转换模式
	 ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
 
	 // 不用外部触发转换,软件开启即可
	 ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
 
	 // 转换结果右对齐
	 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
 
	 // 转换通道 1 个
	 ADC_InitStructure.ADC_NbrOfChannel = 1;
 
	 // 初始化 ADC
	 ADC_Init(ADCx, &ADC_InitStructure);
 
	 // 配置 ADC 时钟N狿 CLK2 的 8 分频,即 9MHz
	 RCC_ADCCLKConfig(RCC_PCLK2_Div8);
 
	 // 配置 ADC 通道转换顺序为 1,第一个转换,采样时间为 55.5 个时钟周期
	 ADC_RegularChannelConfig(ADCx, ADC_CHANNEL, 1,
	 ADC_SampleTime_55Cycles5);
 
	 // ADC 转换结束产生中断,在中断服务程序中读取转换值
	 ADC_ITConfig(ADCx, ADC_IT_EOC, ENABLE);
 
	 // 开启 ADC ,并开始转换
	 ADC_Cmd(ADCx, ENABLE);
 
	 // 初始化 ADC 校准寄存器
	 ADC_ResetCalibration(ADCx);
	 // 等待校准寄存器初始化完成
	 while (ADC_GetResetCalibrationStatus(ADCx));

	 // ADC 开始校准
	 ADC_StartCalibration(ADCx);
	 // 等待校准完成
	 while (ADC_GetCalibrationStatus(ADCx));

	 // 由于没有采用外部触发,所以使用软件触发 ADC 转换
	 ADC_SoftwareStartConvCmd(ADCx, ENABLE);
 }

ADC割り込み構成

NVIC構成
static void ADC_NVIC_Config(void)
{
    
    
	NVIC_InitTypeDef NVIC_InitStructure;

	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

	NVIC_InitStructure.NVIC_IRQChannel = ADC_IRQ;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
 
	NVIC_Init(&NVIC_InitStructure);
}
ADC割り込みを有効にする
// ADC 转换结束产生中断,在中断服务程序中读取转换值
 ADC_ITConfig(ADCx, ADC_IT_EOC, ENABLE);
ADC割り込みサービス機能

ここに画像の説明を挿入します
ここに画像の説明を挿入します

1. ADC1 と ADC2 は割り込みサービス関数を共有します。
2. 割り込みサービス関数内の ADC ステータス レジスタ SR の対応する位置を読み取ります。

void ADC_IRQHandler(void)
{
    
    
	if (ADC_GetITStatus(ADCx,ADC_IT_EOC)==SET) {
    
    
	// 读取 ADC 的转换值
	ADC_ConvertedValue = ADC_GetConversionValue(ADCx);

	}
	ADC_ClearITPendingBit(ADCx,ADC_IT_EOC);
}

独立モードのマルチチャンネル収集

  1. ADC GPIO を初期化します。
  2. ADC 動作パラメータを初期化します。
  3. DMA 動作パラメータを構成します。
  4. ADC によって収集されたデータを読み取ります。

GPIO 構成

static void ADCx_GPIO_Config(void)
{
    
    
	GPIO_InitTypeDef GPIO_InitStructure;

	// 打开 ADC IO 端口时钟
	ADC_GPIO_APBxClock_FUN ( ADC_GPIO_CLK, ENABLE );

	// 配置 ADC IO 引脚模式
	GPIO_InitStructure.GPIO_Pin = ADC_PIN1
	 |ADC_PIN2
	 |ADC_PIN3
	 |ADC_PIN4
	 |ADC_PIN5;
	 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
	 // 初始化 ADC IO
	 GPIO_Init(ADC_PORT, &GPIO_InitStructure);
 }

ADC および DMA モードの構成

static void ADCx_Mode_Config(void)
{
    
    
	DMA_InitTypeDef DMA_InitStructure;
	ADC_InitTypeDef ADC_InitStructure;

	// 打开 DMA 时钟
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
	// 打开 ADC 时钟
	ADC_APBxClock_FUN ( ADC_CLK, ENABLE );
 
	 /* ------------------DMA 模式配置---------------- */
	 // 复位 DMA 控制器
	 DMA_DeInit(ADC_DMA_CHANNEL);
	 // 配置 DMA 初始化结构体
	 // 外设基址为:ADC 数据寄存器地址
	 DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&( ADCx->DR ));
	 // 存储器地址
	 DMA_InitStructure.DMA_MemoryBaseAddr = (u32)ADC_ConvertedValue;
	 // 数据源来自外设
	 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
	 // 缓冲区大小,应该等于数据目的地的大小
	 DMA_InitStructure.DMA_BufferSize = NOFCHANEL;
	 // 外设寄存器只有一个,地址不用递增
	 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
	 // 存储器地址递增
	 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
	 // 外设数据大小为半字,即两个字节
	 DMA_InitStructure.DMA_PeripheralDataSize =
	 DMA_PeripheralDataSize_HalfWord;
	 // 内存数据大小也为半字,跟外设数据大小相同
	 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
	 // 循环传输模式
	 DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
	 // DMA 传输通道优先级为高,当使用一个 DMA 通道时,优先级设置不影响
	 DMA_InitStructure.DMA_Priority = DMA_Priority_High;
	 // 禁止存储器到存储器模式,因为是从外设到存储器
	 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
	 // 初始化 DMA
	 DMA_Init(ADC_DMA_CHANNEL, &DMA_InitStructure);
	 // 使能 DMA 通道
	 DMA_Cmd(ADC_DMA_CHANNEL , ENABLE);
 
	 /* ----------------ADC 模式配置--------------------- */
	 // 只使用一个 ADC,属于单模式
	 ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
	 // 扫描模式
	 ADC_InitStructure.ADC_ScanConvMode = ENABLE ;
	 // 连续转换模式
	 ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
	 // 不用外部触发转换,软件开启即可
	 ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
	 // 转换结果右对齐
	 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
	 // 转换通道个数
	 ADC_InitStructure.ADC_NbrOfChannel = NOFCHANEL;
	 // 初始化 ADC
	 ADC_Init(ADCx, &ADC_InitStructure);
	 // 配置 ADC 时钟N狿 CLK2 的 8 分频,即 9MHz
	 RCC_ADCCLKConfig(RCC_PCLK2_Div8);
	 // 配置 ADC 通道的转换顺序和采样时间
	 ADC_RegularChannelConfig(ADCx, ADC_CHANNEL1, 1,
	 ADC_SampleTime_55Cycles5);
	 ADC_RegularChannelConfig(ADCx, ADC_CHANNEL2, 2,
	 ADC_SampleTime_55Cycles5);
	 ADC_RegularChannelConfig(ADCx, ADC_CHANNEL3, 3,
	 ADC_SampleTime_55Cycles5);
	 ADC_RegularChannelConfig(ADCx, ADC_CHANNEL4, 4,
	 ADC_SampleTime_55Cycles5);
	 ADC_RegularChannelConfig(ADCx, ADC_CHANNEL5, 5,
	 ADC_SampleTime_55Cycles5);
	 // 使能 ADC DMA 请求
	 ADC_DMACmd(ADCx, ENABLE);
	 // 开启 ADC ,并开始转换
	 ADC_Cmd(ADCx, ENABLE);
	 // 初始化 ADC 校准寄存器
	 ADC_ResetCalibration(ADCx);
	 // 等待校准寄存器初始化完成
	 while (ADC_GetResetCalibrationStatus(ADCx));
	 // ADC 开始校准
	 ADC_StartCalibration(ADCx);
	 // 等待校准完成
	 while (ADC_GetCalibrationStatus(ADCx));
	 // 由于没有采用外部触发,所以使用软件触发 ADC 转换
	 ADC_SoftwareStartConvCmd(ADCx, ENABLE);
 }

デュアルADC同期ルールモード取得

「死角ゼロでの STM32 の再生—F103 ガイド」を参照してください。

おすすめ

転載: blog.csdn.net/apythonlearner/article/details/132799538