X



トップページ電気・電子
1002コメント332KB

AVRマイコン総合スレ Part41

■ このスレッドは過去ログ倉庫に格納されています
0001774ワット発電中さん
垢版 |
2018/09/29(土) 13:25:04.41ID:NVU21ZtG
個人でも手軽に使えるAtmelのAVRマイクロプロセッサを中心に語るスレッドです

<公式サイト>
http://www.microchip.com/design-centers/8-bit/microchip-avr-mcus
・AVR Libc Reference Manual:
https://www.microchip.com/webdoc/avrlibcreferencemanual/install_tools_1install_avr_libc.html

<参考になるページ>
・AVRWiki: http://avrwiki.sourceforge.jp/cgi-bin/wiki.cgi?page=AVRWiki
・AVR情報多い-chanさんのpage: http://elm-chan.org/
・avrfreaks.net avrgccその他AVR関連の総本山(英語): http://www.avrfreaks.net/
・TAP-Config: http://ww2.tiki.ne.jp/~maro/
・AVR.jp 日本語のAVR資料他: http://www.avr.jp/
・ATMega168日本語データシート(翻訳中): http://awawa.hariko.com/chira-ura/
・AVR アセンブラのマニュアル(ユーザーズガイド): http://www.atmel.com/Images/doc1022.pdf
・インストラクション(命令セット)の解説: http://www.atmel.com/Images/doc0856.pdf
・条件付きアセンブルの解説(アセンブラ ver. 1.74対応):http://www.atmel.com/Images/doc2550.pdf
・アセンブラとCの連携方法: http://www.atmel.com/Images/doc1234.pdf

前スレ
AVRマイコン総合スレ Part40
https://rio2016.5ch.net/test/read.cgi/denki/1517019258/
0605774ワット発電中さん
垢版 |
2019/01/31(木) 18:43:14.95ID:DV6EpONT
誰しもが通る系の道よ…

固定少数にしても表示が遅い、間に合わないってんで
LCD表示ルーチンの改良してみたり
割り込みでマルチスレッド的に出来ないか?
とか
アセンブラで書くか?
とか、やる訳よ…
0607774ワット発電中さん
垢版 |
2019/01/31(木) 20:44:52.84ID:urqG5+GC
>>602
>>604
その発想は無かったわ

たとえばfloat型数値 3.1415 を小数点第2桁まで文字列にするとしたら
まずこいつをint型にキャストして3を取り出し

(int) 3.1415 → 3

取り出した3を引いて小数点以下を抽出し、

3.1415 - 3 = 0.1415

抽出した小数点以下に100をかけて再びint型でキャストし

0.1415 x 100 = 14.15
(int) 14.15 → 14

3と14を atoi() 使って文字列に変換。ピリオドを間に挟んで結合すれば

文字列 3.14

のできあがり。こういうことか
0610774ワット発電中さん
垢版 |
2019/01/31(木) 21:12:49.71ID:a7jyaf99
30年前だがZ80でどうしてもfloatが使いたくて、MSX-C 買ったらできないでやんの。
しょうがないからアセンブラでやるfloatのライブラリが載ってる本買って、そこだけ関数呼び出し
に書き直してしのいだわ。
0611774ワット発電中さん
垢版 |
2019/01/31(木) 21:40:09.88ID:jvXK8rxN
sprintfが重いって話だろ?
floatの演算自体は仕方なかろうし、大した負荷じゃなかろう。
0612774ワット発電中さん
垢版 |
2019/02/01(金) 00:09:51.79ID:S1ArDI5h
まあでも小数2桁って決まってるんなら最初から100倍しておいて整数で演算するわな。
0613774ワット発電中さん
垢版 |
2019/02/01(金) 06:18:43.11ID:wqKgNkoQ
そう考えると、昔のBASICとか優秀だよな
あれしかメモリなかったのに
0615774ワット発電中さん
垢版 |
2019/02/02(土) 17:49:37.05ID:B6fk9Cou
昔、友人が変数名がアルファベット1文字というVTL系のコンパイラを作っって
私にくれたことがある。
プログラムサイズは512バイト程度だったと思う。
付属のサンプルプログラムが「月面着陸ゲーム」 だった。
0618774ワット発電中さん
垢版 |
2019/02/03(日) 07:07:15.57ID:RZYCs11Q
マルツってdigikey発注代行だろ?
それでこんなに取るのか
ボリ松もびっくりだな
0619774ワット発電中さん
垢版 |
2019/02/03(日) 07:42:25.48ID:4binZOhL
50円でボッタクリ。
じゃあ、Digikey で買えよ。送料払って。
0620774ワット発電中さん
垢版 |
2019/02/03(日) 12:49:52.32ID:8ZNRr/p5
すぐ欲しい数個で買って
数十百個になったら海外通販使う
新しい品種とかは前者で探すのが困難だけど
0623774ワット発電中さん
垢版 |
2019/02/04(月) 01:09:40.55ID:JmCERjpC
>>621
どうせ人件費は0円とかいう無職の発想でしょ
親が買い置きした家にある食い物はタダ、みたいな
0636774ワット発電中さん
垢版 |
2019/02/16(土) 20:18:56.09ID:27MspbiO
UARTで何かデータを受信したら割り込みを発生するテストプログラムを書いてみた。

volatile unsigned char moji='a';

ISR(USART_RX_vect)
{
char x = UDR0;
while (!( UCSR0A & (1<<UDRE0)));
UDR0 = ++moji;
}

int main()
{
UCSR0B = 0x00;
UCSR0A = 0x00;

UCSR0C = 0b00000110;
UBRR0L = 25;
UBRR0H = 0;
UCSR0B = (1<<RXCIE0) | (1<<TXCIE0) | (1<<RXEN0) | (1<<TXEN0);

while(1)
{
}
}

うまく動けばUART経由で一文字打ち込むたびに変数mojiがインクリメントされていきターミナルには

bcdefgh・・・

みたいな感じの文字が表示されてしかるべきなのになぜか

bbbbbb・・・・

といつまでたってもbしか表示されない。なにか設定おかしいところある?
0637774ワット発電中さん
垢版 |
2019/02/16(土) 20:51:41.29ID:F4GluCmK
ATMEGA328P使っておもちゃを改造した。

犠牲になったのはプリキュアのハッピーメロディマイク
https://i.imgur.com/wyrX3VO.jpg
プリキュアの音楽が流れない酷いやつ。

マイクに入るように小さく工作
https://i.imgur.com/yaQAtn8.jpg

無事に収まった
https://i.imgur.com/H2f8TlD.jpg

アニメの音楽が流れるようになった
https://i.imgur.com/pA8g8OQ.mp4
0638774ワット発電中さん
垢版 |
2019/02/16(土) 20:54:26.77ID:rFP3qrWF
>>636
送信完了ベクタが登録されていないので動作がおかしくなっているんじゃない?
送信割り込みを使わないような設定にすれば良いと思う

UCSR0B = (1<<RXCIE0) | (1<<TXCIE0) | (1<<RXEN0) | (1<<TXEN0);

UCSR0B = (1<<RXCIE0) | (0<<TXCIE0) | (1<<RXEN0) | (1<<TXEN0);

main()関数内に sei(); が無いけど、割り込み発生するの?
0639774ワット発電中さん
垢版 |
2019/02/16(土) 21:16:28.97ID:27MspbiO
>>638
> 送信割り込みを使わないような設定にすれば良いと思う

それ!ビンゴだった!
え?どゆこと?
”送信割り込み使う”に設定すると

ISR(USART_TX_vect)
{
}

送信側をきちんと定義してあげないと

ISR(USART_RX_vect)
{
}

受信側の挙動に影響が出るってこと?


sei()はごめん、コピペするの忘れた^^;)
0640774ワット発電中さん
垢版 |
2019/02/16(土) 21:31:46.11ID:rFP3qrWF
>>639
割り込みベクタテーブルの初期値は 0x0000 だったハズ(データシートを読んでみて下さい)
ISR(〜) を定義しないと割り込み発生時に 0x0000 にジャンプする

送信完了→送信完了割り込み発生→ベクタテーブルを参照して 0x0000 にジャンプ(見かけ上、リセット動作となる)

送信完了割り込みが必要無いのなら空の ISR(USART_TX_vect) {} を定義するよりも、送信完了割り込みを禁止したほうがコードサイズが小さくなるし余計な割り込みも発生しませんよ
0641774ワット発電中さん
垢版 |
2019/02/16(土) 21:57:23.03ID:rFP3qrWF
>>639
補足
>受信側の挙動に影響が出るってこと?

 ISR(USART_RX_vect) 内で送信処理しているでしょ
 送信処理が完了すれば ISR(USART_TX_vect) に飛ぼうとするので結果として 0x0000 にジャンプします
0642774ワット発電中さん
垢版 |
2019/02/17(日) 01:07:21.43ID:e3U5fsZq
>>640
そういうことなのね
UARTで一文字送信するたびにリセットボタンを押してたようなものか
どうりで変数が常に初期化されるわけだ

こういう挙動ってちゃんとしっとかんとあかんね(´・ω・`)
0645774ワット発電中さん
垢版 |
2019/02/19(火) 23:46:53.17ID:WmSSklev
ATMEGA328P使って環境モニターっぽいことやってる
常時起動してるのは電池の無駄だからスリープ使ってるんだけど
スリープ復帰後にI2Cセンサとの通信ができなくなることがある。

詳細に調べてみるとスリープモードが
・パワーダウン
・パワーセーブ
・スタンバイ
のときはスリープ復帰後にI2Cが使えない(通信途中でフリーズする)ことが分かった。
ただ唯一、一番省エネ効果が低い
・アイドル
に設定するとスリープ復帰後もI2Cは問題無く使える。

I2Cってディープスリープ状態から復帰後は使えなくなるんだっけ?
0646774ワット発電中さん
垢版 |
2019/02/20(水) 01:43:01.69ID:1DISpaXs
そんな話聞いたことないし、そうだとすれば大炎上してるよ。
ソース晒してみなよ。
0647774ワット発電中さん
垢版 |
2019/02/20(水) 01:46:45.55ID:1DISpaXs
もしかしてTWIの電力削減レジスタ弄って、なおかつウェークアップ後初期化してないとか?
0649774ワット発電中さん
垢版 |
2019/02/20(水) 20:59:33.69ID:+tpxrGaP
>>646
全部掲載はさすがに足りないから無理だけど要所くらいなら・・・
ちなみにTWIの電力削減レジスタとか難しいことは一切やってないよ

やってることだけどRTC使って一定時間ごとにAVRに割り込み(INT0)かけて起動してデータセーブ。
セーブが終わったらスリープして待機。
具体的にはRTC使ってINT0ピンをLowに引っ張って割り込みをかけてやる。
RTCの仕様でそのままLowに引っ張り続けるからI2C経由でAVRからRTCに命令出してHighに戻すよう命令
(release_interruption関数)。

問題はこのI2C通信で発生するっぽい。パワーダウンスリープから目覚めた直後だとI2C通信の途中で応答不能になり
アイドルスリープから目覚めた直後だと問題無く動作する。スリープを一切使わない場合もむろん問題無く動作する。

↓ちなみに以下ソース
0650774ワット発電中さん
垢版 |
2019/02/20(水) 21:00:44.95ID:+tpxrGaP
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include "FatFs/ff.h"
#include "FatFs/diskio.h"

volatile UINT Timer;
ISR(TIMER0_COMPA_vect)
{
Timer++;
disk_timerproc();
}
// 以上FatFsで必要なタイマー割り込み
volatile unsigned char int0_cnt;
ISR(INT0_vect)
{
int0_cnt--;
release_interruption(); // ←I2Cで通信しようとするこの関数で止まる
}
volatile char usart_recvData[256];
volatile unsigned char usart_recv_write;
ISR(USART_RX_vect)
{
char x = UDR0;
usart_recvData[++usart_recv_write] = x;
}
int main(void)
{
TIMSK0 = _BV(OCIE0A);
TCCR0A = _BV(WGM01);
TCCR0B = 0b101;
OCR0A = F_CPU / 1024 / 100 - 1;

EICRA = (0<<ISC01) | (0<<ISC00);
EIMSK = 1<<INT0;

UCSR0B = 0x00;
UCSR0A = 0x00;
UCSR0C = 0b00000110;
UBRR0L = 25;
UBRR0H = 0;
UCSR0B = (1<<RXCIE0) | (0<<TXCIE0) | (1<<RXEN0) | (1<<TXEN0);

sei();
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();

int0_cnt = 5;

while (1)
{
if ( int0_cnt == 0 )
{
int0_cnt = 5;
save_data();
}

sleep_mode();
}
}
0652774ワット発電中さん
垢版 |
2019/02/21(木) 00:17:18.89ID:1mBEjo2+
俺は小心者なので、
割り込みハンドラの中で通信ルーチンコールとか、
怖くて出来ない

スタック食い潰しの原因追求で泣きそう
になったこととかあるし…
0653774ワット発電中さん
垢版 |
2019/02/21(木) 00:33:13.05ID:40+hINCy
INT0割り込み→i2cでRTCにINT0ピンHIGH指示→割込処理から抜ける。でもこのときRTCはまだINT0ピンHIGHの処理完了してないので、またINT0割り込み入る。AVRはi2c始めようとするけどRTCは前の指示実行中なのでしらんぷり。
0654774ワット発電中さん
垢版 |
2019/02/21(木) 01:00:46.20ID:a31cyszz
>>INT0ピンHIGH指示
の後に割り込みをすぐに抜けずに、INT0ピンがHiになるのを待ってから抜ければOKってことか。
0655774ワット発電中さん
垢版 |
2019/02/21(木) 01:16:43.08ID:1mBEjo2+
ちょっと待て
EICRA = (0<<ISC01) | (0<<ISC00);
ってなんぞ?
これじゃ
EICRA=ISC01|ISC00
と同じだから、立ち上がりトリガにならんか?
(他もだけど…)
0656774ワット発電中さん
垢版 |
2019/02/21(木) 01:28:58.76ID:mfwbhZjO
>>655
ならない。無意味ではあるけど…
普通は
EICRA &= ~(_BV(ISC01) |_BV(ISC00) );
かな。
_BV() 使ったり、直接シフトしたり一貫性がないとは思う
0658774ワット発電中さん
垢版 |
2019/02/21(木) 16:56:23.11ID:+p1+Xh6O
>>656
ちょっと興味あったので・・・
DDRA = (0 << PA0) | (0 << PA1) ; は
out DDRA, zero
ふむふむ

DDRA |= (0 << PA0) | (0 << PA1) ; は
in tmp, DDRA
out DDRA, tmp
うーむ -Os オプション付けても刈取らないのね・・・
(atmel stuido 7)
0659774ワット発電中さん
垢版 |
2019/02/21(木) 18:57:34.89ID:dey808pv
意図して読み出した1を書き戻すことも有るからね。バグになっちゃう。
0660774ワット発電中さん
垢版 |
2019/02/22(金) 08:38:26.52ID:nzDShw1O
秋月の通販サイトみたらDIPのAVRマイコンATMEGA1284P−PUが売ってた。
750yen
AVRマイコンの未来は明るい。
0661774ワット発電中さん
垢版 |
2019/02/22(金) 09:38:49.50ID:ZNVWCvt4
来たかっ(ガタッ
0666774ワット発電中さん
垢版 |
2019/02/22(金) 17:50:52.72ID:4EQI3SDG
>DIPだからクソデカくて面白いって話
それどこに書いてる?
0668774ワット発電中さん
垢版 |
2019/02/22(金) 18:44:50.96ID:MEC1rnMB
フラッシュを10,000回書き換えて
書き込み不能にした強者っているのかな
0674774ワット発電中さん
垢版 |
2019/02/22(金) 23:35:36.28ID:5BJLG1gH
> フラッシュを10,000回書き換えて
> 書き込み不能にした強者っているのかな

何回書きかえたら壊れるか(書けなくなるか)に関しては
実際に試して確認した情報を どっかで見たな
0677774ワット発電中さん
垢版 |
2019/02/26(火) 00:57:37.44ID:NFTn/ZGf
ESP-WROOM-02にリセットボタンを付けて連続でパチパチとリセットしてたら、
テレビの受信デシベルが低くなって映像が途切れたりした。
2.4Ghzって地デジの電波に影響あるんだな
0680774ワット発電中さん
垢版 |
2019/02/27(水) 01:03:40.41ID:PlbPXMaw
フラッシュに書き込んだプログラムがいつまで保持されてるのか気になる
たしか100年ぐらいは持つんだっけな?

書き込みを繰り返したやつは酸化膜がやられてて電荷が抜けるのが早くなるだろう
0683774ワット発電中さん
垢版 |
2019/02/27(水) 03:25:04.95ID:MVY/lNE/
ちょっとさっきくしゃみしたら
変換基盤に仮置きしていたATtiny10が全部消えたんだが?
こないだ家電のケンちゃんで書き込み用補助具買ったばかりなんだが?
秋月の10個入り全部消えたんだが?
朝の鼻くそに混ざっていそうなんだが?
0686774ワット発電中さん
垢版 |
2019/02/27(水) 20:47:39.08ID:MVY/lNE/
>>684
バカヤロー鼻くそだって書いてあっだろ!
俺の繊細なケツからあんなもん出てきたらあっという間にパンツ血まみれ
0687774ワット発電中さん
垢版 |
2019/02/27(水) 21:42:41.17ID:T/B+R8oC
SSDなら耐久テストをしたサイトがあったな
東芝製が書き込み禁止にして保護するとか
0689774ワット発電中さん
垢版 |
2019/02/27(水) 22:46:46.58ID:6AVGd6dV
UART経由でターミナルに文字列吐いてからパワーダウンスリープするプログラム作ってみたんだけど、

void uputc(unsigned char x)
{
 while( !(UCSR0A & (1<<UDRE0)) )
 ;

 UDR0 = x;
}

ターミナルに表示される文字列の末尾が文字化けしてしまう。
(上記のプログラムは一文字UARTに送信する関数。
これを連続呼び出しすることで文字列をターミナルに送ってる)

パワーダウンではなくアイドルスリープに変更したり、スリープそのものをしないようにすれば
末尾まで正常に表示されることからUARTの送信バッファから文字が全て吐かれる前に
AVRがスリープしちゃってるのが原因じゃ無いかと踏んだ。

だったら送信バッファが空になるまで待てばいいじゃんと思い、

void uputc(unsigned char x)
{
 while( !(UCSR0A & (1<<UDRE0)) )
 ;

 UDR0 = x;

 while( !(UCSR0A & (1<<UDRE0)) )
 ;
}

と修正してみたけど変わらなかった。他にも送信シフトレジスタが空になったとされるTXCフラグが1
になるまで待ってみたりしたけど、

 while( !(UCSR0A & _BV(TXC0)) || !(UCSR0A & _BV(UDRE0)) )
 ;

これも変わらなかった。最後の一文字までターミナルに無事送り届けられたタイミングを知るには
どうしたらいいのかな?
0690774ワット発電中さん
垢版 |
2019/02/27(水) 23:05:56.16ID:RapFhyb5
>>689
AVRのプログラム経験あまり無いけどバッファが空に成った後に空ループ回しながら暫く待ってスリープは試してみた?
0691774ワット発電中さん
垢版 |
2019/02/27(水) 23:25:39.92ID:ytHC5ZXo
TXCフラグは割り込みを使用していなければ、
プログラムから動的にクリアされなければならない。
UDR0 = x;
の次に
UCSR0A |= _BV(TXC0);
っていれてみれば?
0692774ワット発電中さん
垢版 |
2019/02/27(水) 23:29:04.24ID:1y6F2gOX
>>690の対症療法でもいいが…そもそも根本的な勘違いがある。TXCフラグの説明読んだか?
『The TXCn Flag bit is automatically cleared when a transmit complete interrupt is executed, or it can be cleared by writing a one to its bit location.』
とある。日本語にすると『TXCnフラグは、送信完了割込みを起こすか、自分で1を書くことで初期化できます。』ということだ

つまり、送信完了割込みを使ってないのならば、自分で毎回クリアしないと、最初に何か送信して空になって1になったら…あとはずっと1のままだ!!!

送信中は0で終わったら1に勝手に変わるとかいう便利なものではないぞ???
0693774ワット発電中さん
垢版 |
2019/02/27(水) 23:35:55.82ID:0TOANvas
なぜ動かないんだ!MPUのバグか?
って時の99%は、データシートをちゃんと読んで
無かった自分のせい
0694774ワット発電中さん
垢版 |
2019/02/27(水) 23:40:07.26ID:MwsScFW1
どうでも良いけど、なぜ
loop_until_bit_is_clear();
使わないんだ?
0695774ワット発電中さん
垢版 |
2019/02/27(水) 23:59:49.64ID:6AVGd6dV
>>690
↓みたいにforループ1000回入れてみたら最後までターミナルに正しく表示されるようになったから
 たぶん送信バッファを確実に空にするまで待つ、という戦略であってると思う

void uputc(unsigned char x)
{
 while( !(UCSR0A & (1<<UDRE0)) )
 ;

 UDR0 = x;

 for(int i=0;i<1000;i++)
 ;
}

>>691
ほ、ほんとだ!
void uputc(unsigned char x)
{
 while( !(UCSR0A & (1<<UDRE0)) )
 ;

 UDR0 = x;
 UCSR0A |= _BV(TXC0);

 while( !(UCSR0A & (1<<UDRE0)) )
 ;
}
これでも正しく末尾まで正しくターミナルに表示されるようになった!
>>692
そういうことなのね。自分で1にsetしてやらないと0に戻らないのね。
勉強になった、ありがとうノシ
0696774ワット発電中さん
垢版 |
2019/02/28(木) 06:31:20.36ID:UjtlN9fm
Aliで売ってる1000円以下のJTAGって使い物になる?
0699774ワット発電中さん
垢版 |
2019/02/28(木) 07:46:58.49ID:Nn1mUl6z
>>697
intの前に「volatile」付ければ?

>>695
問題解決良かったね。

>>692
AVR初心者として参考になった。
ありがとう。

>>693
そう。焦れば焦るほどバグ、つまり自分のミスに気付かない。
俺はプログラミングは己れの煩悩を取り払う能力を養う最強の修行法だと解ったわ。
0702774ワット発電中さん
垢版 |
2019/02/28(木) 20:42:53.98ID:uv1Hvimb
>>695
送信後のウエイト処理で見ているフラグが違うと思います。

while ( !(UCSR0A & (1<<TXC0)) );

こうじゃないですか?
■ このスレッドは過去ログ倉庫に格納されています

ニューススポーツなんでも実況