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から選択してくる。
Device EditorのInterconnect Viewで全部「place」する。
そしてクロックまわりの設定。
クロックは色々接続しながら速度を調整できる。
今回は
SystemClock(24MHz)→(10分周)VC1→(100分周)VC3→Timer1&2(24KHz)
になってると思ったけどどうも違うみたいだ。
タイマーはPWMとハードウェアは同じしくみを使っているらしい。Periodの値から1クロック毎にカウントダウンしていって、0になるとタイマー割り込みが起こる。
また、TimerCountOutを外のピンに結び付けておけば、0になった時にHが出力される様だ。
カウント0ではなくCompare値を指定して、その値より小さいかどうかで割り込みを起こすこともできるらしい。
Timer3と4は内部の32.768KHzのクロックを利用してみた。
Periodを32768にしておくと、ちょうど1秒に1回割り込みが起こる。
システムクロックの方から引っ張ってくるのは計算がよくわからないので、ちょっとしたウェイト処理には内蔵32KHzでいいかもしれない。
■I/Oの設定
CY3210-MiniEvalの4つのLEDにつながっているPORT2-0~3をStrongに設定した。
これでLEDが光る。
詳しくは下記参照:
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-TimersCPU: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;
}
}