/********************************************************** タイマch0割り込みによってDMAch1をリピートモードで起動し,正弦波 をDACch0から出力する この動作をチェックするためタイマch1割り込みによってADCch0から 入力し,SCIch1を通してホストPCのターミナルに表示する
このテストプログラム実行時にはDACch0とADCch0を直結すること
このテストプログラムでの転送は,チェックの為にSCI通信を行なってい るため約2msec周期が最高である。SCI通信を止めてしまえば,DMAの性能 まで周期を短くできる
Copyright(C) 4Jan2003 KOSAKA
TNCT **********************************************************/ #include
<3048fone.h> #include "h8_3048fone.h" #define
clearTimer1Flag() (ITU1.TSR.BIT.IMFA=0)
#define WAVEDATASIZE
255 /*波形テーブルの大きさ*/ /*振幅127の正弦波 (255分割)*/ const
signed char SineTable[WAVEDATASIZE] =
{ 0,
3, 6, 9, 12,
15, 18,
21, 24,
27, 30, 34, 37,
39, 42,
45, 48,
51, 54, 57, 60,
62, 65,
68, 70,
73, 75, 78, 80,
83, 85,
87, 90,
92, 94, 96, 98, 100,
102, 104, 105, 107,
109, 110, 112, 113, 115,
116, 117, 118, 119,
120, 121, 122, 123,
124, 124, 125, 125,
126, 126, 126, 126,
126, 126, 126, 126,
126, 126, 125, 125,
124, 124, 123, 122,
122, 121, 120, 119,
118, 116, 115, 114,
112, 111, 109, 108,
106, 104, 103,
101, 99, 97, 95,
93, 91,
88, 86, 84, 82,
79, 77, 74,
72, 69,
66, 64, 61, 58,
55, 53,
50, 47,
44, 41, 38, 35,
32, 29,
26, 23,
20, 17, 14, 10,
7, 4,
1, -1, -4,
-7, -10, -14, -17, -20,
-23, -26, -29, -32,
-35, -38, -41, -44,
-47, -50, -53, -55,
-58, -61, -64, -66,
-69, -72, -74, -77,
-79, -82, -84, -86,
-88, -91, -93, -95,
-97, -99, -101, -103, -104, -106, -108,
-109, -111, -112, -114, -115, -116, -118,
-119, -120, -121, -122, -122, -123, -124,
-124, -125, -125, -126, -126, -126, -126,
-126, -126, -126, -126, -126, -126, -125,
-125, -124, -124, -123, -122, -121, -120,
-119, -118, -117, -116, -115, -113, -112,
-110, -109, -107, -105, -104, -102,
-100, -98, -96, -94, -92,
-90, -87, -85, -83,
-80, -78, -75, -73,
-70, -68, -65, -62,
-60, -57, -54, -51,
-48, -45, -42, -39,
-37, -34, -30, -27,
-24, -21, -18, -15,
-12, -9, -6,
-3 }; /*DAに出力する波形を格納する配列.中央値128とする.*/ unsigned char
wave[WAVEDATASIZE];
void
makeWaveTable(void) { int
i; for (i=0; i<WAVEDATASIZE; i++)
wave[i]=SineTable[i]+128; }
/*
------------------------------------------------- */ /* TIMER
INITIALIZATION */ /* -------------------------------------------------
*/ void initTimer0Int(unsigned short int
period) /*ITUによる割り込みタイマーの設定(越智君2001による)*/ /*割り込み間隔は引数peiodで単位はμsecである*/ /*値は20971以下でなければならない*/ /*20.971msecまで*/ {
unsigned int period25=(unsigned int)((25*(long
int)period+4)>>3); ITU0.TCR.BIT.CCLR=1;
/*GRAのコンペアマッチでTCNTをクリア*/ ITU0.TCR.BIT.CKEG=0;
/*立ち上がりエッジでカウント*/ ITU0.TCR.BIT.TPSC=3;
/*内部クロックφ/8でカウント*/
ITU0.GRA=period25-1;
/*割り込みの周期をperiod[μs]に指定*/ ITU0.TIER.BIT.OVIE=0;
/*オーバーフロー,アンダーフロー発生時割り込みを禁止*/
ITU0.TIER.BIT.IMIEB=0;
/*TCNT=GRBとなったときの割り込みを禁止*/
ITU0.TIER.BIT.IMIEA=1; /*TCNT=GRAとなったときの割り込み要求を許可*/ }
/*
-------------------------------------------------
DMAch0の初期化 ITU0によってリピートモードで起動する バイト転送 転送元はメモリ(フルアドレス)自動インクリメント 転送先はIOレジスタ(ショートアドレス) 初期化手順が大事 自分で初期化関数を作る時は注意すること DTEを読み出してDTE=0を確保して初期化する ETCRの上位・下位には同じカウンタ値を入れる
void *sourceHead
転送元アドレス(テーブルの先頭) int
number
転送データ数 255以下でなければならない void *destination 転送先IOアドレス int
triger 0:ITU0, 1:ITU1,
2:ITU2, 3:AD, 4:SCI0TxE, 5:SCI0Rx,
6:7:ChAフルアドレスモード,ChB外部トリガ -------------------------------------------------
*/ void initDMA0withITU0(void *sourceHead,int number,void
*destination,int triger) { int
dummy; while (DMAC1A.DTCR.BIT.DTE)
DMAC1A.DTCR.BIT.DTE = 0; /*DMA動作 1:許可, 0:禁止*/
DMAC1A.MAR = sourceHead; DMAC1A.IOAR = (unsigned
long int)destination & 0xff; DMAC1A.ETCR =
number+(number<<8);
/*転送カウンタ.下位8bitに繰返数,上位8bitはカウンタ*/
DMAC1A.DTCR.BIT.DTS = triger; /*トリガ*/
DMAC1A.DTCR.BIT.DTIE = 0; /*転送終了で割り込み(1:許可,
0:禁止)*/ DMAC1A.DTCR.BIT.RPE = 1;
/*RPE=1&DTIE=0:repeatMode,
RPE=0:IOMode,RPE=1&DTIE=1:IdleMode*/
DMAC1A.DTCR.BIT.DTID = 0; /*転送後のアドレス 0:++,
1:--*/ DMAC1A.DTCR.BIT.DTSZ = 0; /*転送単位
0:Byte, 1:Word*/ DMAC1A.DTCR.BIT.DTE =
1; /*DMA動作 1:許可, 0:禁止*/ }
/*
------------------------------------------------- */ /* AD CONVERT
*/ /* ------------------------------------------------- */ unsigned
int inputADC(unsigned char ch) { unsigned int
tmp; AD.ADCSR.BYTE = ch; /*
ADC単一モード、 chの値は0,1,2,3のみ*/ AD.ADCSR.BIT.ADST =
1; /* start */ while(AD.ADCSR.BIT.ADF == 0);
/* AD変換終了待機 */ AD.ADCSR.BIT.ADF =
0; tmp = (int)(*((volatile unsigned char
*)(&AD.ADDRA)+ch*2 )<<2)
+ (int)(*((volatile
unsigned char *)(&AD.ADDRA)+ch*2+1)>>6);
return tmp; }
void
initDAC() { DA.DACR.BYTE |= 0xc0; }
main() {
initLed(); initSCI1();
/*SCI-ch1の初期化*/
makeWaveTable();
initDMA0withITU0(wave,WAVEDATASIZE,(void
*)&DA.DADR0,0); initTimer1Int(2000);
/*時間割り込み2msec ch1でチェック用割り込みルーチン用*/
initTimer0Int(2000); /*時間割り込み2msec ch0でDMA用*/
initDAC();
E_INT();
/*CPU割り込み許可*/ startTimer01();
/*時間割り込みタイマスタートch0,ch1*/
while(1);
/*なにもしないループ*/ }
#pragma asm
.SECTION MYVEC, DATA,
LOCATE=H'000070
.ORG H'000070
;IMIA1 .DATA.L
_interrupt_cfunc .SECTION
P,CODE,ALIGN=2 ;これを忘れてはいけない #pragma endasm
#pragma interrupt
(interrupt_cfunc)
void interrupt_cfunc()
/*割り込みルーチン*/ { int y;
static int cnt=0; static int
count=0; static int tick=0;
y=(inputADC(0)>>2)-128;
SCI1_printf("%5d",y); if (((cnt++)&0x7)==0)
SCI1_printf("\n"); clearTimer1Flag();
/*タイマステータスフラグのクリア 忘れないこと*/
count++; if (count==500)
{
count=0; if (tick==1)
{
turnOnLed(0);
turnOffLed(1); } else
{
turnOffLed(0);
turnOnLed(1);
}
tick=1-tick; } }
/* 実行結果
255周期で動作しているのがわかる(ADC,DACによる約2のオフセットがあるため出力値と一致しない)
3 6 9 12
14 17 20 23
26 29 33 36 38
41 44 47 50
53 56 59 61 65
67 70 73 75
77 79 82 84 86
89 91 93 95
98 99 102 103 104 106
108 109 111 112 114 115 116
117 118 119 120 121 122 123
123 124 124 125 125 125 125
125 125 125 125 125 125 124
124 123 123 122 121 121 120
119 118 117 115 114 113 111
110 108 107 105 103 102
100 99 97 94
92 90 87 85
83 81 78 76 73
72 69 65 63
60 57 54 52 49
46 43 41 37
34 31 28 25
22 19 16 13
10 7 4 1
-2 -4 -7 -11 -14 -18
-20 -23 -26 -29 -32 -35 -38
-41 -45 -47 -50 -53 -55 -58
-61 -64 -66 -69 -72 -74 -77
-79 -82 -84 -86 -88 -91 -93
-95 -97 -99 -101 -103 -104 -106 -108 -109 -111 -112
-114 -115 -116 -118 -119 -120 -121 -122 -122 -123 -124
-124 -125 -125 -126 -126 -126 -126 -126 -126 -126 -126
-126 -126 -125 -125 -124 -124 -123 -122 -121 -120 -119 -118 -117
-116 -115 -113 -112 -110 -109 -107 -105 -104 -102
-100 -98 -96 -94 -92 -91 -87
-85 -83 -80 -79 -75 -73 -71
-68 -65 -62 -60 -57 -54 -51
-48 -45 -42 -39 -37 -34 -30
-27 -24 -21 -18 -15 -12
-9 -6 -4 0
3 6 9 12
15 17 21 24
26 29 33 36
39 41 44 47
50 53 56 59
61 65 68 69
72 74 77 79
82 84 86 89
91 93 95 98 99
101 103 104 106 108 109 111
112 114 115 116 117 118 119
120 121 122 123 123 124 124
125 125 125 125 125 125 125
125 125 125 124 124 123 123
122 121 121 120 119 118 117
115 114 113 111 110 108 107
105 103 103 100 99
97 94 92 90 87
85 83 81 78
77 73 72 69
66 63 60 57
54 52 49 46
43 40 38 35
31 28 25 22
19 17 14 10
7 4 1 -2
-5 -7 -10 -14 -17 -20
-23 -26 -29 -32 -35 -38 -41
-44 -47 -50 -53 -55 -58 -61
-64 -66 -69 -72 -74 -77 -79
-82 -84 -86 -88 -91 -93 -95
-97 -99 -101 -103 -104 -106 -108 -109 -111 -112 -114 -115
-116 -118 -119 -120 -121 -122 -122 -123 -124 -124
-125 -125 -126 -126 -126 -126 -126 -126 -126 -126 -126
-126 -125 -125 -124 -124 -123 -122 -121 -120 -119 -118 -117 -116
-115 -113 -112 -110 -109 -107 -105 -104 -102 -100
-98 -96 -94 -92 -90 -87 -85
-83 -80 -78 -75 -73 -70 -68
-65 -62 -60 -57 -54 -51 -48
-45 -42 -39 -37 -34 -30 -27
-24 -21 -18 -15 -13 -9
-6 -4 0
3 6 9 12
14 17 21 24 26
29 33 36 38
42 44 47 50
53 56 59 61
65 67 70 72
75 77 80 82
84 86 89 91
93 95 97 100 101 103
104 106 108 109 111 112 114
115 116 117 118 119 120 121
122 123 123 124 124 125 125
125 125 125 125 125
125 */ |