FC2ブログ

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

回路関係 dsPICでスイッチの値を読み取ろう!

シリアル → 直列
パラレル → 並列

シリアルは原料にトウモロコシ、米、小麦、大麦、オーツ麦などが使われており。
19世紀末、アメリカのバトルクリークにあった保養所の健康食として、ケロッグ兄弟が開発したのが始まりです。
栄養のバランスがよく、調理に手間がかからないので、朝食によく食べられています。

パラレルっていう食品を作ってもいいと思う佐藤であった





今日も愛が足りません





今回はdsPICのクロックの設定(delay)と入力(input)の設定を行います

今回の目標はスイッチの入力がHighならば、LEDを光らせる。
その確認を1秒毎に行うプログラムです。

今回のプログラムは以下の四つを行います。
 1.delayの設定
 2.IOピンの設定
 3.Inputの設定
 4.if文の設定

それでは行きましょう
1.delayの設定
 delayとはその名の通り、「待つ」という命令です。
 今回のプログラムでは「NOP」という命令を繰り返させて「待つ」という命令を行います
 「NOP」とは「何もしない」という命令です
 今回、delayを行うのに以下のような関数を用います

 __delay32()

 この関数は、C30というコンパイラに初期から搭載されているディレイ用の関数です。

 この関数は以下のように説明されています。


There is a __delay32() library function in PIC30-LIBS:

__delay32
Description: Produce a delay of a specified number of clock cycles.
Include: None
Prototype: void __delay32(unsigned long cycles);
Argument: cycles number of cycles to delay.
Remarks: None.
Default Behavior: This function will effect a delay of the requested number of cycles. The
minimum supported delay is 11 cycles (an argument of less than 11 will
result in 11 cycles). The delay includes the call and return statements,
but not any cycles required to set up the arugment (typically this
would be two for a literal value).
File: __delay32.c



英語ですが・・・・・・。

おおざっぱに訳すと

時計サイクルで指定された数の遅れを発生させられます。
遅らせるサイクルの数だけ命令を循環させ遅延を発生させる関数です。

サポートされている一番少ない遅延できる量は、11サイクル(11未満は11のサイクルになる)です。
関数の呼び出しも遅れとして含まれています。

といった感じでしょうか

使い方は

#define Clock 36850000

void delay_ms(unsigned int N){
__delay32(Clock/1000*N);
}

void delay_us(unsigned int N){
__delay32(Clock/1000000*N);
}

といった感じでしょうか

この#define Clock 36850000はFcyの値です
Fcy は FOSC/2 です
つまり、Clockは7.37MHzの半分である3.685MHzになっている。ということです

そして、Clockの周波数をそのまま__delay32に代入すると1秒の遅延となります。
1秒を1000で割れば1m秒
1秒を1000000で割れば1μ秒となります

Nm秒待ちたい場合はそれにNをかければいいです

例えば、10m秒待ちたい。という場合は

__delay32(Clock/1000*10);

と記述すれば良いです。


2.IOピンの設定

今回は入力ポートを使うので

TRISA = 0x0F;
TRISB = 0x8100;
AD1PCFGL = 0xFFFF;

と記述しました。
これにより
 Aポートの0~3bit
 Bポートの8、15bit は 入力ポートとなり
全てのアナログポートはデジタル入力となっています。

AD1PCFGL を書き忘れるとすべての入力ポートがアナログ(デフォルトがアナログになっている)
になってしまうので忘れずに記述しましょう。

また、
Aポートの0bit目をRA0、Aポートの1bit目をRA1・・・・・・。 というふうに呼びます。
Bポートも同様に、0bit目をRB0、1bit目をRB1・・・・・・。というふうに呼びます。
覚えておいて損はないです。


3.Inputの設定

スイッチがONかOFFかを調べる方法は

・割り込みを使う
・if文を使う

の2つの方法があります

割り込みとは、入力の信号の立ち上がり、立ち下がり、もしくわその両方を検知して
設定した関数の処理を行う方法です。

割り込みが入るまで待つ
 → 割り込みがはいる
  → 指定されている関数に飛ばす
   → 処理を行い、最初に戻る(また割り込みを待つ)

上記のような動作になります

if文を使う場合は、

if(条件){

 動作



の条件のところに値を入力しておき、そのとおりになった場合、記述されている動作を行います
今回は、if文で記述します。


4.if文の設定

「設定」といってもそんな大したことではないです
佐藤はif文を使うときはこのように記述しています

・RA0(ポートAの0bit目)がON(1)ならばRB0(ポートBの0bit目)をON(1)にする

if( (PORTA & 0x01) == 0x01){
PORTB = (PORTB | 0x01);
}

・RA0(ポートAの0bit目)がON(1)ならばRB0(ポートBの0bit目)をON(1)にし、RB1はOFF(0)。
 RA1(ポートAの1bit目)がON(1)ならばRB1(ポートBの1bit目)をON(1)にし、RB0はOFF(0)。にする

if( (PORTA & 0x01) == 0x01){
PORTB = (PORTB | 0x01);
PORTB = (PORTB & 0xFD);
}else if( (PORTA & 0x02) == 0x02){
PORTB = (PORTB | 0x02);
PORTB = (PORTB & 0xFE);
}

・・・・・・一気に複雑になりましたね。
私はC30で与えられている1ビットごとの記述等は信用していないので、レジスタごとにこのように記述しています。
少しわかりづらいですが、これが一番問題が発生しにくいです。たぶん。

条件は (PORTA & 0x01) == 0x01 と記述してあります
これは、

 ポートAの0bit目を1とANDをとり、それが1ならば動作を行う。

という条件になります

& はAND演算子です

ANDは両方の値が1ならば1を出力する論理回路です。
この記述だと
 RA0は1とAND
 それ以外は0とANDをとっています
 つまり、 (PORTA & 0x01) の結果は
 0b0000000x となります
 xは1とのANDなので、RA0がそのまま代入されます。

 xは不定の値です。よくある変数xだと思ってください。

----※ 0xと0bについて ※----
0xは16進数、0bは2進数での値を表します。
2進数で表すほうがわかりやすい場合が多いですが、16進数に慣れておくと色々楽になります
ASCIIとかASCIIとか・・・・・・。



動作の部分には

PORTB = (PORTB | 0x02);
PORTB = (PORTB & 0xFE);

といった記述があります。

| は OR演算子です

ORは片方の値が1ならば1を出力する論理回路です。
この記述だと
 RB1は1とOR
 それ以外は0とORをとっています
 つまり、 (PORTB | 0x02) の結果は
 0bxxxxxx1x となります
 xは1とのORなので、RB1以外の値はそのままです。
 
 xは判別する前の、その時の値です。

これらを組み合わせることで、一定周期ごとにスイッチONならばLEDを光らせることが出来ます。
記述すると以下のようになります。


 100msごとにRA0を確認し、
 RA0 = 1(ON)ならば、RB0=1(ON)
 RA0 = 0(OFF)ならば、RB0=0(OFF)
 にするプログラム。

#include "p33FJ32GP202.h"
#define Clock 36850000
_FBS(BWRP_WRPROTECT_OFF&BSS_NO_FLASH);
_FGS(GWRP_OFF&GSS_OFF);
_FOSCSEL(FNOSC_FRCPLL&IESO_OFF);
_FOSC(POSCMD_NONE&OSCIOFNC_ON&IOL1WAY_OFF&FCKSM_CSDCMD);
_FWDT(WDTPOST_PS256&WDTPRE_PR32&WINDIS_OFF&FWDTEN_OFF);
_FPOR(FPWRT_PWR1&ALTI2C_OFF);
_FICD(ICS_PGD3&JTAGEN_OFF);

void delay_ms(unsigned int N)
{
__delay32(Clock/1000*N);
}

void main(void){

int i = 0;
/*PORT*/
TRISA = 0x0F;
TRISB = 0x8100;
AD1PCFGL = 0xFFFF;
/*Clock*/
CLKDIV = 0x3000;
PLLFBD = 0x0026;

/*delay*/
delay_ms(1000);

/*main*/
while(1){
     delay_ms(100);
if( (PORTA & 0x01) == 0x01){
PORTB = (PORTB | 0x01);
}else{
PORTB = (PORTB & 0xFE);
}
}
}


これで、delayと入力が行えるようになりました。
今回はこんなかんじで終了です。

次は・・・・・・。UART?ですかね。




お疲れ様でした。









おまけ


_FICD(ICS_PGD3&JTAGEN_OFF);

の JTAGEN_OFF を JTAGEN_ON とすると、RA4がオープンドレインになってしまいます。
汎用IOポートとしてRA4を用いたい場合は、上記のように記述することをおすすめします。
スポンサーサイト

コメントの投稿

非公開コメント

プロフィール

愛が足りない佐藤

Author:愛が足りない佐藤
佐藤と申します

当ブログをレポートなどの参考文献として明記する場合
名前は
・Yahoo知恵袋
・Wikipedia 
等のあやふやな感じでお願いします

修正したほうが良い箇所などがある場合
コメントをしていただけると幸いです

探したい記事がある場合は、下の

・検索フォーム
・カテゴリ

などを使用してください

・回路
PICマイコン
マイコンとその周辺回路(24V以下)

・遊戯王
炎星幻獣

****まとめて紛失しました****
次元荒行六武、マシンジェネクス、神風ハイビート、炎舞コアキメイル、水精鱗氷結界
・DM
黒月軸五元神、全多色、ハッチャキビート、アナスタシス・フルクリーチャー(アークセラフィム軸)

**********************

出没地域
秋葉原(イエサブ、アメド)
蒲田(ラボ、ホビステ)
大井町(MAX)
下北沢(DORAMA)

検索フォーム
最新記事
カテゴリ
最新コメント
閲覧者数
FC2無料カウンターFC2無料カウンターFC2無料カウンターFC2無料カウンターFC2無料カウンター
月別アーカイブ
Twitter
ブロとも一覧

ちくわの穴には夢がある

遊戯王 大会優勝 デッキレシピ
リンク
ブロとも申請フォーム

この人とブロともになる

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。