2015年9月5日土曜日

AVR コンパイルメモ -makefile を使わない-

Xcode つかってて、なんかbuildとかがうまく行かないこととか出てきた。使い方が悪いんやけど。。。
正直あんまりmakefileの中身とか理解できてないし、fuse bitの書き換えで、AVR何個か死んだし。
これ以上死んでもらうと困る・・・

ということで、makefileが何してるのかとかもちょっとだけ触れてみようと、makefileを使わずに、というか、Xcodeも使わずに、その辺のエディタを使って編集、ターミナルでたたいてbuild的なことをすることにした。

AVR : ATmega168p
CPU : 8MHz(内蔵)
プログラマ : AVR ISP MK2

まず、main.cからオブジェクトファイルを生成。main.oが作られる。
avr-gcc -Os -Wall -DF_CPU=8000000 -mmcu=atmega168p -c main.c -o main.o

次に、オブジェクトファイルmain.oから実行ファイル形式のmain.elfを生成。
avr-gcc -Os -Wall -DF_CPU=8000000 -mmcu=atmega168p -o main.elf main.o

(次に、既にあれば、main.hex ファイルを削除)
rm -f main.hex

次に、main.elfファイルからmain.hexファイルを生成。
avr-objcopy -j .text -j .data -O ihex main.elf main.hex

これで、AVRに書き込むためのファイル(main.hex)を用意できる。
プログラムのサイズを確認する場合は、次のように書く。
avr-size --format=avr --mcu=atmega168p main.elf

ちなみに、CrossPackAVRのmakefileがやってるのと一緒。

次に、書き込み。
AVRとつないでー、なんかその辺は適当に。
つなぎ終わって、電源入れたら、次のように書く。
avrdude -c avrisp2 -P usb -p atmega168p -U flash:w:main.hex:i

これで書き込まれる。今回、内蔵発振子を使って8MHzで駆動させるから、fuse bitも変更しないと行けない。 AVR calculator でググって、サイトでfuse bitを求めて、次のように書く。
avrdude -c avrisp2 -P usb -p atmega168p -U lfuse:w:0xe2:m -U hfuse:w:0xdf:m -U efuse:w:0xf9:m

ちなみに、デフォルトでは、プリスケーラが1/8になってて、1MHz駆動になってるらしい。fuse bitの中にそれを解除する所があるから、変更が必要。

これで終了。
ターミナルつかってると、なんかやってる感じでるよね。

2015年6月15日月曜日

AVR makefile変更 複数ファイルにソースを分割 memo

AVR:ATmega168p  を使用。
開発環境:Xcode version6.2
main.c だけにプログラムを書いてたけど、長くなってきていやになったので、複数ファイルに分けることにした。
main.c、servo.c、servo.h
の3つ。(とりあえずサーボの関数だけ他の所に移そうと思った。)
まず、サイドバー?のプロジェクト直下のfirmwareを右クリック、servo.cを作成する。
同時に、servo.hも作成するか聞かれたので、作っとく。
main.cで
#include "servo.h"
を追加。
servo.hで、必要な関数(servo.cに書くやつ)の名前と引数を追加。
servo.cで、
#include "servo.h"
を追加し、必要な関数、引数を記述。
ここまでは普通。
参照:「c言語 ファイル 分割 関数」とかでググれば出てくる。
http://c-lang.sevendays-study.com/day7.html
http://bituse.info/c/21
http://homepage3.nifty.com/mmgames/c_guide/20-02.html

ビルドしてみる。
"Command + b"をぽち。
エラー発生!はい?
collect2: error: ld returned 1 exit status make: *** [main.elf] Error 1
とか
Unidentified reference ・・・
とか出てくる。
で、servo.c に書いた関数がずらっと並んで、こんなのねーよと怒られる。

makefile を書き換える必要があるらしい。
これは、main.c、servo.c、servo.hがちゃんとリンクされていないから出るっぽい。
しかし、makefileほとんどいじったことないし、いじったからといって解消されるとも限らない。
で、いろんなページみて、解消出来なくて、紆余曲折あって、結論から言うと、file targets が怪しいと。
初期状態では、

# file targets:
main.elf: $(OBJECTS)
$(COMPILE) -o main.elf $(OBJECTS)

となってる。
これに、servo.cをくっつける。

# file targets:
main.elf: $(OBJECTS)
$(COMPILE) -o main.elf $(OBJECTS) servo.c

これで、これだけで、一応コンパイルは通った。
それまでにいろいろ適当に書いてはビルドしてを繰り返して、時間をかけたから、シンプルで若干ショック。
基本的過ぎて、誰も書いてない。(探し方が悪いだけ)
もしかしたら、コンパイル通ったのはたまたまかも知れんけど。

ちなみに、途中、他にもいろいろよくわからんエラーが出たわけやけど、
makefileでの設定?のさいしょ(上で言う"$(COMPILE)"の前)は必ずTabで、spaceはダメらしい。
Tabに見えても実はspace 8個とかになってたら、なんかエラー出る。
上とは違うエラーメッセージやけど。調べてみると吉。

あー。。。。

2014年11月9日日曜日

FT232RL使ってシリアル通信 for mac memo

FT232RLを使ってシリアル通信させる memo (やりながら)
- マイコンはATmega168P。
- FT232RLは秋月電子で購入。ピンだけ自分でハンダ付け。
- FTDI社から対応している Virtual COM Port (VCP) Drivers をダウンロード
  http://www.ftdichip.com/Drivers/VCP.htm
- デフォルトでインストール、再起動。
  テクニカルノート(多分読むべき。でもはじめの方しか読んでない)
  http://www.ftdichip.com/Support/Documents/TechnicalNotes/TN_105%20Adding%20Support%20for%20New%20FTDI%20Devices%20to%20Mac%20Driver.pdf
  インストールガイド(多分読まんでいいと思う)
  http://www.ftdichip.com/Support/Documents/InstallGuides/Mac_OS_X_Installation_Guide.pdf
  テクニカルノートに、ボーレートの変更の仕方とか書いてたから、そこは読むべきだと思うけど、とりあえずデフォルトのままやった。
  あと、編集するファイルをtmpファイルにコピーして、オリジナル消して、編集して、また元の場所に戻すとかやってた。今回は編集してないから無駄に終わったけど。
  ちなみに、sudo使わないと元の場所に戻せなかった。
- FT232RLとPCを接続
- ターミナル立ち上げて、
  MacBook-Pro:/ chuchulabo$ cd /dev

  MacBook-Pro:dev chuchulabo$ ls
- cu.usbserial-A601JU7Q
  tty.usbserial-A601JU7Q
  この二つがあればいい?
- マイコン側のTXDとFT232RL側のRXD
  マイコン側のRXDとFT232RL側のTXD
  をそれぞれつなぐ
- 後、GNDをつないで、真ん中のピンを短絡させる
  (電源USB供給にする)
- 適当なプログラムを書いて、マイコンに書き込む
  (プログラムはコピペした。)
  うしこさんのブログから
  http://usicolog.nomaki.jp/engineering/avr/serialSendReceive.html
- Cool Term をダウンロードして、起動。
- ボーレートとかをマイコンと同じにする。
- PC-マイコン、FT232RL-PC、FT232RL-マイコン全部つないで、通信開始!

ーーーーー結果ーーーーー
なんかよくわからんけど、通信っぽいのはしてるのかな?
とりあえず、表示はされた。
が、絶対間違ってる。
多分、ボーレート設定とか間違えたかな。(そもそもほとんどやってない)
FT232RLのマニュアルのなかでやってない所あるから、多分そのせい。
何にしても、環境は整った!!!
後は設定いじるだけ。と思う。。。

2014年10月12日日曜日

AVRをPCから外したら動かなくなる。。。件

マイコンはPCから外しても動作するはずなのに、なぜか動かない。(もちろん電源はつないでる。)
PCとライタがつながってるUSBを外したら、動かなくなる。
なぜ。。。
make flashで書き込んだのに、動かない。。。

これでずっと悩んでた訳ですが、、、
ATmega168pとライタを分離したらちゃんと動いた。
今まではマイコン-ライタをつないだ状態で、PC-ライタをつなぐUSBをPCから外しているだけだった。
でも、これでは動かないらしく、マイコン-ライタのケーブルを引っこ抜くとちゃんと動いた。
ライタが悪さしてるっぽい。

どのページみてもちゃんと動いてるし、わからんかったけど、すんごく初歩的。。。
あーあ。。。なんで今まで試さなかったのか。。。

何にしても解決してよかた。

2014年10月5日日曜日

AVR(ATMega168P) A/D変換成功!

A/D変換メモ。
だいぶ前の話になるけど、この前のA/D変換は、オーバーフローのせいだったっぽい。
A/D変換は10bitやけど、それを8bitにしたら出来たっぽい。
プログラムは次。(ちなみに、8bitどころか6bitにしてる)


/* Name: main.c
 * Author: <insert your name here>
 * Copyright: <insert your copyright message here>
 * License: <insert your license reference here>
 */

#include <avr/io.h>

void init_PORT(){
    DDRB = 0xff;
    DDRC = 0x00;
    
}


void init_AD(){
    //外部基準電圧AREF, 入力チャネルADC1
    ADMUX = 0x01;
    ADCSRA = 0x80;
}

int main(void)
{
    int x;
    
    init_PORT();
    init_AD();
    
    /* insert your hardware initialization here */
    for(;;){
        ADCSRA |= 0x40;
        while(ADCSRA & 0x40);
        x = ADC;
        //PORTB = (x >> 2);
        /* insert your main loop code here */
        x = x/16;
        PORTB = x;
    }
    return 0;   /* never reached */
}

いろんな人のサイトを参考にしたけど、忘れた。
ちなみに成功したのはちょっと前の話。


2014年6月12日木曜日

A/D変換がうまくいかない

A/D変換のポート使ってセンサーの値読みたいと思ってるけど、なかなかうまくいかない。
多分データの取り出しか、変換完了の判別がうまくいってないんじゃないかと思うんやけど、、、
だれかHELP!

うーん、どうすればいいんやろう?
割り込み許可したし、ADMUXとADCSRA,ADCSRBの設定したのになー・・・
わけわかめ。

2014年6月8日日曜日

PWMでサーボ動かす

PWMでサーボを動かしてみた。
サーボにVCC,GND,PWMの線をつなげば動いた。
今回は、Amazon で2個入り980円で売ってるTowerPro Micro Servo SG90を使った。
PWMはOCR0Bから出した。

サーボは周期を20msくらいにして・・・らしい。
よくわからん。
とりあえず、8bit高速PWM、前置分周を64分周にしたらいいらしい。
ほかにもなんか書いてあったけど、、、よくわからん。
ていうか、前置分周がわからん。
読んだけどわからん。

後、サーボの角度とプログラムでの数値 i は、
i = (角度)/7 + 9
らしい。
i = (角度)/7 + 8
のほうが安定するらしい。

とりあえず、プログラムこんな感じ。



/* Name: main.c
 * Author: <insert your name here>
 * Copyright: <insert your copyright message here>
 * License: <insert your license reference here>
 */

#include <avr/io.h>
#include <util/delay.h>


int main(void)
{
    TCCR0A = 0b10100011;
    TCCR0B = 0b00000011;
    
    DDRD = 0xff;
    
    OCR0A = 0x00;
    OCR0B = 0x00;
    /* insert your hardware initialization here */
    for(;;){
        //if(OCR0A == 0x80) OCR0A = 0x00;
        //OCR0A ++;
        //_delay_ms(1);
        
        OCR0B = 14;
        /* insert your main loop code here */
    }
    return 0;   /* never reached */

}

なんかよくわからんけど、とりあえず動いた。
うーん。。。
とりあえず、次はA/D変換のピン使ってアナログ値を読むことをがんばる。