ATtiny10 用プログラム (3)
DDA (Digital Differential Analyzer) を利用して、サイン/コサイン波形を出力する ATtiny10 用プログラム「var_test.c」を下に示します。
8 ビット phase correct PWM を利用していて、PB0 (ピン 1) および PB1 (ピン 3) から PWM 繰り返し周波数 15.625 kHz で出力されます。
LED を接続していると 1 秒足らずの周期で明滅を繰り返します。
グローバル変数を使った例として示しており、プログラム自体に特に意味はありません。
「var_test.c」
/*********************************************/ /* var_test.c: ATtiny10 global variable test */ /* for AVR GCC Toolchain 3.3.0 */ /* */ /* 2011/12/21: Created by pcm1723 */ /*********************************************/ #include <avr/io.h> #include <avr/interrupt.h> int16_t cos_acc, sin_acc; void attiny10_port_setup( void ) { // set clock prescaler to 1/1 (8 MHz clock) CCP = 0xD8; // set protection signature CLKPSR = 0; // clock prescale = 1/1 (8 MHz clock) // timer mode = 8 bit phase correct PWM (WGM0[3:0] = 0001) TCCR0A = _BV(WGM00); // WGM01:WGM00 = 01 TCCR0B = _BV(CS00); // WGM03:WGM02 = 00, CS00 = 1 (clk/1) // set compare output mode to clear at up, set at down TCCR0A |= (_BV(COM0B1) | _BV(COM0A1)); // COM0x1:COM0x0=10 DDRB |= _BV(DDB0); // set OC0A (pin 1) to output DDRB |= _BV(DDB1); // set OC0B (pin 3) to output } // void attiny10_port_setup() int main() { attiny10_port_setup(); sin_acc = 0; cos_acc = 0x7e00; // initial radius for (;;) { // infinite loop while (!(_BV(TOV0) & TIFR0)) {} // OVerflow occurred? TIFR0 |= _BV(TOV0); // clear Timer OVerflow flag // sin/cos generation by DDA (Digital Differential Analyzer) cos_acc -= (sin_acc >> 11); sin_acc += (cos_acc >> 11); // convert 2's comp to unsigned and set PWM duty OCR0AL = (0x80 ^ ((0xff00 & sin_acc) >> 8)); OCR0BL = (0x80 ^ ((0xff00 & cos_acc) >> 8)); } // for (;;) } // int main()
LED の光の明滅として認識するため、周波数を低くしてありますが、main() 関数内の DDA 処理部で sin_acc / cos_acc を右シフトしているシフト量を「11」から「3」にすると、周波数は 300 Hz 程度となり、PWM 出力を LPF に通せば、音として聞くことができます。
コンパイル結果の HEX ファイル「var_test.hex」を下に示します。
当然、(正しくない) 2 バイト LDS/STS が生成されているので、正しく動作しません。
「var_test.hex」
:100000000AC019C018C017C016C015C014C013C04C :1000100012C011C010C011271FBFCFE5D0E0DEBF56 :10002000CDBF10E0A0E4B0E001C01D93A434B1073F :10003000E1F70ED046C0E4CF88ED8CBF16BF81E05B :100040008EBD8DBD8EB5806A8EBD089A099A0895C1 :10005000F3DF109343001093420080E09EE79093FB :100060004100809340008AB580FFFDCF8AB5816052 :100070008ABD2091420030914300422F532F6BE004 :10008000559547956A95E1F7809140009091410020 :10009000841B950B90934100809340004BE0959515 :1000A00087954A95E1F7820F931F909343008093C1 :1000B0004200892F805886BD80914100805884BDC0 :0600C000D2CFF894FFCF3F :00000001FF
これを、前回の「fix_lds」プログラムで処理した結果を下に示します。
「var_test_fixed.hex」
:100000000AC019C018C017C016C015C014C013C04C :1000100012C011C010C011271FBFCFE5D0E0DEBF56 :10002000CDBF10E0A0E4B0E001C01D93A434B1073F :10003000E1F70ED046C0E4CF88ED8CBF16BF81E05B :100040008EBD8DBD8EB5806A8EBD089A099A0895C1 :10005000F3DF13A9000012A9000080E09EE791A938 :10006000000080A900008AB580FFFDCF8AB58160BD :100070008ABD22A1000033A10000422F532F6BE064 :10008000559547956A95E1F780A1000091A1000080 :10009000841B950B91A9000080A900004BE0959569 :1000A00087954A95E1F7820F931F93A9000082A9D3 :1000B0000000892F805886BD81A10000805884BD32 :0600C000D2CFF894FFCF3F :00000001FF
(レコード・タイプが通常のデータである) HEX レコードは、入力された HEX レコードと同じ開始アドレス、レコード長で出力しているので、両者を比べると、どこに修正が入ったのか分かります。
後で示すコンソール・ログを見ると、lds/sts は 13 ヵ所あったことが記録されています。
この HEX ファイルを ATtiny10 に書き込めば、正常動作します。
コンパイラが出力した HEX ファイルに、もう一段、処理をかぶせるわけですが、どうせ avrosp を走らせるためにコマンド・プロンプトを立ち上げているので、バッチ・ファイルの中に変換処理も含めてしまえば手間はかかりません。
以前の「pgm_tn10.bat」に 1 行追加して次のようにしました。
「fix_tn10.bat」
call comosp fix_lds < .\%1\default\%1.hex > .\%1_fixed.hex avrosp -cCOM1 -dATtiny10 -if%1_fixed.hex -e -pf -vf
プロジェクト・フォルダ内の「default」フォルダの下に生成された HEX ファイルを入力とし、カレント・ディレクトリの下に変換された HEX ファイルを作成し、そのファイル名は、もとの名前の拡張子の '.hex' の前に '_fixed' を追加したものになっています。
コマンド・プロンプトで実行したときの、コンソール画面のログを下に示します。
X:\WSP\AVR>fix_tn10 var_test X:\WSP\AVR>call comosp X:\WSP\AVR>mode com1 baud=115200 data=8 parity=n dtr=off Status for device COM1: ----------------------- Baud: 115200 Parity: None Data Bits: 8 Stop Bits: 1 Timeout: OFF XON/XOFF: OFF CTS handshaking: OFF DSR handshaking: OFF DSR sensitivity: OFF DTR circuit: OFF RTS circuit: ON X:\WSP\AVR>fix_lds 0<.\var_test\default\var_test.hex 1>.\var_test_fixed.hex # 0052: 9310 0043 --> a913 # 0056: 9310 0042 --> a912 # 005e: 9390 0041 --> a991 # 0062: 9380 0040 --> a980 # 0072: 9120 0042 --> a122 # 0076: 9130 0043 --> a133 # 0088: 9180 0040 --> a180 # 008c: 9190 0041 --> a191 # 0094: 9390 0041 --> a991 # 0098: 9380 0040 --> a980 # 00aa: 9390 0043 --> a993 # 00ae: 9380 0042 --> a982 # 00b8: 9180 0041 --> a181 X:\WSP\AVR>avrosp -cCOM1 -dATtiny10 -ifvar_test_fixed.hex -e -pf -vf AVR Open-source Programmer $Revision: 1163 $ (C) 2004 Atmel Corp. Serial port timeout set to 5 sec. Found AVR ISP on COM1! Entering programming mode... Parsing XML file for device parameters... Parsing '.\ATtiny10.xml'... ###### Saving cached XML parameters... Signature matches device! Erasing chip contents... Reading HEX input file for flash operations... ############## Programming Flash contents... Reading Flash contents... Comparing Flash data... Equal! Leaving programming mode...