#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の時 ↑