| ビット | シンボル | ビット名 | 機能 |
|---|---|---|---|
| 7 | 0に設定 | ||
| 6 | MSTUART | UART0スタンバイビット | 0:アクティブ 1:スタンバイ |
| 5 | MSTTRC | タイマRCスタンバイビット | 0:アクティブ 1:スタンバイ |
| 4 | MSTAD | A/Dコンバータスタンバイビット | 0:アクティブ 1:スタンバイ |
| 3 | 0に設定 | ||
| 2 | 0に設定 | ||
| 1 | MSTTRB | タイマRB2スタンバイビット | 0:アクティブ 1:スタンバイ |
| 0 | MSTTRJ | タイマRJ2スタンバイビット | 0;アクティブ 1:スタンバイ |
| ビット | シンボル | ビット名 | 機能 |
|---|---|---|---|
| 7 | −−− | ||
| 6 | −−− | ||
| 5 | −−− | ||
| 4 | −−− | ||
| 3 | −−− | ||
| 2 | TSTOP | タイマRBカウンタ強制停止ビット | 1を書くと、カウント強制停止。読んだ場合、その値は0 |
| 1 | TCSTF | タイマRBカウンタステータスフラグ | TRBMRレジスタのTMOD1ビットが0のとき 0:カウント停止 1:カウント中 TRBMRレジスタのTMOD1ビットが1のとき 0:カウント停止 1:カウント許可状態 |
| 0 | TSTART | タイマRBカウンタ開始ビット | TRBMRレジスタのTMOD1ビットが0のとき 0:カウント停止 1:カウント開始 TRBMRレジスタのTMOD1ビットが1のとき 0:カウント停止 1:カウント許可 |
| ビット | シンボル | ビット名 | 機能 |
|---|---|---|---|
| 7 | −−− | ||
| 6 | −−− | ||
| 5 | −−− | ||
| 4 | −−− | ||
| 3 | INOSEG | ワンショットトリガ極性選択ビット | 0:立ち下がりエッジ 1:立ち上がりエッジ |
| 2 | INOSTG | ワンショットトリガ制御ビット | 0:INT0端子ワンショットトリガが無効 1:INT0端子ワンショットトリガが有効 |
| 1 | TCSTF | タイマRB出力切り換えビット | 0:波形出力 1:固定値出力 |
| 0 | TOPL | タイマRB出力レベル選択ビット | タイマRB出力レベル選択ビットの機能表 |
| 動 作 モ ー ド | 機 能 | |
|---|---|---|
| タイマモード | タイマモードでは0にする | |
| プログラマブル波形発生モード | 0 | プライマリ期間H出力 セカンダリ期間L出力 タイマ停止時L出力 |
| 1 | プライマリ期間L出力 セカンダリ期間H出力 タイマ停止時H出力 |
|
| プログラマブルワンショット発生モード | 0 | ワンショットパルスH出力 タイマ停止時L出力 |
| 1 | ワンショットパルスL出力 タイマ停止時H出力 |
|
| プログラマブルウエイトワンショット発生モード | 0 | ワンショットパルスH出力 タイマ停止時およびウエイト期間にL出力 |
| 1 | ワンショットパルスL出力 タイマ停止時およびウエイト期間にH出力 |
|
| ビット | シンボル | ビット名 | 機能 |
|---|---|---|---|
| 7 | TCKCUT | タイマRBカウントソース遮断ビット | 0:カウントソース供給 1:カウントソース遮断 |
| 6 | TCK2 | タイマRBカウントソース選択ビット | 000:f1(20MHz) 001:f8(2.5MHz) 010:タイマRJ2のアンダーフロー 011:f2(10MHz) 100:f4(5MHz) 101;f32(0.625MHz) 110:f64(0.3125MHz) 111:f128(0.15625MHz) |
| 5 | TCK1 | ||
| 4 | TCK0 | ||
| 3 | TWRC | タイマRB書き込み制御ビット | 0に設定 |
| 2 | TCNT16 | タイマRBカウンタ選択ビット | TRBPRE、TRBPR、TRBSCを 8ビットタイマとして使用するときは0に設定 16ビットタイマとして使用するときは1に設定 |
| 1 | TMOD1 | タイマRB動作モード選択ビット | 00:タイマモード 01:プログラマブル波形発生モード 10:プログラマブルワンショット発生モード 11:プログラマブルウエィトワンショット発生モード |
| 0 | TMOD0 |
(5)タイマRBプリスケーラレジスタ(TRBPRE)
8ビットタイマーとして使う場合、設定値は0〜255の範囲になります。ここで設定した値を、タイマRBモードレジスタで設定したカントソースでカウントダウンしていきます。ここで例えば、trbpre=199 に設定した場合について考えてみます。カウントダウンはカウントソースf2(10MHz)の場合、0.1μs毎に
199 → 198 → ・・・3 → 2 → 1 → 0
となり、アンダーフローになる瞬間に199に更新されます。つまり、0.1μs X 200 = 20μSでカウントソースが200に更新されることになります。
タイマRBプリスケーラレジスタで設定したカウンタソース値のアンダーフローをカウントするレジスタです。設定値は0〜255の範囲です。
ここで例えば、
タイマRBプリスケーラレジスタ trbpre=199
タイマRBプライマリレジスタ trbpr = 49
に設定した場合、プリスケーラレジスタで設定したカウンタソース値のアンダーフローが発生する毎に
49 → 48 → ・・・ 3 → 2 → 1 → 0
とカウントダウンされ、アンダーフローになる瞬間に49に更新されます。つまり、20μS X 50 =1mS毎に割り込みがかかることになります。 以上を整理すると、
割り込み間隔 = タイマRBカウントソース X TRBPRE X TRBPR で計算されます。
今回は、1ms毎に割り込みをかける設定としますので、以下のような設定値にします。
trbpr = 49;
(7)タイマRB割り込み制御レジスタ(TRBIR)
| ビット | シンボル | ビット名 | 機能 |
|---|---|---|---|
| 7 | TRBIE | タイマRB割り込み許可ビット | 0:割り込み禁止 1;割り込み許可 |
| 6 | TRBIF | タイマRB割り込み要求フラグ | 0:割り込み要求なし 1:割り込み要求あり |
| 5 | |||
| 4 | |||
| 3 | |||
| 2 | |||
| 1 | |||
| 0 |
タイマRB2のプログラマブル波形発生モード使ってみます。ルネサスアプロケーションノート の例を参考にしています。プログラマブル波形発生モードは、任意のパルス幅のH出力(プライマリ期間)、L出力(セカンダリ期間)をTRBO端子(p1_3またはp4_2)から連続して出力します。
関係するレジスタは、モジュールスタンバイ制御レジスタ(MSTCR)、タイマRB制御レジスタ(TRBCR)、タイマRB I/O制御レジスタ(TRBIOC)、タイマRBモードレジスタ(TRBMR)、タイマRBプリスケーラレジスタ(TRBPRE)、タイマRBプライマリレジスタ(TRBPR)、タイマRBセカンダリレジスタ(TRBSC)、タイマRB割り込み制御レジスタ(TRBIR)、割り込み優先レベルレジスタ(ILVLC)、の他に、ポート1機能マッピングレジスタがあります。(T)で説明済みのレジスタについては、設定値のみを下に記載します。
mstrb = 0;
tstartt_trbcr = 0;
trbcr = 0x04;
trbir = 0x00;
trbmr= 0x39; タイマRBモードレジスタ 0011 1001に設定
カウントソースをf2(10MHz)に設定
プログラマブル波形発生モード
trbioc= 0x00; trbioc=0x01に設定すると、HとLの波形が反転します
trbpre= 0xfa; タイマRBプリスケーラレジスタ。
8ビットレジスタとして使っています。
プリスケーラ 0xfa(249)に設定する。trbpr、trbscに設定した値が
アンダーフローする毎にtrbpreが(249+1)=250回カウントダウンをする
trbsc = 0x4f; タイマRBセカンダリレジスタ。
8ビットレジスタとして使っています。
出力パルスのL出力の長さを指定するレジスタ。
セカンダリ間隔0x4f(79+1)、出力パルスのL出力の長さを、
250*80*1/10MHz=2msに初期設定
trbpr = 0xc7; タイマRBプライマリレジスタ。
8ビットレジスタとして使っています。
出力パルスのH出力の長さを指定するレジスタ。
プライマリ間隔0xc7(199+1) 出力パルスのH出力の長さを、
250*200*1/10MHz=5msに初期設定
上記の、タイマRBセカンダリレジスタ(trbsc)、タイマRBプライマリレジスタ(trbpr)はこの順に設定する
必要があります。また、これらのレジスタをプログラム実行中に可変させることによってH幅、L幅を可変
させることができます。更新タイミング等は、マニアル表14.6「8ビットプリスケーラ付き8ビットタイマ時の
TRBPR、TRBSCレジスタのリロードレジスタ更新タイミング」に詳しく書かれています。
asm(”nop”); 安定するまで2サイクルの時間待ちをする
asm(”nop”); 安定するまで2サイクルの時間待ちをする
trbif_trbir=0; 割り込み要求フラグをクリャーする
trbie_trbir=1; 割り込み許可
pml1=0xc0; ポート1機能マッピングレジスタ p1_3をTRBO端子に指定する。
または p13sel0=1;
p13sel1=1
p4_2を出力端子にする場合は、
pml4=0x10;
または、p42sel0=0;
p42sel1=1; に設定する。
◎プログラム
p1_3から、初期設定値、H出力長さ5ms、L出力長さ2msのパルスを出力します。
プログラムの中で、p1_7からボリュームの抵抗値を読み込みAD変換した値を使っ
てtrbsc、trbprの値を変更してパルスのデューティー比を変更しています。AD変換
値を確認するためにLCDに出力してオシロスコープに表示させています。LCDの表
示に時間がかかるのでリアルタイムにはほど遠いのですが、実際のモータの回転ス
ピードをデューティ比で制御するときにはLCDの表示はさせていません。
1)メイン関数
#include "sfr_r8m12a.h"
#include "i2clcd_ctrl.h"
#define CLOCK 20000
void main(void)
{
int ad;
unsigned char d;
unsigned int i,j;
unsigned int rd[4];
unsigned char str0[8];
unsigned char str1[8];
init();
I2C_LCD_init(); // LCD初期化
I2C_SDA_OUT; // SDAピン出力に設定
for(i=0;i<8;i++){
str0[i] = ' ';
str1[i] = ' ';
}
wait_ms(100);
asm("FCLR I"); /* Interrupt disabled */
timer_rb2_init(); /* Timer RB2 initialized */
asm("FSET I"); /* Interrupt enabled */
while(1){
ad=Get_AD7()>>2; // ボリューム値PWM
d=(unsigned char)ad/2;// 0〜127
trbsc = 0xc7-d; // 8ビットタイマ:secondary period 5ms〜2ms
asm("nop"); // wait for at least two cycles
asm("nop"); // wait for at least two cycles
trbpr = 0x4f+d;// 8ビットタイマ:primary period 2ms〜5ms
asm("nop"); // wait for at least two cycles
asm("nop"); // wait for at least two cycles
/* LCDに表示する */
for(i=0;i<4;i++){ // 0〜255を各桁に分解する
rd[i] = d%10;
d = d/10;
}
str1[0]='A';str1[1]='M';str1[2]='P';str1[3]='=';
str1[7]=rd[0]+0x30;
str1[6]=rd[1]+0x30;
str1[5]=rd[2]+0x30;
str1[4]=rd[3]+0x30;
I2C_SDA_OUT; // SDAピン出力に設定
I2C_LCD_cursor(1,0); // 1行目0より表示
I2C_LCD_str(str0); // 表示文字列出力
wait_ms(1000);
I2C_LCD_cursor(2,0); // 2行目0より表示
I2C_LCD_str(str1);
wait_ms(100);
}
}
/* I/O初期化関数 */
void init(void)
{
unsigned short i = 0;
/**** 高速オンチップオシレータで動作する場合 ****/
prc0 = 1;// プロテクトレジスタ解除
hocoe = 1;// 高速オンチップオシレータ発振開始
for(i=0;i<50;i++);//発振安定まで待つ
hscksel =1;// 高速オンチップオシレータ選択ビットを1にする
scksel =1;// システム基準クロックを高速にする
prc0 = 0;// プロテクトレジスタ禁止
pd1 = 0x7f; // p1_0,p1_1,p1_3:出力 0111 1111
}
/* RB2初期化 */
void timer_rb2_init(void)
{
msttrb = 0; // msttrb=0タイマRBスタンバイビット タイマRBを有効
tstart_trbcr=0; // タイマRBカウント停止
while(tcstf_trbcr==1);// timer RB count stop waiting
tstop_trbcr = 1; // タイマRB制御レジスタ:レジスタ,カウンタ初期化
trbir = 0x00; // タイマRB割り込み制御レジスタ 割り込み禁止
trbmr = 0x31; // タイマRBモードレジスタ:プログラマブル波形発生モード01:f1 31:f2 0011 0001
trbioc = 0x00; // タイマRB I/O 制御レジスタ
/* 8ビットタイマ時の設定 */
trbpre= 0xf9; // 8ビットタイマ:prescaler 0xf9:249
trbsc = 0xc7; // 8ビットタイマ:secondary period c7:1/10MHz * 250 * 200=5ms
asm("nop"); // wait for at least two cycles
asm("nop"); // wait for at least two cycles
trbpr = 0x4f; // 8ビットタイマ:primary period 4f: 1/10MHz * 250 * 80 =2ms
asm("nop"); // wait for at least two cycles
asm("nop"); // wait for at least two cycles
trbif_trbir=0; // タイマRB割り込み要求フラグ clear
trbie_trbir=1; // タイマRB割り込み許可
ilvlc = 0x01; // 割り込み優先レベル設定 Level=1
pml1 = 0xc0; // ポート1機能マッピングレジスタ P1_3:TRBO
tstart_trbcr=1; // タイマRBカウントstart
while(tcstf_trbcr == 0);// タイマRB count start waiting
}
#pragma interrupt _timer_rb2(vect=24)
void _timer_rb2(void)
{
trbif_trbir = 0; /* interrupt request flag clear */
}
2)LCDコントロール関数 i2clcd_ctrl.c
/* インクルード */
#include "sfr_r8m12a.h" /* R8C/M12A SFRの定義ファイル */
#include "i2clcd_ctrl.h"
/* 液晶初期化関数 */
void I2C_LCD_init(void)
{
wait_ms(100);
I2C_LCD_cmd(0x38); // Function set 8bit 21Line Normal mode
wait_us(30);
I2C_LCD_cmd(0x39); // Function set 8bit 21Line Extended mode
wait_us(30);
I2C_LCD_cmd(0x14); // Internal OSC Frequency 183Hz BIAS 1/5
wait_us(30);
I2C_LCD_cmd(0x35); // Contrast set 0x70:2.7V 〜 0x30:3.0v 0x35
wait_us(30);
I2C_LCD_cmd(0x56); // Power Icon Contrast control
wait_us(30);
I2C_LCD_cmd(0x6c); // Follow control 3.3v
wait_ms(400);
I2C_LCD_cmd(0x38); // Set normal mode
wait_us(30);
I2C_LCD_cmd(0x0c); // Display ON
wait_us(30);
I2C_LCD_cmd(0x01); // Clear Display
wait_ms(10);
}
/* 開始条件 */
void I2C_start(void)
{
I2C_SDA_OUT;
I2C_H_CLK();
I2C_S_SDA;
delay();
I2C_C_SDA;
delay();
I2C_L_CLK();
delay();
}
/* 終了条件 */
void I2C_stop(void)
{
I2C_SDA_OUT;
I2C_L_CLK();
I2C_C_SDA;
delay();
I2C_H_CLK();
delay();
I2C_S_SDA;
delay();
}
/* クロックをHighにする */
void I2C_H_CLK(void)
{
I2C_S_SCL;
delay();
}
/* クロックをLowにする */
void I2C_L_CLK(void)
{
I2C_C_SCL;
delay();
}
/* ACKNOWLEDGE */
void ack(void)
{
I2C_SDA_IN;
I2C_S_SCL;
delay();
I2C_C_SCL;
delay();
I2C_SDA_OUT;
}
/* 書き込みの基本関数 */
/* 引数 data 8ビットデータ */
/* 戻り値 ack */
int I2C_write(unsigned char data)
{
int i;
int ack;
I2C_SDA_OUT;
for(i=0;i<8;i++){ // 1ビト毎にクロックと共に送信
if(data & 0x80){
I2C_S_SDA;
}
else{
I2C_C_SDA;
}
delay();
I2C_H_CLK();
I2C_L_CLK();
data<<=1;
}
I2C_SDA_IN;
I2C_H_CLK();
I2C_L_CLK();
ack=I2C_SDA_data;
I2C_SDA_OUT;
delay();
return ack;
}
/* 読み込み基本関数 */
/* 引数 なし */
/* 戻り値 読み込んだ8ビットデータ */
static unsigned char I2C_read(void)
{
int i;
unsigned char data;
data=0;
I2C_SDA_IN;
for(i=0;i<8;i++){
data<<=1;
I2C_S_SCL;
delay();
data |=(I2C_SDA_data);
I2C_C_SCL;
delay();
}
I2C_S_SCL;
delay();
I2C_S_SDA;
delay();
I2C_C_SDA;
delay();
I2C_C_SCL;
delay();
return data;
}
/* 液晶へのコマンド出力関数 */
void I2C_LCD_cmd(unsigned char cmd)
{
I2C_start(); // スタートコンディ゙ション
I2C_write(ADD); // アドレス指定
// C0+RS+000000 C0=1:連続で通信可 C0=0:stopコンディションで終了
// RS=0:次のバイトでコントロールコード送信可能
// I2C_write(0x80); // 次はコマンド出力を指定 連続
I2C_write(0x00); // 次はコマンド出力を指定 連続ではない
I2C_write(cmd); // コマンド送信出力
I2C_stop(); // ストップコンディション
wait_us(50);
// delay();
}
/* 液晶への1文字出力関数 */
void I2C_LCD_data(unsigned char data)
{
I2C_start(); // スタートコンディ゙ション
I2C_write(ADD); // アドレス指定
// C0+RS+000000 C0=1:連続で通信可 C0=0:stopコンディションで終了
// RS=1:次のバイトでデータ出力を指定
// I2C_write(0xc0); // 次はデータ出力を指定 連続
I2C_write(0x40); // 次はデータ出力を指定 連続ではない
I2C_write(data); // 1文字データ出力
I2C_stop(); // ストップコンディション
wait_us(50);
// delay();
}
/* 液晶への文字列表示関数 */
void I2C_LCD_str(char* ptr)
{
while(*ptr !=0){
I2C_LCD_data(*ptr++);
}
}
/* 液晶画面のクリャー関数 */
void I2C_LCD_clear(void)
{
I2C_LCD_cmd(0x01);
}
/* 液晶のカーソル位置設定関数 */
void I2C_LCD_cursor(unsigned char line,unsigned char cursor)
{
if(line == 1){
I2C_LCD_cmd(0x80 | cursor);
}
else{
I2C_LCD_cmd(0xc0 | cursor);
}
}
/* タイマ本体 us単位のwait関数 */
void wait_us(unsigned long usec)
{
usec = (usec * CLOCK) / 45000;
while(usec --);{}
}
/* タイマ本体 ms単位のwait関数 */
void wait_ms(unsigned long msec)
{
unsigned int i;
for(i=0;i<msec;i++){
wait_us(1000);
}
}
/* 6usの遅れ関数 */
void delay(void)
{
unsigned char i;
for(i=0;i<5;i++){}
}
/* AN7端子AD変換関数 */
int Get_AD7(void)
{
int data;
p17sel0 = 0;// ポート1機能マッピングレジスタ1 AN7入力
p17sel1 = 0;
mstad = 0; // モジュールスタンバイ制御レジスタをアクティブ
mstcr = 0x00;// モジュールスタンバイ制御レジスタをアクティブ
admod = 0x03;// A/D動作 0x0b:繰り返しモード 0x03:単発モード f1(20MHz)
adinsel = 0x81;// A/D入選択レジスタ AN7
adcon0 = 0x01;// AD変換スタート
while(adcon0 && 0x01); // A/D変換終了待ち(単発モード)
data = ad1;
return data;
}
3)ヘッダーファイル i2clcd_ctrl.h
#define I2C_S_SCL p1_1=1 // I2Cクロック p1_1を1にする
#define I2C_C_SCL p1_1=0 // I2Cクロック p1_1を0にする
#define I2C_S_SDA p1_0=1 // I2Cデータ p1_0を1にする
#define I2C_C_SDA p1_0=0 // I2Cデータ p1_0を0にする
#define I2C_SDA_IN pd1_0=0 // p1_0を入力ポートに設定
#define I2C_SDA_OUT pd1_0=1 // p1_0を出力ポートに設定
#define I2C_SDA_data p1_0 // データポートをp1_0に設定
#define ADD 0x7c // アドレス 0B 0111 110+0(c/w)
#define CLOCK 20000
/* プロトタイプ宣言 */
void init(void);
void I2C_LCD_init(void);
void timer_rb2_init(void); /* Initial setting of Timer RB2 SFR */
void _timer_rb2(void); /* Timer RB2 interrupt processing */
void wait_us(unsigned long usec);// us単位のタイマ
void wait_ms(unsigned long msec);// ms単位のタイマ
void delay(void);// 6usの遅延関数
int Get_AD7(void);
void I2C_start(void);// I2C開始
void I2C_stop(void);// I2Cストップ
void ack(void);// ACKNOWLEDGE信号受信
void I2C_H_CLK(void);// クロックHigh
void I2C_L_CLK(void);// クロックLow
void I2C_LCD_init(void);// lcd初期化関数
int I2C_write(unsigned char data);// 書き込みの基本関数
static unsigned char I2C_read(void);// 読み込みの基本関数
void I2C_LCD_cmd(unsigned char cmd);// 液晶へのコマンド出力関数
void I2C_LCD_data(unsigned char data);// 液晶への1文字出力関数
void I2C_LCD_str(char* ptr);// 液晶への文字列表示関数
void I2C_LCD_clear(void);// 液晶のクリャー関数
// カーソル位置設定関数 line(行数):1 or 2 cursor(左端からの位置):0〜f
void I2C_LCD_cursor(unsigned char line,unsigned char cursor);
LCDにボリュームのAD変換値を表示している |
![]() オシロスコープ 5msと2ms |