目次

D/Aコンバータ処理

 テストボードのP4.7には、LEDが接続されています。

 P4.4からP4.7は、A/Dコンバータ、D/Aコンバータとの
 兼用ピンになっているので、GP3CONで接続を切替えて
 使います。




 P4.7に接続されたLEDに、正弦波を出力して
 じわーっとした点灯と消灯をさせてみます。
 P4.7には、DAC3が割当てられています。

 D/Aコンバータは12ビットなので、0〜4095を
 2の12乗で割った振幅テーブルを作成します。
 2048を、中央の出力電圧としておきます。

 テーブルを配列で実現するとして、0〜63の
 範囲で出力を繰り返すと、仕様で与える点灯
 と消灯になる寸法です。



 振幅テーブルTcl/Tkを利用して作成しました。
 Tcl/Tkのソースコードは、以下です。

#!/bin/sh
# initialize amplitude
set mulx 2047
# generate pi
set pi2 [expr 2*(atan(1) * 4)]
# clear string
set tmp ""
# generate code
for { set j 0 } { $j < 64 } { incr j } {
  # calculate
  set valx [expr int($mulx * ( sin((2 * $j * $pi2) / 64) + 1)) ]
  # concatenate
  set i [format "0x%04X," $valx]
  # concatenate
  set tmp "$tmp $i"
  # judge
  if { [expr $j % 8 ] == 7 } {
    puts $tmp
    # clear
    set tmp ""
  }
}

 I/Oリダイレクトを利用して、次のようにパラメータを
 ファイルに保存しました。
------------------------------------------------------------------
  0x07FF, 0x098E, 0x0B0E, 0x0C70, 0x0DA6, 0x0EA5, 0x0F62, 0x0FD6,
  0x0FFE, 0x0FD6, 0x0F62, 0x0EA5, 0x0DA6, 0x0C70, 0x0B0E, 0x098E,
  0x07FF, 0x066F, 0x04EF, 0x038D, 0x0257, 0x0158, 0x009B, 0x0027,
  0x0000, 0x0027, 0x009B, 0x0158, 0x0257, 0x038D, 0x04EF, 0x066F,
  0x07FE, 0x098E, 0x0B0E, 0x0C70, 0x0DA6, 0x0EA5, 0x0F62, 0x0FD6,
  0x0FFE, 0x0FD6, 0x0F62, 0x0EA5, 0x0DA6, 0x0C70, 0x0B0E, 0x098E,
  0x07FF, 0x066F, 0x04EF, 0x038D, 0x0257, 0x0158, 0x009B, 0x0027,
  0x0000, 0x0027, 0x009B, 0x0158, 0x0257, 0x038D, 0x04EF, 0x066F,
------------------------------------------------------------------
 振幅テーブルは、配列で次の記述にしました。

const static UWORD table_sin[BUFSIZE] = {
  0x07FF, 0x098E, 0x0B0E, 0x0C70, 0x0DA6, 0x0EA5, 0x0F62, 0x0FD6,
  0x0FFE, 0x0FD6, 0x0F62, 0x0EA5, 0x0DA6, 0x0C70, 0x0B0E, 0x098E,
  0x07FF, 0x066F, 0x04EF, 0x038D, 0x0257, 0x0158, 0x009B, 0x0027,
  0x0000, 0x0027, 0x009B, 0x0158, 0x0257, 0x038D, 0x04EF, 0x066F,
  0x07FE, 0x098E, 0x0B0E, 0x0C70, 0x0DA6, 0x0EA5, 0x0F62, 0x0FD6,
  0x0FFE, 0x0FD6, 0x0F62, 0x0EA5, 0x0DA6, 0x0C70, 0x0B0E, 0x098E,
  0x07FF, 0x066F, 0x04EF, 0x038D, 0x0257, 0x0158, 0x009B, 0x0027,
  0x0000, 0x0027, 0x009B, 0x0158, 0x0257, 0x038D, 0x04EF, 0x066F
};

 P4.7をDAC3に割当て設定は、以下です。
   GP4CON = 0x20000000 ;

 31〜28の4ビットで、DACを指定します。
 この4ビット以外は、GPIOで利用する
 設定としました。

 D/Aコンバータは、timer1と同期して値を変化
 させられるので、振幅テーブルから値をもって
 くるように指定します。

 この設定には、CON(CONFIGURE)レジスタの5ビット
 が該当するので、このビットを1に設定します。

 D/Aコンバータ、A/Dコンバータには、リファレンス
 電圧が必要になるので、AVddを選択します。

 この指定は、CONレジスタの1、0ビット目で指定します。
  1. 00 power down
  2. 01 max voltage = DACref
  3. 10 max voltage = 2.5V
  4. 11 max voltage = AVdd
 さらに、D/Aコンバータのカウントレジスタを  ユーザークリアかを、CONレジスタの4ビット  で指定します。  まとめると、以下となります。  DAC3CON = 0x33 ;  timer1を使い、周期割込みを発生させD/Aコンバータに  データを出力する方式を採用します。  フラグを利用し一定周期で、DACレジスタ値を更新する  方式としました。  ADcU7026のタイマーは、ダウンカウントタイプなので  LDレジスタにリロードのカウント値を設定します。  また、CONレジスタでクロックソースの選択と分周比  を指定します。  全ソースコードは、以下。 #include <ADuC7026.h> #define OFF 0 #define ON OFF+1 /* data definitions */ typedef unsigned char UBYTE ; typedef signed char SBYTE ; typedef unsigned short UWORD ; typedef signed short SWORD ; typedef unsigned long ULONG ; typedef signed long SLONG ; #define BUFSIZE 64 /* Table is placed in Flash/EE */ const static UWORD table_sin[BUFSIZE] = { 0x07FF, 0x098E, 0x0B0E, 0x0C70, 0x0DA6, 0x0EA5, 0x0F62, 0x0FD6, 0x0FFE, 0x0FD6, 0x0F62, 0x0EA5, 0x0DA6, 0x0C70, 0x0B0E, 0x098E, 0x07FF, 0x066F, 0x04EF, 0x038D, 0x0257, 0x0158, 0x009B, 0x0027, 0x0000, 0x0027, 0x009B, 0x0158, 0x0257, 0x038D, 0x04EF, 0x066F, 0x07FE, 0x098E, 0x0B0E, 0x0C70, 0x0DA6, 0x0EA5, 0x0F62, 0x0FD6, 0x0FFE, 0x0FD6, 0x0F62, 0x0EA5, 0x0DA6, 0x0C70, 0x0B0E, 0x098E, 0x07FF, 0x066F, 0x04EF, 0x038D, 0x0257, 0x0158, 0x009B, 0x0027, 0x0000, 0x0027, 0x009B, 0x0158, 0x0257, 0x038D, 0x04EF, 0x066F }; void IRQ_Handler(void) __irq; void init_usr(void); void init_dac(void); void init_timer1(void); void dac_perform(void); /* global variables */ volatile UWORD ptr ; volatile UBYTE tflag ; int main(void) { /* initialize user */ init_usr(); /* endless loop */ while(ON) { /* cycle handler */ if ( tflag == ON ) { /* clear flag */ tflag = OFF ; /* DAC handling */ dac_perform(); } } /* dummy return */ return (0); } void IRQ_Handler(void) __irq { /* clear timer 1 interrupt flag */ T1CLRI = 0xff ; /* USO timer handler */ tflag = ON ; } void init_usr(void) { /* initialize table pointer */ ptr = 0 ; /* clear flag */ tflag = 0 ; /* initialize timer1 */ init_timer1() ; /* enable timer 1 interrupt */ IRQEN = GP_TIMER_BIT ; /* P4.7 <= DAC3 */ GP4CON = 0x20000000 ; /* initialize D/A converter */ init_dac(); } void init_timer1(void) { /* set relocatable value */ T1LD = 32768 ; /* select clock source , prescaler 1:1 */ T1CON = (1 << 9); } void init_dac(void) { /* DAC configuration synchoronuse timer_1 (2^5) range AVdd/AGND (2^4) */ DAC3CON = 0x33 ; /* start from midscale */ DAC3DAT = 0x08000000; } void dac_perform(void) { /* impress */ DAC3DAT = (*(table_sin+ptr) << 16); /* update pointer */ ptr++; if ( ptr == BUFSIZE ) { ptr = 0 ; } }
目次

inserted by FC2 system