PICおよびAVRのワンチップマイコンの特徴
計算処理を行うALU(演算論理装置),メモリ,プログラムを格納するROM,IOポートなどが一つのチップに納められています.
最近では,フラッシュROM内蔵のものが多く出回っておりプログラムが簡単に何度でも書き換え可能なので,初心者への敷居が低くなっています.
プログラムメモリとデータメモリが独立しているハーバードアーキテクチャを採用しています.
アナログコンパレータやADコンバータを持ったものもあり,色々な応用が考えられます.
多くのワンチップマイコンでは,プログラムメモリやデータメモリとは別に,EEPROMを持っているものが多くあります.データが不揮発性ですから,あら
かじめ必要なデータを入れておいたり,実行中に得られたデータを保存しておいたりなどの用途が考えられます.
消費電力が非常に小さく,LEDを光らせるような簡単なものなら,充電電池だけでも丸1日連続動作が可能です.
本ページでは主にAVRマイコンの紹介を行います.(PICの概要とサンプルプログラムはこちら)
ワンチップマイコンを使うためには,構成図を見て全体の概要を理解し,汎用レジスタ,プログラムメモリ,データメモリ(RAM),IOレジスタ,
EEPROMの違いについて理解する必要があります.
空行とセミコロン(;)より右側は無視されます.
コロン(:)で終わる行はラベルで,ジャンプなどで使われます.
数値は,10進数(0-255),16進数(0X00-0XFF),2進数(0B00000000-0B11111111)が使えます.
スペースには,空行よりタブを使うのが望ましいです.
IOレジスタの使い方
マイコンの各種設定の変更は,IOレジスタの決められたアドレスにデータを書くことによって行います.
(IOポートを使ったデータの入力)
IOポートを使い外部からデータを入力する場合には,まずIOレジスタの設定で使いたいピンを入
力に設定する必要があります.例えばPortBの0ビットを入力ポートとして設定するには,IOレジスタのアドレス0X17(DDRB)のビット0に0を
書き込みます.PB0のピンに5V(Hi)の電圧がかかっていれば,IOレジスタのアドレス0X16(PINB)のビット0を読み出すと値が1となりま
す.PB0のピンに0V(Hi)の電圧がかかっていれば,読み出した値は0となります.
(IOポートを使ったデータの出力)
IOポートを使い外部にデータを出力する場合には,まずIOレジスタの設定で使いたいピンを出力に設定する必要があります.例えばPortAの7ビットを
出力ポートとして設定するには,IOレジスタのアドレス0X1A(DDRA)のビット7に1を書き込みます.IOレジスタのアドレス0X1B
(PORTA)のビット7に,1を書き出すとPB7のピン電圧が5Vに,0を書き出すとPB7のピン電圧が0Vになります.
IOレジスタのアドレスには略称があり(例えば0X1AはDDRA),定義ファイルをインクルードすることで使えます.
.INCLUDE "tn26def.inc"
またプログラム中で頻繁に使う数値やIOアドレスは,自分で定義することができます.
割り込みについて
マイコンでは,ある条件で現在の処理を中断し別な処理を行いたい場合があります.これを割り込みといいます.代表的なものは,電源投入時(リセット)の割
り込みです.プログラムの先頭の数行は,特定の割り込みに対応しています.
スタックポインタ
スタックポインタはサブルーチンのスタックが配置されるデータメモリのスタック領域を示します.通常はデータメモリの最終アドレス(RAMEND)を入れ
ておきます.スタックポインタの設定は,RESET:の直後に入れておくのが望ましいです.
AVR最初の一歩(AT90S1200)
購入したプログラムライタを使って,簡単なプログラムでAVR1200を動かすまでの説明です.
必要なもの:アセンブラソフト,ライタとライタ用書き込みソフト
atmel社のHPからダウンロードしたavr.exe(アセンブラソフト)をインストールする.1200def.incなどのインクルードファイルも入
手しアセンブラファイルと同じフォルダに入れておく.
アセンブラコード(ソースファイル)を任意のエディタで編集し,*.asmの形式で保存する.アセンブラソフトでコンパイルすると*.hexが作られる.
ライタをパソコンに接続し,ライタ用書き込みソフトで*.hexをマイコンにダウンロードする.
4つのLEDを順次点滅させる例.
安定動作のために推奨されるコンデンサなどを全て省いて4つのLEDを順次光らせる回路を作ってみました.電源は充電式電池4個で取っています.電池から
電源を供給して,なおかつマイコン1個だけを動かしているので,ノイズはほとんど問題にならないので省きました.水晶振動子ではなくセラロックなどを使う
場合には,両端にコンデンサ22pを入れて下さい.
RESET端子はデフォルトでは,プルアップされていますので何もつながなくても構いません。
ソースコード
.def a1 =R16
.def cnt1 =R17
.def cnt2 =R18
.def cnt3 =R19
rjmp Reset
reti
reti
reti
Reset:
ldi a1,0xFF
out 0x17,a1 ;0x17 = PortB direction to Output
main:
ldi a1,0x01
out 0x18,a1
rcall Time
ldi a1,0x02
out 0x18,a1
rcall Time
ldi a1,0x04
out 0x18,a1
rcall Time
ldi a1,0x08
out 0x18,a1
rcall Time
rjmp main
Time:
ldi cnt1,10 ;10ms x 10=100ms
Loop1:
ldi cnt2,100 ;0.1ms x 100=10ms
Loop2:
ldi cnt3,100 ;100ns x 10 cycle x 100=0.1ms
Loop3:
nop
nop
nop
nop
nop
nop
nop
dec cnt3
brne Loop3
dec cnt2
brne Loop2
dec cnt1
brne Loop1
ret
ソースコードの注意
プログラムでPinBなどを使わず直接アドレスで書けば.include "1200def.inc"
はいらない.インクルードファイルを使う場合,同一フォルダ内にアセンブルコードとインクルードファイルを置いておく。レジスタに定数をとる命令ではレジ
スタ指定にR16〜31しか指定できない。
AVRマイコン(AT90S1200-12)の特徴
20PIN
価格はPICより安い.
電源電圧は4−6V(AT90S1200-4は2.7−6V)
クロックは水晶またはセラミック発振子,内蔵のRC発振が使える.ただし外部<=>内部の切り替えにはヒューズビットの設定が必要.
1クロックで1命令を実行するので早い!
512ワード(ステップ)のプログラムが可能.
32個のレジスタを持つ.
64バイトのEEPROM(不揮発性メモリ)を持つ
5V電源のみでプログラム書き込みが可能.>書き込み回路の自作が容易.
15ピンのIOを持つ.
IO出力から約20mA流せるのでLEDを光らせるのには十分.
アナログコンパレータ内蔵.
ATtiny26L最初の一歩
ATtiny26Lは1200と同じ20ピンながら,AD変換機能も持った優れものです.
(クロック)ATtiny26Lは最高8MHz,ATtiny26は最高16MHzです.内部発振回路と外部発振回路を選ぶことができます.
ATtiny26Lは,初期設定が1MHzの内部発振モードになっています.また外部発振回路を使う場合,水晶発振子とセラミック発振子では設定が異なり
ます.
(AD変換)10ビット分解能のAD変換機能を持っています.2.56Vの基準電圧に対するAD変換機能を持っているので上位8ビットのAD変換値は,
0.01V刻みになっていて都合が良いです.
(プログラムの書き込み)1200と同じようにSP12を使ってプログラムの書き込みができます.ただしピン配置が違うので書き込み回路は別に作る必要が
あります.また_sp12devの旧バージョンにはATtiny26Lの情報が入っていないので,新バージョンを入手する必要があります.
3つのLEDを順次点滅させる例
1200との大きな違いは,割り込みのバリエーションが増えていることと,SPにRAMENDを保存する点です.
LED26.ASMTiny26実行の手順
.INCLUDE "tn26def.inc"
RJMP RESET
RETI
RETI
RETI
RETI
RETI
RETI
RETI
RETI
RETI
RETI
RETI
RESET: LDI R16,RAMEND
OUT SP,R16
LDI R16,0XFF
OUT DDRA,R16 ;PA=OUTPUT
MAIN: LDI R21,0X01
OUT PORTA,R21
RCALL TIME
LDI R21,0X02
OUT PORTA,R21
RCALL TIME
LDI R21,0X04
OUT PORTA,R21
RCALL TIME
LDI R21,0X00
OUT PORTA,R21
RCALL TIME
RJMP MAIN
TIME: LDI R24,10
LOOP1: LDI R23,100 ;1ms x 100=100ms
LOOP2: LDI R22,100 ;1000ns x 10 cycle x 100=1ms
LOOP3: NOP
NOP
NOP
NOP
NOP
NOP
NOP
DEC R22
BRNE LOOP3
DEC R23
BRNE LOOP2
DEC R24
BRNE LOOP1
RET
LDI: 1
DEC: 1
BRNE: ジャンプする場合は2,それ以外は1
1重ループ
LDI R20,10
LOOP1:
DEC R20
BRNE LOOP1
n1*3クロック
2重ループ
LDI R21,5
LOOP2:
LDI R20,10
LOOP1:
DEC R20
BRNE LOOP1
DEC R21
BRNE LOOP2
(n1+1)*n2*3クロック
3重ループ
LDI R22,6
LOOP3:
LDI R21,5
LOOP2:
LDI R20,10
LOOP1:
DEC R20
BRNE LOOP1
DEC R21
BRNE LOOP2
DEC R22
BRNE LOOP3
((n1+1)*n2+1)*n3*3クロック
サブルーチンの例
RCALL(3クロック),RET(4クロック)で呼んで帰ってくるまでに+7クロックが必要となります.
...
...
RCALL TIME
...
...
TIME:
LDI R22,6
LOOP3:
LDI R21,5
LOOP2:
LDI R20,10
LOOP1:
DEC R20
BRNE LOOP1
DEC R21
BRNE LOOP2
DEC R22
BRNE LOOP3
RET
掛け算の例題
R16×R17がR19(LOW)R20(High)に入ります.
.include "1200def.inc"
RJMP RESET ;reset handle
RETI
RETI
RETI
RESET:
LDI R16,100
LDI R17,50
LDI R18,0
LDI R19,0
LDI R20,0
LDI R21,8 ;COUNTER
LP1: ROR R16
BRCC LP2
ADD R19,R17
ADC R20,R18
LP2: CLC
ROL R17
ROL R18
DEC R21
BRNE LP1
LP3: RJMP LP3
2KHzの信号を作る
;26L2kHz.asm ATtiny26L (Ext. Osc. ceramic 8MHz)電子オルゴール(旧バージョン:1200)
;sp12 -wF11111110 for ceramic osc
;or sp12 -wF11001111
;sp12 -wF11101110 NG for ceramic osc
;FuseBitの設定が正しくないと発振周波数が狂ってしまう.
;セラミックでは1%ほど周波数がずれる.
;2KHz TIME:250uS=2000clocks
.INCLUDE "tn26def.inc"
RJMP RESET
RETI
RETI
RETI
RETI
RETI
RETI
RETI
RETI
RETI
RETI
RETI
RESET:
LDI R16,RAMEND
OUT SP,R16
LDI R16,0XFF
OUT DDRB,R16 ;PB=OUTPUT
MAIN: SBI PORTB,0
RCALL TIME
NOP
NOP
CBI PORTB,0
RCALL TIME
RJMP MAIN
TIME: LDI R24,10
LOOP1: LDI R23,65 ;1ms x 100=100ms
LOOP2:
DEC R23
BRNE LOOP2
DEC R24
BRNE LOOP1
LDI R24,3
LOOP3: DEC R24
BRNE LOOP3
RET