AKI H8-3069ネット対応マイコンでWDTインターバルタイマ割り込みを使う方法の記事を昨日書きました。

日付が変わったので、今日は全プログラムを惜しげもなく(笑)公開します。

ヤフー検索しても出ていないので、ここだけの記事だと思います。(WDTでインターバルタイマ割り込みを使う人が私だけなのかも…)

 

フォルダ

Cドライブ直下に3069_2という作業フォルダを作って、ram3068.xとramcrt0.Sを付属のCDからコピーしています。

o,coff,motファイルはmakeを.実行すると出来るファイルです。

 

プログラム

h8s.s

 .h8300h
 .section .text
 .global _wait
 .global _sleep
 .global _permit_irq
 .global _prohibit_irq

_wait:
 mov.l #0x00500000,er0
.L2:
 dec.l #1,er0
 bne .L2
rts

_permit_irq:
 andc.b #0x7f,ccr  ; 割り込み許可
 rts

_prohibit_irq:
 orc.b #0x80,ccr  ; 割り込み禁止
 rts
 
 .end

 

ccrを操作しなくても動いたのでh8s.sは必要なさそうですが一応載せておきます。

 

wdt_header.h

typedef union {
    unsigned char BYTE;        /*  Byte Access */
    struct {                   /*  Bit  Access */
        unsigned char OVF :1;  /*    OVF       */
        unsigned char WTIT:1;  /*    WT/IT     */
        unsigned char TME :1;  /*    TME       */
        unsigned char     :2;  /*              */
        unsigned char CKS :3;  /*    CKS       */
    } BIT;
} TCSR_t;

/* WDT TCSR Byte Read Address*/
#define WDT_TCSR_BREAD (*(volatile TCSR_t *)0xFFFF8C)
/* WDT TCSR Word Write Address*/
#define WDT_TCSR_WWRITE (*(volatile unsigned short *)0xFFFF8C)
#define writeWDT_TCSR(x) (WDT_TCSR_WWRITE=0xa500+x)
#define clearWDT_TCNT() (WDT_TCSR_WWRITE=0x5a00)
#define writeWDT_TCNT(x) (WDT_TCSR_WWRITE=0x5a00+x)

#define RSTCSR (*(volatile unsigned char *)0xffff8f)

 

led.cに入れても良かったのですが煩雑になりそうなので分けました。

 

led.c

#include <h8/reg3067.h>
#include <h8/syscall.h>
#include "wdt_header.h"

#define IRQ0 12  /* IRQ0割り込みベクタ番号 */
#define WOVI 20  /* WOVI割り込みベクタ番号 */

//============================================================
// prot 1の割り込み設定
//============================================================
void init_irq0(void){
 ISCR = 0x01;   /* 立下りエッジで割り込みを発生 */
 ISR = 0x00;    /* 割り込みフラグクリア */
 IER = 0x01;    /* IRQ0の割り込みを許可 */
}

void initWatchdogTimerINT(int intervalIndex)
{
 TCSR_t tcsr;
 tcsr=WDT_TCSR_BREAD;
 tcsr.BIT.TME = 0;      /*タイマ・割り込みディスエイブル*/
 writeWDT_TCSR(tcsr.BYTE);
 tcsr.BIT.CKS=(intervalIndex&0x7); /*クロック選択*/
 tcsr.BIT.WTIT = 0;     /*インターバルタイマとして使用*/
 tcsr.BIT.OVF = 0;
 writeWDT_TCSR(tcsr.BYTE);
 TCR0_8 = 0x20; /* OVI許可 */
}

void startWatchdogTimer(void)
{
 TCSR_t tcsr;
 tcsr=WDT_TCSR_BREAD;
 tcsr.BIT.OVF = 0;
 tcsr.BIT.TME = 1;   /*タイマ・割り込みイネイブル*/
 writeWDT_TCSR(tcsr.BYTE);
}

void irq0(void){
 printf("\nirq0_start!\n");
 if(P6DR == 0xF8){
  P6DR = 0xF9;
 } else {
  P6DR = 0xF8;
 }
}

unsigned int c;

void wdtINT(void){
 TCSR_t tcsr;
 P6DR = 0xF9;
 //printf("wdt overflow!!\n");
 tcsr=WDT_TCSR_BREAD;
 tcsr.BIT.OVF = 0;
 tcsr.BIT.TME = 1;   /* タイマ・割り込みディスエイブル */
 writeWDT_TCSR(tcsr.BYTE);
 c++;
 printf("C=%d\n", c);
 P6DR = 0xF8;
}

int main(void){
 TCSR_t tcsr;
 int i;
 c = 0;
 
 P6DDR = 0x01;
 init_irq0();
 initWatchdogTimerINT(7);

 int_regist(IRQ0, irq0);
 int_regist(WOVI, wdtINT);

 if(int_regist(IRQ0, irq0)!=0){
  printf("\nIRQ0 is already used.\n");
 }

 if(int_regist(WOVI, wdtINT)!=0){
  printf("WDT is already used.\n");
 }

 printf("TCSR=%0x\n", TCSR);
 startWatchdogTimer();  /*時間割り込みタイマスタート*/
 clearWDT_TCNT();
 
 while(1){
 }

 return 0;
}

 

メインプログラムです。

irq0割り込みとP60でLEDを点滅させている部分は無くてもOKです。

 

Makefile

TARGET  = led.mot

CFLAGS  = -O -mh -mint32
TOOL_PREFIX = h8300-hms-
CC  = $(TOOL_PREFIX)gcc
AS  = $(TOOL_PREFIX)as

LDSCRIPT = ram3068.x
CRT0  = ramcrt0.S
SRCS  = led.c
ASM   = h8s.s

all : $(TARGET)


$(TARGET): $(TARGET:.mot=.coff)
 $(TOOL_PREFIX)objcopy -O srec $(TARGET:.mot=.coff) $@


$(TARGET:.mot=.coff): Makefile $(LDSCRIPT) $(SRCS:.c=.o) $(FUNC:.c=.o)\
   $(H8:.c=.o) $(ASM:.s=.o) $(CRT0) $(ASRCS) $(LIBS)
 $(CC) $(CFLAGS) -T $(LDSCRIPT) -nostartfiles $(CRT0) $(ASRCS)\
  $(SRCS:.c=.o) $(FUNC:.c=.o) $(ASM:.s=.o) -o $@ $(LIBS) -lc -lgcc

write:
 put.exe $(TARGET) com8

clean :
 rm -f $(TARGET)
 rm -f $(TARGET:.mot=.exe)
 rm -f $(SRCS:.c=.o)
 rm -f $(FUNC:.c=.o)
 rm -f $(ASM:.s=.o)

 

ASM=h8s.sの行は無くてもOKです。

 

実行手順

コマンドプロンプトを起動して、C:\3069_2に移動

makeとmake writeを実行

 

TeraTeamを起動してH8マイコンをリセット

H8/OSのプロンプトが表示されるので「exec ffde40」を実行

WDTインターバルタイマ割り込みが掛かる度にCがインクリメントされているのがわかります。

 

以上でWDTインターバルタイマ割り込みの記事は終わりです。

 

WDTインターバルタイマをAM2302(温湿度センサー)の読み込みに利用しようと思っていたのですが16ビットタイマの方がCPUクロックを分周無しで使えそうなので次回からは16ビットタイマを使ってみます。

 

以上、ご利用下さい。(。・ω・)ノ゙

 

MENUに戻る