;Cからの呼び出し uint16_t result = acadc(); ;Cから呼び出されるアセンブラ関数において、r0/r18-25/X(r26-27)/Z(r30-31)はpush-pop不要で使用できる。 #include ;レジスタ(SFR)のアドレスのオフセット差し引き #define _PORTB _SFR_IO_ADDR(PORTB) #define _DDRB _SFR_IO_ADDR(DDRB) #define _ACSR _SFR_IO_ADDR(ACSR) .section .text ;このアセンブラ関数をプログラム領域に置く .global acadc ;外部に(C側に)関数acadc()を公開する .func acadc ;このアセンブラ内で定義する関数名 acadc: ldi XH, 0 ;カウンタにするワードレジスタを初期化 ldi XL, 0 cbi _DDRB, PB0 ;入力(PB0はAIN0ピン) sbi _PORTB, PB0 ;プルアップ(コンデンサの充電開始) ADC_COUNT: adiw XL, 1 ;ワードレジスタをインクリメント sbis _ACSR, ACO ;ACSRレジスタのACOビットが立ったら次の命令をスキップ rjmp ADC_COUNT sbi _DDRB, PB0 ;出力 cbi _PORTB, PB0 ;Lレベル(コンデンサを放電) movw r24, XL ;戻り値はr25-24 ret .endfunc