秋月電子のLEDマトリックス表示装置を使って、ポータブル・ゲーム・システムを 作りました。
電池駆動ですから、ポータブルですよ。
部品番号 | 品名 | 規格 | 個数 | メーカ | 調達先 |
---|---|---|---|---|---|
U1 | マイコン | MC9S08QG8CPB | 1 | Freescale | digi-key |
U2 | 汎用ロジック | 74HCT04 | 1 | 東芝 | 梅澤無線 |
U3 | 3端子レギュレータ | TA48M033 | 1 | 東芝 | 秋月電子 |
- | ICソケット | 14P DIP | 1 | - | 秋月電子 |
- | ICソケット | 16P DIP | 1 | - | 秋月電子 |
- | 32×16ドットLEDマトリックス表示装置パーツセット | K-00798 | 1 | - | 秋月電子 |
R1 | カーボン抵抗 | 1.0kΩ 1/4W | 1 | KOA | 秋月電子 |
R2 | カーボン抵抗 | 2.2kΩ 1/4W | 1 | KOA | 秋月電子 |
R3, R4, R5, R6 | カーボン抵抗 | 100Ω 1/4W | 1 | KOA | 秋月電子 |
R7 | カーボン抵抗 | 10kΩ 1/4W | 1 | KOA | 秋月電子 |
C1, C4 | アルミ電解コンデンサ | 100µF 25V | 2 | Ruby-con | マルツパーツ |
C2, C5, C6, C7 | 積層セラミックコンデンサ | 0.1µF 50V | 4 | ムラタ製作所 | 秋月電子 |
C3 | 積層セラミックコンデンサ | 0.33µF 50V | 1 | ムラタ製作所 | 秋月電子 |
SW1 | 押しボタンスイッチ | DP1-120 | 1 | フジソク | 梅澤無線 |
VR1 | 可変抵抗器 | 10kΩ B 16φ | 1 | - | 梅澤無線 |
- | ツマミ | - | 1 | - | 梅澤無線 |
CN4 | ターミナル・ブロック | 2P | 1 | - | 秋月電子 |
PS1 | 圧電スピーカ | PS1740 | 1 | TDK | digi-key |
HD1 | ボックス・ピン・ヘッダ | 2×3 | 1 | - | ダイセン電子 |
- | 片面ユニバーサル基板 | ICB-96G | 1 | サンハヤト | - |
- | ワッシャつきなべビス | 3mm×10mm | 4 | - | 廣杉計器 |
- | スペーサ | M3 15mm | 4 | - | 廣杉計器 |
このアプリケーションは、表示装置として秋月電子でキットとして販売されている 32×16ドットの表示装置を流用しました。 このキットは、48ビットのデータを16ビットずつ3系統のシリアルデータとして 送受信するように設計されています。
もちろん、このまま使用することも出来ますが、 このインターフェースを使用するときには、以下の問題点が有ります。
どちらも、16ピンのMC9S08QG8を使用するときには大きな問題になります。 そこで、表示装置の配線を工夫して、データ線を完全に直列にしました。
キットでは、3本のデータ出力端子が装備されているので、 そのうちの2本をキットの入力端子に戻してやります。 こうすると、マイコンからは48ビットの1本のシリアルインターフェースとして見る事ができます。 完全なシリアル・インターフェースは、 Serial Peripheral Interface (SPI) モジュールを使用してデータの送信を行うことができます。 そのため、ソフトウェア処理のオーバヘッドが減少し、パフォーマンスの向上が期待できます。
LED表示装置は5Vの電源を必要としますが、 マイコンの最大電源電圧は3.6Vです。 このギャップを埋めるために、74HCT04という5V電源で動作する TTLレベル信号対応の汎用ロジックICを使って、 インターフェースを作成しました。
74HCT04を使ったインターフェースは、マイコンから表示装置への一方通行になります。 表示装置からのシリアル出力を受け取るなどの反対方向のインターフェースでは、 74HC4049という入力端子からVCCへの保護ダイオードを省略したICを使用することができます。 今回は、表示装置にデータを送信するだけなので、反対方向のインターフェースは実装していません。
このアプリケーションでは、5Vの電源のみを取り入れて動作しており、 マイコンで必要な3.3Vの電源は、基板上のTA48033Sで作っています。
このアプリケーションは、ProcessorExpertを基本として作成されていますが、 それだけではゲームに必要なリアルタイムアプリケーションには出来ませんでした。 リアルタイムアプリケーションとするために、 MC9S08QG8に搭載されているSPIモジュールを利用し、ソフトウェアの負担を減らしました。 また、PWMを直接操作することにより、PWM周期を計算するためのオーバヘッドを削減しました。
それでも、なお、基本的な部分はProcessorExpertを利用して記述されているので、 理解のしやすいソフトウェアになっています。
/** ################################################################### ** Filename : LedMat.C ** Project : LedMat ** Processor : MC9S08QG8CPB ** Compiler : CodeWarrior HCS08 C Compiler ** ###################################################################*/ /* MODULE LedMat */ /* Including used modules for compiling procedure */ #include "Cpu.h" #include "Events.h" #include "SM1.h" #include "Strobe.h" #include "Latch.h" #include "TI1.h" #include "Pot.h" #include "Shoot.h" #include "Tpm.h" /* Include shared modules, which are used for whole project */ #include "PE_Types.h" #include "PE_Error.h" #include "PE_Const.h" #include "IO_Map.h"
#pragma DATA_SECTION SHORT MY_ZEROPAGE //================================================================ // Multiple purpose flag register. // All boolean varibales are combined into a structure and // assigned to a SHORT addressing segment to reduce RAM // area and codes. // // target_exhausted : // indicates if all TARGET objects are gone. // action_requested : // indicates an ACTION is expected by periodic timer event. // music_played : // indicates a MUSIC is played. // hit : // indicates a bullet reached to the ceil. //================================================================ struct Flag { bool target_exhausted:1; bool action_requested:1; bool music_played:1; bool hit:1; } flag; #pragma DATA_SECTION DEFAULT
//================================================================ // State machine management. //================================================================ #pragma DATA_SECTION SHORT MY_ZEROPAGE //---------------------------------------------------------------- // Global variables for State-Machine. // // action : // STATE object for game sequence state-machine. //---------------------------------------------------------------- void (*action)(void); #pragma DATA_SECTION DEFAULT
//================================================================ // Random Number Generator //================================================================ #pragma DATA_SECTION SHORT MY_ZEROPAGE //---------------------------------------------------------------- // Global variables for Random number generator. // // n_rand : // Random number register is implemented as a 16-bit // counter. //---------------------------------------------------------------- word n_rand; #pragma DATA_SECTION DEFAULT
//================================================================ // Sono object management. //================================================================ //---------------------------------------------------------------- // Structure Sono describing a piece of sound. //---------------------------------------------------------------- typedef struct { byte count; // Length of Sono word period; // Period parameter for PWM. } Sono; #pragma DATA_SECTION SHORT MY_ZEROPAGE //-------------------------------------------------------- // Global variables for SONO object manager. // // Following variables are used by the SONO manager // and never used by user program immediately. // User programs should use METHODs, like sono_queue() // and sono_disable(). // // sono_count : // Number of ticks left for current SONO. // 0 - No SONO executed. // 255 - Current SONO has infinite length. // sono_queue : // Sono in the QUEUE. //-------------------------------------------------------- byte sono_count; Sono sono_queue; #pragma DATA_SECTION DEFAULT //---------------------------------------------------------------- // sono_dispatch : // Dispatch a Sono object management. This function is // typically invoked by the periodical timer event handler. //---------------------------------------------------------------- void sono_dispatch(void) { // Update PWM period if requested. if ((sono_count == 0) || (sono_count == 255)) { // If currently played Sono completed, // check queue status. if (sono_queue.count > 0) { // Accept queue if exists. TPMMOD = sono_queue.period - 1; // Set period TPMC0V = sono_queue.period / 2; // Set duty to 50% sono_count = sono_queue.count; // Set SONO timer sono_queue.count = 0; // Reset the queue } else { // Stop SONO TPMC0V = TPMMOD; // Set duty to 0% } } // ignore infinite length if (sono_count == 255) return; // Stop SONO at last tick if a MUSIC played. if (flag.music_played && sono_count == 1) { // Stop SONO TPMC0V = TPMMOD; // Set duty to 0% } // Decrement SONO timer sono_count--; } //---------------------------------------------------------------- // sono_queue_in : // Queue in line a Sono object. // // Parameter: // sono : // Pointer to a SONO object to be queued in. // Returns: // TRUE if the SONO object is accepted to QUEUE. // FaLSE if the QUEUE buffer is full. //---------------------------------------------------------------- bool sono_queue_in(const Sono *sono){ bool result; // No interrupt allowed to protect QUEUE buffer. Cpu_DisableInt(); if (sono_queue.count == 0) { // Add into queue if queue is empty. sono_queue = *sono; result = TRUE; } else { // Queue is full. result = FALSE; } Cpu_EnableInt(); return result; } //---------------------------------------------------------------- // sono_disable : // Disable SONO currently played and discard SONO in queue. //---------------------------------------------------------------- void sono_disable(void) { // No interrupt allowed to protect QUEUE buffer. Cpu_DisableInt(); TPMC0V = TPMMOD; // Set duty to 0% to stop SONO sono_count = 0; // Discard currently played SONO sono_queue.count = 0; // Discard SONO in QUEUE. Cpu_EnableInt(); }
//================================================================ // MUSIC object management. //================================================================ #pragma DATA_SECTION SHORT MY_ZEROPAGE //---------------------------------------------------------------- // Variables for MUSIC object manager. // A MUSIC is described as a list of Sono. // // music_score : // Pointer to a MUSIC currently played. // music_index : // Index counter to indicating a Sono. //---------------------------------------------------------------- const Sono * music_score; byte music_index; #pragma DATA_SECTION DEFAULT //---------------------------------------------------------------- // music_init : // Initialize the MUSIC dispatcher. // // Parameter: // score : // Pointer to a MUSIC score to be played. //---------------------------------------------------------------- void music_init(const Sono *score) { // Initialize global variables. music_score = score; music_index = 0; // Set music_played flag to make a MUSIC oriented SONO. flag.music_played = TRUE; } //---------------------------------------------------------------- // music_dispatch : // Dispatch function to play a MUSIC score. // This function is onvoked by the ACTION states periodically. //---------------------------------------------------------------- void music_dispatch(void) { if (music_score) { // Play MUSIC if a music_score specified. // Queue a SONO in score. if (sono_queue_in(&music_score[music_index])) { // Increment index if the SONO was accepted. music_index++; // Rewind the MUSIC index if a STOP code detected. if (music_score[music_index].count == 0) { music_index = 0; } } } }
//================================================================ // MUSIC Score // MUSIC scores are described as an array of SONO object. //================================================================ //---------------------------------------------------------------- // Period parameter for music score. //---------------------------------------------------------------- const word P_3Fis = 8000000 / 740; const word P_3Gis = 8000000 / 831; const word P_3A = 8000000 / 880; const word P_3H = 8000000 / 988; const word P_4Cis = 8000000 / 1109; const word P_4D = 8000000 / 1175; const word P_4E = 8000000 / 1319; const word P_4Fis = 8000000 / 1480; const word P_4Gis = 8000000 / 1661; const word P_4A = 8000000 / 1760; //---------------------------------------------------------------- // Piano Sonate K331, Mozart //---------------------------------------------------------------- const Sono sonate[] = { 24, P_4Cis, // DO# 8, P_4D, // RE 16, P_4Cis, // DO# 32, P_4E, // MI 16, P_4E, // MI 24, P_3H, // SI 8, P_4Cis, // DO# 16, P_3H, // SI 32, P_4D, // RE 16, P_4D, // RE 32, P_3A, // RA 16, P_3A, // RA 32, P_3H, // SI 16, P_3H, // SI 32, P_4Cis, // DO# 8, P_4E, // MI 8, P_4D, // RE 32, P_4Cis, // DO# 16, P_3H, // SI 24, P_4Cis, // DO# 8, P_4D, // RE 16, P_4Cis, // DO# 32, P_4E, // MI 16, P_4E, // MI 24, P_3H, // SI 8, P_4Cis, // DO# 16, P_3H, // SI 32, P_4D, // RE 16, P_4D, // RE 32, P_3A, // RA 16, P_3H, // SI 32, P_4Cis, // DO# 16, P_4D, // RE 32, P_4Cis, // DO# 16, P_3H, // SI 32, P_3A, // RA 16, 0, // - 24, P_4E, // MI 8, P_4Fis, // FA# 16, P_4E, // MI 32, P_4Fis, // FA# 16, P_4Fis, // FA# 4, P_4Fis, // FA# 4, P_4Gis, // SO# 16, P_4A, // RA 8, P_4Gis, // SO# 16, P_4Fis, // FA# 16, P_4Fis, // FA# 16, P_4E, // MI 16, P_4E, // MI 16, P_4E, // MI 16, P_4Cis, // DO# 16, P_3A, // RA 16, P_4E, // MI 16, P_4D, // RE 16, P_3H, // SI 16, P_4E, // MI 16, P_4Cis, // DO# 16, P_3A, // RA 32, P_4Cis, // DO# 16, P_3H, // SI 24, P_4Cis, // DO# 8, P_4D, // RE 16, P_4Cis, // DO# 32, P_4E, // MI 16, P_4E, // MI 24, P_3H, // SI 8, P_4Cis, // DO# 16, P_3H, // SI 32, P_4D, // RE 16, P_4D, // RE 32, P_3A, // RA 16, P_3H, // SI 32, P_4Cis, // DO# 16, P_4D, // RE 32, P_4Cis, // DO# 16, P_3H, // SI 32, P_3H, // SI 16, P_4Cis, // DO# 32, P_4Cis, // DO# 16, P_4D, // RE 32, P_4E, // MI 8, P_4Fis, // FA# 4, P_4Gis, // SO# 4, P_4A, // RA 32, P_3A, // RA 8, P_4Cis, // DO# 8, P_3H, // SI 32, P_3A, // RA 16, 0, // - 0, 0 // STOP }; //---------------------------------------------------------------- // Dash!! noritan.org //---------------------------------------------------------------- const Sono dash[] = { 8, P_3Fis, // FA# 8, P_3Fis, // FA# 8, P_3A, // RA 8, P_3A, // RA 8, P_3Fis, // FA# 8, P_3Fis, // FA# 8, P_3A, // RA 8, P_3A, // RA 8, P_3Fis, // FA# 8, P_3Fis, // FA# 8, P_3A, // RA 16, P_4D, // RE 8, P_4Cis, // DO# 8, P_3H , // SI 8, P_3A, // RA 8, P_3Fis, // FA# 8, P_3Fis, // FA# 8, P_3A, // RA 8, P_3A, // RA 8, P_3Fis, // FA# 8, P_3Fis, // FA# 8, P_3A, // RA 8, P_3A, // RA 8, P_3Fis, // FA# 8, P_3Fis, // FA# 8, P_3A, // RA 16, P_4D, // RE 8, P_4Cis, // DO# 8, P_3H , // SI 8, P_4Cis, // DO# 8, P_3H , // SI 8, P_3H , // SI 8, P_4D, // RE 8, P_4D, // RE 8, P_3H , // SI 8, P_3H , // SI 8, P_4D, // RE 8, P_4D, // RE 8, P_3H , // SI 8, P_3H , // SI 8, P_4D, // RE 16, P_4Fis, // FA# 8, P_4E , // MI 8, P_4D, // RE 8, P_4Cis, // DO# 8, P_4Cis, // DO# 8, P_4Cis, // DO# 8, P_3H , // SI 8, P_3H , // SI 8, P_4Cis, // DO# 8, P_4Cis, // DO# 8, P_3H , // SI 8, P_3H , // SI 8, P_4D, // RE 8, P_4Cis, // DO# 8, P_3H , // SI 16, P_4D, // RE 8, P_4Cis, // DO# 8, P_3H , // SI 8, P_3A, // RA 0, 0 // STOP };
//================================================================ // SPI communication manager. //================================================================ #pragma DATA_SECTION SHORT MY_ZEROPAGE //---------------------------------------------------------------- // Global variables for SPI communication. // // These variables are not directly controlled by user // programs because all SPI requests are invoked by // METHODs. // // spi_size : // Number of data bytes sent by SPI module. This value // indicates how many bytes should be received by SPI // module too. // spi_callback : // A callback function executed when an expected size // of data received by SPI module. //---------------------------------------------------------------- word spi_size; void (*spi_callback)(bool); #pragma DATA_SECTION DEFAULT //---------------------------------------------------------------- // spi_start : // Method to start a SPI transfer. // // Parameter: // tx_data : // Pointer to data to be sent by SPI module. // size : // The number of bytes to be sent by SPI module. // callback : // A callback function to be invoked when a transfer // completed or failed. //---------------------------------------------------------------- void spi_start( byte * tx_data, byte size, void (*callback)(bool) ) { byte err_code; word n_sent; // Flush TX/RX buffers. (void)SM1_ClearRxBuf(); (void)SM1_ClearTxBuf(); // Register the size of data and the callback function. spi_size = size; spi_callback = callback; // Start a SPI communication to send a data block err_code = SM1_SendBlock(tx_data, size, &n_sent); // Confirm error code if (err_code == ERR_OK) { // Block accepted successfully. if (n_sent != size) { // Size mismatch - abort transfer. (void)SM1_ClearTxBuf(); } } else { // Error reported - abort transfer. (void)SM1_ClearTxBuf(); } } //---------------------------------------------------------------- // spi_OnRxChar : // // An interrupt handler invoked when a byte of data // received by SPI module. A callback function specified // by user programs is executed with an argument FALSE // to indicate successful transfer when expected size // of data are received. //---------------------------------------------------------------- void spi_OnRxChar(void) { if (SM1_GetCharsInRxBuf() >= spi_size) { // Received data is larger than expected. (*spi_callback)(FALSE); } } //---------------------------------------------------------------- // spi_OnError : // // An interrupt handler invoked when error were detected // by SPI module. A callback function specified by user // programs is executed with an argument TRUE to indicate // illegal transfer. //---------------------------------------------------------------- void spi_OnError(void) { (*spi_callback)(TRUE); }
//================================================================ // LED Display controller //================================================================ #pragma DATA_SECTION SHORT MY_ZEROPAGE //---------------------------------------------------------------- // Global variables for LED display. // // fb : // Frame buffer of LED display. 64 bytes of memory array // describes the state of 512 LEDs. // led_tx : // A packet to be sent to matrix LED display by SPI module. //---------------------------------------------------------------- byte fb[64]; byte led_tx[6]; #pragma DATA_SECTION DEFAULT //---------------------------------------------------------------- // Table array for LED display. // These tables are assigned as CONST and placed on ROM. // // bit_pattern[] : // Look-up table to calculate (1 << (7-n)) // bit_pattern_r[] : // Look-up table to calculate (1 << (n)) //---------------------------------------------------------------- const byte bit_pattern[] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }; const byte bit_pattern_r[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }; //---------------------------------------------------------------- // led_display : // Method to invoke a SPI transfer driving a ROW. // // Parameter: // row : // The ROW number to be driven. No LEDs driven when // row is larger than or equal to 16. //---------------------------------------------------------------- void led_display(byte row) { // Callback function for LED packet transfer. void led_display_cb(bool); // Index base for the ROW in fb array. byte index = row * 4; if (row < 16) { // Copy a row in fb array into led_tx buffer. led_tx[0] = fb[index + 3]; led_tx[1] = fb[index + 2]; led_tx[2] = fb[index + 1]; led_tx[3] = fb[index + 0]; // Select a row. if (row < 8) { // Upper half case. led_tx[4] = bit_pattern_r[row]; led_tx[5] = 0; } else { // Lower half case. led_tx[4] = 0; led_tx[5] = bit_pattern_r[row - 8]; } } else { // Blanking period - no ROW selected. led_tx[4] = 0; led_tx[5] = 0; } // Send a SPI transfer. spi_start(led_tx, 6, led_display_cb); } //---------------------------------------------------------------- // led_display_cb : // Callback function when a transfer for LED display // completed. // // Parameter: // error : // TRUE if the SPI transfer was failed and FALSE if the // SPI transfer is successfully completed. //---------------------------------------------------------------- void led_display_cb(bool error) { if (!error) { // Drop unnecessary received data. (void)SM1_ClearRxBuf(); // Toggle LATCH signal to drive LEDs. Latch_SetVal(); Latch_ClrVal(); // Set STROBE signal to enable LED drivers. Strobe_SetVal(); } else { // Drop characters in buffer. (void)SM1_ClearRxBuf(); } } //---------------------------------------------------------------- // pset : // Low-level function to set a pixel on frame buffer. // // Parameter: // x, y : // Position of a pixel to be set. //---------------------------------------------------------------- void pset(byte x, byte y) { fb[((y & 15) << 2) + ((x & 31) >> 3)] |= bit_pattern[x & 7]; } //---------------------------------------------------------------- // pclr : // Low-level function to clear a pixel on frame buffer. // // Parameter: // x, y : // Position of a pixel to be cleared. //---------------------------------------------------------------- void pclr(byte x, byte y) { fb[((y & 15) << 2) + ((x & 31) >> 3)] &= ~bit_pattern[x & 7]; } //---------------------------------------------------------------- // fb_clear : // Clear specified ROWs. // // Parameter: // row_start : // The upper-most ROW to be cleared. // row_count : // The number of ROWs to be cleared. //---------------------------------------------------------------- void fb_clear( const byte row_start, const byte row_count ) { // Index base for the ROW in fb array. byte index = row_start * 4; byte i; for (i = 0; i < row_count; i++) { fb[index++] = 0; fb[index++] = 0; fb[index++] = 0; fb[index++] = 0; } } //---------------------------------------------------------------- // fb_shiftLeft : // Shift left specified row in the frame buffer. // // Parameter: // row_start : // The upper-most ROW to be shifted. // row_count : // The number of ROWs to be shifted. //---------------------------------------------------------------- void fb_shiftLeft( const byte row_start, const byte row_count ) { // Index base for the ROW in fb array. byte index = row_start * 4; byte row; byte data; for (row = 0; row < row_count; row++) { /* __asm { clrh ldx index asl @fb+0,X rol @fb+1,X rol @fb+2,X rol @fb+3,X } */ data = fb[index + 0] << 1; if (fb[index + 1] & 128) { data++; } fb[index + 0] = data; data = fb[index + 1] << 1; if (fb[index + 2] & 128) { data++; } fb[index + 1] = data; data = fb[index + 2] << 1; if (fb[index + 3] & 128) { data++; } fb[index + 2] = data; fb[index + 3] <<= 1; index += 4; } }
//================================================================ // MESSAGE object management. //================================================================ #pragma DATA_SECTION SHORT MY_ZEROPAGE //---------------------------------------------------------------- // Global variables for message manager. // These variables are used by both 11 and 7 points fonts. // // message_table : // Pointer to a MESSAGE currently displayed. // message_index : // Index indicating a character in a message. // message_char : // Index indicating a character in a font list. // message_column : // Index indicating a pixel column in a font. //---------------------------------------------------------------- const byte * message_table; byte message_index; byte message_char; byte message_column; #pragma DATA_SECTION DEFAULT //---------------------------------------------------------------- // message_init : // Initialize the MESSAGE dispatcher to start a message // stream. // // Parameter: // message : // Pointer to a MESSAGE. //---------------------------------------------------------------- void message_init(const byte *message) { message_table = message; message_index = 0; message_column = 0; } //---------------------------------------------------------------- // fonts11[][] : // 10cols X 11rows font data table. // A character consists of 10 WORD data. The first WORD // of a character describes the left side pixel. The LSB // of the WORD describes the lower pixel. //---------------------------------------------------------------- const word fonts11[][10] = { 0x3fe, 0x7ff, 0x7ff, 0x401, 0x401, 0x401, 0x401, 0x7ff, 0x7ff, 0x3fe, // 0 0x001, 0x401, 0x401, 0x7ff, 0x7ff, 0x7ff, 0x7ff, 0x001, 0x001, 0x001, // 1 0x39f, 0x79f, 0x79f, 0x411, 0x411, 0x411, 0x411, 0x7f1, 0x7f1, 0x3e1, // 2 0x39e, 0x79f, 0x79f, 0x421, 0x421, 0x421, 0x421, 0x7ff, 0x7ff, 0x3de, // 3 0x0fc, 0x1fc, 0x3fc, 0x604, 0x404, 0x7ff, 0x7ff, 0x7ff, 0x004, 0x004, // 4 0x7ce, 0x7cf, 0x7cf, 0x441, 0x441, 0x441, 0x441, 0x47f, 0x47f, 0x43e, // 5 0x3fe, 0x7ff, 0x7ff, 0x421, 0x421, 0x421, 0x421, 0x7bf, 0x7bf, 0x39e, // 6 0x700, 0x700, 0x700, 0x400, 0x41f, 0x43f, 0x47f, 0x7e0, 0x7c0, 0x780, // 7 0x3de, 0x7ff, 0x7ff, 0x421, 0x421, 0x421, 0x421, 0x7ff, 0x7ff, 0x3de, // 8 0x3ce, 0x7ef, 0x7ef, 0x421, 0x421, 0x421, 0x421, 0x7ff, 0x7ff, 0x3fe, // 9 0x0ff, 0x3ff, 0x3ff, 0x710, 0x410, 0x410, 0x710, 0x3ff, 0x3ff, 0x0ff, // A 0x401, 0x7ff, 0x7ff, 0x7ff, 0x401, 0x401, 0x401, 0x7ff, 0x3fe, 0x1fc, // D 0x401, 0x7ff, 0x7ff, 0x7ff, 0x421, 0x421, 0x471, 0x471, 0x603, 0x603, // E 0x7ff, 0x7ff, 0x7ff, 0x020, 0x020, 0x020, 0x020, 0x7ff, 0x7ff, 0x7ff, // H 0x000, 0x000, 0x401, 0x7ff, 0x7ff, 0x7ff, 0x7ff, 0x401, 0x000, 0x000, // I 0x7ff, 0x7ff, 0x3ff, 0x180, 0x0c0, 0x0c0, 0x180, 0x3ff, 0x7ff, 0x7ff, // M 0x7ff, 0x7ff, 0x7ff, 0x420, 0x430, 0x438, 0x43c, 0x7ef, 0x7c7, 0x383, // R 0x3ce, 0x7ef, 0x7ef, 0x421, 0x421, 0x421, 0x421, 0x7bf, 0x7bf, 0x39e, // S 0x600, 0x400, 0x400, 0x7ff, 0x7ff, 0x7ff, 0x7ff, 0x400, 0x400, 0x600, // T 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000 // blank }; //---------------------------------------------------------------- // message_11_dispatch : // Dispatch function to draw a column of a character // representing by fonts11[] table. // // Parameter: // row_start : // The upper-most ROW number to draw a character. //---------------------------------------------------------------- void message_11_dispatch(const byte row_start) { word msg_data; word mask; byte row; // Select a character to be drawn. if (message_column == 0) { // Load a new character if left-most pixel selected. if (message_table[message_index] == 255) { // Rewind index value to ZERO. message_index = 0; } // Get a character from message. message_char = message_table[message_index++]; } // Prepare a column data to be drawn in msg_data. if (message_column < 10) { msg_data = fonts11[message_char][message_column]; } else { // Set blank pixel as gap between characters. msg_data = 0; } // Draw a pixel pattern. // Set a pixel if set in character font. mask = 1 << (11 - 1); for (row = 0; row < 11; row++) { if (msg_data & mask) { pset(31, row + row_start); } mask >>= 1; } // Revert pixel column index to left-most. if (++message_column >= 12) { message_column = 0; } } //---------------------------------------------------------------- // fonts7[][] : // 7cols X 7rows font data table. // A character consists of 7 BYTE data. The first BYTE // of a character describes the left side pixel. The LSB // of the BYTE describes the lower pixel. //---------------------------------------------------------------- const byte fonts7[][7] = { 0x3e, 0x7f, 0x41, 0x41, 0x41, 0x7f, 0x3e, // 0 0x00, 0x00, 0x21, 0x7f, 0x7f, 0x01, 0x00, // 1 0x23, 0x67, 0x4d, 0x49, 0x49, 0x79, 0x31, // 2 0x22, 0x63, 0x49, 0x49, 0x49, 0x7f, 0x36, // 3 0x1e, 0x3e, 0x62, 0x42, 0x7f, 0x7f, 0x02, // 4 0x7a, 0x7b, 0x49, 0x49, 0x49, 0x4f, 0x06, // 5 0x3e, 0x7f, 0x49, 0x49, 0x49, 0x6f, 0x26, // 6 0x60, 0x60, 0x40, 0x47, 0x4f, 0x78, 0x70, // 7 0x36, 0x7f, 0x49, 0x49, 0x49, 0x7f, 0x36, // 8 0x32, 0x7b, 0x49, 0x49, 0x49, 0x7f, 0x3e, // 9 0x7f, 0x3f, 0x10, 0x08, 0x10, 0x3f, 0x7f, // M 0x00, 0x00, 0x41, 0x7f, 0x7f, 0x41, 0x00, // I 0x32, 0x7b, 0x49, 0x49, 0x49, 0x6f, 0x26, // S 0x7f, 0x7f, 0x49, 0x49, 0x49, 0x41, 0x41, // E 0x7f, 0x7f, 0x41, 0x41, 0x63, 0x3e, 0x1c, // D 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // blank }; //---------------------------------------------------------------- // message_7_dispatch : // Dispatch function to draw a column of a character // representing by fonts7[] table. // // Parameter: // row_start : // The upper-most ROW number to draw a character. //---------------------------------------------------------------- void message_7_dispatch(const byte row_start) { byte msg_data; byte mask; byte row; // Select a character to be drawn. if (message_column == 0) { // Load a new character if left-most pixel selected. if (message_table[message_index] == 255) { // Rewind index value to ZERO. message_index = 0; } // Get a character from message. message_char = message_table[message_index++]; } // Prepare a column data to be drawn in msg_data. if (message_column < 7) { msg_data = fonts7[message_char][message_column]; } else { // Set blank pixel as gap between characters. msg_data = 0; } // Draw a pixel pattern. // Set a pixel if set in character font. mask = 1 << (7 - 1); for (row = 0; row < 7; row++) { if (msg_data & mask) { pset(31, row + row_start); } mask >>= 1; } // Revert pixel column index to left-most. if (++message_column >= 8) { message_column = 0; } }
//================================================================ // ACTION control functions. //================================================================ //---------------------------------------------------------------- // request_action : // An ACTION requested by a periodical timer. // This function is typically invoked by a timer event // handler to set the action_requested flag. The main // function executes an ACTION when the flag is set. //---------------------------------------------------------------- void request_action(void) { flag.action_requested = TRUE; }
//================================================================ // TARGET object management. //================================================================ //---------------------------------------------------------------- // Constant declarations. // // MAX_TARGET : // Maximum number of TARGETs on the screen. // TARGET_PER_STAGE : // Number of TARGETs appears on a stage. // TARGET_INTERVAL : // Interval time of TARGET constructions. // TARGET_TIMER_OVERFLOW : // Timer count causing OVERFLOW. // TARGET_TIMER_EXPLODE : // Timer count to finish explosion. //---------------------------------------------------------------- #define MAX_TARGET (12) const byte TARGET_PER_STAGE = 40; const byte TARGET_INTERVAL = 13; const byte TARGET_TIMER_OVERFLOW = 80; const byte TARGET_TIMER_EXPLODE = 30; //---------------------------------------------------------------- // Type definition of the TARGET status enumeration. // // TARGET_NONE : // TARGET is not on the screen. // TARGET_ALIVE : // TARGET is on the screend and moving. // TARGET_EXPLODE : // TARGET is now exploding. //---------------------------------------------------------------- typedef enum { TARGET_NONE = 0, TARGET_ALIVE = 1, TARGET_EXPLODE = 2 } TargetStatus; //---------------------------------------------------------------- // Property structure describing a TARGET. // // status : TargetStatus // Status of the TARGET. // timer : // TARGET specific timer counter. // speed : // Speed of the TARGET move. // x, y : // Position of the TARGET. //---------------------------------------------------------------- typedef struct { TargetStatus status; byte timer; byte speed; byte x; byte y; } Target; Target targets[MAX_TARGET]; #pragma DATA_SECTION SHORT MY_ZEROPAGE //---------------------------------------------------------------- // Global variables for TARGET management. // // target_count : // Number of TARGETs had been constructed. // target_missed : // Number of TARGETs missed and gone. // target_on_stage : // Number of TARGETs ib the screen. // target_construct_timer : // Timer counter for TARGET construction. //---------------------------------------------------------------- byte target_count; byte target_missed; byte target_on_screen; byte target_construct_timer; #pragma DATA_SECTION DEFAULT //---------------------------------------------------------------- // target_draw : // Draw a TARGET on the frame buffer. // // Parameter: // target : // Pointer to a TARGET object. //---------------------------------------------------------------- void target_draw(const Target *target) { byte x = target->x; byte y = target->y; // Set 3 pixels pset(x + 0, y); pset(x + 1, y); pset(x + 2, y); } //---------------------------------------------------------------- // target_wipe : // Wipe a TARGET on the frame buffer. // // Parameter: // target : // Pointer to a TARGET object. //---------------------------------------------------------------- void target_wipe(const Target *target) { byte x = target->x; byte y = target->y; // Clear 3 pixels pclr(x + 0, y); pclr(x + 1, y); pclr(x + 2, y); } //---------------------------------------------------------------- // target_destructAll : // Destruct all TARGET objects. //---------------------------------------------------------------- void target_destructAll(void) { byte id; for (id = 0; id < MAX_TARGET; id++) { targets[id].status = TARGET_NONE; } target_on_screen = 0; } //---------------------------------------------------------------- // target_destruct : // Destruct a specified TARGET objects. //---------------------------------------------------------------- void target_destruct(Target *target) { if (target->status != TARGET_NONE) { target->status = TARGET_NONE; target_on_screen--; } } //---------------------------------------------------------------- // target_construct : // Construct a TARGET object if possible. // // Returns: // TRUE if a TARGET is successfully constructed, // or FALSE if failed to construction. //---------------------------------------------------------------- bool target_construct(void) { byte id; Target *target; for (id = 0; id < MAX_TARGET; id++) { // Find an empty slot. if (targets[id].status == TARGET_NONE) { // Initialize a TARGET object. target = &targets[id]; target->status = TARGET_ALIVE; target->x = 29; target->y = (n_rand & 7) + 1; target->speed = ((n_rand >> 3) & 15) + 10; target->timer = 0; // Increment count of TARGET constructed. target_count++; target_on_screen++; // Return TRUE on success. return TRUE; } } // Return FALSE on fail. return FALSE; } //---------------------------------------------------------------- // explode_sono : // An object to make an explosion SONO. //---------------------------------------------------------------- const Sono explode_sono = { 10, 53000 }; //---------------------------------------------------------------- // target_explode : // Start an explosion sequence of a TARGET. //---------------------------------------------------------------- void target_explode(Target *target) { // Initialize timer counter. target->timer = 0; // Update the state. target->status = TARGET_EXPLODE; // Start an explosion SONO. (void)sono_disable(); (void)sono_queue_in(&explode_sono); } //---------------------------------------------------------------- // target_action : // Typical ACTION of a TARGET object. // // Parameter: // target : // Pointer to a TARGET object. //---------------------------------------------------------------- void target_action(Target *target) { switch (target->status) { case TARGET_ALIVE: // TARGET is moving on the screen. target->timer += target->speed; if (target->timer > TARGET_TIMER_OVERFLOW) { // Individual timer cause OVERFLOW. target->timer -= TARGET_TIMER_OVERFLOW; // wipe TARGET to move target_wipe(target); if (target->x > 0) { // Check the position of TARGET. // Move left the TARGET if still on the screen. (target->x)--; // Draw a TARGET at new position. target_draw(target); } else { // The TARGET is gone. target_missed++; // Increment MISSED counter. // Destruct the TARGET. target_destruct(target); } } else { // Redraw the TARGET to refresh. target_draw(target); } break; case TARGET_EXPLODE: // TARGET is exploding. if (target->timer & 1) { // Draw TARGET if the timer counter is ODD target_draw(target); } else { // Wipe TARGET if the timer counter is EVEN target_wipe(target); } // Check if the explosion time finished. if (++(target->timer) > TARGET_TIMER_EXPLODE) { // Wipe TARGET certainly target_wipe(target); // Destruct the TARGET object. target_destruct(target); } case TARGET_NONE: default: // Nothing to do for TARGET out of screen. break; } }
//================================================================ // CANON object management. //================================================================ //---------------------------------------------------------------- // Constant definition for CANON object. // // y_canon : // Y-position of the CANON object. // POT_HYSTERISIS : // Hysterisis value for conversion from pot_value to // x_canon. The x_canon value will be stable in spite // of the noise on ADC. //---------------------------------------------------------------- const byte y_canon = 14; const byte POT_HYSTERISIS = 4; #pragma DATA_SECTION SHORT MY_ZEROPAGE //---------------------------------------------------------------- // Global variables for CANON. // // x_canon : // X-Position of CANON object. (0 <= x_canon <= 29) //---------------------------------------------------------------- byte x_canon; #pragma DATA_SECTION DEFAULT //---------------------------------------------------------------- // draw_canon : // Draw a CANON object on the frame buffer. //---------------------------------------------------------------- void draw_canon(void) { // Set 4 pixels. pset(x_canon + 0, y_canon + 1); pset(x_canon + 1, y_canon + 1); pset(x_canon + 1, y_canon + 0); pset(x_canon + 2, y_canon + 1); } //---------------------------------------------------------------- // wipe_canon : // Wipe a CANON object on the frame buffer. //---------------------------------------------------------------- void wipe_canon(void) { // Clear 4 pixels. pclr(x_canon + 0, y_canon + 1); pclr(x_canon + 1, y_canon + 1); pclr(x_canon + 1, y_canon + 0); pclr(x_canon + 2, y_canon + 1); } //---------------------------------------------------------------- // canon_action : // Typical ACTION of CANON object. // // Adjustment constant calculation : // x_canon is adjusted to 14.5 when pot_value is 128 // and pot_value is 4 times faster than x_canon. // In addition, the direction of x_canon is opposite to // the pot_value's one due to hardware mis-implement. // ouch!!! // // -(x_canon - 14.5) * 4 = (pot_value - 128) // pot_value = 186 - (x_canon * 4) //---------------------------------------------------------------- void canon_action(void) { byte exp_pot; // POT value expected from x_canon. byte pot_value; // Measured POT value. byte err_code; // Error code returned by ADC bean. // Measure and Get position err_code = Pot_Measure(TRUE); err_code = Pot_GetValue8(&pot_value); // Wipe CANON object wipe_canon(); // Calculate expected pot_value from x_canon exp_pot = 186 - x_canon * 4; // Adjust position // Move CANON if pot_value is too larger or smaller than // expected value. Hysterisis constant if (pot_value >= exp_pot + POT_HYSTERISIS) { if (x_canon > 0) { x_canon--; } } else if (pot_value <= exp_pot - POT_HYSTERISIS) { if (x_canon < 29) { x_canon++; } } // Draw CAONON object. draw_canon(); }
//================================================================ // BULLET object management. //================================================================ #pragma DATA_SECTION SHORT MY_ZEROPAGE //---------------------------------------------------------------- // Global variables for BULLET object. // // x_bullet, y_bullet : // Position of BULLET object. y_bullet==0 means BULLET // is not on the screen. //---------------------------------------------------------------- byte x_bullet; byte y_bullet; #pragma DATA_SECTION DEFAULT //---------------------------------------------------------------- // Constant table declaration. // // bullet_sono[] : // List of SONO object describing the Music Effects of // the BULLET object. //---------------------------------------------------------------- const Sono bullet_sono[16] = { 2, 4000000 / 523, // DO 2, 4000000 / 523, // DO 2, 4000000 / 554, // DO# 2, 4000000 / 587, // RE 2, 4000000 / 622, // RE# 2, 4000000 / 660, // MI 2, 4000000 / 699, // FA 2, 4000000 / 740, // FA# 2, 4000000 / 784, // SO 2, 4000000 / 831, // SO# 2, 4000000 / 880, // RA 2, 4000000 / 932, // RA# 2, 4000000 / 988, // SI 2, 4000000 / 1047, // DO 2, 4000000 / 1109, // DO# 2, 4000000 / 1175 // RE }; //---------------------------------------------------------------- // draw_bullet : // Draw a BULLET object on the frame buffer. //---------------------------------------------------------------- void draw_bullet(void) { // Set 2 pixels pset(x_bullet + 0, y_bullet - 1); pset(x_bullet + 0, y_bullet - 0); } //---------------------------------------------------------------- // wipe_bullet : // Wipe a BULLET object on the frame buffer. //---------------------------------------------------------------- void wipe_bullet(void) { // Clear 2 pixels pclr(x_bullet + 0, y_bullet - 1); pclr(x_bullet + 0, y_bullet - 0); } //---------------------------------------------------------------- // bullet_trigger : // Check if a SHOOT event occurs. // // Returns: // TRUE if a SHOOT event occurs, and FALSE otherwise. //---------------------------------------------------------------- byte bullet_trigger(void) { // Implement just check the Shoot button status. return !Shoot_GetVal(); } //---------------------------------------------------------------- // bullet_action : // Typical ACTION of the BULLET object including // construction. Only one BULLET can be put on the // screen. //---------------------------------------------------------------- void bullet_action(void) { // Construct bullet if button pushed. if (y_bullet == 0) { if (bullet_trigger()) { x_bullet = x_canon + 1; y_bullet = y_canon; } } // Return immediately if no BULLET exists if (y_bullet == 0) { return; } // Wipe to move the BULLET. wipe_bullet(); // Go forward. y_bullet--; // Check if the BULLET reached to ceil if (y_bullet == 0) { // Set HIT flag. flag.hit = TRUE; } else { // Draw a BULLET object. draw_bullet(); // Queue a Sono according to y_bullet. (void)sono_queue_in(&bullet_sono[y_bullet]); } } //---------------------------------------------------------------- // bullet_collision : // Do a collision process if the BULLET collide with // the specified TARGET. // // Parameter: // target : // Pointer to a TARGET to be checked. //---------------------------------------------------------------- void bullet_collision(Target *target) { // Check if the BULLET collide with the TARGET if ( (y_bullet > 0) && (target->status == TARGET_ALIVE) && (x_bullet >= (target->x) + 0) && (x_bullet <= (target->x) + 2) && (y_bullet == (target->y)) ) { // Wipe the BULLET. wipe_bullet(); // Destruct the BULLET. y_bullet = 0; // Initialize the TARGET for explosion. target_explode(target); } }
//================================================================ // Game algorithm state machine. //================================================================ //---------------------------------------------------------------- // shoot_to_start : // An opening message displayed in PROLOGUE. // This message uses 11-row font. //---------------------------------------------------------------- const byte shoot_to_start[] = { 17, // 'S' 13, // 'H' 0, // 'O' 0, // 'O' 18, // 'T' 19, // ' ' 18, // 'T' 0, // 'O' 19, // ' ' 17, // 'S' 18, // 'T' 10, // 'A' 16, // 'R' 18, // 'T' 19, // ' ' 19, // ' ' 255 // STOP }; //---------------------------------------------------------------- // prologue_action : // State description of the PROLOGUE state. //---------------------------------------------------------------- void prologue_action(void) { // Prototype declaration. void game_init(void); // Play MUSIC. music_dispatch(); // Move CANON object. canon_action(); // Execute a BULLET related ACTION. bullet_action(); // Shift the screen to LEFT. fb_shiftLeft(1, 11); // Transition to GAME if a bullet reached to ceil and // a complete character of the message appeared. if (flag.hit && message_column == 0) { game_init(); } else { // Dispatch the message at ROW#1. message_11_dispatch(1); } } //---------------------------------------------------------------- // prologue_init : // Initialization part of the PROLOGUE state. //---------------------------------------------------------------- void prologue_init(void) { // Clear the message area. fb_clear(0, 14); // Initialize MESSAGE dispatcher. message_init(shoot_to_start); // Initialize MUSIC dispatcher. music_init(dash); // Clear HIT flag to detect bullet event. flag.hit = FALSE; // Transition to the PROLOGUE state. action = prologue_action; } //---------------------------------------------------------------- // game_action : // State description of the GAME state. //---------------------------------------------------------------- void game_action(void) { byte id; void epilogue_init(void); // Do all TARGET's action. for (id = 0; id < MAX_TARGET; id++) { target_action(&targets[id]); } // Move CANON object. canon_action(); // Execute a BULLET related ACTION. bullet_action(); // collision detection. for (id = 0; id < MAX_TARGET; id++) { bullet_collision(&targets[id]); } // Construct a TARGET if requested. if (target_count < TARGET_PER_STAGE) { if (++target_construct_timer > TARGET_INTERVAL) { target_construct_timer = 0; // Construct a TARGET if possible. (void)target_construct(); } } // Check if all TARGETs are constructed and disappeared. if (target_count >= TARGET_PER_STAGE) { if (target_on_screen == 0) { epilogue_init(); } } } //---------------------------------------------------------------- // game_init : // Initialization part of the GAME state. //---------------------------------------------------------------- void game_init(void) { // Clear the message area. fb_clear(0, 14); // Destruct all TARGET objects. target_destructAll(); // Reset TARGET object counter. target_count = 0; target_missed = 0; // Set to Music Effect mode. flag.music_played = FALSE; // Transition to the GAME state. action = game_action; } //---------------------------------------------------------------- // message_missed[] : // A message displayed when a stage is over. // The NUMBER part is replaced by a program. //---------------------------------------------------------------- byte message_missed[] = { 0, // '0' 0, // '0' 0, // '0' 15, // ' ' 10, // 'M' 11, // 'I' 12, // 'S' 12, // 'S' 13, // 'E' 14, // 'D' 15, // ' ' 15, // ' ' 255 // STOP }; //---------------------------------------------------------------- // epilogue_action : // State description of the EPILOGUE state. //---------------------------------------------------------------- void epilogue_action(void) { // Play MUSIC. music_dispatch(); // Move CANON object. canon_action(); // Execute a BULLET related ACTION. bullet_action(); // Shift the screen to LEFT. fb_shiftLeft(3, 7); // Transition to PROLOGUE if a bullet reached to ceil and // a complete message appeared. if (flag.hit && message_index == 1) { prologue_init(); } else { // Dispatch the message at ROW#3. message_7_dispatch(3); } } //---------------------------------------------------------------- // epilogue_init : // Initialization part of the EPILOGUE state. //---------------------------------------------------------------- void epilogue_init(void) { // Clear the message area. fb_clear(0, 14); // Create a EPILOGUE message. // Set the MISSED count to the message. message_missed[2] = target_missed % 10; if (target_missed < 10) { message_missed[1] = 15; } else { message_missed[1] = (target_missed / 10) % 10; } if (target_missed < 100) { message_missed[0] = 15; } else { message_missed[0] = (target_missed / 100); } // Initialize MESSAGE dispatcher. message_init(message_missed); // Initialize MUSIC dispatcher. music_init(sonate); // Clear HIT flag to detect bullet event. flag.hit = FALSE; // Transition to the EPILOGUE state. action = epilogue_action; } void main(void) { /* Write your local variable definition here */ /*** Processor Expert internal initialization. DON'T REMOVE THIS CODE!!! ***/ PE_low_level_init(); /*** End of Processor Expert internal initialization. ***/ /* Write your code here */ /* For example: for(;;) { } */ prologue_init(); for (;;) { // Main loop to invoke STATE function // if requested by the periodical timer event. if (flag.action_requested) { flag.action_requested = FALSE; (*action)(); } // Random number genertor is implemented as a simple counter. n_rand++; } /*** Don't write any code pass this line, or it will be deleted during code generation. ***/ /*** Processor Expert end of main routine. DON'T MODIFY THIS CODE!!! ***/ for(;;){} /*** Processor Expert end of main routine. DON'T WRITE CODE BELOW!!! ***/ } /*** End of main routine. DO NOT MODIFY THIS TEXT!!! ***/ /* END LedMat */ /* ** ################################################################### ** ** This file was created by UNIS Processor Expert 2.99 [03.85] ** for the Freescale HCS08 series of microcontrollers. ** ** ################################################################### */
/** ################################################################### ** Filename : Events.C ** Project : LedMat ** Processor : MC9S08QG8CPB ** Beantype : Events ** Version : Driver 01.02 ** Compiler : CodeWarrior HCS08 C Compiler ** Date/Time : 2007/04/28, 18:01 ** Abstract : ** This is user's event module. ** Put your event handler code here. ** Settings : ** Contents : ** SM1_OnRxChar - void SM1_OnRxChar(void); ** SM1_OnTxChar - void SM1_OnTxChar(void); ** SM1_OnError - void SM1_OnError(void); ** ** (c) Copyright UNIS, spol. s r.o. 1997-2006 ** UNIS, spol. s r.o. ** Jundrovska 33 ** 624 00 Brno ** Czech Republic ** http : www.processorexpert.com ** mail : info@processorexpert.com ** ###################################################################*/ /* MODULE Events */ #include "Cpu.h" #include "Events.h" /* ** =================================================================== ** Event : TI1_OnInterrupt (module Events) ** ** From bean : TI1 [TimerInt] ** Description : ** When a timer interrupt occurs this event is called (only ** when the bean is enabled - <"Enable"> and the events are ** enabled - <"EnableEvent">). This event is enabled only if ** a interrupt service/event is enabled. ** Parameters : None ** Returns : Nothing ** =================================================================== */ void TI1_OnInterrupt(void) { /* Write your code here ... */ extern void sono_dispatch(void); extern void led_display(byte row); extern void request_action(void); // Static variable for software timer. static byte sono_timer = 0; static byte spi_timer = 0; static byte action_timer = 0; // SONO manager invoked every 23msec if (++sono_timer >= 26) { sono_timer = 0; sono_dispatch(); } // SPI commnication scheduling. led_display(spi_timer); if (++spi_timer >= 16) { spi_timer = 0; } // Action requested every 50msec if (++action_timer >= 56) { action_timer = 0; request_action(); } } /* ** =================================================================== ** Event : SM1_OnRxChar (module Events) ** ** From bean : SM1 [SynchroMaster] ** Description : ** This event is called after a correct character is ** received. ** The event is available only when the <Interrupt ** service/event> property is enabled. ** Parameters : None ** Returns : Nothing ** =================================================================== */ void SM1_OnRxChar(void) { /* Write your code here ... */ extern void spi_OnRxChar(void); // Invoke actual event handler in MAIN. spi_OnRxChar(); } /* ** =================================================================== ** Event : SM1_OnError (module Events) ** ** From bean : SM1 [SynchroMaster] ** Description : ** This event is called when a channel error (not the error ** returned by a given method) occurs. The errors can be ** read using <GetError> method. ** The event is available only when the <Interrupt ** service/event> property is enabled. ** Parameters : None ** Returns : Nothing ** =================================================================== */ void SM1_OnError(void) { /* Write your code here ... */ extern void spi_OnError(void); // Invoke actual event handler in MAIN. spi_OnError(); } /* END Events */ /* ** ################################################################### ** ** This file was created by UNIS Processor Expert 2.99 [03.85] ** for the Freescale HCS08 series of microcontrollers. ** ** ################################################################### */
2007-07-16 : 暫定的に発行
Updated: $Date: 2007/07/15 15:02:09 $
Copyright (C) 2007 noritan.org ■