R8C/2LでPWM
概要
タイマRCとタイマRDにPWMモードがあり、タイマRCで3本、
タイマRDは1チャンネルあたり3本の2チャンネル出力可能。
加えて、タイマRBのプログラマブル波形出力モードもPWM出力が可能なので、
合計10本のPWM出力が可能。
タイマRB: プログラマブル波形発生モード
2つのリロードレジスタの値を、カウンタに交互にリロードし、アンダーフローするたびに出力を反転させるモード。リロードレジスタ(8bit)の値の偏りによって、PWM出来る。
関係するレジスタの設定するビット
-
TRBIOC: タイマRB I/O制御レジスタ
bit0(TOPL): プライマリ期間とセカンダリ期間どちらで端子がHIGHになるか
bit1(TOCNT): 1を書くとGPIOとしての出力をできる
-
TRBMR: タイマRBモードレジスタ
モードの設定とカウントソースの選択に使う。
bit0-1(TMOD0-1): 01でプログラマブル波形発生モード
bit3(TWRC): 1を設定する
bit4-5(TCK0-1): クロックソースの選択
-
TRBPRE, TRBSC, TRBPR: タイマRB
プリスケーラ/セカンダリ/プライマリレジスタ
TRBPREの設定値で分周したクロックを使い、TRBSCとTRBPRの値の偏りによって
PWM信号を生成する。
-
TRBCR: タイマRB制御レジスタ
bit0(TSTART): 1を書くとカウント開始
利用例
void setpwm_trb(int r){
if(r == 0){
p1_3 = 0;
tocnt_trbioc = 1;
}else if(r == 255){
p1_3 = 1;
tocnt_trbioc = 1;
}else{
trbsc = 254 - r;
trbpr = r - 1;
tocnt_trbioc = 0;
}
}
int main(){
volatile int t, i;
prc2 = 1;
pd0 = 0b00101111;
pd1 = 0b11111111;
pd2 = 0b11111111;
pd3 = 0b00111000;
pd4 = 0b00100000;
trbioc = 0b00000000;
trbmr = 0b00001001;
trbpre = 4 - 1;
trbsc = 0xfd;
trbpr = 0x00;
trbcr = 0b00000001;
while(1){
for(i = 0; i < 256; i++){
setpwm_trb(i);
for(t = 0; t < 8000; t++);
}
}
}
この例では、クロック源f1を1/4に分周して、
trbscとtrbprの和が254になるよう保つことで
メインクロック(f1)の1024(=256*4)分の1の周波数のPWMを出力する。
dutyを100%や0%にしたいときには
trbiocのtocntビットを立ててGPIO出力を利用する。
タイマC: PWMモード
TRCカウンタをカウントアップしながら
TRCGRAのコンペア一致とTRCGRB-TRCGRDのコンペア一致で
それぞれTRCIOB-TRCIOD端子の出力を変化させることのできるモード。
TRCGRAのコンペア一致と同時にカウンタをリセットすることも可能。
これは言い換えれば、TRCGRAに周期、TRCGRB-TRCGRDにHighの幅を指定することで
最大3本のPWM出力が可能であるといえる。(出力は個別に無効化できる)
関係するレジスタの設定するビット
利用例
int main(){
volatile int t, i;
prc2 = 1;
pd0 = 0b00101111;
pd1 = 0b11111111;
pd2 = 0b11111111;
pd3 = 0b00111000;
pd4 = 0b00100000;
trccr1 = 0b10001110;
trcmr = 0b10001111;
trcier = 0b00000000;
trcoer = 0b00000001;
trcgra = 1000 - 1;
trcgrb = 0;
trcgrc = 0;
trcgrd = 0;
tstart_trcmr = 1;
while(1){
for(i = 0; i < 1000; i++){
trcgrb = i;
trcgrc = (i + 333) % 1000;
trcgrd = (i + 666) % 1000;
for(t = 0; t < 2000; t++);
}
}
}
この例では、TRCIOB-TRCIODの各端子から
それぞれ少しずつdutyの違うPWM出力をする。
周期はシステムクロックの1/1000になる。