初めてのPIC 0x14
レス数が1000を超えています。これ以上書き込みはできません。
.
_ _ PICをさわるのは今日が初めて、という超初心者のためのスレです。
(O>――<O) PIC選び、PICを使った回路は、誰でも最初は不安なものです。
/ (・) (・) ヽ 恥ずかしがらずに何でも聞いてください。速攻で教えてくれますよ。
○ /▼\ ○ 質問のしかたは、初心者質問スレの発言1を見てくださいね。
|(ヽ二フ ) |
/  ̄ ̄ ̄ ヽ
f ヽ / | PIC関係のスレは、レベルに合わせて以下のスレもありますので、活用しましょう。
ヽ \ / ノ ・PIC専用のスレ
| \_ )(_/ ! 本家本元のPICスレです。口の悪い人もいますが、楽しくやってるみたい。
| | ここの話がわかるようになれば、あなたはもう一人前のPICerです。
| | ・マイコンソフト 悩み事相談室
| | ̄ ̄| | マイコンソフトやツールの質問は、こちらでどうぞ。的確な回答があります。
(_ノ ヽ_)
質問するときは…
・PICの型番と開発環境を明記しましょう。
・プログラムは、レス内に直接書き込まず右記を利用しましょう。 ttp://codepad.org/ ttps://pastebin.com/
・解決したら結果報告しましょう。
・Atmel買収以降アンチによる荒らしも横行しているので無視しましょう。
・先輩たちの雑談は「PIC専用のスレ」でお願いします。
ハード、ソフト情報
・統合開発環境 MPLAB X ttp://www.microchip.com/mplab/mplab-x-ide
・コンパイラ(XC8 XC16 XC32) ttp://www.microchip.com/mplab/compilers(高機能版のみ有料)
・コード生成プラグイン(MCC) ttp://www.microchip.com/mplab/mplab-code-configurator
・マイクロチップ・ライブラリ(MLA) ttp://www.microchip.com/mplab/microchip-libraries-for-applications
・PIC一覧、スペック検索
ttp://www.microchip.com/ParamChartSearch/chart.aspx?branchID=1005
ttp://www.microchip.com/maps/microcontroller.aspx
・初心者はPIC16F1以降の型番で始めると無理なく始められます。
MCCを使えば、最初からPIC32で始めるのもありです。
・プログラムの書込みには書込器が必要です。
予算に応じてPICkit4、SNAPなどを購入しましょう。
ttp://akizukidenshi.com/catalog/g/gM-13854/
eBayやAliExpressで買えるPICkit3の中華クローンも十分な性能が報告されています。
過去スレ
0x13 2019/02/15〜 ttps://rio2016.5ch.net/test/read.cgi/denki/1550166200/
0x12 2018/09/19〜 ttps://rio2016.5ch.net/test/read.cgi/denki/1537343778/
0x11 2018/08/05〜 ttps://rio2016.5ch.net/test/read.cgi/denki/1533446166/
0x10 2018/06/29〜 ttps://rio2016.5ch.net/test/read.cgi/denki/1530265723/
0x0F 2018/05/01〜 ttps://rio2016.5ch.net/test/read.cgi/denki/1525183933/
では、質問どうぞ〜っ >>911
理解できなかったので全部RBにしてLED8個達成しますた…
ヨシッ! >>900
ソースの「{ }」「else」を置く位置が間違いやすい位置に置かれているので、
今後のこともあるので、直した方が良いですよ。
else は、ifと同じ位置に置に。
} は 対応する } と同じ位置に置いたほうがいいです。
インデントにはTABを使いましたょう。こんな感じです。
if(ima7 < ontime7 && senkou7 == 1){ // TAB1つ
RA7 = 1; // TAB2つ
} else { // TAB1つ
RA7 = 0; // TAB2つ
} // TAB1つ
さらにこの場合0〜7まで同じ処理が続くので、以下のように書くと、
0〜7の数字の位置が一定になり、みんな同じことをしているんだな、とわかりやすいです。
if(ima1 < ontime1 && senkou1 == 1){ RA1 = 1; } else { RA1 = 0; }
if(ima2 < ontime2 && senkou2 == 1){ RA2 = 1; } else { RA2 = 0; }
if(ima3 < ontime3 && senkou3 == 1){ RA3 = 1; } else { RA3 = 0; } という具合です。
別の書き方として、こんなのもあります。RA= という代入のイメージで、RA= を2回書かなくても良いので、わかりやすいです。
RA1 = (ima1 < ontime1 && senkou1 == 1)? 1 : 0; // 真なら1、偽なら0
RA2 = (ima2 < ontime2 && senkou2 == 1)? 1 : 0; // 真なら1、偽なら0
RA3 = (ima3 < ontime3 && senkou3 == 1)? 1 : 0; // 真なら1、偽なら0
また、if()の条件は、3つ以上書くと、勘違いしやすいので、()を使って単純にするのも良いと思います。
if( (ima3<ontime3) && (senkou3==1) ){ >>914
そもそもifを使うのがダサいし、
おんなじような処理を何回も書くのもダサいな はじめてなんだからまあまずは一番基本の書き方でいいんじゃない?
んで関数化してりビット演算やcaseや三項演算子やらでスマートにかけることをまなんでいけばいいんや。 switch() case: で、うまく書けると見やすいですよね。 みなさんありがとです
まだ全然意味を理解してないけどやりたいことはボチボチ出来はじめているんでまたよろしくです ICSPのPGC.Dの先に繋がる回路がトランジスタアレイなんだけど何も対策しないで大丈夫?
RB6/7は出力になっててアレイの先に繋がるのはLEDだけど。 >>920
RB6/7は出力 で トランジスタアレイ が繋がっている、ということですよね。
・出力でもOKです。
・トランジスタアレイは、デジタルトランジスタですよね?
負荷4.7kくらいなら大丈夫です。 お聞きしたいんだがこんな物作りたいんだけど作例とかありますかね?
4bitのON/OFF情報を送信側のPICで読み取って、USARTで受信側のPICに送信して出力するって感じで。
定番のリモコンICも考えましたが無線かIr前提だし、TWELITEにI/O機能があるけどデカイし高いんで・・・。
そう言う作例があれば参考に出来るんですけど、あいにく殆どCは書けないんで参考が欲しいんです。
よろしくお願いします! >>924
Cを書けないとして、なになら書けるのかとか、Cを読めるのかとか、これまでのマイコンや回路の知識とか
できることを書かないとみんな何もアドバイスしにくい。
Cが読めるなら、PIC16Fでこなすなら、UARTのついたもので、できるだけ新しいもの(PIC16F18xxxあたり)を選んで、
MCCでクロック、ポート、UARTの設定をしたら、あとはひといき。
まったくマイコン経験がないなら、PICではなくて、Arduino から入ったほうが作例は多いよ。 優しいなあ
俺なら「宿題は自分でやれ」と言って終わりだね つうか趣味でPICやらリモコンICやらIrDAやら弄ってるならC書けないとかあり得んじゃん
どんなん入り口からこの世界に入ったのよ XC8のdelay()は実際はマクロで、内部でnopに展開されてると聞いたのですが
delay_ms(10)とかで10msの『待ち』を作った場合、その間は割り込みは禁止
されてしまうのでしょうか?
delay処理の間に割り込み要因が発生したらちゃんと割り込みさせようと思ったら
どうすればいいんでしょうか。 >>930
割り込みを禁止しない限り割り込みは有効なはず
注意点としてはdelayはNOPをループされてるはずなので、割り込み中に時間が掛かればその分時間がズレる >>928
>つうか趣味でPICやらリモコンICやらIrDAやら弄ってるならC書けないとかあり得んじゃん
すくなくとも>>924には、そう確定するだけの話は書いてないと思うんだけど。 >>932
ありがとうございます
delay()の間も割り込みを禁止していなければ普通に割り込みは発生するんですね
しかしそうなるとnoploopの間に割り込みが発生したらdelay()の時間が正確じゃ
なくなってしまいますね。うーん、困ったなぁ >>935
正確さを期待するなら、ペリフェラルのタイマーを使うのが近道だと思うのだけど。 >>924
初心者なので参考にならないかもだけど、作ってみた
https://i.imgur.com/XUjzueg.jpg
MCCで初期設定してプログラムしたのは以下の部分のみ
送信部
void main(void)
{
SYSTEM_Initialize();
uint8_t SendValue;
while (1)
{
__delay_ms(100);
SendValue = in1_GetValue();
SendValue = (SendValue<<1) + in2_GetValue();
SendValue = (SendValue<<1) + in3_GetValue();
SendValue = (SendValue<<1) + in4_GetValue();
EUSART_Write(SendValue);
}
}
受信部
void main(void)
{
SYSTEM_Initialize();
uint8_t ReceiveValue ;
while (1)
{
ReceiveValue = EUSART_Read();
out4_LAT = ReceiveValue ;
out3_LAT = ReceiveValue >> 1;
out2_LAT = ReceiveValue >> 2;
out1_LAT = ReceiveValue >> 3;
}
} >>938
だとしたら>>929って妄想ひどいね。 XC8を使っていますが、関数から返り値を複数戻したい場合に通常のCなら
呼び出し側で変数を宣言して、そのポインタを引数として渡すことが多いと
思います
XC8でも同じようにやればいいでしょうか?
それともパフォーマンスを考慮してグローバル変数を介したほうがいいんでしょうか?
そこまで小賢しい事を考えても大してパフォーマンスは変わらないならポインタを使った
ほうが良いでしょうか? どうパフォーマンスが変わるというのか
どうアセンブルされるかわからんからそういう頓珍漢なことを言う >>942
基本、変数のアドレスは固定だから、大した違いは無いと思う。 >>942
馬鹿が無理して口出してこなくていいよ。寒いだけだから
>>940
厳密なことを言えばGlobal変数を介した方がコードは短くなります
ただ無視出来る範囲だと思います
XC8のPRO版での最適化結果なのでPRO版以外は違うコートかも知れませんが、
変数ポインタ経由で値を1個もらう場合ですが、メモリ上に2つの変数領域(a, b)が確保されます
関数を呼ぶ際にbにaのアドレスを入れてから関数を呼び、関数側はbが指し示すアドレスに
処理結果を入れます
なので関数呼び出しの際の「bにaのアドレスをセットする」処理の分、コードが長くなります
といってもmovlw、movmfだけで済むのでたった4byteです。
>942のようなマウントしか脳の無い馬鹿は無視していいです >>940
ちなみに、Cで書いたコードがどのようにコンパイルされたかの結果はLSTファイルに出力されますので
気になる場合はLSTファイルをチェックして下さい
割と納得できる結果になっている場合もあれば、たまにびっくりする様な結果を吐いている場合があります
そういう場合はその部分だけインラインアセンブラで自分で記述してやりましょう と言いつつお前もマウントとろうとしてるじゃん爺
爺同士の醜いマウント合戦 ID:uUHm7pbS は「いかなる場合もマウントしてはいけない」とは書いてないし、
「と言いつつお前もマウントとろうとしてる」という批判は的外れ。 ID:uUHm7pbSのマウントはきれいなマウントニダ ピックでソフトウェアーシリアル受信を行いたいのですが、色々調べても
よくわかりません。言語はC言語でXC8を使っています
INT割り込みか状態変化割り込みでスタートビットの変化を検出したら、
あとはタイマー割り込みを使って一定周期でポートの状態を見ればよい
8ビットパリティなしストップ1なら9回タイマ割り込みがかかった所で
1バイトの受信終了)と思っていたのですが、4倍オーバーサンプリングとか
8倍オーバーサンプリングというのがよくわかりません
前述のような考え方の処理じゃ問題ありますでしょうか? 久々に工作しようとPICKITを秋月で見たら4になってた
買って色々インストールしたらわけわかんねー?!
なんだIDE/IPEってww
久々過ぎたなw >>950
原理的には、ボーレイトを b とすればスタートビット検出後 n / b + 0.5 / b 時間
ごとに受信データの 0/1 を判定すればよい。
割り込み機能の無い baseline でもフリーランタイマーと次にサンプルすべき時間
を比較することで実現は可能。ただし、単純ではない他の処理も同時実行しようと
するとプログラミングが極端に難しくなる。
オーバーサンプリングはデータに乗る短いノイズやジッター(ゆらぎ)による誤動作
の対策に有効な手段だがソフトウェア処理が難しくなる。
ゆらぎノ
片づけ脳いんとをtrue愛称アー. 順+ + nbしたらその後ビットどうインプリメントdouソフトウェアーシリアル受信を行いたいということはtoiuのですが >>950
原理的には、ボーレイトを b とすればスタートビット検出後 n / b + 0.5 / b 時間
ごとに受信データの 0/1 を判定すればよい。
割り込み機能の無い baseline でもフリーランタイマーと次にサンプルすべき時間
を比較することで実現は可能。ただし、単純ではない他の処理も同時実行しようと
するとプログラミングが極端に難しくなる。
オーバーサンプリングはデータに乗る短いノイズやジッター(ゆらぎ)による誤動作
の対策に有効な手段だがソフトウェア処理が難しくなる。 >>952が後半突然発狂したけど、特にいつものことなの? > ただし、単純ではない他の処理も同時実行しようと
> するとプログラミングが極端に難しくなる。
ソフトウェアのUARTを自作すると、割込み付きハードウェア処理の有り難みを実感するよな。
いわんやDMAにおいてをや。
うーん、マルチタスクを動かせれば少しは楽になるかな? >>954 プレビューが不本意にオフになっていると、たまにゴミ付きでアップしちまうだ。
>>955 9600bps だと 1bit 100μs 程度以内には次のビットを確実に見ないといけないので
状態遷移で疑似マルチタスク的なことをやっても baseline だと忙しさの点で難易度が高い。 >>956
サンプリングをタイマ割込みで処理できれば、他の同時処理もそんなに面倒では無いのにね。
オーバーヘッドが少なくて、10uS位でディスパッチすればいけるかもしれないと思った。 >>953
すいません、せっかく回答頂いたんですが内容が理解出来ませんでした
>ボーレイトを b とすればスタートビット検出後 n / b + 0.5 / b 時間
>ごとに受信データの 0/1 を判定すればよい。
ここで言うnは何を指していますでしょうか?
あと
>オーバーサンプリングはデータに乗る短いノイズやジッター(ゆらぎ)に
>よる誤動作の対策に有効な手段
ということはやっぱりオーバーサンプリング処理というのをやったほうが
良いってことでしょうか? >>958
シリアル通信の基礎、スタートビット、データビット、ストップビットの概念は判ってる?
n はデータビット(厳密にはデータビット+1)
n / b + 0.5 / b は各データビットの中央部の時間(タイミング)。
オーバーサンプリング処理はやったほうが良いに決まっているが、難しいことを
考えると先に進めなくなるので、まずは各データビットの中央部のタイミングで
0/1 判定し、それをシフトする方法でやってみるのが良いと思う。 全二重じゃなくて、送信側と受信側でタイミング合わせて、一度に転送できるバイト数も制限すればベースラインで38400bpsくらいまで可能だけどかなりきついし面倒だな
昔々Writer509とかいうのがあったじゃない、あれが12F509で割り込み使わないポーリングの半二重の38400bpsだった PICのBaseLineでポーリング処理していろいろな物作ってるけど
PICでタイミング合わせるのはそれほど難しくないので、みなさんも
試してみてはいかがですか
シリアル伝送、ソフトPWM、1-wireのslave、赤外線データ伝送など
そこそこの速度で動作します
下手に割り込みに頼るとメイン処理が割り込みによって間に合わなくなる
割り込みのオーバーヘッドが意外にデカくてデータを取りこぼす
デバッグがしにくくバグが生じやすいなど
高速処理できるチップの場合のみ割り込みが自由詩使えると思っています ポーリング中に合間を縫ってメイン処理ができるなら割込みでもできる 割り込み処理はフラグを立てるだけ。
メインループは各割り込みフラグをチェックしてサブルーチンをコールするだけ。 インターバルタイマー割り込みだけで全部やるのはありだよ。
1msあればかなりのことができる。 >>964
BGMをFM音源6音で再生しながら
メイン処理させるときは、割り込みでフラグ立て作業終わった後に
FM音源にコマンドセットする処理をする >>964
フラグを使うだけなら、割り込み要らないだろ? >>967
メインループでタイマーカウンタの読み取りやるの? >>968
割り込みを有効にしなくても、フラグは立つ。 タイマーは使うが、割り込みは必須ではない
カウンタの値をポーリングして1ms進んでいたら処理をすればいいだけ >>967
タイマー割り込みはカウントアップもする。
1ms割り込みがあるとしたら、10回数えて10msフラグを立てる、1000回数えて1秒フラグを立てる。
メインでフラグが立ってたらフラグとカウンタをクリアしてタイマー処理ルーチンを呼ぶ。 >>971
話が少し逸れるが、割り込みごとに2〜4バイトくらいの固定値を加え、
あるビットのキャリーを見ることにより、より正確な1秒にチューニング
することもできるよ。
#割り込みでもフラグ見るだけでもタイマーのポーリングでも同じだが 割り込み使わなくていいっつってるやつは
大したことやった経験ないからそういう結論なわけで
まぁ、そういう間抜けはスルーしとけ >>973
割込みを使って処理できることを知っていて、
割込みを使わずに工夫して処理する、というのも有りだよ。
>>969 のように割込み要求フラグをポーリングで処理するのも有りだし。
割込みを使わなくても良い、と言う人は間抜けでは無いと思うナ、私は。 初心者が割込みを覚えると、割込みが使えるなら何でも割込みで処理する、になる。
そして次のレベルに進むと、割込みが必須な場合だけ割込みを使う、になり、
やがてマルチタスクと組み合わせて必要最小限の割込みを使う、になる。
(個人の感想です)w 低消費電力にしようと思ったら、無分別に「ポーリングでいいや」とは言えないですよね。 モーターの代わりに内燃機関を使えば消費電力が抑えられるのでは。 >>976
なんで? 1msごとにスリープするのか? >>976
タイマーを使ってもポーリーングでもコア部分は常に動いているので
大して電力の差は出ないよ
一般的に省電力に貢献するのは周辺ペリフエラルを停止するのが
常に動作させている時の省電力で効果がある方法です
それ以外ではSLEEPにするのが一番省電力だけどすべてが止まってしまうし
ので正確な制御がしづライト思います。
精度がいらない方法ならそれでも可能だと思うけど、ちょっと疑問です SLEEP すれば消費電流がガクンと下がる。
割り込みのない baseline でも SLEEP しては
一定時間後 WDT で起きてパパッと処理する
方法により、単三乾電二本で計算上数年以上
動作する筈のモノを作ったことがあるよ。
ちなみに割り込みなしでも複数の状態遷移表
を作ってウンウン考えて作ればかなり複雑な
事でもできるよ。 はずのモノってことは動かしてないのか。
完成したら使わないってありがちポイ。 >>981 作ってからまだ1年半した経ってないから × 1年半した
○ 1年半しか
あと、電池の液漏れの方が先かもしれんので
はずと書いた >>979
>タイマーを使ってもポーリーングでもコア部分は常に動いているので
>大して電力の差は出ないよ
タイマーを使ってもポーリングしてたら減らないね。 >計算上数年以上動作する筈のモノ
あはは。あるある。計算上10年とかだと、試せないし。 フジカラーの100年プリントとか子供心にどうやって検証したの?って思った。
先生に質問して「何十倍もの過酷な環境下での劣化具合から推定して」と説明されても納得できなかったな。 >>982
メカでってどういう意味?
ならZ80互換マイコン使え ターゲットPICだけどプログラミング自体の問題の質問はどうしたらいい?
ム板とか行くべき?
CCSCでUARTを実装したんだけど、文字が勝手に流れてしまって内部で処理できない。
手動にも対応したいから、改行コード来るまで内部で取り込んでおくってどういう風に描けばいい?
while文か何かで改行文字が来るまで待ちたいんだけど、while文自体の中にwhile文置けないとかある? やっぱりこっちか。書き込んでも良いんだけど、
環境
12F1612
X 5.25
CCSC 5.083
通信はTera Term
該当部分のソースコード
while(TRUE)
if(kbhit(upper))
{
while(( string = fgetc(upper)) != EOF ){
GETS(string);
}
get_upper();
}
これが素通りしてしまう。1文字目で出力先、2文字目で正しいデータかどうか見たいんだけど。
手打ちだと1文字ずつ送らされてしまって判断してない(upperに無制限で流しだしてる)模様。 >>992に追記で、このプログラムは動かないのを追記するの忘れてた。
ともかくこんな感じでどう書けばいいかのアドバイスが欲しいです。
基本一文ずつUART信号が入って来るんですが、手動でもテストしたいのでGETSした後どう記述すべきか、みたいなアドバイスが欲しいです。
現在は一文で入ってきて、一文ごとに送り出す予定です。 >>993
文字が勝手に流れてしまって
とは、どのような動きですか?
その辺を説明して欲しいです >>993
質問自体がよくわからないけど、
C的な一般論でアドバイスすると、kbhit は1バイトを受信しているかを確認する
処理で、fgetc はその1バイトを受け取る処理でそこまでは何となくわかるが、
2個目の while で kbhit 確認しないで fgetc やり続けるし、すでに fgetsc で受
信データを読み取ったのに、その後に GETS ?何やってるの?と思いました。 >>992
適当に作ってみた
MPLAB X IDE MCC+XC8
(20文字改行コードはLF)
#define SerialInputBufSize 20
void main(void) {
SYSTEM_Initialize();
INTERRUPT_GlobalInterruptEnable();
INTERRUPT_PeripheralInterruptEnable();
uint8_t InputBufCount = 0;
uint8_t SerialInputBuf[SerialInputBufSize];
while (1) {
if (EUSART_is_rx_ready() == 1) { //シリアル受信の判定
uint8_t ReceiveValue = EUSART_Read();
EUSART_Write(ReceiveValue);
SerialInputBuf[InputBufCount++] = ReceiveValue;
if (ReceiveValue == '\n') { //エンター入力判定
printf("\ninputdata\n");
for (uint8_t i = 0; i < InputBufCount; i++) {
EUSART_Write(SerialInputBuf[i]);
}
printf("\n");
InputBufCount = 0;
} else {
if (InputBufCount == SerialInputBufSize) { //文字数オーバーの処理
printf("\n!!over !!\n");
InputBufCount = 0;
}
}
}
}
} https://i.imgur.com/jJ5szlM.jpg
Aliで勝った高価な(106円送料込)USBシリアル変換コードが使えなかったので
動作検証するために夜中にUSBシリアル変換モジュールにピンヘッダはんだ付けしたんよ(笑) ケーブルタイプのっておそらくPL2303(のパチモン)だろうからWin10ではドライバーをごにょごにょしないと使えないんじゃないかな
検索すればたぶんやり方は出てくるはず このスレッドは1000を超えました。
新しいスレッドを立ててください。
life time: 109日 23時間 47分 33秒 レス数が1000を超えています。これ以上書き込みはできません。