目次
過去の日記
AVRマイコンのC言語の方言(?)に、_BV(bit)っていうマクロがある。
これは、
#define _BV(bit) (1 << (bit))
という風に定義されている。
これ、実はすっごい便利。PSoCではデフォルトで定義されてないので、俺は自分で定義して使ってる。
PRT1DR |= 0x82;
って書いてあるとなんのこっちゃ?って混乱してしまう。だけど、
PRT1DR |= _BV(7)|_BV(1);
って書くと、あぁ、1ビット目と7ビット目を1にしたいんだな。ってぱっと見てわかる。
ほかにも、
#define LED_blue 3 ... PRT1DR |= _BV(LED_blue); PRT1DR &= ~_BV(LED_blue);
とか書くと、あぁ、青色LEDを付けたい/消したいんだなってすぐわかる。
PSoCは2進数が使えるけど、他のマイコンでは使えなかったり、2進数でも8ケタになると読みにくいから、あまり使ってない・・
他にも、AVRにはビット操作をするのに楽なマクロがいろいろある。
http://avrwiki.jpn.ph/wiki.cgi?page=Getting+Started+Notes+-+Ports#p9
dataseetによると、
OutputPeriod = sourceClockPeriod x (periodRegisterValue + 1)
となっている。
今たとえば、Sysclockを24MHz、sourceClockPeriod(VC1の値)を12のとき、
10kHzがほしい時は、periodRegisterValueを199にしなければならない。
今まで200を入れていたけど、厳密には間違いだったようだ・・orz
実測してみると、
period | frequancy[kHz] |
200 | 9.94438 |
199 | 9.99410 |
約50Hzずれている。(10kHz/200= 50Hz)
PSoC内蔵のクロックだけ(ILO)だと、最大+/-2.5%ずれる精度(accuracy)
ここで、外付けの水晶を使うと、さらに高精度(accuracy)になる、はず。
やり方はTechnical Reference Manual(http://www.cypress.com/?rID=3208 )に書いてあるけど、
Application NoteのAN2027(http://jp.cypress.com/?id=1029&rtID=5&rID=26009 )の方が詳しい。
#というか最初TRMだけ見てたらハマった・・
P1[0]とP1[1]の間に水晶を置き、それぞれの端子からコンデンサを付けてVddに繋ぐ。
Designerで、それぞれのピンの設定を以下のようにする。
グローバルリソースを変更
32k_Select | External |
PLL_Mode | Ext_Lock |
結論から言うと、P1[1]側に12pF、P1[2]側に100pFをつなげる(20 Pin SSOPの場合)。
PLLを使わない時は、TRMに書いてあるようにC1とC2(≒20pF)でいいんだけど、
実際使うときはPLLモードで使う(らしい)。
#ここは読んでてもなんとなくしか理解できなかった・・
P1[0]とP1[1]は、プログラムを書き込むピンでもある。水晶をつなげたままでもプラグラムは書き込める。
ただし!実行させるときはMiniProgは外さないといけない。MiniProg容量負荷が大きすぎる?のか水晶がしっかり発振できない。
10kHzごとにパルスを出してみた。オシロスコープの周波数カウンタの表示。
ILO(内蔵) | 10.07kHz |
ECO(水晶) | 9.94434kHz |
ここのサイトがすごくまとまってました。http://bluefish.orz.hm/sdoc/psoc3.html
先生のページ(http://akita11.jp/plan/osc/ → Know-hows / Tips)に書いてあった。
手持ちの、Trancend 2GBではちゃんと波形を保存できました!
グローバルリソース SysClk 24MHz CPU_Clock CycClk/1
//割り込み関数 #pragma interrupt_handler Timer8_ISR void Timer8_ISR(){ //LEDモジュール LED_On(); LED_Off(); }
上の条件の時、タイマ割り込みの周期の上限は約46kHzだった。
これ以上の周期で割り込みをかけようと思っても、46kHzで頭打ち。留意しましょう。