目次
前
次
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ビット目で指定します。
- 00 power down
- 01 max voltage = DACref
- 10 max voltage = 2.5V
- 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 ; }
}
目次
前
次