ATMELのAT-Tiny26,ATmega,R8Cなどのワンチップマイコン,C言語,JAVAなどのプログラミング言語の入門のためのページです.サンプルプログラムを中心に紹介します.他にもLinixや数学ソフトなどの紹介も行います.

このブログを検索

あなたは 番目のお客様です.

2013年2月28日木曜日

R8C M12Aサンプルプログラム

R8C/Tiny M11A およびM12Aのサンプルプログラム集
クロックは内部発振20MHzを使っています.
M11Aを使う場合#includeを書き換えてください.
M11A およびM12Aは低価格で,高速で,AD変換,シリアル通信を備えているので,簡単な作業は全部これでできてしまいます.
秋月のマイコン開発キットを買うとソフト(開発環境HEW+書き込みのFlashSta.exe)が付いています.
USBシリアルモジュールと接続するだけで,書き込み回路を自作することも可能です.
E8aエミュレータを使って書き込みをする場合,VCC,GND,RESET,MODEを接続して,書き込みができます.
//*******************************************
/*
LEDの点滅
*/
#include  "sfr_r8m12a.h"

void main(void);

void main(void)
{
unsigned int i;
prc0=1;
hocoe=1;
for(i=0;i<1000;i++){}
hscksel=1;
scksel=1;
prc0=0;
pd3_4=1;     //p3_4を出力に設定
while(1){
 p3_4=0;       //LED off
 for(i=0 ; i<50000 ; i++){};
 p3_4=1;       //LED on
 for(i=0 ; i<50000 ; i++){};
 }
}
//*******************************************
/*
AD変換のテスト 変換値に合わせてLEDをPWM変調する
AD AN0 and PWM p3_4
m12Aは10bitのAD変換を行う
*/

#include  "sfr_r8m12a.h"

void main(void);

void main(void)
{
unsigned int i,n;
//Clock=20Mhz
prc0=1; //Protect off 
hocoe=1;
for(i=0;i<2000;i++){}
hscksel=1;
scksel=1;
prc0=0; //Protect on

pd3_4=1;     //p3_4を出力に設定
//AD
mstad=0;
admod=0B00000011;
adinsel=0B00000000; //AN0
while(1){
 adcon0=0b00000001; //Start AD
 while(adcon0 & 0B00000001){} //wait AD finish
 n=ad0;
 n=n>>2;
 p3_4=1;       //LED on
 for(i=0; i<n; i++){};
 p3_4=0;       //LED off
 for(i=n; i<255; i++){};
 }
}

//*******************************************
/*
test serial com 9600bps
PCからaを転送するとLEDがon,bを転送するとLEDがoff
その他の英小文字を転送すると大文字が帰ってきます.
*/
#include  "sfr_r8m12a.h"

void Utx(char data); // 1文字送信
char Urx(void);  // 1文字受信
void main(void);

void main(void)
{
unsigned int i,n;
char dat;
//Clock=20Mhz
prc0=1; //Protect off 
hocoe=1;
for(i=0;i<2000;i++){}
hscksel=1;
scksel=1;
prc0=0; //Protect on
//Set UART0
mstuart = 0;
p15sel2=0; //P1_5:RX
p15sel1=0;
p15sel0=1;
p14sel2=0; //P1_4:TX
p14sel1=0;
p14sel0=1;
u0mr=0x05; //UART mode:8bit
u0c0=0x10; //source:f1
u0brg=129; //f1/(bps*16)-1=20M/(9600*16)-1=129.2
te_u0c1=1; //TX enable
re_u0c1=1; //RX enable

pd3_4=1;     //p3_4を出力に設定
//AD
//mstad=0;
//admod=0B00000011;
//adinsel=0B00000000; //AN0
while(1){
 dat = Urx();
 if(dat=='a')p3_4=0; //P1_1 Lレベル(LED:on)
 if(dat=='b')p3_4=1; //P1_1 Hレベル(LED:off)
 if(dat>'b'){  //c以降は大文字を返す
  dat=dat-'a'+'A';
  Utx(dat);
  }
 }//while
}

void Utx(char data)
{
 while(ti_u0c1 != 1){}; // データ転送待ち
 u0tbl = data;  // 送信バッファ(U0TBL)にデータセット
}       

char Urx(void)
{
 int data0;
    char data;    // 受信データ格納変数
//   char err;    // エラーデータ格納変数
    while (ri_u0c1 != 1){}; // 受信待ち
 data0 = u0rb;   // 受信データの取り出し
 data=(char)data0;
    return data;
}

//*******************************************
/*
6マイクロsの遅延
*/
#include "sfr_r8m12a.h"

void main(void);
void delay(void);

void main(void)
{
 unsigned int i;
// System clock Int 20MHz
 prc0=1; //Protect off 
 hocoe=1;
 for(i=0;i<1000;i++){}
 hscksel=1;
 scksel=1;
 prc0=0; //Protect on

 pd3_4=1;// P1_2 output
 while(1){
 p3_4=0;
 delay();
 p3_4=1;
 delay();
 delay();
 delay();
 delay();
 }
 
}
//delay 6Us
void delay(void)
{
 unsigned char i;
 for(i=0;i<5;i++){}//6Us
} //delay

//*******************************************
/*
delay using Timer RB
delay()待ち関数,単位はマイクロ秒
カウンタソースf2=10MHz
関数を呼び出すと4.7Usほど余計にかかる.
*/
#include "sfr_r8m12a.h"

void main(void);
void delay(unsigned char);

void main(void)
{
 unsigned int i;
// System clock Int 20MHz
 prc0=1; //Protect off 
 hocoe=1;
 for(i=0;i<1000;i++){}
 hscksel=1;
 scksel=1;
 prc0=0; //Protect on

 pd3_4=1;// P1_2 output
 while(1){
 p3_4=0;
 delay(10);
 p3_4=1;
 delay(90);
 }
 
}

void delay(unsigned char t)
{
// tstop_trbcr = 1;// タイマRBカウント強制停止
 mstcr &= 0x71;// Timer RB2 Active 
 trbmr=0b00000000; //f1(20MHz) タイマモード
// trbmr=0b00110000; //f2(10MHz) タイマモード
 trbpre=20-1;
 trbpr=t-1;
 asm("nop");
 asm("nop");
 tstart_trbcr=1; //カウント開始
 while(trbpr!= 0);
 tstop_trbcr = 1;// タイマRBカウント強制停止
} //delay

//*******************************************
/*
delay using Timer RC
delay()待ち関数,単位はms
タイマRCのカウンタソースをシステムクロック/32とし,カウンタ値が625になるまでの周期で繰り返す.
*/
#include "sfr_r8m12a.h"

void main(void);
void delay(unsigned int t);

void main(void)
{
 unsigned int i;
// System clock Int 20MHz
 prc0=1; //Protect off 
 hocoe=1;
 for(i=0;i<1000;i++){}
 hscksel=1;
 scksel=1;
 prc0=0; //Protect on
 
 pd1_2=1;// P1_2 output
 while(1){
 p1_2=0;
 delay(500);
 p1_2=1;
 delay(500);
 }
 
}

void delay(unsigned int t)
{
//20MHz f32=625000Hz
 unsigned int i=0;
 msttrc=0; //Timer RC Active
 trccr1 = 0b01000000;// f32
 cclr_trccr1=1; //コンペア一致Aでカウンタクリア
 trcgra = 625-1;// Period  1kHz 
 trccnt=0; //Timer RCクリア
 imfa_trcsr=0;//コンペア一致フラグ
 cts_trcmr = 1;//count start 
 while(i<=t){
 while(imfa_trcsr==0);//カウンタとTRCGRAが一致するまで待つ
 imfa_trcsr=0;//コンペア一致フラグをクリア
 i++; 
 }
 cts_trcmr = 0;//count stop
} //delay
 

//*******************************************
/*
test EEP
BLOCK Aでデータフラッシュの書き込みと読み出しテスト
03000h-037FFh
*/
#include  "sfr_r8m12a.h"
#define BLOCK_A  ((unsigned char *)0x03000) // BLOCK A first address
#define BLOCK_B  ((unsigned char *)0x03400) // BLOCK B first address
void Utx(char data); // 1文字送信
char Urx(void);  // 1文字受信
void eepwrite(unsigned int,unsigned char);
unsigned char eepread(unsigned int);
void main(void);

void main(void)
{
unsigned int i,n;
char dat;

//Clock=20Mhz
prc0=1; //Protect off 
hocoe=1;
for(i=0;i<2000;i++){}
hscksel=1;
scksel=1;
prc0=0; //Protect on
//Set UART0
mstuart = 0;
p15sel2=0; //P1_5:RX
p15sel1=0;
p15sel0=1;
p14sel2=0; //P1_4:TX
p14sel1=0;
p14sel0=1;
u0mr=0x05; //UART mode:8bit
u0c0=0x10; //source:f1
u0brg=129; //f1/(bps*16)-1=20M/(9600*16)-1=129.2
te_u0c1=1; //TX enable
re_u0c1=1; //RX enable

do{ dat = Urx();
 }while(dat!='s');//開始命令を待つ
//書き込み
for(i=0;i<1024*2;i++)eepwrite(i,(unsigned char)i);
//読み出し
for(i=0;i<1024*2;i++){n=eepread(i);
 Utx(n/100+'0');
 n=n%100;
 Utx(n/10+'0');
 n=n%10;
 Utx(n+'0');
 Utx('\n');
 }

while(1){}//while
}

void Utx(char data)
{
 while(ti_u0c1 != 1){}; // データ転送待ち
 u0tbl = data;  // 送信バッファ(U0TBL)にデータセット
}       

char Urx(void)
{
 int data0;
    char data;    // 受信データ格納変数
    while (ri_u0c1 != 1){}; // 受信待ち
 data0 = u0rb;   // 受信データの取り出し
 data=(char)data0;
    return data;
}


void eepwrite(unsigned int i,unsigned char data)
{
 unsigned char *addr;
// Flash control register set
 fmr01 = 0;
 fmr01 = 1; //CPU書き換えモード有効
 fmr02 = 0;
 fmr02 = 1; //EW1モード
 addr = BLOCK_A;
 addr+=i;  //set address
 *addr=0x40; //Write command
 *addr=data; //Write
 while(fst7 == 0);//wait until complete
 fmr01 = 0; //CPU書き換えモード無効
}

unsigned char eepread(unsigned int i)
{
 unsigned char *addr,data;
// Flash control register set
 fmr01 = 0;
 fmr01 = 1; //CPU書き換えモード有効
 fmr02 = 0;
 fmr02 = 1; //EW1モード
 addr = BLOCK_A;
 addr+=i;  //set address
 *addr=0xFF; //Read command
 data = *addr; //Read
 fmr01 = 0; //CPU書き換えモード無効
 return data; //Write 
}

//*******************************************
/*
m12a test Int 割り込みのテスト
通常動作はLEDの点滅,割り込みで一定時間LEDを連続点灯する
p4_5をint0として使うp45sel0=1;p45sel1=0; 
優先レベル設定はILVLE5~ILVLE4
sect30.incは書き換えず,
#pragma interrupt 関数名(vect=割り込み番号)
として割り込みベクタを定義する
INT0の割り込み番号は29
*/
#include  "sfr_r8m12a.h"
#pragma interrupt int0(vect=29)

void main(void);
void int0(void);

void main(void)
{
 unsigned int i;
 prc0=1;
 hocoe=1;
 for(i=0;i<1000;i++){}
 hscksel=1;
 scksel=1;
 prc0=0;

 int0en=1; //set Int
 int0f0=1;//intf0=0b00000011;Int 0 フィルタあり、f32でサンプリング
 int0f1=1;
 p45sel0=1;//P4_5 をINT0に設定
 p45sel1=0; 
 ilvle=0b00010000;//INT0 割り込み優先レベル1
 asm("FSET I");//割り込み許可
 pd3_4=1;     //p3_4を出力に設定
 while(1){
  p3_4=0;       //LED off
  for(i=0 ; i<50000 ; i++){};
  p3_4=1;       //LED on
  for(i=0 ; i<50000 ; i++){};
 }
}

void int0(void)
{
 unsigned int i,j;
  p3_4=1;       //LED off
  for(j=0;j<10;j++)for(i=0;i<50000;i++){};
}

//*******************************************
/*
Timer RCを使い矩形波を出力する.
Output:TRCGRB
PERIOD:TRCCRA

*/
#include "sfr_r8m12a.h"

void main(void);
void clock_init(void);/* System clock setting */
void timer_rc(void);

void main(void)
{
 clock_init();/* System clock Int 20MHz */
 timer_rc();/* Timer RC PWM */
 while(1);
}

void clock_init(void)
{
 unsigned int i;
 //Clock=Int 20Mhz
 prc0=1; //Protect off 
 hocoe=1;
 for(i=0;i<1000;i++){}
 hscksel=1;
 scksel=1;
 prc0=0; //Protect on
}
void timer_rc(void)
{
 unsigned int i;
 p1= 0x00;/*All pin: Low */
 pd1_2=1;/* TRCIOB P1_2 18pin: output */
 pml1 = 0b00010000;/* P1_2:TRCIOB selected */
 msttrc=0; //Timer RC Active **************!
 pwm2_trcmr=1;//PWMモード
 pwmb_trcmr=1;//TRCIOB PWMモード選択ビット
// trccr1 = 0b01000010;/* f32 TOB */
 trccr1 = 0b00000010;/* f1 TOB */
 cclr_trccr1=1; //コンペア一致Aでカウンタクリア
 asm("nop");
 asm("nop");
 polb_trccr2=1;//TRDIOB output level: H
 trcgra = 20000-1;// Period  20MHz/20000 = 10kHz 
 trcgrb = 20000/2-1;// PWM B 
 eb_trcoer=0;// TRCIOB Pin Output enabled 
 cts_trcmr = 1;// TRCCNT count start 
}


//*******************************************
/*
R8C m12aを使いクロックモジュールRTC-8564NBでI2Cのテスト
m12a+RTC-8564NB
A4:SDA A5:SCL,RTC-8564NB:Slave Adress=0B1010001
"s+Enter"で秒のリセットs=0,
"tAADD+Enter"でRTC-8564NBの指定するアドレスの値を変更する.
02(Sec),03(Min),04(Hour),05(Day),07(Month),08(Year)
*/
#include "sfr_r8m12a.h"
#define s_SCL p4_2=1
#define c_SCL p4_2=0
#define s_SDA p1_0=1
#define c_SDA p1_0=0
#define SDA_IN pd1_0=0
#define SDA_OUT pd1_0=1
#define SDA_data p1_0
#define AD 0B1010001

void main(void);
void delay(void);
void start(void);
void stop(void);
void ack(void);
void i2cwrite(unsigned int add,unsigned char dat);
unsigned char i2cread(unsigned char address);
void Utx(char data);
char Urx(void);

void main(void)
{
 unsigned int i;
 unsigned char data,data2,a,b,x1,x2;
// System clock Int 20MHz
 prc0=1; //Protect off 
 hocoe=1;
 for(i=0;i<1000;i++){}
 hscksel=1;
 scksel=1;
 prc0=0; //Protect on
//Set I2C
 pd4_2=1;// SCL OUT
 pd1_0=1;// SDA In or OUT
 s_SDA;// set SDA
//Set UART0 9600bps
 mstuart = 0;
 p15sel2=0; //P1_5:RX
 p15sel1=0;
 p15sel0=1;
 p14sel2=0; //P1_4:TX
 p14sel1=0;
 p14sel0=1;
 u0mr=0x05; //UART mode:8bit
 u0c0=0x10; //source:f1
 u0brg=129; //f1/(bps*16)-1=20M/(9600*16)-1=129.2
 te_u0c1=1; //TX enable
 re_u0c1=1; //RX enable
 
 while(1){
 if(ri_u0c1 != 0){ //Serial.available
 a=Urx();
 //Set s =0
 if(a=='s')i2cwrite(0x02,0x00);//Address,Data
 //Set m h d
 if(a=='t'){ a=Urx();b=Urx();
 x1=(a-'0')*16+(b-'0');//Address
 a=Urx(); b=Urx();
 x2=(a-'0')*16+(b-'0');//Data
    i2cwrite(x1, x2);
 }//t  
 }// if(ri_u0c1 != 0)
  
 data=i2cread(0x04);//Hour
 data2=(data>>4)&0B00000011; 
 Utx('0'+data2);
 Utx('0'+(data&0B00001111));
 Utx(':');
 data=i2cread(0x03);//Min
 data2=(data>>4)&0B00000111; 
 Utx('0'+data2);
 Utx('0'+(data&0B00001111));
 Utx(':');
 data=i2cread(0x02);//Sec
 data2=(data>>4)&0B00000111; 
 Utx('0'+data2);
 Utx('0'+(data&0B00001111));
 Utx('\n');
 for(i=0;i<50000;i++)delay();
 for(i=0;i<50000;i++)delay();
 }
 
}

void delay(void){
 unsigned char i;
 for(i=0;i<5;i++){}//delay 6Us
} //delay
 
void start(void){
 s_SDA;// set SDA
 s_SCL; // set CLK
 delay();
 c_SDA; // clear SDA
 c_SCL; // clear CLK
 delay();
 }
void stop(void){
 c_SDA; // clear SDA
 s_SCL; // set CLK
 delay();
 s_SDA;// set SDA
 c_SCL; // clear CLK
 delay();
 }

void Hclk(void){//SDAがhighで1クロック
 s_SDA;// set SDA
 s_SCL; // set CLK
 delay();
 c_SCL; // clear CLK
 delay();
 }

void Lclk(void){//SDAがlowで1クロック
 c_SDA; // clear SDA
 s_SCL; // set CLK
 delay();
 c_SCL; // clear CLK
 delay();
 }

void ack(void){
 SDA_IN;
 s_SCL; // set CLK
 delay();
 c_SCL; // clear CLK
 delay();
 SDA_OUT;
 }

void i2cwrite(unsigned int add,unsigned char dat){//
 unsigned int k;
 unsigned char i;
 start();
 i=AD<<1;
 for(k=0B10000000;k>0;k=k>>1)if(k & i)Hclk();
        else Lclk();
 ack();//ACK
 i=add; //
 for(k=0B10000000;k>0;k=k>>1)if(k & i)Hclk();
        else Lclk();
 ack();//ACK
 i=dat; //
 for(k=0B10000000;k>0;k=k>>1)if(k & i)Hclk();
        else Lclk();
 ack();//ACK
 stop();//Stop
 }

unsigned char i2cread(unsigned char address){
 unsigned char i;
 unsigned int k;
 start();
 i=AD<<1;
 for(k=0B10000000;k>0;k=k>>1)if(k & i)Hclk();
        else Lclk();
 ack();//ACK
 i=address; //
 for(k=0B10000000;k>0;k=k>>1)if(k & i)Hclk();
        else Lclk();
 ack();//ACK
 start();
 i=(AD<<1)+0B00000001;
 for(k=0B10000000;k>0;k=k>>1)if(k & i)Hclk();
        else Lclk();
 ack();//ACK        
 SDA_IN; //SDAを入力に変更
 i=0;
 for(k=0B10000000;k>0;k=k>>1){
  s_SCL; // set CLK
  delay();  
  if(SDA_data)i+=k;
  c_SCL; // clear CLK
  delay();
  }
 SDA_OUT; //SDAを出力に変更
 ack();//ACK
 stop();//Stop
 return i;
 }

void Utx(char data){
 while(ti_u0c1 != 1){}; // データ転送待ち
 u0tbl = data;  // 送信バッファ(U0TBL)にデータセット
 }       

char Urx(void){
 int data0;
    char data;    // 受信データ格納変数
    while (ri_u0c1 != 1){}; // 受信待ち
 data0 = u0rb;   // 受信データの取り出し
 data=(char)data0;
    return data;
 }

//*******************************************
/*
アセンブラプログラム
*/

;LEDtest.a30 簡単なR8/C m12Aのアセンブラプログラム
;空のプロジェクトに,XX.a30とXX.incを入れる
;スタックポインタの初期化を忘れずに
 .INCLUDE sfr_r8m12a.inc

 .SECTION PROGRAM, CODE
 .ORG  0E000h
Start:
 LDC #0500H,ISP ;スタックポインタの初期化(サブルーチンに必須)
 BSET prc0  ; 外部クロック
 BSET hocoe
 NOP
 NOP
 NOP
 NOP
 NOP
 NOP
 NOP
 BSET hscksel
 BSET scksel
 BSET hocoe
 BCLR prc0  ; 外部クロックへの切り替え完了
 MOV.B #00010000b,p3  ; ポートに出力する初期値の設定
 MOV.B #00010000b,pd3 ; ポートの方向を出力に設定

Loop: MOV.B #00000000b, p3 ; p3_4 on
 JSR TIME
 MOV.B #00010000b, p3 ; p3_4 off
 JSR TIME
 JMP Loop  ; LED点滅を繰り返す

TIME:    ;時間消費のサブルーチン
 MOV.W #50, r1  ; 0.5秒ループ
LP01: MOV.W #28571, r0 ; 10ミリ秒ループ
LP02: SBJNZ.W #1, r0, LP02
 SBJNZ.W #1, r1, LP01
 RTS

 .SECTION FIXVECTOR, ROMDATA
 .ORG 0FFFCh
 .LWORD Start | 0FF000000h 
 .END