
AVRマイコンを用いてサーボを8個制御するプログラムをC言語で作っています。使っているマイコンはATmega64LでサーボはフタバのS3003、AVRstudio4.17とAVR-GCCを用いてコンパイルやシュミレートをしています。
プログラムはサーボを8個動かすために
タイマ2の比較一致割り込みで2.5msの周期をつくり
タイマ0の比較一致割り込みで0.5ms~2.5msのパルスをつくり
main関数でサーボの角度を制御するというものです。サーボ8個の角度の保持にはグローバル変数を用いています。
「サーボ初期位置→サーボ2個移動して固定」はうまくいくんですが「サーボ初期位置→※サーボ2個移動→さらに他のサーボ2個移動→はじめに動かしたサーボ2個を初期位置へ」というプログラムを書いたら、なぜか※をつけた「サーボ2個移動」の部分が実行されずその次の行動から実行されてしまいます。これはAVRに書き込んで確認したもので、シュミレータで確認するためにwait()などの待つ処理を除いてシュミレートしてみたのですが、「サーボ2個移動」の2行を飛ばして実行してしまっています。
具体的に飛ばされている部分は後述のソースコードのdo{・・・}while(1);の中の
servopos[FR_LEG]=31;
servopos[RL_LEG]=31;
で、do{・・・}while(1);の無限ループはservopos[FR_JOINT]=70;からservopos[RL_LEG]=94;を無限ループしています。
電気回路、C言語ともに初心者なので見当がつかず、いろいろ試したり調べてみてもわかりませんでした。
質問は「なぜこのようにプログラムを数行飛ばして実行してしまっているのか」です。ソースコードの指摘をしていただけると有り難いです。
ソースコード
#include <avr/io.h>
#include <avr/interrupt.h>
#define RL_JOINT 0
#define FR_JOINT 1
#define FL_LEG 2
#define RL_LEG 3
#define FL_JOINT 4
#define RR_JOINT 5
#define RR_LEG 6
#define FR_LEG 7
uint8_t phase=0;
uint8_t servopos[8]={94,94,94,94,94,94,94,94};
/*
void wait(uint16_t w){
while(w--){
volatile uint16_t i=200;
while(i--);
}
}
*/
ISR(TIMER2_COMP_vect){
PORTC=0x00;
TCNT0=0;
}
ISR(TIMER0_COMP_vect){
PORTC |= (1<<phase);
OCR0 = servopos[phase];
phase++;
if(phase>7){phase=0;}
}
int main( void ){
//ポート設定
DDRC=0xFF;
PORTC=0x00;
//タイマ0設定
OCR0 = 94;
TCCR0 |= (1<<WGM01)|(1<<CS02)|(1<<CS00);
TIMSK |= (1<<OCIE0);
//タイマ2設定
OCR2 = 79;
TCCR2 |= (1<<WGM21)|(1<<CS22);
TIMSK |= (1<<OCIE2);
// 全体割り込み許可
sei();
do{
// wait(10000);
servopos[FR_LEG]=31;
servopos[RL_LEG]=31;
//wait(1000);
servopos[FR_JOINT]=70;
servopos[RL_JOINT]=70;
//wait(1000);
servopos[FR_LEG]=94;
servopos[RL_LEG]=94;
}while(1);
}
No.1ベストアンサー
- 回答日時:
こんにちは。
servopos[FR_LEG]=31; // ←1
servopos[RL_LEG]=31;
<中略>
servopos[FR_LEG]=94; // ←2
servopos[RL_LEG]=94;
1の処理の後、その変数を使う事なく2の処理で新しい値(94)をセットしているため、コンパイラ君が
「ん?もしかして1の処理って要らないんじゃね?」
と気を利かせて、1を削除したと思われます。
処理1にも意味があるんだよ、という事をvolatileというキーワードで教えてあげればよいと思います。
回答ありがとうございます。volatileで宣言したらうまく動作しました。
volatile修飾子というのをはじめて知ったので調べてみました。AVR wikiのよくある質問を見てみたら「コンパイラが勝手にループの中の式を削除しちゃうんですけど。」というところにvolatile修飾子のことが書いてありました。指摘してくださったとおり最適化の対象になるみたいです。
これで滞りなくプログラミングできそうです。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
CPU負荷率の安全な上限と計...
-
電車で待機列の割り込みについ...
-
sleep関数の原理について
-
割り込みの衝突
-
定周期での割り込み
-
volatileについて
-
Macターミナルで実行中のプログ...
-
TCP/IP通信時のサーバーからの受信
-
Excel(VBA)でSetTimer関数を使...
-
AIXでのプロセス使用メモリの最...
-
C# シリアル通信でデータ受信...
-
FOM出版の公認テキスト&問題集...
-
メッセージボックスのボタン名変更
-
powershell を使いカレントディ...
-
Windows上で、シグナル(SIGTERM...
-
プロセスIDの取得方法について
-
エクセルVBA 大容量CSVファイル...
-
UdpClient 送信元のIPアドレ...
-
vb.netでEXCEL起動がうまくでき...
-
アプリケーションが終了するま...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
電車で待機列の割り込みについ...
-
CPUの処理量を減らすコーデ...
-
スーパーのレジで並んでいたら...
-
このレジの並び方は間違ってま...
-
Amazonfireタブレットにわから...
-
CPU負荷率の安全な上限と計...
-
【組込み】割り込み中のstatic...
-
USJでの割り込み
-
VB6でSendKeyを利用したTab移動...
-
irqbalance って
-
インバウンドで迷惑している人...
-
VB.NET スレッドからのイベント...
-
デュアルCPUのパソコンでCPUを1...
-
Timerコンポーネントのインター...
-
C言語でPICマイコン開発
-
Arduinoのプログラムで質問です。
-
マイコンSH-2の割り込みを用い...
-
H8マイコンでの割り込み(シリ...
-
優先度順方式とプリエンプショ...
-
マイコン C言語 割り込み処理...
おすすめ情報