はじめに
以前の出版物では、
STM32、C ++、およびFreeRTOS。 最初から開発。 パート1私
は湖に向けて出発する方法と、SR7、SR4、SR6の要件がどのようにリリースされたかに焦点を当てました。 プロジェクトの要件を思い出させてください:
SR0:デバイスは、3つのパラメーターを測定する必要があります(3つの変数があります):
マイクロプロセッサー温度 、
VDDA 電圧 、
可変抵抗器による電圧SR1:デバイスは、これらの変数の値を
インジケーターに表示する必要があります。
SR2:
マイクロプロセッサーの温度の単位は摂氏で、その他のパラメーターはボルトです。
SR3:
ボタン1を押すと、
ディスプレイに次の測定変数の画面が
表示されます。
SR4:
ボタン1が押されると、
LED 1は状態を変更する必要があります
SR5:
ボタン2を押すと、イン
ディケーターは変数の表示モードを変数の常時表示から順次に変更する必要があります(1.5秒ごとに画面を変更します)。
SR6:
ボタン2を押すと、
LED 2の状態が変わるはずです。
SR7:
LED 3は1秒ごとに1回点滅します。
開発:ADC
新しいマイクロコントローラーのすべての知恵を理解したと判断したので、3つの値を測定するためにSR0の最も野心的な要件(実際はこれがデバイスの主な機能です)を取ることにしました。
まず、ADCに対処する必要がありました。 特に、マイクロコントローラのドキュメントを読むことなく、特別なツールCrt-CとCtr-Vを装備して、このユニットをオンザフライで使用することに決めたので、LEDとボタン制御アーキテクチャのコピーを描きました。

しかし、一般的に非常に機能しているこの素晴らしい図面を実現し始めた彼は、ドキュメントを読むことに興味を持ち、DMAチャネルを使用してアクティブなオブジェクトなしでそれを行うことができることに気付きました。 もちろん、すべてのマイクロコントローラーにそのようなユニットがあるわけではないという単純な理由で、そのようなアーキテクチャーは既にプロセッサーに依存していますが、マイクロコントローラーの機能を使用して物事を少し簡素化する方法を示すことは興味深いと思います。
そして、このようにそれをやり直しました:

すべてのアーキテクチャの準備ができており、ここで私は凍結しています。 ADCのセットアップはポートよりも少し複雑であることがわかりました。また、可変抵抗を使用して電圧を頑固に測定していません。 Vddaには温度がありますが、変数を使用する方法はありません。 繰り返しますが、同じリソースがADCの構成に役立ち、
STM32Lプロジェクトの作成に
役立ちました
。 ADC-A / Dコンバーターおよび
STM32L。 DMAコントローラー そして、ボードOlimexのドキュメントとともにダウンロードされた可変デモプロジェクトに対処します。 彼は、別のレッグのPortD.Pin1プロセッサを接続するだけでよいことが判明しました。 いつものように、私はすべての鉄の設定を__low_level_init()に投げました
クラス実装ファイル自体:
adc.cpp #include <stm32l1xx.h> // STM2 #include "adc.h" // #include "susuassert.h" //for ASSERT #include "bitutil.h" // SETBIT, CLRBIT #define ADC1_DR_ADDRESS ((tU32)0x40012458) /******************************************************************************* * Function: constructor * Description: DMA RAM, * ******************************************************************************/ cAdc::cAdc(const tU32 memoryBaseAddr, const tU8 measureCount) { ASSERT(measureCount != 0); this->initDma(memoryBaseAddr, measureCount); } /******************************************************************************* * Function: switchOn * Description: ******************************************************************************/ tBoolean cAdc::switchOn(void) { tBoolean result = FALSE; // , 299 CD00240194.pdf SETBIT(ADC1->CR2, ADC_CR2_ADON); result = tBoolean(CHECK_BIT_SET(ADC1->SR, ADC_SR_ADONS)); return result; } /******************************************************************************* * Function: startConversion() * Description: ******************************************************************************/ tBoolean cAdc::startConversion(void) { tBoolean result = FALSE; // , 299 CD00240194.pdf SETBIT(ADC1->CR2, ADC_CR2_SWSTART); result = tBoolean(CHECK_BIT_SET(ADC1->SR, ADC_SR_STRT)); return result; } /******************************************************************************* * Function: getValue() * Description: ******************************************************************************/ tF32 cAdc::getValue(void) const { tF32 result = ADC1->DR; return result; } /******************************************************************************* * Function: isConversionReady() * Description: ? ******************************************************************************/ tBoolean cAdc::isConversionReady(void) { tBoolean result = tBoolean(CHECK_BIT_SET(ADC1->SR, ADC_SR_EOC)); return result; } /******************************************************************************* * Function: initDma() * Description: DMA ******************************************************************************/ void cAdc::initDma(const tU32 memoryBaseAddr, const tU8 measureCount) { // - . DMA1_Channel1->CPAR = ADC1_DR_ADDRESS; // - RAM. DMA1_Channel1->CMAR = memoryBaseAddr; DMA1_Channel1->CNDTR = measureCount; // DMA SETBIT(DMA1_Channel1->CCR, DMA_CCR1_EN); }
インジケーターへの出力がまだないため、デバッガーの下でのみ作業を確認することができました。 ただし、その前に、main()にクラスの新しいインスタンスの作成を追加する必要があります
デバッグ用に開始し、次の図を取得しました。channelValue[]配列の3つの値がすべて変更され、赤で強調表示されていることがわかります。 私は値をチェックしませんでしたが、一目で-ほぼ同様のもの。

いつものように、プロジェクトはここに保存されました:
IAR 6.50のADC、ボタン、LED開発:変数
そして、ADCは機能しているように見え、これらのユニットとゼロの山を人々が理解できるものに変える時が来ましたが、温度と電圧があります:
最初に、すべての変数に対して単一のインターフェースを考えました。 ここでは、仮想メソッドは1つしかありません。独自の計算と、計算された値を取得する1つの方法です。

そして、温度がどのようになるかを描きました。

そしてその後、測定結果を平滑化するフィルターがあればいいと思いました。 また、すべての変数にはフィルターが必要なので、インターフェースの形で作成できます。 その結果、次の概念が作成されました。

温度クラスは、インターフェース計算メソッドを実装します。 しかし、ここでは、マイクロコントローラーに配線された工場係数を使用して温度を計算するために、コメントを作成する必要があります。理論的には、このコードを別のプラットフォームに移植するには、不揮発性パラメーターにアクセスするクラスを作成し、これらの係数を必要とするクラスにこのクラスへのリンクを渡す必要があります、この場合、温度。 しかし、私は本当に3つの要因のために時間を使い果たしたくなかったし、町をやりたくなかったので、時間の不足のためにそのような枠を消し去り、港がここでは動作しないことを心に刻みます(大丈夫:))。 この全体の実装は次のようになります。
変数VddaおよびTrimmer(可変抵抗器)でも同じフォーカスが繰り返されます。 アーキテクチャは、cTemeperatureクラスのアーキテクチャと同じです。
まあ、それがプロジェクトの主な要件であり、計画よりも長くかかったことを認めなければなりません-ほぼ7日間。 しかし、これは可変抵抗器の電圧に関する誤解によるものです。非常に長い間、何も測定されないのは愚かです。 私はOlimexボードの開発者をスパイすることをよく考えました:) 1つの小さなタスクが残っていました-インディケータへの出力。 8年前の最後のプロジェクトは、インジケータードライバーが組み込まれたPIC16のみで、インジケーターは非常にシンプルなので、複雑なものはないと思いました。 そして、それがどのように起こったのか、最後の部分で説明します。