; Copyright 2006 Yamane Akira ; ATmega48 USARTのデモプログラム ; システム・クロック 8MHz ; USARTボーレート19.2Kbps 文字長8ビット、1ストップビット ; パリティ無し ; ターミナルへプロンプト・メッセージを送り、ターミナルからの ; 数値を受け取り、STK500のLEDを点灯する。 ; Programmed by A.Yamane (8/15/2005) .include "m48def.inc" ; .org 0x0000 rjmp RESET ; .org 0x1A PORT_init: ; ポートの初期化サブルーチン LDI r16,0xFF OUT PORTB, r16 OUT DDRB, r16 OUT PORTC, r16 OUT PORTD, r16 LDI r16, 0x00 OUT DDRC, r16 OUT DDRD, r16 ret USART_init: ; USARTの初期化サブ・ルーチン clr r16 sts UCSR0B, r16 ; mega48のUSARTレジスタは0〜0x3F内に無いので sts UCSR0A, r16 ; in,out 命令は使用できない ldi r17, ((1<< UCSZ01)|(1<< UCSZ00)) sts UCSR0C, r17 ; 非同期、パリティ無、ストップ1、文字長8ビット ldi r18, 25 ; ボーレート19200bps sts UBRR0L, r18 ; 設定 sts UBRR0H, r16 ; 上位バイトは0 ldi r17, ((1<< RXEN0) | (1<< TXEN0)) sts UCSR0B, r17 ; 受信、送信をイネーブル ret USART_Transmit: ; R16のデータを送信するサブ・ルーチン lds R2,UCSR0A SBRS R2, 5 ; UCSR0AレジスタのUDRE0ビットが1 rjmp USART_transmit ; になるまで待つ sts UDR0, R16 ; USARTデータ・レジスタにデータをセット ret USART_Receive: ; 受信したデータをR16へ戻す、サブ・ルーチン lds R2, UCSR0A sbrs R2, 7 ; UCSR0AレジスタのRXC0ビットが1 rjmp USART_Receive ; になるまで待つ lds R16, UDR0 ; データを読み、R16に載せて戻す ret ; プログラムはここからスタート RESET: CLI ; 念のため割込み禁止 LDI r16, low(RAMEND) ; スタック・ポインターの初期化 OUT SPL, r16 LDI r16, high(RAMEND) OUT SPH, r16 rcall PORT_init ; ポートの初期化呼び出し rcall USART_init ; USARTの初期化呼び出し main: ldi r16,0x0d ; キャリッジ・リターン rcall USART_Transmit ; USARTへ送信 ldi r16,0x0a ; ライン・フィード rcall USART_Transmit ; USARTへ送信 ldi ZH, high(message1<< 1) ; Zポインターの値をmessage1にセット ldi ZL, low(message1<< 1) ; Wordアドレスとバイトアドレスの変換 ; のため1ビットシフト string_out: lpm r16, Z+ ; message1のデータをr16へ取り出しZポインターを+1 cpi r16, 0x00 ; データが0かを調べる breq End_String_out ; もし0であったならば End_String_outへブランチ rcall USART_Transmit ; 0でなければ、1文字USARTへ出力 rjmp String_out ; 繰り返す End_String_out: rcall USART_Receive ; ターミナルからのキー入力 rcall USART_Transmit ; エコーバック subi r16, 0x31 ; ASCIIコードを数値に変更 brlt main ; 0と制御文字が入力された場合再入力へ cpi r16, 8 ; 9とアルファベットの文字が入力された場合、 brge main ; 再入力へ ldi r18, 0b00000001 ; ビット0 loop: subi r16, 0x01 ; 入力されたビット位置を−1 brlt LED_on ; 入力されたビット位置が1であればシフトの必要なし lsl r18 ; −1した結果が負にならなければ左へ1ビットシフト rjmp loop ; 繰り返す LED_on: com r18 ; LEDはロー出力で点灯するのでデータを反転 out PORTB, r18 ; LED点灯 rjmp main message1: .db "Input LED Position 1 - 8: ",0 ; メッセージ、フラッシュに置く