#if 0 /* コンパイルしたくない理由を書く */ : /* コメントがあっても大丈夫 */ #endifコンパイルしたいときは 0 を 1 に書き換えます。senshuさんに教えていただきました。
#include <avr/pgmspace.h> // 必要です int main (void) { char msg[43]; strcpy_P(msg,PSTR("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ")); string_out(msg); strcpy_P(msg,PSTR("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb")); string_out(msg); strcpy_P(msg,PSTR("ccccccccccccccccccccccccccccccccccccccccccc")); string_out(msg); }strcopy_PはROMからSRAMへのコピー、PSTRはROMにある文字列のアドレス取得、strin_out()は通信ルーチン(ここには書いていない)です。 includeファイルに注意が必要です。 ↑
# MCU name MCU = attiny2313 ################################################################################################## F_CPU = 8000000 ################################################################################################## TARGET = pwmh1 ################################################################################################## SRC = $(TARGET).c ################################################################################################## EXTRAINCDIRS = ##################################################################################################このようにしておくと変更場所がわかりやすく、また、取りこぼしがありません。 ↑
D: CD D:\prog\test1 REM C:\WinAVR\utils\bin\make clean C:\WinAVR\utils\bin\make all |
sbi() → PORTx |= _BV() cbi() → PORTx &= ~_BV() inp() → data = PORTx or =PINx outp() → PORTx = dataと書き換えれば殆ど終わりです。(私のファイルにあったのはこの4種のマクロだけでした。)
/* For old avr-libc */ #define _cbi(p, q) ((p) &= ~_BV(q)) #define _sbi(p, q) ((p) |= _BV(q)) #define _outp(p, q) q = p #define _inp(p) pおまけ:新バージョンの makefile は少し親切になりました。ROMの使用率%などを示してくれます。
/* deprecated.h */ #define BV(bit) (1<<(bit)) #define cbi(addr,bit) addr&=~_BV(bit) #define sbi(addr,bit) addr|=_BV(bit) #define outp(data,addr) addr=(data) #define inp(addr) (addr) #define outb(addr,data) addr=(data) #define inb(addr) (addr) #define PRG_RDB(addr) (pgm_read_byte(addr))出典はAVR-Wikiの「deprecated macroを使う?」のようです。↑
void wait(unsigned int time){ // 100μS単位のwaitルーチン (クロック8MHzのとき) unsigned char lpcnt; // 引数6で600μSとなる (1MHzなら1で800μs) __asm__ __volatile__("\n" "CPU_wait_entry%=:\n\t" "ldi %0,200\n" //CK 100us/8MHz "CPU_wait_lp%=:\n\t" "nop\n\t" "dec %0\n\t" "brne CPU_wait_lp%=\n\t" "sbiw %1,1\n\t" "brne CPU_wait_entry%=\n\t" :"=&a"(lpcnt) :"w"(time) ); return; }時間を決めるのは、 nop dec brne の3ステップ(4クロックサイクル)を200回繰り返しているところです。クロックが8MHzとすると
void wait(unsigned int time) // 100us wait ルーチン。 クロック設定のこと。 { // 25MHzでも 260ms までとれる。 time*=8; // 8MHzのとき。timeにF_CPU(MHz)をかける。重要!! unsigned char lpcnt; __asm__ __volatile__("\n" "Entry%=: \n\t" "ldi %0,24\n" // 計算値は25。24の方が実測値は良い。 "Loop%=: \n\t" // 上の行で 24 のときは100us、249にすれば1msのルーチンになる。 "nop\n\t" "dec %0\n\t" "brne Loop%=\n\t" "sbiw %1,1\n\t" "brne Entry%=\n\t" :"=&a"(lpcnt) :"w"(time) ); return; }↑
#define F_CPU 1000000UL // 1MHzのとき <util/delay.h>より前に定義してください //14.7456MHzの時は #define F_CPU 14.7456E6 とも書ける #include <util/delay.h> void wait_ms(uint16_t); void wait_ms(uint16_t t) { //ウエイトルーチン 引数1で1ms while (t--) _delay_ms(1); }(2010.07.04追記)最近のWINAVRでは(2008年以降は間違いなく)大きな引数が取れない制限が無くなりました。
#define F_CPU 1000000UL // 1MHzのとき。 <util/delay.h>より前に定義してください //14.7456MHzの時は #define F_CPU 14.7456E6 とも書ける #include <util/delay.h> _delay_ms(100); // 100ms _delay_ms(1000); // 1秒 _delay_ms(5000); // 5秒同様に _delay_us()も拡張されています。
switch(式){ case 定数式1: 文11 文12...;break; case 定数式2: 文21 文22...;break; ・・・ case 定数式n: 文n1 文n2...;break; default: 文1 文2... }breakがないと次の行の文を実行してしまいます。特別な意図がない限りbreakを書きます。式には整数型、文字型が使われます。↑
void wait(uint8_t x){ uint8_t y,z; for(y=1;y<x;y++){z=y*2;}} と書いても、と書いても同じです。字下げはプログラムの深さを見やすくします。終わりの「}」は始まりの文の頭とそろえて
また,
、 void wait(uint8_t x){ uint8_t y,z; for(y=1;y<x;y++){ z=y*2; } }
void hyouji(uint8_t x){ x=x+5; // xに5を足したものをxに代入する PORTA=x; // portAに出力 文の最後の「;」を忘れないように。PORTは大文字で定義されています }これでよいのですが、コンパイラは上からコンパイルするので、main関数の中のhyouji(a)に出会ったときに、hyouji関数を知らん!と
if(a==b){ x=5; sub(); }else{ x=0; sub2(); }複数の条件があるとき: if((a==b) && (c>d)){ ・・・・ } //a=bかつc>dの時 ↑