IAR環境でのAtmega16 CマむクロコントロヌラヌのプログラミングずJTAGデバッグ、パヌト1





はじめに



私の意芋では、䞖界に存圚するほずんどすべおのマむクロコントロヌラヌのプログラミングを迅速に孊習するには、技術文曞の孊習に加えお、C蚀語を習埗し、JTAGデバッグを䜿甚する必芁がありたす。 私の考えを説明したす。 C蚀語コンパむラは、既存のほずんどすべおのマむクロコントロヌラヌに察応しおいたす。 そのため、蚀語Cはクロスプラットフォヌムアセンブラヌずしおの地䜍を確立しおいたす。 圌の知識により、マむクロコントロヌラの新しいファミリごずにアセンブリ手順を孊ぶ必芁がなくなりたす。 JTAGデバッグは、むンサヌキット゚ラヌ怜玢の可胜性を提䟛するだけでなく、内郚からマむクロコントロヌラヌを調査するのにも圹立ちたす。 単玔なマむクロコントロヌラでさえデバッグせずに単玔にプログラミングする堎合、入力ず出力を備えたブラックボックスずしおシステムの研究にアプロヌチするこずは誰にずっおも明らかだず思いたす。 このアプロヌチは、特に初期段階では、孊習を困難にしたす。 䞀方、JTAGを䜿甚するず、内郚に入り、プログラムが段階的に実行される方法を確認し、メモリずレゞスタで䜕が起こるかを確認し、ブレヌクポむントぞの興奮を開始し、プログラムの逆アセンブルされたバヌゞョンを実行できたす。 この機胜により、孊習を倧幅にスピヌドアップできたす。



AVR、STM8、MSP430、AVR32、STM32、EFM32、Renesas RXなどのマむクロコントロヌラヌには、C蚀語コンパむラずJTAGむンタヌフェむスを䜿甚したデバッグがありたす。 これらの倚くのマむクロコントロヌラヌの単䞀のクロスプラットフォヌム環境は、Embedded Workbenchです。 環境は有料ですが、30日間の無料バヌゞョンたたはコヌドサむズ制限のあるバヌゞョンを䜿甚するこずができたす。 今月の新しい家族の最初の研究のために十分かもしれたせん。 その埌、家族に぀いお決心し、無料のツヌルで家族ず䞀緒に仕事を続けるか、小芏暡プロゞェクトの堎合はサむズが制限されおいるバヌゞョンのコヌドを䜿甚するかを決定できたす。 倧芏暡な商甚補品の堎合は、この媒䜓も賌入できたす。



たた、AVR、STM8、MSP430ファミリヌで孊習を開始するこずをお勧めしたす。 これらのマむクロコントロヌラの動䜜は、比范的単玔なコマンドシステム、少数のプロセッサレゞスタおよび呚蟺機噚を備えおいるため、理解が容易です。 簡単な䟋を䜜成し、埐々に独自のラむブラリを䜜成するこずから始めた方が良いでしょう。 これはすべお頭でよく芆われおいたす。 最初の知り合いにずっお、これは非垞に成功しおいたす。

以䞋で説明する䟋では、AVRがマむクロコントロヌラの䞖界で最も人気のあるファミリであるため、AVRを遞択したした。 始めるのは簡単だず思いたすが、それに限定するべきではありたせん。



JTAGデバッガヌの遞択



Cで蚘述されたプログラムのむンサヌキットデバッグには、AVRマむクロコントロヌラヌ甚のJTAGデバッガヌが必芁です。 最も手頃な䟡栌で補造が容易なのは、AVR JTAGICE独自のデバッガヌのクロヌンです。 このようなクロヌンは、 eBayで䜎䟡栌で泚文できたす。 品質は宝くじのようなものです。







クロヌンは、たずえばOlimexによっおも生成されたす 。 COMポヌトを介しおコンピュヌタヌに接続するクラシックバヌゞョンず、USBむンタヌフェむスを介した接続の新しいバヌゞョンがありたす。







このようなクロヌンの個人生産では、独自のプリント基板を䜜成できない堎合、DIPコンポヌネントのみを䜿甚できるため、むンストヌルが簡単になりたす。 JTAGICEクロヌンを含む初期バヌゞョンのEvertoolは 、そのようにしお䜜成されたした。



]



ほずんどのJTAGICEクロヌンは、次の図に瀺す図に基づいおいたす。 より正確には、JTAGICEセクションず呌ばれる郚分です。 デバッガヌのコアはAtmega16Lマむクロコントロヌラヌです。 JTAGICEクロヌンをUSB経由で接続したい堎合は、 MAX3232レベル倉換チップをFTDI FT232チップに倉曎したす。 ただし、FT232はDIPパッケヌゞでリリヌスされおおらず、このチップを搭茉したDIPモゞュヌルの䟡栌は非垞に高くなっおいたす。 したがっお、ここでは、1぀の回路基板ずDIPコンポヌネントだけで降りるこずはできたせん。 现いワむダヌでFT232をブレッドボヌドにはんだ付けするか、塩玠を含む通垞のフットプリントで単局のプリント回路基板を゚ッチングする必芁がありたす。







ファヌムりェアは、AVR Studio 4のむンストヌルフォルダヌにあるか、 ここからダりンロヌドできたす 。

䞊蚘のJTAGICEクロヌンの欠点は、 AVR Studio 6でサポヌトされおいないこずです。 ただし、AVR Studio 4の叀いバヌゞョンずAVR甹IARの叀いバヌゞョンず新しいバヌゞョンでは、これらのクロヌンは十分にサポヌトされおいたす。

埌で曞かれたCコヌド䟋をデバッグするために、このスキヌムに埓っお䜜成されたクロヌンを䜿甚したした。 その䞭のMAX3232チップは、本質を倉えないADM3202の代替品です。







JTAGICEのこのクロヌンは私に匕き継がれたした。 私は職堎で電子廃棄物の入った箱を芋぀けたした。 うたくいかなかったので、再フラッシュするこずにしたした。 写真に芋られるように、Atmega16LをプログラミングするためのAVR ISPコネクタはサむズを瞮小するために出力されないため、なぜ特別なアダプタを䜜成する必芁がありたしたか。 ファヌムりェアの埌、JTAGICEは「死埌の䞖界」の寿呜を獲埗し、獲埗したした。

COMポヌトが時代遅れになった今、私は「旧友」を捚おず、USB-RS-232ケヌブルコンバヌタヌを賌入したした 。







デバッグボヌド



デバッグボヌドずしお、ブレッドボヌドに組み立おたデゞタル枩床蚈を䜿甚したす。 ボヌドはUSBで駆動され、コアはDIPパッケヌゞのAtmega16マむクロコントロヌラヌです。 マむクロコントロヌラヌは、呚波数が16 MHzの氎晶振動子からクロックを䟛絊され、必芁最小限の受動郚品のセット氎晶の堎合は22 pFコンデンサ、リセットラむンを電源にプルするための10kΩ抵抗、電源の堎合は0.1ÎŒFコンデンサで結ばれたす。 マむクロコントロヌラの暙準プログラミングおよびデバッグ甚に、2぀の暙準6ピンAVR ISPおよび10ピンAVR JTAG゜ケットが取り付けられおいたす。 ボヌドには、アナログ枩床センサヌ、3桁の静的7セグメントむンゞケヌタ、および远加のLEDがありたす。 衚瀺LEDおよびむンゞケヌタセグメントは、500オヌムの電流制限抵抗噚を介しおマむクロコントロヌラに接続されおいたす。 3぀の7セグメントむンゞケヌタヌはそれぞれ、ポヌトA、B、Dのいずれかの端子0から6に接続されたす。LEDはポヌトDの7番目の端子に接続されたす。アナログセンサヌ出力はポヌトAの7番目の端子に接続されたす内蔵ADCのチャンネル7 







すべおの芁玠はMGTFワむダではんだ付けされたした。







IAR開発環境



プログラムの䜜成ずデバッグには、Atmel AVR環境甚のIAR Embedded Workbench、぀たりコヌドサむズ制限が4 Kbの無料バヌゞョンを䜿甚したす。 AVRファミリヌのマむクロコントロヌラヌ甚のC蚀語の小さなプロゞェクトの堎合、これで十分です。

ここに行っお、珟圚のAVR甹IARの最新バヌゞョンが提䟛するものを読んでみたしょう。 前述のJTAGICEデバッガヌは、以前ず同様にサポヌトされおいたす。







サポヌトされるファミリのリストには、megaAVRが含たれたす。







JTAGデバッガヌずデバッグボヌドが動䜜するこずを確認した埌、IARをダりンロヌドしたす 。



むンストヌラヌを䜿甚するず、キックスタヌトラむセンスに登録できたす。







むンストヌル埌、IARを登録するには、登録フォヌムに蚘入する必芁がありたす。







アンケヌトぞの蚘入埌、キヌがメヌルに届きたす。キヌを入力するず、無料の登録枈みキックスタヌトバヌゞョンが無制限に届きたす。







タスク甚の空のプロゞェクトを䜜成したす。 AVR Studio 4を䜿甚しお出力16進ファむルをフラッシュする必芁がある堎合に備えお、C蚀語ずオプションAVR Studio 4互換出力を遞択したす。







蚀語を遞択するず、完党に空のほが空の゜ヌスファむルが衚瀺されたす。







プロゞェクトの蚭定に移りたしょう。 なぜなら Atmega16のプログラムを䜜成し、プロセッサヌ構成の列でこのマむクロコントロヌラヌを遞択したす。







[デバッガ]メニュヌ項目で、[JTAGICE]を遞択したす。







デバッガヌ-> JTAGICEのメニュヌ項目で、デバッガヌが接続されおいるCOMポヌト番号を遞択したす。







環境ラむブラリヌ内のマむクロコントロヌラヌの呚蟺レゞスタヌの重芁なビットの定矩を正しく動䜜させるには、以䞋も行う必芁がありたす。

[党般オプション]-> [システム]メニュヌ項目の[I / O-Include files]チェックボックスでビット定矩を有効にしたす。







プログラミングずデバッグ


䟋の説明を始める前に、IAR環境のいく぀かの機胜を説明する必芁がありたす。 Atmega16のレゞスタアドレス定矩を含むiom16.hヘッダヌファむルには、次のように内郚呚蟺レゞスタの特定のビットにアクセスできるマクロが含たれおいたす。



... * Examples of how to use the expanded result: * TCCR2 |= (1<<5); * or if ENABLE_BIT_DEFINITIONS is defined * TCCR2 |= (1<<COM21); * or like this: * TCCR2_Bit5 = 1; * or like this: * TCCR2_COM21 = 1; ***************************************************************************/
      
      







実際、これらのオプションのいずれかを䜿甚できたす。 実際、ここでの遞択は、特定のオプションを䜿甚するこずの利䟿性ず、曞かれおいる内容のその埌の理解の単玔さです。

IAR環境では、__ delay_cyclesx組み蟌み遅延関数を䜿甚できたす。xはティック単䜍の遅延時間です。 この堎合、1クロックサむクルの遅延は1/16000000 = 62.5 nsです。

これらの2぀のポむントがわかったので、排他的論理和を䜿甚しおLEDが単玔に点滅する最初の䟋に進みたす。



 /*  */ #include <ioavr.h> #include <intrinsics.h> /* */ //  #define F_CPU 16000000 /*  */ //   #define DELAY_US(us) __delay_cycles((F_CPU / 1000000) * (us)); //   #define DELAY_MS(ms) __delay_cycles((F_CPU / 1000) * (ms)); /*  */ //   void main( void ) { //   //  // 7-   D   DDRD_DDD7 = 1; // 7-   D   "0" PORTD_PORTD7 = 0; //   for(;;) { // 7-   D  "0"  "1"   "1"  "0" //    PORTD_PORTD7 ^= 1; //    DELAY_MS(1000); }//end for }
      
      







必芁な期間の遅延の圢成を簡玠化するために、遅延マクロ関数DELAY_USusおよびDELAY_MSmsを䜜成したす。これにより、サむクルではなくマむクロ秒およびミリ秒単䜍で遅延を蚭定できたす。 次に、メむンプログラムのメむン関数に移動したす。この関数は、マむクロコントロヌラヌをオンにした埌、たたはリセット埌に取埗したす。 スむッチを入れた埌に最初にすべきこずは、このケヌスでは動䜜に必芁な呚蟺ブロックを構成するこずです。これはポヌトDの1぀のピンのみです。ピンに構成するには、DDRDデヌタ方向レゞスタのDDD7ビットを1に蚭定するだけです。 足に「1」5 Vを蚭定するには、PORTDデヌタレゞスタのPORTD7ビットを蚭定する必芁がありたす。足に「0」グランドを蚭定するには、PORTD7ビットをリセットする必芁がありたす。 詳现に぀いおは、 デヌタシヌトをご芧ください。







制埡レゞスタDDRDおよびPORTDのビットを蚭定および曞き蟌むために、ビット単䜍の分離および結合なしで単に曞き蟌むDDRD = 0x01、DDRD = 0x00のは望たしくありたせんDDRD | = 0x01、DDRD=〜0x01、DDRD | =1 << 0、 DDRD=〜1 << 0。これにより、この操䜜の前に蚭定されたレゞスタの残りのビットが消去されるためです。 これを理解するこずが重芁です。

調敎埌、メむンの無限for;;ルヌプに入りたす。このルヌプでは、原則ずしお、メむンプログラムロゞックが実行されたす。 マむクロコントロヌラプログラムを実装するこのようなモデルは、スヌパヌサむクルシステムず呌ばれたす。 この無限サむクルは、呚蟺ナニットの凊理の䞭断䞭および䜎消費電力モヌドぞの切り替え䞭は䞀時停止され、マむクロコントロヌラヌがリセットされおオフになった堎合にのみ停止したす。

メむンの無限ルヌプでは、orを陀くビット挔算を䜿甚しお、「0」から「1」ぞ、次に「1」から「0」ぞの䞀定の切り替えがありたす。 これは、マクロ関数DELAY_MSmsによっお提䟛される1秒の遅延で発生したす。

次に、JTAGICEを䜿甚しおこの䟋をロヌドしおデバッグしたす。 これを行うには、[プロゞェクト]-> [ダりンロヌドずデバッグ]メニュヌ項目をクリックするか、Ctrl + Dキヌを抌すか、赀い䞉角圢のアむコンをクリックしたす。その埌、コヌドに構文゚ラヌがない堎合、ステップバむステップのコマンドを䜿甚できるデバッグモヌドに切り替えたす。オヌバヌ、ステップむン、ステップアりト、次のステヌトメント、移動、リセット。 さらに、ブレヌクポむントを䜿甚する可胜性がありたす。 これにより、プログラムをステップごずに実行し、ポヌトDのプロセッサレゞスタずDDRDおよびPORTDレゞスタの各ステップで䜕が起こるかを確認し、実行しおから停止し、ブレヌクポむントたで開始できたす。 これはすべお、゚ラヌを芋぀けるためのツヌルを提䟛するだけでなく、マむクロコントロヌラヌの動䜜をよりよく理解するのにも圹立ちたす。 圌ずより速く働くこずを孊びなさい。







2番目の䟋もLEDの点滅ですが、远加のマクロ機胜を䜿甚しおいたす。



 /*  */ #include <ioavr.h> #include <intrinsics.h> /* */ //  #define F_CPU 16000000 //    #define DELAY_TIME 1000 //     //  #define LED_DDR DDRD #define LED_PORT PORTD #define LED_PIN DDD7 /*  */ //   #define LED_INIT() ( LED_DDR |= (1<<LED_PIN) ); //  #define LED_LOW() ( LED_PORT &=~ (1<<LED_PIN) ); //  #define LED_HIGH() ( LED_PORT |= (1<<LED_PIN) ); //  #define LED_TOG() ( LED_PORT ^= (1<<LED_PIN) ); //   #define DELAY_US(us) __delay_cycles((F_CPU / 1000000) * (us)); //   #define DELAY_MS(ms) __delay_cycles((F_CPU / 1000) * (ms)); /*  */ //   void main( void ) { //   //  LED_INIT(); //  LED_LOW(); //   for(;;) { //  LED_TOG(); //    DELAY_MS(DELAY_TIME); }//end for }
      
      







マクロ関数アプロヌチは、2぀の方法で䟿利になりたす。 1぀は、コヌドの可読性を向䞊させるこずです。 2぀目は、可胜な修正の簡玠化です。 ここで、LEDを別のポヌトの別のピンに再構成する必芁がある堎合は、LED_DDR、LED_PORT、LED_PINの3぀の定矩を倉曎し、プログラムテキスト党䜓を修正しないでください。 ラむブラリを曞くずき、これは人生を倧いに単玔化したす。

3番目の䟋は、ステヌトマシンを䜿甚した点滅LEDの実装です。 ステヌトマシンは、珟圚の状態に応じお゚ンドレスサむクルがブランチに分割されるマむクロコントロヌラヌファヌムりェアモデルを実装するためのオプションの1぀です。



 /*  */ #include <ioavr.h> #include <intrinsics.h> /* */ //  #define F_CPU 16000000 //    #define DELAY_TIME_LF 1000 #define DELAY_TIME_AF 500 #define DELAY_TIME_HF 100 //     #define LIMIT_CNT_LF 4 #define LIMIT_CNT_AF 8 #define LIMIT_CNT_HF 40 //  #define UCHAR unsigned char //    #define STATE_LOW_FREQ_BLINK 0 #define STATE_AVR_FREQ_BLINK 1 #define STATE_HIGH_FREQ_BLINK 2 //     //  #define LED_DDR DDRD #define LED_PORT PORTD #define LED_PIN DDD7 /*  */ //   #define LED_INIT() ( LED_DDR |= (1<<LED_PIN) ); //  #define LED_LOW() ( LED_PORT &=~ (1<<LED_PIN) ); //  #define LED_HIGH() ( LED_PORT |= (1<<LED_PIN) ); //  #define LED_TOG() ( LED_PORT ^= (1<<LED_PIN) ); //   #define DELAY_US(us) __delay_cycles((F_CPU / 1000000) * (us)); //   #define DELAY_MS(ms) __delay_cycles((F_CPU / 1000) * (ms)); /*   */ //    UCHAR curr_state = STATE_LOW_FREQ_BLINK; //    //  UCHAR state_cnt = 0; /*  */ //   void main( void ) { //   //  LED_INIT(); //  LED_LOW(); //   for(;;) { //  switch(curr_state) { //      case STATE_LOW_FREQ_BLINK: //  LED_TOG(); //    DELAY_MS(DELAY_TIME_LF); //  state_cnt++; //     //,    if (state_cnt==LIMIT_CNT_LF) { curr_state = STATE_AVR_FREQ_BLINK; //  state_cnt = 0; }//end if break; //      case STATE_AVR_FREQ_BLINK: //  LED_TOG(); //    DELAY_MS(DELAY_TIME_AF); //  state_cnt++; //     //,    if (state_cnt==LIMIT_CNT_AF) { curr_state = STATE_HIGH_FREQ_BLINK; //  state_cnt = 0; }//end if break; //      case STATE_HIGH_FREQ_BLINK: //  LED_TOG(); //    DELAY_MS(DELAY_TIME_HF); //  state_cnt++; //     //,    if (state_cnt==LIMIT_CNT_HF) { curr_state = STATE_LOW_FREQ_BLINK; //  state_cnt = 0; }//end if break; } }//end for }
      
      







この䟋では、STATE_LOW_FREQ_BLINK、STATE_AVR_FREQ_BLINK、STATE_HIGH_FREQ_BLINKの3぀の状態があり、それぞれ䜎呚波数、䞭呚波数、高呚波数のLEDの点滅に察応しおいたす。 各状態には、各状態パスで実行される独自の遅延倀DELAY_TIME_LF、DELAY_TIME_AF、DELAY_TIME_HFがありたす。 各状態にある同じ期間は、LIMIT_CNT_LF、LIMIT_CNT_AF、LIMIT_CNT_HFの定矩によっお提䟛され、各状態の切り替えパスの数を決定したす。 switchステヌトメントは、curr_state倉数の珟圚の倀に埓っお状態間の切り替えを提䟛したす。 state_cnt倉数は、状態切り替え制限に達するたで、各状態パスで増分されたす。 ifステヌトメントは、切り替え制限に達したかどうかを刀別したす。 制限に達するず、次の状態ぞの遷移が発生し、state_cntパスカりンタヌがリセットされたす。



デバッグ䞭に、䞊蚘で既に説明したこずに加えお、View-> Watchでcurr_stateずstate_cnt倉数の倀を芋るこずができたす。







4番目の䟋は、マむクロコトロヌラヌの8ビットタむマヌTIMER0を䜿甚するこずを目的ずしおいたす。 この䟋では、ポヌトDの6番目のピンに接続された7セグメントむンゞケヌタヌセグメントの1぀が2番目のLEDずしお䜿甚されたす。



 /*  */ #include <ioavr.h> #include <intrinsics.h> #include <ina90.h> /* */ //  #define F_CPU 16000000 //   #define TCNT0_VALUE 99 //    #define T0_TICK_CNT_LIMIT 100 //  #define UINT unsigned int /*  */ //   #define DELAY_US(us) __delay_cycles((F_CPU / 1000000) * (us)); //   #define DELAY_MS(ms) __delay_cycles((F_CPU / 1000) * (ms)); /*   */ //     T0 UINT T0_tick_cnt=0; /*  */ //   void main( void ) { //   //  // 6-   D   DDRD_DDD6 = 1; // 6-   D   "0" PORTD_PORTD6 = 0; //  // 7-   D   DDRD_DDD7 = 1; // 7-   D   "0" PORTD_PORTD7 = 0; //  ( Normal) TCCR0_CS02=1;//   16 000 000  TCCR0_CS01=0;// 16 000 000  / 1024 = 15 625  TCCR0_CS00=1;// 1 / 15 625  = 0,000064  =64  TCNT0 = TCNT0_VALUE; // 156 * 0,000064 c = 0,009984 c (10 ) //      255-156 = 99 TIMSK_TOIE0=1; //      //  _SEI(); //   for(;;) { //     _NOP(); // 6-   D  "0"  "1"   "1"  "0" //    PORTD_PORTD6 ^= 1; //    DELAY_MS(500); }//end for } /*   T0  */ #pragma vector=TIMER0_OVF_vect __interrupt void ISR_TickTimer(void) { //     _NOP(); //    T0 T0_tick_cnt++; //  1  if (T0_tick_cnt >= T0_TICK_CNT_LIMIT) { //    T0 T0_tick_cnt=0; // 7-   D  "0"  "1"   "1"  "0" //    PORTD_PORTD7 ^= 1; } //   //   TCNT0=TCNT0_VALUE; }//end func
      
      







この䟋では、メむン関数で、LEDを蚭定した埌、TCCRO制埡レゞスタのビットを蚭定するこずで構成されるれロタむマヌが蚭定されたす。 なぜなら 通垞のタむマヌモヌドを䜿甚する堎合、ビットWGM00およびWGM01はれロになりたす。 初期倀はすでにれロであるため、それらには觊れたせん。 ビットCS00、CS01、CS02は、16 MHzのクロック呚波数の最倧分呚噚1024を取埗するように蚭定されたす。







分割埌、タむマヌの呚波数は15625 Hzになりたす。これは64ÎŒsのティックに察応したす。 ティックに156156 * 0.000064 c = 0.009984 c = 10ミリ秒を掛けるず、10ミリ秒に最も近くなりたす。 したがっお、10 msごずにオヌバヌフロヌむベントを凊理するための割り蟌み生成を受信するには、レゞスタ99255-156 = 99をカりントTCNT0にロヌドする必芁がありたす。 なぜなら タむマヌは99からカりントを開始し、255に達するず割り蟌みが生成され、156ティックのパスを取埗したす。







さらにこの䟋では、れロタむマヌのオヌバヌフロヌに察する割り蟌みを生成するために、TIMSK割り蟌みマスキングレゞスタのTOIE0ビットが蚭定されたす。 その埌、マクロ関数_SEIを䜿甚しお、すべおのマスクされた割り蟌みのグロヌバルな解決を行いたす。







すべおの割り蟌みベクトルの定矩は、iom16.hヘッダヌファむルにありたす。



 /*==============================*/ /* Interrupt Vector Definitions */ /*==============================*/ /* NB! vectors are specified as byte addresses */ #define RESET_vect (0x00) #define INT0_vect (0x04) #define INT1_vect (0x08) #define TIMER2_COMP_vect (0x0C) #define TIMER2_OVF_vect (0x10) #define TIMER1_CAPT_vect (0x14) #define TIMER1_COMPA_vect (0x18) #define TIMER1_COMPB_vect (0x1C) #define TIMER1_OVF_vect (0x20) #define TIMER0_OVF_vect (0x24) #define SPI_STC_vect (0x28) #define USART_RXC_vect (0x2C) #define USART_UDRE_vect (0x30) #define USART_TXC_vect (0x34) #define ADC_vect (0x38) #define EE_RDY_vect (0x3C) #define ANA_COMP_vect (0x40) #define TWI_vect (0x44) #define INT2_vect (0x48) #define TIMER0_COMP_vect (0x4C) #define SPM_RDY_vect (0x50)
      
      







プログラムのロゞックは、メむンルヌプず割り蟌みハンドラヌの準䞊列動䜜を提䟛するスヌパヌサむクルを備えたシステムの最初の䟋で既に説明されおいたす。 メむンルヌプでは、ポヌトDの6番目のピンが500 msの呚期で切り替えられたす。 メむンルヌプは10ミリ秒ごずに䞭断され、れロタむマヌオヌバヌフロヌによる割り蟌みを凊理したす。 凊理は、このむベントで呌び出されるISR_TickTimerハンドラヌ関数を䜿甚しお実行されたす。 この関数では、倉数T0_tick_cntをむンクリメントするこずにより、10ミリ秒のティックがカりントされたす。 倉数T0_tick_cntが100に達するず぀たり、1秒が経過するず、このむベントはハンドラヌのifステヌトメントを䜿甚しお決定されたす。 その埌、倉数T0_tick_cntはポヌトDのピン7を切り替えたす。これにより、1000ミリ秒の呚期で2番目のLEDが点滅したす。

この䟋をデバッグする堎合、メむンルヌプず割り蟌みハンドラヌの䞡方にブレヌクポむントを蚭定できたす。







5番目の䟋は、䜜業のロゞックによるず、前の䟋ですが、マクロ関数を䜿甚しおいたす。



 /*  */ #include <ioavr.h> #include <intrinsics.h> #include <ina90.h> /* */ //  #define F_CPU 16000000 //    #define DELAY_TIME 500 //     //   #define LED1_DDR DDRD #define LED1_PORT PORTD #define LED1_PIN DDD7 //     //   #define LED2_DDR DDRD #define LED2_PORT PORTD #define LED2_PIN DDD6 //      #define F_CPU_DIV_1 (0<<CS02)|(0<<CS01)|(1<<CS00) #define F_CPU_DIV_8 (0<<CS02)|(1<<CS01)|(0<<CS00) #define F_CPU_DIV_64 (0<<CS02)|(1<<CS01)|(1<<CS00) #define F_CPU_DIV_256 (1<<CS02)|(0<<CS01)|(0<<CS00) #define F_CPU_DIV_1024 (1<<CS02)|(0<<CS01)|(1<<CS00) //     #define TCNT0_VALUE 99 //     #define T0_TICK_CNT_LIMIT 100 //  #define UINT unsigned int /*  */ //    #define LED1_INIT() ( LED1_DDR |= (1<<LED1_PIN) ); //   #define LED1_LOW() ( LED1_PORT &=~ (1<<LED1_PIN) ); //   #define LED1_HIGH() ( LED1_PORT |= (1<<LED1_PIN) ); //   #define LED1_TOG() ( LED1_PORT ^= (1<<LED1_PIN) ); //    #define LED2_INIT() ( LED2_DDR |= (1<<LED2_PIN) ); //   #define LED2_LOW() ( LED2_PORT &=~ (1<<LED2_PIN) ); //   #define LED2_HIGH() ( LED2_PORT |= (1<<LED2_PIN) ); //   #define LED2_TOG() ( LED2_PORT ^= (1<<LED2_PIN) ); //    #define TIMER0_SET_CLK_DIV(x) ( TCCR0 |= x ); //     #define TIMER0_SET_CNT(x) ( TCNT0 = x ); //      #define TIMER0_OVF_INT_ON() ( TIMSK|=(1<<TOIE0) ); //   #define DELAY_US(us) __delay_cycles((F_CPU / 1000000) * (us)); //   #define DELAY_MS(ms) __delay_cycles((F_CPU / 1000) * (ms)); /*   */ //     T0 UINT T0_tick_cnt=0; /*  */ //   void main( void ) { //   //  LED1_INIT(); LED2_INIT(); //  LED1_LOW(); LED2_LOW(); //  ( Normal) TIMER0_SET_CLK_DIV(F_CPU_DIV_1024);//   16 000 000  // 16 000 000  / 1024 = 15 625  // 1 / 15 625  = 0,000064  =64  TIMER0_SET_CNT(TCNT0_VALUE); // 156 * 0,000064 c = 0,009984 c (10 ) //      255-156 = 99 TIMER0_OVF_INT_ON(); //      //  _SEI(); //   for(;;) { //     _NOP(); //   LED1_TOG(); //    DELAY_MS(DELAY_TIME); }//end for } /*   T0  */ #pragma vector=TIMER0_OVF_vect __interrupt void ISR_TickTimer(void) { //     _NOP(); //    T0 T0_tick_cnt++; //  1  if (T0_tick_cnt >= T0_TICK_CNT_LIMIT) { //    T0 T0_tick_cnt=0; //   LED2_TOG(); }//end for //   //   TIMER0_SET_CNT(TCNT0_VALUE); }//end func
      
      







蚭定がマクロTIMER0_SET_CLK_DIVXを甚いお行った堎合を瀺し、コントロヌルのビットは、れロTCCROタむマレゞスタ、呚波数を分割しおクロック定矩F_CPU_DIV_1、F_CPU_DIV_8、F_CPU_DIV_64、F_CPU_DIV_256、F_CPU_DIV_1024のセットから遞択される方法を決定する匕数x。 初期倀は、マクロ関数TIMER0_SET_CNTxを䜿甚しおアカりントレゞスタTCNT0に蚘録されたす。匕数xは初期倀そのものですこの堎合、TCNT0_VALUE = 99。 TIMSK割り蟌みマスクレゞスタのTOIE0ビットの蚭定は、マクロ関数TIMER0_OVF_INT_ONを䜿甚しお実行されたす。

IARプロゞェクトの圢匏のすべおの䟋は、 ここからダりンロヌドできたす 。



おわりに



この投皿に関心がある堎合は、次のパヌトでは、内蔵ADCである7セグメントでの䜜業䟋を怜蚎したす。 その埌、デゞタル枩床蚈の゜フトりェアプロゞェクトで怜蚎したすべおの䟋を収集したす。



加算



IARで蚘述されたプログラムの16進ファむルを取埗する必芁がある堎合、これを行うこずはたったく難しくありたせん。 以䞋のスクリヌンショットのように、蚭定を行うには、[リンカヌ]-> [出力]タブおよび[リンカヌ]-> [远加出力]タブのプロゞェクト蚭定で十分です。 その埌、サブフォルダヌ[プロゞェクト名] \ Debug \ ExeでProject-> Rebuild Allをクリックしおプロゞェクトをリビルドするず、hexファむルが芋぀かりたす。 AVR910プログラマヌ、STK500クロヌン、たたは他の利甚可胜なプログラマヌで瞫うこずができたす。










All Articles