ラベル AVR の投稿を表示しています。 すべての投稿を表示
ラベル AVR の投稿を表示しています。 すべての投稿を表示

2011年8月23日火曜日

AVR assembly

投稿タイトル漢字二文字縛りに疲れて「俺は自由奔放に生きてやるぜー!」とか叫んでるパパです。もうひとつ言うと普段の一人称は「僕」なパパです。こんちは。

最近アセンブリの勉強をはじめまして、ちまちまとやっとるワケです。はい。
あ、そうそう、
アセンブリ:言語の名前
アセンブラ:コンパイルするやつ
アセンブル:コンパイルすること
らしいです。

で、試しに書いてみたそーす。
そーす
  1.include "m64def.inc"
  2.def unset = R16
  3.def set = R17
  4.def led = R18
  5.CSEG
  6        ldi unset,0x00
  7        ldi set,0xFF
  8        out DDRA,unset
  9        out DDRD,set
10        out PORTA,set
11        out PORTD,unset
12LOOP:
13        in led,PINA
14        lsl led
15        com led
16        out PORTD,led
17        jmp LOOP
18


みたいな感じです。あっ、左の数字は行数です。
ちなみに環境構築はこちら(top)「のぅわべたぁ」様、こちら(top)「AVR使用記-kuman」様を参考にさせて頂きました。

上のソースの回路は、マイコンはATmega64、PINAにはスイッチを負論理で接続、PORTDにはLEDを接続しています。動作としてはPORTAに接続された負論理スイッチが押されたら1bitシフトしてbit反転してLEDに出力するっつーやつです。こんな説明で分かるのかなぁ(爆)

もうちょい真面目に解説すると、
1行目:ATmega64の定義ファイル取り込み
2行目:R16レジスタの名前をunsetに設定。
3行目:R17レジスタの名前をsetに設定。
4行目:R18レジスタの名前をledに設定。
2~4行目はプログラムかじったことのある人なら分かると思いますが、define、つまり設定とか言いつつただの置換です。

5行目:.CSEG
AVRプログラムはこの「.CSEG」の行から始まります。

6行目:ldiという命令で0x00という定数をunsetと設定した(?)レジスタ = R16レジスタに代入。
7行目:同じく0xFFという定数をsetと設定したレジスタ = R17レジスタに代入。
8行目:DDRAレジスタにunsetの中身(=0x00)を代入。
9行目:DDRDレジスタにsetの中身(=0xFF)を代入。
10行目:PORTAレジスタにsetの中身(=0xFF)を代入。
11行目:PORTDレジスタにunsetの中身(=0x00)を代入。
6~11行目でなぜDDRやPORTのレジスタに定数を直接代入しないかというと、「できないから」なんです。
で、6、7行目の代入と8~11行目の代入で別の命令を使っていますが、後述します。

12行目:LOOP:
ここでは「ラベル」を設定しています。C言語のgoto文をご存知なら、分かると思いますが、あれと一緒と考えて大丈夫だと思います。17行目の記述と関係してくるので、詳しくはそっちで。。。

13行目:PINAレジスタの中身をledと設定したレジスタ(=R18レジスタ)に代入。
14行目:lsl命令でledレジスタを1bit左にシフトしたものを求め、ledレジスタに再び代入。
15行目:com命令でledレジスタの1の補数(=bit反転したもの)を求め、ledレジスタに代入。
16行目:PORTDレジスタにledレジスタの中身を代入。
13~16行目がこのプログラムのメインです。ここで「負論理接続のスイッチが押されたら1bitシフトして反転したものを出力」しています。

17行目:jmp LOOP LOOPラベルのある部分(12行目)まで移動してプログラム続行(無限ループ)

ちなみに、手軽にアセンブルできるようにmakeファイル書いたんでついでに載せときます。
こっちの説明はめんどいんで割愛で。

 1PROJECT=test
 2#--------                                                                    
 3all:
 4        avra $(PROJECT).asm
 5
 6clean:
 7        rm $(PROJECT).cof $(PROJECT).eep.hex $(PROJECT).hex $(PROJECT).obj
 8
 9flash:
10        avrdude -p m64 -c avrispmkII -P usb -e
11        avrdude -p m64 -c avrispmkII -P usb -U flash:w:$(PROJECT).hex -F
12
13.PHONY: all clean

でわでわ

2011年7月2日土曜日

安定

日々睡魔と課題と腹を突きにくる友達から逃げて生きているパパです。こんばんは。

最近、Ubuntuでのプログラム開発が軌道に乗ってきました。
前は
  1. Ubuntuで書きかける
  2. コンパイルかける
  3. コンパイル通らねええ
  4. もしくは通ってもちゃんと焼けねええ
  5. こんなときこそWindows!!
  6. 再起動してWindows軌道
  7. 開発ぞっこー
  8. 原因:自分の単純なミスでUbuntuでもなんとかなりそう
  9. でも再起動めんどいからそのままぞっこー
ってな流れでしたが、最近はkateで書いてmakeしてavrdudeで焼いてfusebitもこいつでいじって、ができるようになりました。

やったぜっ!!


これが今の開発環境です。
学科柄emacsの使い方も押えてるので、近々そっちに乗り換えよーかなーとか思ったり。

-----

はてさて、いきなりですが、ひとつのプログラムを複数人で書く、って結構大変ですね。

ひとつのプログラムをふたりで書いてますが、「その」プログラムに対する見解が人によって違うと、細かいとこの操作性なりなんなりが変わってきたり、てか同じでもプログラム見ただけで「こことここは違う人が書いたなぁー」って分かるようになってる。

人によってプログラム全然違いますからね。

でもそれっておもしろいですよね。例えば、僕は極力マイコン側の演算を押え、動作速度をできる限り確保しようとしてますが、一緒に組んでる相手方はソースコードの見やすさ、最終的なメンテナンスの容易さを追求してて、同じようなことしても全然違うんですよね。

こうやって、人のプログラム見るのもおもしろいことです。あれ?何の話だったっけ?

さぁ、今からはまたプログラム書こうかな。

でわでわ

2011年6月11日土曜日

PWMをAD変換

こんばんは。パパです。
今日は授業中に思いついたことをやってみたので報告します。
ずばり、「PWMはAD変換できるのか」です。

もし、これが成功すればひじょーに便利になることがあります。
うちのモタドラにはマイコンを載せていますが、そのマイコンで受け取ったPWMをAD変換すれば、らくらくPWM値を取りこめるという・・・!

・・・なんかアホなことしてる気がしますが、気のせいです。UARTとかはピンの関係上もったいないですし、SPI通信なんていわずもがな。

・実験方法
  1. atmega88にPWMを出力するプログラムを書く。そのときの設定は8bit高速PWM動作、分周なし、とする。
  2.  別に用意したatmega88にA/D変換し、その値をPWMに出力するプログラムを書く。この設定は特に考えないが、8bit高速PWM動作、64分周に設定した。
  3. 一つ目の88のPWMピンと二つ目の88のA/D変換ピンを接続し、10MHzで動作させる。
  4. 同様に一つ目の88のPWMの分周を変えてみる。
・結果
  1. 一つ目のマイコンが分周なしだったときにはA/D変換は一応成功した。
  2. 分周をかけると、A/D変換は失敗した。
これより、10MHzで8bit高速PWM動作、分周なし、ではA/D変換は成功することが分かった。

けっこうおもしろかったです。実際にモタドラに応用するかどうかは別にして・・・
あと、はじめてavrdudeでfusebitをいじりました。fusebitには割と苦手意識がありましたが、意外とあっけなく成功して肩透かしを喰らったような。。。

参考にしたURL: toshi_hirasawaの日記(top)

今日の投稿はここまで。

でわでわ

2011年4月23日土曜日

夢叶 -UbuntuでAVRを使う-

チョーお久しぶりです.パパです.とりあえず長年数カ月の夢が叶ったので,報告です.

UbuntuでAVRが使えたあああぁぁぁ!!!

一昨年の冬に一回目のトライ,去年の冬に二回目のトライ,今回三回目のトライ.
三度目の正直です.正直者にはいいことがあるのです!!

ちょっと興奮してしまいましたが,その備忘録&報告を,と思いまして.

参考にさせていただいたブログ様
1.玉虫色に染まれ!(top)様の以下の二つの記事
http://d.hatena.ne.jp/over80/20090302/1236006771
http://d.hatena.ne.jp/over80/20100506/avr_build

2.かみはバラバラになった(top)様の以下の記事
http://d.hatena.ne.jp/ymizushi/20100811/p1
です.

Ubuntuで楽しいAVR
1.環境構築編
以下のものをsynapticパッケージマネージャーでインストール
1.コンパイルするときに必要なもの
・gcc-avr
・binutils-avr
・avr-libc
2.焼くときに必要なもの
・avrdude
2.コンパイル編
玉虫色に染まれ!様の二つ目のリンク先の真ん中らへんのMakefileをコピペでMakefileを作り,makeでコンパイル.
3.焼く!
自分の環境に合わせて,avrdudeで書き込みですッ!!
sudo avrdude -p m168 -c avrispmkII -P usb -U flash:w:chr_lcd.ihex
これで成功しました.
やったー

久々の投稿でした.
でわでわ

2011年3月18日金曜日

よくわからんfusebit

お久しぶりです.マジお久しぶりです.パパです.
ロボットランサー&合同ロボコンのプログラム指導でてんやわんやしている今日この頃,たまには更新しようかなと思った所存です.
ロボットランサー,震災の影響で延期になりました.なんていうか,既にホテルや学割もキャンセルしたのに未だに実感ないです.寝て起きたらランサーやっぱやるよーみたいな.

では本題

今日はfusebitの話題です.題して「よくわからんfusebit」.よくわからないけどわかりたい,というパパの願望丸出しのタイトルです.

とりあえず有名な一冊,「AVRマイコン活用ブック」を片手にmega168のfusebitをいじってみました.
というよりは,いじる必要にせまられました.部室のmega88さんが足りないので168さんに頼ることになりました.

部室でのできごと
mega88が足りないことに気づく

mega168を後輩に使うよう指導

焼けないとか言われる

友達に焼き方を教わる

後輩に教える

PWMがおかしいと言われる

調べる 調べる 調べる

fuse bitを活用ブック片手にいじる

うごく

やったー

みたいな感じでしょうか.

閑話休題

今回PWMがちゃんと動かなかったのは,マイコンのクロックの設定がちゃんとできていなかったことです.多分.で,このマイコンの外部クロック設定をする方法を書きます.理解してません.メモです.他のマイコン/環境でやってどうなっても知りません.
mega168さんの場合,外部クロックを設定するにはFuseLowByteだけをいじってやればいいようです.(他のマイコンどーなんだろ?)
LowByte

ビット76543210
名前CKDIV8CKOUTSUT1SUT0CKSEL3CKSEL2CKSEL1CKSEL0
初期値01100010

となっています.では,それぞれのbitの説明を...
・7bit「CKDIV8」
CPUクロックの分周比を設定します.

設定値機能
0(初期値)CPUクロックを入力クロックの1/8倍する
1CPUクロックを入力クロックそのままにする

部室で使ってる時は「1」で設定しました.
・6bit「CKOUT」
CPUクロックの出力する/しないを設定します.

設定値機能
0CPUクロックをCLK0端子から出力する
1(初期値)CPUクロックをCLK0端子から出力しない

よく分かりませんけど,とりあえあず「1」で設定.
・5bit 4bit「SUT」
活用ブックの要約:マイコンが動き始めるまでの時間を設定するよー.詳しくはデータシートみてねー
分かんない.マジ分かんない.とりあえず初期値「10」に.誰か教えてくださいです.

・3bit 2bit 1bit 0bit「CKSEL3~0」
CPUクロックの元のクロックの週力方法の設定.

設定値機能
0000XTAL1端子から外部クロックを入力
0010(初期値)内部の周期(8MHz)の発振を使用.
0011128kHz内部RC発振(よくわからん)
0110~0111フルスイングクリスタル発振子.XTAL1とXTAL2の2ピンから発振を入力.011x:0.4~20MHz.部室では0110でも0111でも成功した.
1000 ~1111ローパワークリスタル発振子.XTAL1とXTAL2の2ピンから発振を入力101x:0.9~3.0MHz,110x:3.0~8.0MHz,111x:8.0~16.0MHz
結論.よくわからんいや,まじよくわからんもっと勉強しなければと思う今日この頃.これからもがんばります. でわでわ

2011年3月9日水曜日

よくわかるWindowsでのAVRdudeのつかいかた

こんにちは.パパです.
昨日UbuntuでAVRを使おうと思ってAVRdudeについて調べましたが,Winでの方法しかわかりませんでした.ので,一応それをレポートとして載せておきます.

レポートと言いつつ,じっさいはこちらtop)の方法にのっとってやっただけです.(汗

下の方の「ダウンロード/download」の「avrdude.exe Version 5.6 binary (with USBasp software control of ISP speed patch)」と「avrdude-GUI Version 1.0.5 実行バイナリ」をダウンロード.前者がAVRに焼くavrdudeというコンソールプログラムの本体で,後者がavrdudeをGUIで簡単に使うツールです.

avrdude本体を解凍し,avrdude-GUIも解凍し,AVRdude-GUIを起動.
AVRdude-GUI
avrdude.exe FileにAVRdudeのパスを設定.Programmer,Port,Deviceを自分の環境&焼くマイコンに合わせて設定した後,Frashに焼く.hexファイルのパスを設定.「Erase-Write-Verify」をクリックすると焼けます.

使ってみた感想としては,まれに応答なしになりますが,ちゃんと焼けます.既にコンパイルを通した物であればAVRStudioを立ち上げることなくプログラムを焼くことができるので,割と便利です.

で,結論.

UbuntuでAVRdude使いてぇ~

UbuntuにもAVRdudeのパッケージいれたんですけど,うまく動かないのです.どーしたらいーんだろー?

誰か教えてくださいです.

今日はここまで.

でわでわ

2011年2月11日金曜日

A/D変換のミス

約一週間ぶりになってしまいました.お久しぶりです.パパです.
前回UPしたpfunction.c,にミスが入ってました.と,いうのはA/D変換時の「A/D変換クロック選択」を指定していなかったことです.

これは何者かといいますと,まず,A/D変換の説明からはじめなければなりません.

A/D 変換とは,端的に言えば,アナログデータをデジタルデータへ変換するものです.というのも,基本的にマイコンは,デジタルデータしか扱うことができません.具体的には,"0"と"1"の二種類ですが,時にはビミョーな値を読み取りたいといったこともでてくるでしょう.例えば,センサーがそれにあたります.温度センサーとかでも,温度が高い・低いの二種類では困りますよね.

このときに微妙な値を安易に"0","1" に分けてしまうのではなく,"0:5" や"0:95" などの値に変換
してプログラムに持ち込むのがA/D 変換です.

具体的な使い方は,他にまわすとして,このとき考え方として,A/D変換は別のハードでかけていると考えると分かりやすいと思います.ですからA/D変換をかけている最中に別の処理をすることもできますし,ただ待っている,というのでもいいと思います.

それはいいとして,A/D変換を別ハードでかけているということは,そのハードにも周波数を送ってやらないといけません.今回のミスはその周波数を設定していなかった,ということです.AVRwiki様(top)によると,50~200kHzに設定してやらないとダメみたいです.で,データシートを見ると,ADPSの2~0で周波数を設定するみたいですね.


データシートより
で,部室で使っているAVRは10MHzで動かしているので,64分周を設定しました.いままでビミョーに安定しなかったのが,これでちゃんと安定したので,ホントによかったです.

書きなおしたpfunction.cもupしておきますね.ADConvertとADstartにはaにチャンネル選択を,bにクロック選択を0~7までで入れて使ってくださいね.

/**************************************
 pfunction.c
 作成者:パパ
 ver,2.5
**************************************/
#define sbi(addr,bit)        addr|=(1<<bit)
#define cbi(addr,bit)        addr&=~(1<<bit)
#define ibi(addr,bit)        addr^=(1<<bit)
uint8_t ADConvert(uint8_t a,uint8_t b)
{
        ADMUX = 0x60|a;
        ADCSRA = 0xC0|b;
        loop_until_bit_is_clear(ADCSRA,ADSC);
        return ADCH;
}
void ADCstart(uint8_t a,uint8_t b)
{
        ADMUX = 0x60|a;
        ADCSRA = 0xC0|b;
}
uint8_t ADCfinish(void)
{
        loop_until_bit_is_clear(ADCSRA,ADSC);
        return ADCH;
}
uint16_t AbsolteValue(int a)
{
        if(a < 0)
        a = -a;
        return a;
}
ふぅ,長文書くと疲れるなぁ.

でわでわ

2011年2月6日日曜日

pfunction.c

AVRをより簡単に使うために...
自分がAVRで結構使うけど設定がめんどくさいという機能を関数化しました.
pfunctionは前から作ってたんですけど,もっと便利にならないかなぁとか思いまして...
とりあえずA/D変換を簡単にする機能と,winAVRから削除されたsbi,cbiを実装しました.
以下ソース.pfunction.cで保存して#includeで取り込んでご自由にお使いくださいね.
/**************************************
 pfunction.c
 作成者:パパ
 ver,2.0
**************************************/
#define sbi(addr,bit) addr|=(1<<bit)
#define cbi(addr,bit) addr&=~(1<<bit)
#define ibi(addr,bit) addr^=(1<<bit)
uint8_t ADConvert(int a)
{
        ADMUX = 0x60|a;
        ADCSRA = 0xC0;
        loop_until_bit_is_clear(ADCSRA,ADSC);
        return ADCH;
}
uint16_t AbsolteValue(int a)
{
        if(a < 0) a = -a;
        return a;
}
void ADCstart(int a)
{
        ADMUX = 0x60|a;
        ADCSRA = 0xC0;
}
uint8_t ADCfinish(void)
{
        loop_until_bit_is_clear(ADCSRA,ADSC);
        return ADCH;
}
※注意:このソースコードをみてなんとなく使い方が分かる方以外は使わないでください.自分で組むプログラムでブラックボックスを使うのは怖い気がするので...

でわでわ

※このソースコードにはミスがあります.2011年2月11日付けのものを使ってください.

2011年1月30日日曜日

この子ってカタカナ扱えるんだ〜

昨日知ったこと.
部室にあるこのLCD,SC1602BS*っていうんですが,昨日いろいろ調べているうちにこの子が半角カナを扱えることが発覚.
早速プログラムを書き換えて半角カナを試してみることに.
文字コードとか調べて入力する必要あるかな〜とか思ってたら,実は実は,部で使ってるLCD用のコードに既に半角カナ扱えるような仕組みが整ってたんですよ.びっくりしました.
右の写真がLCDでカタカナを表示させたところです.
このLCDを持っている人は試してみてください.持ってない人も,秋月で500円くらいで買えるようなので,試してみてはいかがでしょうか.

2011年1月27日木曜日

ブログタイトル変更,あと始めてのAVR

わずか三回目の投稿でブログタイトルを変更してしまいました・・・
早い・・・(汗

というわけで,AVRの記事でも書いてみようかなと.

とりあえずはあれですね,AVRとは何者なのかと.

端的にいうと,AVRとはAtmel社が販売しているマイコンの一種で,megaシリーズ,tinyシリーズなどとAVRのなかでもいくつか種類があります.
そんなAVRでできることは,電圧をかけたりやめたりというのを書き込まれた(焼いた)プログラムどおりにこなしていくだけです.

えっ,それだけ?と思われるかもしれませんが,それだけです.

ただ,ちゃんとプログラムなので周りの状況に応じて動作を変えることができます.例えば,ここに電圧がかかってたら,ここの電圧をだす,とか,時間がこれだけたったら電圧だすのをやめる,とか.これでちゃんとモーターも液晶も制御できます.

AVRで調べるとA/D変換やらPWMやら難しそうな言葉,機能がたくさんでてくると思いますが,基本は以上の通りです.

長文書くって大変ですね.今回はここまでです.

でわでわ