CY3210-MiniEval基盤にCY8C29466マイコンを置いて、16ビットタイマーを4つ置いて動かした。

1秒毎?ぐらいで動かしてみたが、動いたは動いたけどまだ正確な仕組みがわからない。特にクロックの分周まわり。

ちなみに16bitタイマーはデジタルブロックを2つ消費するので、29466では同時に8個まで使える。

今回はPSoC CPU 基板 (ストロベリーリナックス社) – 趣味の電子工作研究工房 – 楽天ブログ(Blog)がとても参考になった。

■今回のコード

Source Code (PSoC Designer4.3 + C Compiler)

■タイマーの配置とクロック設定

Device EditorのUser Module Selection Viewから選択してくる。

PSoC 16bit Timer



Device EditorのInterconnect Viewで全部「place」する。

そしてクロックまわりの設定。

PSoC 16bit Timer

クロックは色々接続しながら速度を調整できる。

今回は

SystemClock(24MHz)→(10分周)VC1→(100分周)VC3→Timer1&2(24KHz)

になってると思ったけどどうも違うみたいだ。

タイマーはPWMとハードウェアは同じしくみを使っているらしい。Periodの値から1クロック毎にカウントダウンしていって、0になるとタイマー割り込みが起こる。

また、TimerCountOutを外のピンに結び付けておけば、0になった時にHが出力される様だ。

カウント0ではなくCompare値を指定して、その値より小さいかどうかで割り込みを起こすこともできるらしい。

PSoC 16bit TimerPSoC 16bit TimerPSoC 16bit TimerPSoC 16bit Timer

Timer3と4は内部の32.768KHzのクロックを利用してみた。

Periodを32768にしておくと、ちょうど1秒に1回割り込みが起こる。

システムクロックの方から引っ張ってくるのは計算がよくわからないので、ちょっとしたウェイト処理には内蔵32KHzでいいかもしれない。

■I/Oの設定

CY3210-MiniEvalの4つのLEDにつながっているPORT2-0~3をStrongに設定した。

これでLEDが光る。

PSoC 16bit Timer

詳しくは下記参照:

s.h.log: CY8C29466のGPIOでLEDピコピコさせた

■プログラム−Timer割り込み設定

boot.asmを見ると外部入力割込みの時と同じようにljmp命令が書かれていて、_Timer16_1_ISRを呼び出している。

org24h;PSoCBlockDBB01InterruptVector

ljmp_Timer16_1_ISR

reti

Library Source/timer16_1int.asm の中の _Timer16_1_ISR からさらに _INT_Timer16_1 に飛ぶように設定する。

(boot.asmに直接書くとDevice Editorいじった時に書き換えられてしまう為)

_Timer16_1_ISR:

;@PSoC_UserCode_BODY@(Donotchangethisline.)

;—————————————————

;Insertyourcustomcodebelowthisbanner

;—————————————————

;NOTE:interruptserviceroutinesmustpreserve

;thevaluesoftheAandXCPUregisters.

ljmp_INT_Timer16_1

;—————————————————

;Insertyourcustomcodeabovethisbanner

;—————————————————

;@PSoC_UserCode_END@(Donotchangethisline.)

reti

main.c にpragmaとINT_Timer16_1関数を書くと、割り込み時に実行される。

#pragmainterrupt_handlerINT_Timer16_1

voidINT_Timer16_1(void){

//code

}

■プログラム−main.c

Source Code (PSoC Designer4.3 + C Compiler)

ここからはC言語で。

前述の割り込みを4つのタイマー全てに設定して、LEDが点いていたら消灯、消えていたら点灯するコードを書いた。

M8C_EnableGInt は全割り込みの許可。

Timer16_1_EnableInt() と Timer16_1_Start()はLibrary Headers/timer16_1.hに書かれている。

AVRと違ってタイマーはStart()したら回り続ける。

止めるのはTimer16_1_Stop(void)。Period値は動作中に書き換えられるらしい。

/***

Blink4LEDsby416bit-Timers

CPU:CY8C2946624MHz(Internal)

Compiler:PSoCDesigner4.3+CCompiler

Date:2007/4/2

Author:ShoHashimoto

WebSite:http://shokai.org

***/

#include//partspecificconstantsandmacros

#include”PSoCAPI.h”//PSoCAPIdefinitionsforallUserModules

#define_BV(BIT)(1<
#definesbi(BYTE,BIT)(BYTE|=_BV(BIT))

#definecbi(BYTE,BIT)(BYTE&=~_BV(BIT))

#defineLED0_ON()sbi(PRT2DR,0);//LED0on

#defineLED0_OFF()cbi(PRT2DR,0);//LED0off

#defineLED1_ON()sbi(PRT2DR,1);

#defineLED1_OFF()cbi(PRT2DR,1);

#defineLED2_ON()sbi(PRT2DR,2);

#defineLED2_OFF()cbi(PRT2DR,2);

#defineLED3_ON()sbi(PRT2DR,3);

#defineLED3_OFF()cbi(PRT2DR,3);

volatilecharledStat[4];//stateof4LEDs

voidmain()

{

M8C_EnableGInt;//EnableGlobalInterrupt

Timer16_1_EnableInt();//EnableTimer1

Timer16_1_Start();//StartTimer1

Timer16_2_EnableInt();

Timer16_2_Start();

Timer16_3_EnableInt();

Timer16_3_Start();

Timer16_4_EnableInt();

Timer16_4_Start();

}

#pragmainterrupt_handlerINT_Timer16_1

voidINT_Timer16_1(void){

if(ledStat[0]){

LED0_ON();//on

ledStat[0]=0;//nextisoff

}

else{

LED0_OFF();//off

ledStat[0]=1;//nextison

}

}

#pragmainterrupt_handlerINT_Timer16_2

voidINT_Timer16_2(void){

if(ledStat[1]){

LED1_ON();

ledStat[1]=0;

}

else{

LED1_OFF();

ledStat[1]=1;

}

}

#pragmainterrupt_handlerINT_Timer16_3

voidINT_Timer16_3(void){

if(ledStat[2]){

LED2_ON();

ledStat[2]=0;

}

else{

LED2_OFF();

ledStat[2]=1;

}

}

#pragmainterrupt_handlerINT_Timer16_4

voidINT_Timer16_4(void){

if(ledStat[3]){

LED3_ON();

ledStat[3]=0;

}

else{

LED3_OFF();

ledStat[3]=1;

}

}