デヌタシヌト 2 を読む: STM32 の SPI。 STM8 の PWM、タむマヌ、割り蟌み

デヌタシヌト 2 を読む: STM32 の SPI。 STM8 の PWM、タむマヌ、割り蟌み

В 最初の郚分 私は、Arduino パンツから育った趣味の゚レクトロニクス ゚ンゞニアに、マむクロコントロヌラヌのデヌタシヌトやその他のドキュメントを読むべき方法ずその理由を䌝えようずしたした。 文章が倧きくなったので、別の蚘事で実践䟋を玹介するこずを玄束したした。 たあ、圌は自分自身をミルクキノコず呌んでいたした...

今日は、デヌタシヌトを䜿甚しお、STM32 (Blue Pill) および STM8 コントロヌラヌ䞊のタスク、非垞に単玔ですが倚くのプロゞェクトに必芁なタスクを解決する方法を説明したす。 すべおのデモ プロゞェクトは私のお気に入りの LED 専甚であり、LED を倧量に点灯させるため、あらゆる皮類の興味深い呚蟺機噚を䜿甚する必芁がありたす。

たたしおもテキストが膚倧になっおしたったので、䟿宜䞊、コンテンツを次のように䜜成したした。

STM32 Blue Pill: DM16 ドラむバヌを備えた 634 個の LED
STM8: XNUMX ぀の PWM ピンのセットアップ
STM8: 8 ぀のピンに XNUMX ぀の RGB LED、割り蟌み

免責事項: 私ぱンゞニアではなく、゚レクトロニクスに関する深い知識があるふりをする぀もりもありたせん。この蚘事は私のようなアマチュアを察象ずしおいたす。 実際、私は XNUMX 幎前、自分自身を察象者だず考えおいたした。 もしその時、誰かが「芋慣れないチップのデヌタシヌトを読むのは怖くない」ず蚀っおくれおいたら、私はむンタヌネットでコヌドを探したり、ハサミず粘着テヌプを䜿っお束葉杖を発明したりするのに倚くの時間を費やすこずはなかったでしょう。

この蚘事はプロゞェクトではなくデヌタシヌトに焊点を圓おおいるため、コヌドはあたり敎っおいなく、しばしば窮屈になる可胜性がありたす。 プロゞェクト自䜓は非垞にシンプルですが、新しいチップを初めお知るのには適しおいたす。

私の蚘事が、同じように趣味に没頭する段階にある誰かの助けになれば幞いです。

STM32

DM16 および SPI を備えた 634 個の LED

Blue Pill (STM32F103C8T6) ず DM634 LED ドラむバヌを䜿甚した小芏暡プロゞェクト。 デヌタシヌトを䜿甚しお、ドラむバヌ、STM IO ポヌトを特定し、SPI を構成したす。

DM634

16 個の 16 ビット PWM 出力を備えた台湟補チップで、チェヌン接続できたす。 ロヌ゚ンドの12ビットモデルは囜内プロゞェクトで知られおいたす ラむトパック。 か぀お、DM63x ず有名な TLC5940 のどちらかを遞択する際、いく぀かの理由から DM を遞択したした。1) Aliexpress の TLC は間違いなく停物ですが、これは停物ではありたせん。 2) DM には、独自の呚波数発生噚を備えた自埋 PWM がありたす。 3) アリからの小包を埅぀よりも、モスクワで安く買える可胜性がある。 そしおもちろん、既成のラむブラリを䜿甚するのではなく、自分でチップを制埡する方法を孊ぶのは興味深いこずでした。 珟圚、チップは䞻に SSOP24 パッケヌゞで提䟛されおおり、アダプタにはんだ付けが簡単です。

台湟のメヌカヌなので、 デヌタシヌト チップは䞭囜語英語で曞かれおいるので、楜しいでしょう。 たずピン配列を芋おみたしょう(ピン接続) どの脚を䜕に接続するかを理解するため、およびピンの説明 (ピンの説明。 16ピン:

デヌタシヌト 2 を読む: STM32 の SPI。 STM8 の PWM、タむマヌ、割り蟌み
DCシンク゜ヌス(オヌプンドレむン)

シンク / オヌプンドレむン出力 – 排氎; 流入電流源。 アクティブ状態では出力はグランドに接続されたす。LED はカ゜ヌドによっおドラむバヌに接続されたす。 もちろん、電気的には、これは「オヌプンドレむン」ではありたせん(オヌプンドレむン) ですが、デヌタシヌトではドレむン モヌドのピンに察するこの指定がよく芋られたす。

デヌタシヌト 2 を読む: STM32 の SPI。 STM8 の PWM、タむマヌ、割り蟌み
出力電流倀を蚭定するための REXT ず GND 間の倖付け抵抗

REXT ピンずグランドの間に基準抵抗が蚭眮され、出力の内郚抵抗を制埡したす。デヌタシヌトの 9 ペヌゞのグラフを参照しおください。 DM634 では、この抵抗を゜フトりェアで制埡するこずもでき、党䜓の明るさを蚭定したす (グロヌバルな明るさ); この蚘事では詳现には觊れたせんが、ここには 2.2  3 kOhm の抵抗を眮くだけです。

チップの制埡方法を理解するために、デバむス むンタヌフェむスの説明を芋おみたしょう。

デヌタシヌト 2 を読む: STM32 の SPI。 STM8 の PWM、タむマヌ、割り蟌み

はい、これが、栄光の䞭囜語英語です。 これを翻蚳するのは問題がありたす。その気になれば理解できたすが、別の方法もありたす。機胜的に類䌌した TLC5940 ぞの接続がデヌタシヌトでどのように説明されおいるかを芋おください。

デヌタシヌト 2 を読む: STM32 の SPI。 STM8 の PWM、タむマヌ、割り蟌み
... デバむスにデヌタを入力するために必芁なピンは XNUMX ぀だけです。 SCLK 信号の立ち䞊がり゚ッゞにより、デヌタが SIN ピンから内郚レゞスタにシフトされたす。 すべおのデヌタがロヌドされた埌、短い High XLAT 信号が、順次転送されたデヌタを内郚レゞスタにラッチしたす。 内郚レゞスタは、XLAT 信号レベルによっおトリガヌされるゲヌトです。 すべおのデヌタは最䞊䜍ビットから最初に送信されたす。

ラッチ – ラッチ/ラッチ/ロック。
立ち䞊がり゚ッゞ – パルスの立ち䞊がり゚ッゞ
MSBファヌスト – 最䞊䜍 (巊端) ビットの前方。
デヌタをクロックする – デヌタを順番に (ビットごずに) 送信したす。

単語 はチップのドキュメントによく蚘茉されおおり、さたざたな方法で翻蚳されおいるため、理解のために蚱可したす。

小芏暡な教育プログラムLED ドラむバヌは本質的にはシフト レゞスタヌです。 "シフト" シフト) 名前に含たれる - デバむス内のデヌタのビットごずの移動: 内郚に抌し蟌たれる新しいビットごずに、その前にあるチェヌン党䜓が前方に抌し出されたす。 シフト䞭に LED が無秩序に点滅するのを誰も芳察したくないため、プロセスはダンパヌによっお䜜業レゞスタヌから分離されたバッファヌ レゞスタヌで行われたす ( ) は、ビットが目的の順序で配眮される䞀皮の埅合宀です。 すべおの準備が完了するず、シャッタヌが開き、ビットが動䜜し、前のバッチず眮き換えられたす。 蚀葉 マむクロ回路のドキュメントでは、どのような組み合わせで䜿甚されるかに関係なく、ほずんどの堎合、そのようなダンパヌを意味したす。

したがっお、DM634 ぞのデヌタ転送は次のように実行されたす。DAI 入力を遠方の LED の最䞊䜍ビットの倀に蚭定し、DCK をプルアップおよびプルダりンしたす。 DAI 入力を次のビットの倀に蚭定し、DCK をプルしたす。 すべおのビットが送信されるたで続きたす (出勀)、その埌、LAT をプルしたす。 これは手動で行うこずができたす (ビットバン) ですが、STM32 では XNUMX ぀のコピヌで提䟛されるため、このために特別に調敎された SPI むンタヌフェむスを䜿甚するこずをお勧めしたす。

ブルヌピル STM32F103

はじめに: STM32 コントロヌラヌは、芋た目よりも Atmega328 よりもはるかに耇雑です。 たた、省゚ネルギヌのため、起動時にはほがすべおのペリフェラルの電源がオフになっおおり、クロック呚波数は内郚゜ヌスからの 8 MHz です。 幞いなこずに、STM プログラマはチップを「蚈算䞊の」72 MHz たで匕き䞊げるコヌドを䜜成しおおり、私が知っおいるすべおの IDE の䜜成者はそれを初期化手順に組み蟌んでいたので、クロックする必芁はありたせん (ただし、 本圓に望むならできたす。 ただし、呚蟺機噚の電源をオンにする必芁がありたす。

ドキュメント: Blue Pill には人気の STM32F103C8T6 チップが搭茉されおおり、それに関する圹立぀ドキュメントが XNUMX ぀ありたす。

デヌタシヌトでは次のこずに興味があるかもしれたせん。

  • ピン配眮 – チップのピン配眮 – ボヌドを自分たちで䜜るこずにした堎合。
  • メモリ マップ – 特定のチップのメモリ マップ。 リファレンスマニュアルにはラむン党䜓のマップがあり、私たちのものにないレゞスタに぀いおも蚀及されおいたす。
  • ピン定矩テヌブル - ピンの䞻な機胜ず代替機胜をリストしたす。 「青い錠剀」に぀いおは、ピンずその機胜のリストを含む、より䟿利な画像をむンタヌネット䞊で芋぀けるこずができたす。 したがっお、すぐに Google で Blue Pill のピン配列を怜玢し、この写真を手元に眮いおおきたす。

デヌタシヌト 2 を読む: STM32 の SPI。 STM8 の PWM、タむマヌ、割り蟌み
泚意: むンタヌネットからの画像に誀りがあり、コメントで指摘されたした。ありがずうございたす。 写真は差し替えられおいたすが、これは教蚓です。情報はデヌタシヌトからではなく確認する方が良いです。

デヌタシヌトを削陀し、リファレンス マニュアルを開き、今埌はそれのみを䜿甚したす。
手順: 暙準入出力を凊理し、SPI を構成し、必芁な呚蟺機噚をオンにしたす。

入出力

Atmega328 では、I/O は非垞に単玔に実装されおいるため、STM32 オプションが豊富にあるため混乱する可胜性がありたす。 ここで必芁なのは結論だけですが、これらにも XNUMX ぀の遞択肢がありたす。

デヌタシヌト 2 を読む: STM32 の SPI。 STM8 の PWM、タむマヌ、割り蟌み
オヌプンドレン、プッシュプル、オルタナティブプッシュプル、オルタナティブオヌプンドレン

「プルプッシュ」抌し匕き) は Arduino からの通垞の出力であり、ピンは HIGH たたは LOW の倀を取るこずができたす。 しかし、「オヌプンドレむン」では、 耇雑さただし、実際にはここではすべおが単玔です。

デヌタシヌト 2 を読む: STM32 の SPI。 STM8 の PWM、タむマヌ、割り蟌み
デヌタシヌト 2 を読む: STM32 の SPI。 STM8 の PWM、タむマヌ、割り蟌み
出力蚭定 / ポヌトが出力に割り圓おられおいる堎合: / 出力バッファが有効: / – オヌプン ドレむン モヌド: 出力レゞスタの「0」は N-MOS を有効にし、出力レゞスタの「1」はポヌトを Hi-Z モヌドのたたにしたす ( P-MOS はアクティブになりたせん) / – プッシュプル モヌド: 出力レゞスタの「0」は N-MOS をアクティブにし、出力レゞスタの「1」は P-MOS をアクティブにしたす。

オヌプンドレむンずのすべおの違い (オヌプンドレむン) 「プッシュプル」から (抌し匕き) は、最初のピンでは HIGH 状態を受け入れるこずができないずいうこずです。出力レゞスタに XNUMX を曞き蟌むず、高抵抗モヌドになりたす (高むンピヌダンス, ハむれット。 れロを曞き蟌むず、ピンは䞡方のモヌドで論理的にも電気的にも同じように動䜜したす。

通垞の出力モヌドでは、ピンは出力レゞスタの内容をブロヌドキャストするだけです。 「代替」では、察応するペリフェラルによっお制埡されたす (9.1.4 を参照)。

デヌタシヌト 2 を読む: STM32 の SPI。 STM8 の PWM、タむマヌ、割り蟌み
ポヌト ビットが代替機胜ピンずしお蚭定されおいる堎合、ピン レゞスタは無効になり、ピンはペリフェラル ピンに接続されたす。

各ピンの代替機胜に぀いおは、「 ピンの定矩 デヌタシヌトはダりンロヌドしたむメヌゞにありたす。 ピンに耇数の代替機胜がある堎合はどうすればよいかずいう質問に察する答えは、デヌタシヌトの脚泚にありたす。

デヌタシヌト 2 を読む: STM32 の SPI。 STM8 の PWM、タむマヌ、割り蟌み
耇数のペリフェラルが同じピンを䜿甚する堎合、代替機胜間の競合を避けるために、(適切な RCC レゞスタ内の) ペリフェラル クロック むネヌブル ビットを䜿甚しお切り替えるペリフェラルを䞀床に XNUMX ぀だけ䜿甚する必芁がありたす。

最埌に、出力モヌドのピンにもクロック速床がありたす。 これも゚ネルギヌ節玄機胜の XNUMX ぀であり、私たちの堎合は最倧倀に蚭定するだけで、忘れおしたいたす。

぀たり、SPI を䜿甚しおいたす。これは、XNUMX ぀のピン (デヌタずクロック信号) が「代替プッシュプル機胜」である必芁があり、もう XNUMX ぀のピン (LAT) が「通垞のプッシュプル」である必芁があるこずを意味したす。 ただし、それらを割り圓おる前に、SPI に぀いお考えおみたしょう。

SPI

もう䞀぀の小さな教育プログラム

SPI たたは Serial Peripheral Interface (シリアル ペリフェラル むンタヌフェむス) は、MK を他の MK や倖郚の䞖界ず接続するためのシンプルで非垞に効果的なむンタヌフェむスです。 その動䜜原理は、䞭囜補 LED ドラむバヌに぀いおはすでに説明したした (リファレンス マニュアルのセクション 25 を参照)。 SPI はマスタヌ (「マスタヌ」) モヌドずスレヌブ (「スレヌブ」) モヌドで動䜜できたす。 SPI には XNUMX ぀の基本チャネルがありたすが、そのすべおが䜿甚できるわけではありたせん。

  • MOSI、マスタヌ出力/スレヌブ入力: このピンはマスタヌ モヌドでデヌタを送信し、スレヌブ モヌドでデヌタを受信したす。
  • MISO、マスタヌ入力/スレヌブ出力: 逆に、マスタヌで受信し、スレヌブで送信したす。
  • SCK、シリアル クロック: マスタヌでデヌタ送信の呚波数を蚭定するか、スレヌブでクロック信号を受信したす。 基本的にビヌトを打぀こず。
  • SS、奎隷遞択: このチャネルの助けを借りお、奎隷は自分に䜕かが求められおいるこずを知りたす。 STM32 では、これは NSS ず呌ばれたす。ここで、N = 負、぀たりこのチャンネルにアヌスがある堎合、コントロヌラヌはスレヌブになりたす。 オヌプンドレむン出力モヌドずうたく組み合わせるこずができたすが、それはたた別の話です。

他のものず同様、STM32 の SPI は機胜が豊富であるため、理解するのがやや難しくなりたす。 たずえば、SPI だけでなく I2S むンタヌフェむスでも動䜜する可胜性があり、ドキュメントではそれらの蚘述が混圚しおいるため、適時に䜙分な郚分を削陀する必芁がありたす。 私たちのタスクは非垞に単玔です。MOSI ず SCK のみを䜿甚しおデヌタを送信するだけです。 セクション 25.3.4 (半二重通信、半二重通信) に進みたす。 1 ぀のクロックず 1 ぀の単方向デヌタ ワむダ (1 ぀のクロック信号ず 1 ぀の単方向デヌタ ストリヌム):

デヌタシヌト 2 を読む: STM32 の SPI。 STM8 の PWM、タむマヌ、割り蟌み
このモヌドでは、アプリケヌションは送信専甚モヌドたたは受信専甚モヌドで SPI を䜿甚したす。 / 送信専甚モヌドはデュプレックス モヌドず䌌おいたす。デヌタは送信ピン (マスタヌ モヌドの MOSI たたはスレヌブ モヌドの MISO) で送信され、受信ピン (それぞれ MISO たたは MOSI) は通垞の I/O ピンずしお䜿甚できたす。 。 この堎合、アプリケヌションは Rx バッファを無芖するだけで枈みたす (読み取られた堎合、そこにデヌタは転送されたせん)。

わかりたした。MISO ピンは空いおいたす。LAT 信号をそれに接続したしょう。 STM32 ではプログラムで制埡できる、非垞に䟿利なスレヌブ遞択を芋おみたしょう。 セクション 25.3.1 SPI の抂芁の同じ名前の段萜を読みたす。

デヌタシヌト 2 を読む: STM32 の SPI。 STM8 の PWM、タむマヌ、割り蟌み
゜フトりェア制埡 NSS (SSM = 1) / スレヌブ遞択情報は、SPI_CR1 レゞスタの SSI ビットに含たれたす。 倖郚 NSS ピンは、他のアプリケヌションのニヌズのために空き状態のたたになりたす。

レゞスタに曞き蟌む時が来たした。 SPI2 を䜿甚するこずにし、デヌタシヌトのセクション 3.3 メモリ マップでそのベヌス アドレスを探したす。

デヌタシヌト 2 を読む: STM32 の SPI。 STM8 の PWM、タむマヌ、割り蟌み

さお、始めたしょう:

#define _SPI2_(mem_offset) (*(volatile uint32_t *)(0x40003800 + (mem_offset)))

「マスタヌ モヌドでの SPI の蚭定」ずいうわかりやすいタむトルのセクション 25.3.3 を開きたす。

デヌタシヌト 2 を読む: STM32 の SPI。 STM8 の PWM、タむマヌ、割り蟌み

1. SPI_CR2 レゞスタのビット BR[0:1] でシリアル クロック呚波数を蚭定したす。

レゞスタは、同じ名前のリファレンス マニュアルのセクションにたずめられおいたす。 アドレスシフト(アドレスオフセット) CR1 – 0x00 の堎合、デフォルトではすべおのビットがクリアされたす (リセット倀 0x0000):

デヌタシヌト 2 を読む: STM32 の SPI。 STM8 の PWM、タむマヌ、割り蟌み

BR ビットはコントロヌラのクロック分呚噚を蚭定し、SPI が動䜜する呚波数を決定したす。 STM32 の呚波数は 72 MHz になりたす。デヌタシヌトによるず、LED ドラむバヌは最倧 25 MHz の呚波数で動䜜するため、2 で割る必芁がありたす (BR[0:001] = XNUMX)。

#define _SPI_CR1 0x00

#define BR_0        0x0008
#define BR_1        0x0010
#define BR_2        0x0020

_SPI2_ (_SPI_CR1) |= BR_0;// pclk/4

2. CPOL ビットず CPHA ビットを蚭定しお、デヌタ転送ずシリアル クロック タむミングの関係を定矩したす (240 ペヌゞの図を参照)。

ここでは回路図ではなくデヌタシヌトを読んでいるので、704 ペヌゞ (SPI の䞀般的な説明) にある CPOL および CPHA ビットのテキスト説明を詳しく芋おみたしょう。

デヌタシヌト 2 を読む: STM32 の SPI。 STM8 の PWM、タむマヌ、割り蟌み
クロックの䜍盞ず極性
SPI_CR1 レゞスタの CPOL ビットず CPHA ビットを䜿甚するず、XNUMX ぀のタむミング関係をプログラムで遞択できたす。 CPOL (クロック極性) ビットは、デヌタが送信されおいないずきのクロック信号の状態を制埡したす。 このビットはマスタヌ モヌドずスレヌブ モヌドを制埡したす。 CPOL がリセットされるず、SCK ピンは䌑止モヌドで Low になりたす。 CPOL ビットがセットされおいる堎合、SCK ピンは䌑止モヌド䞭に High になりたす。
CPHA (クロック䜍盞) ビットがセットされおいる堎合、䞊䜍ビット トラップ ストロヌブは SCK 信号の XNUMX 番目の゚ッゞです (CPOL がクリアの堎合は立ち䞋がり、CPOL がセットされおいる堎合は立ち䞊がり)。 デヌタはクロック信号の XNUMX 番目の倉化によっおキャプチャされたす。 CPHA ビットがクリアされおいる堎合、䞊䜍ビット トラップ ストロヌブは SCK 信号の立ち䞊がり゚ッゞです (CPOL がセットされおいる堎合は立ち䞋がり゚ッゞ、CPOL がクリアされおいる堎合は立ち䞊がり゚ッゞ)。 デヌタはクロック信号の最初の倉化時にキャプチャされたす。

この知識を吞収するず、䞡方のビットがれロのたたでなければならないずいう結論に達したす。 䜿甚されおいないずきは SCK 信号を Low のたたにしお、デヌタをパルスの立ち䞊がり゚ッゞで送信するようにしたす (図を参照)。 ラむゞング゚ッゞ DM634 デヌタシヌトに蚘茉されおいたす)。

ずころで、ここで私たちは ST デヌタシヌトの語圙の特城に初めお遭遇したした。そこには「ビットをれロにリセットする」ずいうフレヌズが曞かれおいたす。 少しリセットするためにずしない 少しクリアするために、䟋えばアトメガのような。

3. DFF ビットを蚭定しお、デヌタ ブロックが 8 ビット圢匏であるか 16 ビット圢匏であるかを決定したす。

DM16 のように 634 ビット PWM デヌタの送信に煩わされないように、特に 12 ビット DM633 を䜿甚したした。 DFF を XNUMX に蚭定するのは理にかなっおいたす。

#define DFF         0x0800

_SPI2_ (_SPI_CR1) |= DFF; // 16-bit mode

4. SPI_CR1 レゞスタの LSBFIRST ビットを蚭定しおブロック フォヌマットを決定したす

LSBFIRST は、その名前が瀺すように、最䞋䜍ビットを最初に送信を構成したす。 しかし、DM634 は最䞊䜍ビットから始たるデヌタを受信したいず考えおいたす。 したがっお、リセットしたたたにしたす。

5. ハヌドりェア モヌドで、NSS ピンからの入力が必芁な堎合は、バむト転送シヌケンス党䜓で NSS ピンに High 信号を印加したす。 NSS ゜フトりェア モヌドでは、SPI_CR1 レゞスタの SSM ビットず SSI ビットを蚭定したす。 NSS ピンを出力ずしお䜿甚する堎合は、SSOE ビットのみを蚭定する必芁がありたす。

SSM ず SSI をむンストヌルしお、NSS ハヌドりェア モヌドを忘れたす。

#define SSI         0x0100
#define SSM         0x0200

_SPI2_ (_SPI_CR1) |= SSM | SSI; //enable software control of SS, SS high

6. MSTR ビットず SPE ビットをセットする必芁がありたす (NSS 信号が High の堎合にのみセットされたたたになりたす)。

実際には、これらのビットを䜿甚しお SPI をマスタヌずしお指定し、オンにしたす。

#define MSTR        0x0004
#define SPE         0x0040

_SPI2_ (_SPI_CR1) |= MSTR; //SPI master
//кПгЎа все гПтПвП, включаеЌ SPI
_SPI2_ (_SPI_CR1) |= SPE;

SPI が構成されたので、ドラむバヌにバむトを送信する関数をすぐに䜜成したしょう。 25.3.3「マスタヌモヌドでの SPI の蚭定」の続きを読む:

デヌタシヌト 2 を読む: STM32 の SPI。 STM8 の PWM、タむマヌ、割り蟌み
デヌタ転送順序
バむトが Tx バッファに曞き蟌たれるず、送信が開始されたす。
デヌタバむトは次の䜍眮でシフトレゞスタにロヌドされたす。 平行 最初のビットの送信䞭に (内郚バスから) モヌドに移行し、その埌、ビットが送信されたす。 䞀連 MOSI ピン モヌド。CPI_CR1 レゞスタの LSBFIRST ビットの蚭定に応じお、最初たたは最埌のビットが転送されたす。 TXEフラグはデヌタ送信埌にセットされたす。 Txバッファからシフトレゞスタたでたた、CPI_CR1 レゞスタの TXEIE ビットがセットされおいる堎合は割り蟌みも生成したす。

STM コントロヌラの SPI 実装の XNUMX ぀の機胜に泚目しおいただくために、翻蚳の䞭でいく぀かの単語を匷調したした。 Atmega では TXE フラグ (送信が空です、Tx は空であり、デヌタを受信する準備ができおいたす) は、バむト党䜓が送信された埌にのみ蚭定されたす。 アりト。 ここで、このフラグはバむトが内郚シフト レゞスタに挿入された埌に蚭定されたす。 すべおのビットを同時に (䞊列に) プッシュしおデヌタを順次送信するため、バむトが完党に送信される前に TXE がセットされたす。 これは重芁な理由です。 LED ドラむバヌの堎合、送信埌に LAT ピンをプルする必芁がありたす。 すべお デヌタ、぀たりTXE フラグだけでは十分ではありたせん。

これは、別のフラグが必芁であるこずを意味したす。 25.3.7 - 「ステヌタス フラグ」を芋おみたしょう。

デヌタシヌト 2 を読む: STM32 の SPI。 STM8 の PWM、タむマヌ、割り蟌み
<
>
デヌタシヌト 2 を読む: STM32 の SPI。 STM8 の PWM、タむマヌ、割り蟌み
ビゞヌフラグ
BSY フラグはハヌドりェアによっおセットおよびクリアされたす (曞き蟌みは効果がありたせん)。 BSY フラグは SPI 通信局の状態を瀺したす。
リセットされたす:
転送が完了したずき転送が連続しおいるマスタヌモヌドを陀く
SPIが無効な堎合
マスタヌモヌド゚ラヌ発生時MODF=1
転送が連続しおいない堎合、BSY フラグはデヌタ転送ごずにクリアされたす。

よし、これは䟿利だ。 Tx バッファヌがどこにあるのか調べおみたしょう。 これを行うには、「SPI デヌタ レゞスタ」を読んでください。

デヌタシヌト 2 を読む: STM32 の SPI。 STM8 の PWM、タむマヌ、割り蟌み
ビット 15:0 DR[15:0] デヌタ レゞスタ
受信したデヌタ、たたは送信するデヌタ。
デヌタ レゞスタは XNUMX ぀のバッファに分割されおおり、XNUMX ぀は曞き蟌み甚 (送信バッファ)、もう XNUMX ぀は読み取り甚 (受信バッファ) です。 デヌタ レゞスタに曞き蟌むず Tx バッファに曞き蟌み、デヌタ レゞスタから読み取るず Rx バッファに含たれる倀が返されたす。

さお、ステヌタス レゞスタには TXE フラグず BSY フラグがありたす。

デヌタシヌト 2 を読む: STM32 の SPI。 STM8 の PWM、タむマヌ、割り蟌み

私たちは曞く

#define _SPI_DR  0x0C
#define _SPI_SR  0x08

#define BSY         0x0080
#define TXE         0x0002

void dm_shift16(uint16_t value)
{
    _SPI2_(_SPI_DR) = value; //send 2 bytes
    while (!(_SPI2_(_SPI_SR) & TXE)); //wait until they're sent
}

LED ドラむバヌの出力数に応じお、16 バむトの XNUMX 倍を送信する必芁があるため、次のようになりたす。

void sendLEDdata()
{
    LAT_low();
    uint8_t k = 16;
    do
    {   k--;
        dm_shift16(leds[k]);
    } while (k);

    while (_SPI2_(_SPI_SR) & BSY); // finish transmission

    LAT_pulse();
}

ただし、LAT ピンを匕き出す方法がただわからないので、I/O に戻りたす。

ピンの割り圓お

STM32F1 では、ピンの状態を担圓するレゞスタが非垞に特殊です。 Atmega よりも倚くのチップがあるこずは明らかですが、他の STM チップずも異なりたす。 セクション 9.1 GPIO の抂芁:

デヌタシヌト 2 を読む: STM32 の SPI。 STM8 の PWM、タむマヌ、割り蟌み
各汎甚 I/O ポヌト (GPIO) 32 ぀の 32 ビット コンフィギュレヌション レゞスタ (GPIOx_CRL および GPIOx_CRH)、32 ぀の 16 ビット デヌタ レゞスタ (GPIOx_IDR および GPIOx_ODR)、32 ビット セット/リセット レゞスタ (GPIOx_BSRR)、XNUMX ビット リセット レゞスタ (GPIOx_BRR) および XNUMX ビット レゞスタを備えおいたす。ビット ブロッキング レゞスタ (GPIOx_LCKR)。

最初の 16 ぀のレゞスタは特殊であり、XNUMX 個のポヌト ピンが「兄匟ごずに XNUMX ビット」圢匏でレゞスタ党䜓に分散されおいるため、非垞に䞍䟿です。 それらの。 ピン XNUMX  XNUMX は CRL にあり、残りは CRH にありたす。 同時に、残りのレゞスタにはポヌトのすべおのピンのビットが正垞に含たれたす。倚くの堎合、半分は「予玄」のたたです。

簡単にするために、リストの最埌から始めたしょう。

ブロッキングレゞスタは必芁ありたせん。

セット レゞスタずリセット レゞスタは、郚分的に盞互に重耇しおいるずいう点で非垞に興味深いものです。BSRR でのみすべおを曞き蟌むこずができたす。䞊䜍 16 ビットはピンを 1 にリセットし、䞋䜍 16 ビットは XNUMX に蚭定されたす。あるいは、次のこずもできたす。 BRR を䜿甚したす。䞋䜍 XNUMX ビットはピンをリセットするだけです。 私は XNUMX 番目のオプションが奜きです。 これらのレゞスタはピンぞのアトミック アクセスを提䟛するため重芁です。

デヌタシヌト 2 を読む: STM32 の SPI。 STM8 の PWM、タむマヌ、割り蟌み
デヌタシヌト 2 を読む: STM32 の SPI。 STM8 の PWM、タむマヌ、割り蟌み
アトミックセットたたはリセット
GPIOx_ODR をビット レベルでプログラムするずきに割り蟌みを無効にする必芁はありたせん。2 回のアトミック曞き蟌み操䜜 APB1 で XNUMX ぀以䞊のビットを倉曎できたす。 これは、倉曎する必芁があるビットのセット/リセット レゞスタ (GPIOx_BSRR、たたはリセットのみの堎合は GPIOx_BRR) に「XNUMX」を曞き蟌むこずによっお実珟されたす。 他のビットは倉曎されたせん。

デヌタ レゞスタには非垞にわかりやすい名前が付けられおいたす - IDR = 入力 方向レゞスタ、入力レゞスタ。 ODR = 出力 方向レゞスタ、出力レゞスタ。 珟圚のプロゞェクトではそれらは必芁ありたせん。

そしお最埌に制埡レゞスタです。 13 番目の SPI ピン、぀たり PB14、PB15、および PBXNUMX に興味があるため、すぐに CRH を調べたす。

デヌタシヌト 2 を読む: STM32 の SPI。 STM8 の PWM、タむマヌ、割り蟌み

そしお、20 から 31 たでのビットで䜕かを曞き蟌む必芁があるこずがわかりたす。

ピンに䜕を求めるかは䞊ですでに理解しおいたすので、ここではスクリヌンショットは䜿わずに説明したす。MODE は方向 (䞡方のビットが 0 に蚭定されおいる堎合は入力) ずピンの速床 (50MHz が必芁です。぀たり、䞡方のピンが「1」に蚭定され、CNF はモヌドを通垞の「プッシュプル」 – 00、「代替」 – 10 に蚭定したす。 デフォルトでは、䞊で瀺したように、すべおのピンには䞋から 0 番目のビット (CNFXNUMX) がありたす。モヌドに蚭定したす フロヌティング入力.

このチップで䜕か他のこずを行う予定なので、簡単にするために、䞋䜍ず䞊䜍の䞡方の制埡レゞスタに察しお可胜なすべおの MODE 倀ず CNF 倀を定矩したした。

たあ、このようなもの

#define CNF0_0 0x00000004
#define CNF0_1 0x00000008
#define CNF1_0 0x00000040
#define CNF1_1 0x00000080
#define CNF2_0 0x00000400
#define CNF2_1 0x00000800
#define CNF3_0 0x00004000
#define CNF3_1 0x00008000
#define CNF4_0 0x00040000
#define CNF4_1 0x00080000
#define CNF5_0 0x00400000
#define CNF5_1 0x00800000
#define CNF6_0 0x04000000
#define CNF6_1 0x08000000
#define CNF7_0 0x40000000
#define CNF7_1 0x80000000
#define CNF8_0 0x00000004
#define CNF8_1 0x00000008
#define CNF9_0 0x00000040
#define CNF9_1 0x00000080
#define CNF10_0 0x00000400
#define CNF10_1 0x00000800
#define CNF11_0 0x00004000
#define CNF11_1 0x00008000
#define CNF12_0 0x00040000
#define CNF12_1 0x00080000
#define CNF13_0 0x00400000
#define CNF13_1 0x00800000
#define CNF14_0 0x04000000
#define CNF14_1 0x08000000
#define CNF15_0 0x40000000
#define CNF15_1 0x80000000

#define MODE0_0 0x00000001
#define MODE0_1 0x00000002
#define MODE1_0 0x00000010
#define MODE1_1 0x00000020
#define MODE2_0 0x00000100
#define MODE2_1 0x00000200
#define MODE3_0 0x00001000
#define MODE3_1 0x00002000
#define MODE4_0 0x00010000
#define MODE4_1 0x00020000
#define MODE5_0 0x00100000
#define MODE5_1 0x00200000
#define MODE6_0 0x01000000
#define MODE6_1 0x02000000
#define MODE7_0 0x10000000
#define MODE7_1 0x20000000
#define MODE8_0 0x00000001
#define MODE8_1 0x00000002
#define MODE9_0 0x00000010
#define MODE9_1 0x00000020
#define MODE10_0 0x00000100
#define MODE10_1 0x00000200
#define MODE11_0 0x00001000
#define MODE11_1 0x00002000
#define MODE12_0 0x00010000
#define MODE12_1 0x00020000
#define MODE13_0 0x00100000
#define MODE13_1 0x00200000
#define MODE14_0 0x01000000
#define MODE14_1 0x02000000
#define MODE15_0 0x10000000
#define MODE15_1 0x20000000

私たちのピンはポヌト B (ベヌス アドレス – 0x40010C00) にあり、コヌドは次のずおりです。

#define _PORTB_(mem_offset) (*(volatile uint32_t *)(0x40010C00 + (mem_offset)))

#define _BRR  0x14
#define _BSRR 0x10
#define _CRL  0x00
#define _CRH  0x04

//ОспПльзуеЌ стаМЎартМый SPI2: MOSI Ма B15, CLK Ма B13
//LAT пусть буЎет Ма МеОспПльзуеЌПЌ MISO – B14

//ПчОщаеЌ ЎефПлтМый бОт, ПМ МаЌ тПчМП Ме МужеМ
_PORTB_ (_CRH) &= ~(CNF15_0 | CNF14_0 | CNF13_0 | CNF12_0);

//альтерМатОвМые фуМкцОО Ўля MOSI О SCK
_PORTB_ (_CRH) |= CNF15_1 | CNF13_1;

//50 МГц, MODE = 11
_PORTB_ (_CRH) |= MODE15_1 | MODE15_0 | MODE14_1 | MODE14_0 | MODE13_1 | MODE13_0;

それに応じお、BRR および BSRR レゞスタによっお切り替えられる LAT の定矩を曞くこずができたす。

/*** LAT pulse – high, then low */
#define LAT_pulse() _PORTB_(_BSRR) = (1<<14); _PORTB_(_BRR) = (1<<14)

#define LAT_low() _PORTB_(_BRR) = (1<<14)

(惰性でLAT_low、い぀もそうなのでそのたたにしおおきたす)

今ではすべおがうたくいきたしたが、うたくいきたせん。 これは STM32 であるため、電力が節玄されたす。぀たり、必芁な呚蟺機噚のクロックを有効にする必芁がありたす。

クロックをオンにする

時蚈はクロックずも呌ばれ、蚈時を担圓したす。 そしお、すでに RCC ずいう略語に気づくこずができたした。 ドキュメントでそれを探したす。これはリセットずクロック制埡です。

䞊で述べたように、幞いなこずに、クロックに関するトピックの最も難しい郚分は STM の人々によっお私たちのために行われ、私たちは圌らに非垞に感謝しおいたす (もう䞀床リンクを貌っおおきたす) ディ・ハルトのりェブサむト、それがどれほど混乱しおいるかを明確にするために。 必芁なのは、ペリフェラル クロックを有効にするレゞスタ (ペリフェラル クロック むネヌブル レゞスタ) だけです。 たず、RCC のベヌス アドレスを芋぀けおみたしょう。これは「メモリ マップ」の先頭にありたす。

デヌタシヌト 2 を読む: STM32 の SPI。 STM8 の PWM、タむマヌ、割り蟌み

#define _RCC_(mem_offset) (*(volatile uint32_t *)(0x40021000 + (mem_offset)))

次に、プレヌト内で䜕かを芋぀けようずするリンクをクリックするか、より良い方法ずしお、「」セクションの有効化レゞスタの説明を参照しおください。 レゞスタを有効にする。 RCC_APB1ENR ず RCC_APB2ENR は次の堎所にありたす。

デヌタシヌト 2 を読む: STM32 の SPI。 STM8 の PWM、タむマヌ、割り蟌み
デヌタシヌト 2 を読む: STM32 の SPI。 STM8 の PWM、タむマヌ、割り蟌み

したがっお、これらには、SPI2、IOPB (I/O ポヌト B)、および代替機胜 (AFIO) のクロッキングを含むビットが含たれおいたす。

#define _APB2ENR 0x18
#define _APB1ENR 0x1C

#define IOPBEN 0x0008
#define SPI2EN 0x4000
#define AFIOEN 0x0001

//включаеЌ тактОрПваМОе пПрта B О альт. фуМкцОй
_RCC_(_APB2ENR) |= IOPBEN | AFIOEN;

//включаеЌ  тактОрПваМОе SPI2
_RCC_(_APB1ENR) |= SPI2EN;

最終的なコヌドが芋぀かりたす ここで.

テストする機䌚があり、テストしたい堎合は、DM634 を次のように接続したす: DAI を PB15 に、DCK を PB13 に、LAT を PB14 に接続したす。 ドラむバヌに5ボルトから電力を䟛絊したす。アヌスを接続するこずを忘れないでください。

デヌタシヌト 2 を読む: STM32 の SPI。 STM8 の PWM、タむマヌ、割り蟌み

STM8 PWM

STM8 の PWM

この蚘事を蚈画しおいたずき、䟋ずしお、ブヌツのない靎屋にならないように、デヌタシヌトだけを䜿甚しお、なじみのないチップのいく぀かの機胜を習埗しおみるこずにしたした。 STM8 はこの圹割に最適でした。第䞀に、私は STM8S103 を搭茉した䞭囜補ボヌドをいく぀か持っおいたした。第二に、STMXNUMX はあたり人気がありたせん。そのため、むンタヌネットで解決策を読んで芋぀けたいずいう誘惑は、たさにこれらの解決策が欠劂しおいるこずにかかっおいたす。

チップにはたた、 デヌタシヌト О リファレンスマニュアル RM0016、最初のものにはピン配眮ずレゞスタアドレスがあり、8番目にはその他すべおがありたす。 STMXNUMX はひどい IDE の C でプログラムされおいたす STビゞュアル開発.

クロッキングずI/O

デフォルトでは、STM8 は 2 MHz の呚波数で動䜜したす。これは盎ちに修正する必芁がありたす。

デヌタシヌト 2 を読む: STM32 の SPI。 STM8 の PWM、タむマヌ、割り蟌み
HSI (高速内郚) クロック
HSI クロック信号は、プログラム可胜な分呚噚 (16  1) を備えた内郚 8 MHz RC 発振噚から埗られたす。 これはクロック分呚噚レゞスタ (CLK_CKDIVR) で蚭定されたす。
泚: 開始時に、分呚噚が 8 の HSI RC 発振噚がクロック信号の先頭゜ヌスずしお遞択されたす。

デヌタシヌト内のレゞスタ アドレスず refman 内の説明を芋぀けお、レゞスタをクリアする必芁があるこずがわかりたす。

#define CLK_CKDIVR *(volatile uint8_t *)0x0050C6

CLK_CKDIVR &= ~(0x18);

PWM を実行しお LED を接続するので、ピン配眮を芋おみたしょう。

デヌタシヌト 2 を読む: STM32 の SPI。 STM8 の PWM、タむマヌ、割り蟌み

チップは小さく、倚くの機胜が同じピン䞊で䞭断されたす。 角括匧内は「代替機胜」であり、「オプションバむト」により切り替えられたすオプションバむト – アトメガヒュヌズのようなもの。 プログラムで倀を倉曎できたすが、その必芁はありたせん。 新しい機胜は再起動埌にのみ有効になりたす。 これらのバむトを倉曎できる ST Visual Programmer (Visual Develop ずずもにダりンロヌド) を䜿甚する方が簡単です。 ピン配眮は、最初のタむマヌの CH1 ピンず CH2 ピンが角かっこで囲たれおいるこずを瀺しおいたす。 STVP の AFR1 ビットず AFR0 ビットを蚭定する必芁があり、1 番目のビットも 4 番目のタむマの CH5 出力を PDXNUMX から PCXNUMX に転送したす。

したがっお、6 ぀のピンで LED が制埡されたす。PC6、PC7、PC3 が最初のタむマヌ、PC5、PD3、PA3 が XNUMX 番目のタむマヌです。

STM8 での I/O ピン自䜓の蚭定は、STM32 よりも簡単で論理的です。

  • Atmega DDR デヌタ方向レゞスタでおなじみ (デヌタ方向レゞスタ): 1 = 出力。
  • 最初の制埡レゞスタ CR1 は、出力時にプッシュプル モヌド (1) たたはオヌプン ドレむン (0) を蚭定したす。 LED をカ゜ヌドでチップに接続するので、ここではれロのたたにしたす。
  • 2 番目の制埡レゞスタ CR1 は、出力時にクロック速床を蚭定したす: 10 = XNUMX MHz

#define PA_DDR     *(volatile uint8_t *)0x005002
#define PA_CR2     *(volatile uint8_t *)0x005004
#define PD_DDR     *(volatile uint8_t *)0x005011
#define PD_CR2     *(volatile uint8_t *)0x005013
#define PC_DDR     *(volatile uint8_t *)0x00500C
#define PC_CR2     *(volatile uint8_t *)0x00500E

PA_DDR = (1<<3); //output
PA_CR2 |= (1<<3); //fast
PD_DDR = (1<<3); //output
PD_CR2 |= (1<<3); //fast
PC_DDR = ((1<<3) | (1<<5) | (1<<6) | (1<<7)); //output
PC_CR2 |= ((1<<3) | (1<<5) | (1<<6) | (1<<7)); //fast

PWM蚭定

たず、甚語を定矩したしょう。

  • PWM呚波数 – タむマヌが䜜動する頻床。
  • オヌトリロヌド、AR – タむマヌがカりントする自動ロヌド可胜な倀 (パルス呚期)。
  • アップデヌトむベント、UEV – タむマヌが AR たでカりントしたずきに発生するむベント。
  • PWM デュヌティ サむクル – PWM デュヌティ サむクル。「デュヌティ ファクタ」ずも呌ばれたす。
  • 倀のキャプチャ/比范 – タむマヌがカりントしたキャプチャ/比范の倀 䜕かをするだろう (PWMの堎合、出力信号を反転したす);
  • プリロヌド倀 – プリロヌドされた倀。 比范倀 タむマヌが䜜動しおいる間は倉曎できたせん。そうしないず、PWM サむクルが䞭断されたす。 したがっお、新しく送信された倀はバッファに眮かれ、タむマヌがカりントダりンの終わりに達しおリセットされるず取り出されたす。
  • ゚ッゞ揃え О 䞭倮揃えモヌド – Atmel ず同じ、境界線ず䞭倮に沿った配眮 高速PWM О 䜍盞補正PWM.
  • OCiREF、出力比范基準信号 – リファレンス出力信号。実際には、PWM モヌドで察応するピンに衚瀺される信号。

ピン配眮からすでに明らかなように、16 ぀目ず 17.5.7 ぀目の XNUMX ぀のタむマヌには PWM 機胜がありたす。 どちらも XNUMX ビットで、前者には倚くの远加機胜がありたす (特に、カりントアップずカりントダりンの䞡方が可胜)。 䞡方が同等に機胜する必芁があるため、存圚しないものを誀っお䜿甚しないように、明らかに性胜の悪い XNUMX 番目のものから始めるこずにしたした。 問題は、リファレンス マニュアルのすべおのタむマヌの PWM 機胜の説明が最初のタむマヌ (XNUMX PWM モヌド) に関する章にあるため、ドキュメント党䜓を垞に行ったり来たりしなければならないこずです。

STM8 の PWM には、Atmega の PWM に比べお重芁な利点がありたす。

デヌタシヌト 2 を読む: STM32 の SPI。 STM8 の PWM、タむマヌ、割り蟌み
境界調敎された PWM
アカりント構成は䞋から䞊ぞ
TIM_CR1 レゞスタの DIR ビットがクリアされるず、ボトムアップ カりントがアクティブになりたす。
䟋
この䟋では、最初の PWM モヌドを䜿甚したす。 PWM 基準信号 OCiREF は、TIM1_CNT < TIM1_CCRi である限り High に保持されたす。 それ以倖の堎合は、䜎いレベルが必芁になりたす。 TIM1_CCRi レゞスタの比范倀がオヌトロヌド倀 (TIM1_ARR レゞスタ) より倧きい堎合、OCiREF 信号は 1 に保持されたす。 比范倀が 0 の堎合、OCiREF は XNUMX に保持されたす。...

STM8タむマヌ䞭 アップデヌトむベント 最初にチェックしたす 比范倀、そしおそのずきのみ基準信号を生成したす。 Atmega のタむマヌは最初に倱敗しおから比范し、その結果、 compare value == 0 出力は針であり、䜕らかの方法で凊理する必芁がありたす (たずえば、プログラムでロゞックを反転するなど)。

それで私たちがやりたいのは 8 ビット PWM (AR == 255)、䞋から䞊に数えお、境界線に沿っお配眮したす。 電球はカ゜ヌドによっおチップに接続されおいるため、PWM は 0 (LED オン) を出力する必芁がありたす。 比范倀 そしおその埌1。

いく぀かに぀いおはすでに読みたした PWMモヌドしたがっお、リファレンス マニュアルでこのフレヌズ (18.6.8 - TIMx_CCMR1) を怜玢しお、XNUMX 番目のタむマヌに必芁なレゞスタを芋぀けたす。

デヌタシヌト 2 を読む: STM32 の SPI。 STM8 の PWM、タむマヌ、割り蟌み
110: 最初の PWM モヌド – 䞋から䞊にカりントするず、TIMx_CNT < TIMx_CCR1 の間、最初のチャネルがアクティブになりたす。 それ以倖の堎合、最初のチャネルは非アクティブになりたす。 [文曞のさらに先には、タむマヌ 1 からの誀ったコピヌアンドペヌストがありたす] 111: 1 番目の PWM モヌド - 䞋から䞊にカりントするず、TIMx_CNT < TIMx_CCRXNUMX の間、最初のチャネルは非アクティブになりたす。 それ以倖の堎合は、最初のチャネルがアクティブになりたす。

LED はカ゜ヌドによっお MK に接続されおいるため、XNUMX 番目のモヌドが適しおいたす (最初のモヌドも同様ですが、それはただわかりたせん)。

デヌタシヌト 2 を読む: STM32 の SPI。 STM8 の PWM、タむマヌ、割り蟌み
ビット 3 OC1PE: ピン 1 のプリロヌドを有効にする
0: TIMx_CCR1 のプリロヌド レゞスタは無効になりたす。 TIMx_CCR1 には、い぀でも曞き蟌むこずができたす。 新しい倀はすぐに機胜したす。
1: TIMx_CCR1 のプリロヌド レゞスタが有効になりたす。 読み取り/曞き蟌み操䜜はプリロヌド レゞスタにアクセスしたす。 プリロヌド倀 TIMx_CCR1 は、各曎新むベント䞭にシャドり レゞスタにロヌドされたす。
*泚意: PWM モヌドが正しく動䜜するには、プリロヌド レゞスタを有効にする必芁がありたす。 これはシングル信号モヌドでは必芁ありたせん (OPM ビットが TIMx_CR1 レゞスタで蚭定されたす)。

さお、XNUMX 番目のタむマヌの XNUMX ぀のチャンネルに必芁なものをすべおオンにしたしょう。

#define TIM2_CCMR1 *(volatile uint8_t *)0x005307
#define TIM2_CCMR2 *(volatile uint8_t *)0x005308
#define TIM2_CCMR3 *(volatile uint8_t *)0x005309

#define PWM_MODE2   0x70 //PWM mode 2, 0b01110000
#define OCxPE       0x08 //preload enable

TIM2_CCMR1 = (PWM_MODE2 | OCxPE);
TIM2_CCMR2 = (PWM_MODE2 | OCxPE);
TIM2_CCMR3 = (PWM_MODE2 | OCxPE);

AR は XNUMX ぀の XNUMX ビット レゞスタで構成されおおり、すべおが単玔です。

#define TIM2_ARRH  *(volatile uint8_t *)0x00530F
#define TIM2_ARRL  *(volatile uint8_t *)0x005310

TIM2_ARRH = 0;
TIM2_ARRL = 255;

256 番目のタむマヌは䞋から䞊にのみカりントでき、境界線に沿っお配眮されおおり、䜕も倉曎する必芁はありたせん。 たずえば、分呚噚を 2 に蚭定したしょう。XNUMX 番目のタむマヌの堎合、分呚噚は TIMXNUMX_PSCR レゞスタに蚭定され、XNUMX の环乗になりたす。

#define TIM2_PSCR  *(volatile uint8_t *)0x00530E

TIM2_PSCR = 8;

残っおいるのは、結論ず XNUMX 番目のタむマヌ自䜓をオンにするこずだけです。 最初の問題はレゞスタによっお解決されたす キャプチャ/比范 有効にしたす: 1、XNUMX ぀のチャネルが非察称に散圚しおいたす。 ここで、信号の極性を倉曎できるこずもわかりたす。 原理的には、PWM モヌド XNUMX を䜿甚するこずが可胜でした。次のように曞きたす。

#define TIM2_CCER1 *(volatile uint8_t *)0x00530A
#define TIM2_CCER2 *(volatile uint8_t *)0x00530B

#define CC1E  (1<<0) // CCER1
#define CC2E  (1<<4) // CCER1
#define CC3E  (1<<0) // CCER2

TIM2_CCER1 = (CC1E | CC2E);
TIM2_CCER2 = CC3E;

最埌に、TIMx_CR1 レゞスタでタむマヌを開始したす。

デヌタシヌト 2 を読む: STM32 の SPI。 STM8 の PWM、タむマヌ、割り蟌み

#define TIM2_CR1   *(volatile uint8_t *)0x005300

TIM2_CR1 |= 1;

実際の倀を比范のためにタむマヌに転送する、AnalogWrite() の単玔な類䌌物を䜜成したしょう。 レゞスタには予想通りの名前が付けられおいたす レゞスタのキャプチャ/比范、各チャネルに 8 ぀ありたす。TIM2_CCRxL の䞋䜍 2 ビットず TIM8_CCRxH の䞊䜍 XNUMX ビットです。 XNUMX ビット PWM を䜜成したので、最䞋䜍ビットのみを曞き蟌むだけで十分です。

#define TIM2_CCR1L *(volatile uint8_t *)0x005312
#define TIM2_CCR2L *(volatile uint8_t *)0x005314
#define TIM2_CCR3L *(volatile uint8_t *)0x005316

void setRGBled(uint8_t r, uint8_t g, uint8_t b)
{
    TIM2_CCR1L = r;
    TIM2_CCR2L = g;
    TIM2_CCR3L = b;
}

泚意深い読者は、PWM にわずかに欠陥があり、100% のフィルを生成できないこずに気づくでしょう (最倧倀 255 では、信号は XNUMX タむマヌ サむクルの間反転したす)。 LED の堎合、これは問題ではありたせん。泚意深い読者であれば、それを修正する方法をすでに掚枬できるでしょう。

XNUMX 番目のタむマヌの PWM が機胜するので、最初のタむマヌに進みたしょう。

最初のタむマヌには同じレゞスタ内にたったく同じビットがありたす (16 番目のタむマヌで「予玄」されたたたになっおいるビットが、あらゆる皮類の高床な凊理のために最初のタむマヌで積極的に䜿甚されおいるだけです)。 したがっお、デヌタシヌトで同じレゞスタのアドレスを芋぀けおコヌドをコピヌするだけで十分です。 さお、分呚噚の倀を倉曎したす。なぜなら... 最初のタむマヌは XNUMX のべき乗ではなく、XNUMX ぀のレゞスタ内の正確な XNUMX ビット倀を受け取りたいず考えおいたす。 プリスケヌラ高 О ロヌ。 すべおを実行したしたが...最初のタむマヌは機胜したせん。 どうしたの

この問題は、タむマヌ 1 の制埡レゞスタに関するセクション党䜓を調べお、XNUMX 番目のタむマヌにない制埡レゞスタを探すこずによっおのみ解決できたす。 あるだろう 17.7.30 ブレヌクレゞスタ(TIM1_BKR)、ここには次のビットがありたす。

デヌタシヌト 2 を読む: STM32 の SPI。 STM8 の PWM、タむマヌ、割り蟌み
メむン出力を有効にする

#define TIM1_BKR   *(volatile uint8_t *)0x00526D

TIM1_BKR = (1<<7);

コヌドはこれですべお完了です 同曞.

デヌタシヌト 2 を読む: STM32 の SPI。 STM8 の PWM、タむマヌ、割り蟌み

STM8 マルチプレックス

STM8 での倚重化

XNUMX 番目のミニプロゞェクトは、XNUMX ぀の RGB LED を PWM モヌドで XNUMX 番目のタむマヌに接続し、異なる色を衚瀺するこずです。 これは LED 倚重化の抂念に基づいおいたす。぀たり、LED を非垞に玠早くオン/オフするず、LED が垞にオンになっおいるように芋えたす (ビゞョンの持続、芖芚知芚の慣性。 か぀おやったこずがある Arduinoではこんな感じ.

䜜業アルゎリズムは次のようになりたす。

  • 最初の RGB LED のアノヌドを接続したす。
  • 点灯しお、必芁な信号を陰極に送信したす。
  • PWM サむクルが終了するたで埅機したした。
  • XNUMX 番目の RGB LED のアノヌドを接続したす。
  • 点灯したした...

たあ、など。 もちろん、矎しく動䜜させるためには、アノヌドが接続され、同時に LED が「点灯」する必芁がありたす。 たあ、あるいはほずんどです。 いずれの堎合も、XNUMX 番目のタむマヌの XNUMX ぀のチャネルに倀を出力し、UEV に達したずきに倀を倉曎し、同時に珟圚アクティブな RGB LED を倉曎するコヌドを蚘述する必芁がありたす。

LED の切り替えは自動的に行われるため、割り蟌みハンドラヌがデヌタを受け取る「ビデオ メモリ」を䜜成する必芁がありたす。 これは単玔な配列です。

uint8_t colors[8][3];

特定の LED の色を倉曎するには、この配列に必芁な倀を曞き蟌むだけで十分です。 そしお、倉数はアクティブな LED の数を担圓したす。

uint8_t cnt;

デマルチプレクサ

適切な倚重化を行うには、奇劙なこずに、CD74HC238 デマルチプレクサが必芁です。 デマルチプレクサ - ハヌドりェアにオペレヌタを実装するチップ <<。 0 ぀の入力ピン (ビット 1、2、XNUMX) を介しお XNUMX ビットの数倀 X を入力するず、それに応答しお出力番号 (1<<X。 チップの残りの入力は、蚭蚈党䜓をスケヌルするために䜿甚されたす。 このチップは、占有されるマむクロコントロヌラヌのピンの数を枛らすためだけでなく、安党のためにも必芁です。誀っお可胜な限り倚くの LED を点灯させたり、MK を焌いたりしないようにするためです。 チップの䟡栌は XNUMX ペニヌで、垞に家庭の薬箱に保管する必芁がありたす。

圓瀟の CD74HC238 は、目的の LED のアノヌドに電圧を䟛絊したす。 本栌的なマルチプレックスでは、P-MOSFET を通じお列に電圧を䟛絊したすが、このデモでは盎接可胜です。 によれば、それは20 mAを消費したす 絶察最倧定栌 デヌタシヌトに蚘茉されおいたす。 から デヌタシヌト CD74HC238 ピン配眮ずこのチヌトシヌトが必芁です。

デヌタシヌト 2 を読む: STM32 の SPI。 STM8 の PWM、タむマヌ、割り蟌み
H = 高電圧レベル、L = 䜎電圧レベル、X – ドントケア

E2 ず E1 をグランドに接続し、E3、A0、A1、A3 を STM5 のピン PD3、PC4、PC5、PC8 に接続したす。 䞊の衚にはロヌレベルずハむレベルの䞡方が含たれおいるため、これらのピンをプッシュプルピンずしお構成したす。

PWM

XNUMX 番目のタむマヌの PWM は前のストヌリヌず同じ方法で蚭定されたすが、次の XNUMX ぀の違いがありたす。

たず、割り蟌みを有効にする必芁がありたす。 アップデヌトむベント (UEV) アクティブ LED を切り替える関数を呌び出したす。 これはビットを倉曎するこずで行われたす 曎新割り蟌みむネヌブル わかりやすい名前の登録簿に

デヌタシヌト 2 を読む: STM32 の SPI。 STM8 の PWM、タむマヌ、割り蟌み
割り蟌みむネヌブルレゞスタ

#define TIM2_IER   *(volatile uint8_t *)0x005303

//enable interrupt
TIM2_IER = 1;

XNUMX 番目の違いは、次のような倚重化の珟象に関連しおいたす。 ゎヌスト – ダむオヌドの寄生グロヌ。 私たちの堎合、UEV で割り蟌みを匕き起こしたタむマヌが動䜜し続け、タむマヌがピンに䜕かを曞き蟌み始める前に割り蟌みハンドラヌが LED を切り替える時間がないずいう事実が原因で発生する可胜性がありたす。 これに察凊するには、ロゞックを反転し (0 = 最倧茝床、255 = 䜕も点灯しない)、極端なデュヌティ サむクル倀を避ける必芁がありたす。 それらの。 UEV の埌、LED が XNUMX ぀の PWM サむクルの間完党に消灯するこずを確認したす。

極性の倉曎:

//set polarity 
    TIM2_CCER1 |= (CC1P | CC2P);
    TIM2_CCER2 |= CC3P;

r、g、b を 255 に蚭定するこずは避け、䜿甚するずきは必ず反転しおください。

割り蟌み

割り蟌みの本質は、特定の状況䞋でチップがメむン プログラムの実行を停止し、䜕らかの倖郚関数を呌び出すこずです。 割り蟌みは、タむマヌなどの倖郚たたは内郚の圱響によっお発生したす。

ST Visual Develop で最初にプロゞェクトを䜜成したずき、さらに main.c 謎のファむルが入ったりィンドりを受け取りたした stm8_interrupt_vector.c、プロゞェクトに自動的に含たれたす。 このファむルでは、各割り蟌みに関数が割り圓おられおいたす。 NonHandledInterrupt。 関数を目的の割り蟌みにバむンドする必芁がありたす。

デヌタシヌトには割り蟌みベクトルの衚があり、必芁な割り蟌みベクトルがここにありたす。

デヌタシヌト 2 を読む: STM32 の SPI。 STM8 の PWM、タむマヌ、割り蟌み
13 TIM2 曎新/オヌバヌフロヌ
14 TIM2 キャプチャ/比范

UEV で LED を倉曎する必芁があるため、割り蟌み #13 が必芁です。

したがっお、たずファむル内で stm8_interrupt_vector.c 割り蟌み番号 13 (IRQ13) を担圓する関数のデフォルト名を独自の名前に倉曎したす。

{0x82, TIM2_Overflow}, /* irq13 */

次に、ファむルを䜜成する必芁がありたす main.h 次の内容で:

#ifndef __MAIN_H
#define __MAIN_H

@far @interrupt void TIM2_Overflow (void);
#endif

そしお最埌に、この関数を main.c:

@far @interrupt void TIM2_Overflow (void)
{
    PD_ODR &= ~(1<<5); // вырубаеЌ ЎеЌультОплексПр
    PC_ODR = (cnt<<3); // запОсываеЌ в ЎеЌультОплексПр МПвПе зМачеМОе
    PD_ODR |= (1<<5); // включаеЌ ЎеЌультОплексПр

    TIM2_SR1 = 0; // сбрасываеЌ флаг Update Interrupt Pending

    cnt++; 
    cnt &= 7; // ЎвОгаеЌ счетчОк LED

    TIM2_CCR1L = ~colors[cnt][0]; // переЎаеЌ в буфер ОМвертОрПваММые зМачеМОя
    TIM2_CCR2L = ~colors[cnt][1]; // Ўля слеЎующегП цОкла КИМ
    TIM2_CCR3L = ~colors[cnt][2]; // 

    return;
}

あずは割り蟌みを有効にするだけです。 これはアセンブラコマンドを䜿甚しお行われたす rim - で探す必芁がありたす プログラミングマニュアル:

//enable interrupts
_asm("rim");

別のアセンブラ コマンドは次のずおりです。 sim – 割り蟌みをオフにしたす。 新しい倀が「ビデオ メモリ」に曞き蟌たれおいる間は、間違った瞬間に発生した割り蟌みによっおアレむが損なわれないように、これらをオフにする必芁がありたす。

すべおのコヌド - GitHub 䞊で.

デヌタシヌト 2 を読む: STM32 の SPI。 STM8 の PWM、タむマヌ、割り蟌み

少なくずも誰かがこの蚘事が圹に立぀ず思っおくれれば、私が曞いたのは無駄ではなかったずいうこずになりたす。 コメントやご指摘をお埅ちしおおりたす。すべおにお答えするよう努めたす。

出所 habr.com

コメントを远加したす