2016年4月24日日曜日

DDS(ATtiny861A版)

ATtiny2313からの移植。PWM周りのφ(..)メモメモ

初めてtiny861Aを使ったが、ピンの配置が揃っててヨイ感じ

PWM出力(OC1A, OC1B, OC1D)に1kΩ+0.1uFのCRフィルタ追加で60Hz3相正弦波を出力



/*
 * PWM_test.c
 *
 * Created: 2016/04/24 3:16:25
 * Author : kingyo
 * MPU    : ATtiny861A@24.576MHz
 */ 

#include <avr/io.h>
#define F_CPU 24576000UL
#include <util/delay.h>
#include <avr/interrupt.h>

/* DDS */
static uint32_t acc1 = 0, acc2 = 0, acc3 = 0;
static uint32_t adder1, adder2, adder3;

/* (1 / 2^32) / (6.917317 * 10^-6) */
#define DDS_RES 0.0003365909

/* 正弦波波形テーブル */
const uint8_t sinewave[] =
{
 0x80,0x83,0x86,0x89,0x8c,0x8f,0x92,0x95,0x98,0x9c,0x9f,0xa2,0xa5,0xa8,0xab,0xae,
 0xb0,0xb3,0xb6,0xb9,0xbc,0xbf,0xc1,0xc4,0xc7,0xc9,0xcc,0xce,0xd1,0xd3,0xd5,0xd8,
 0xda,0xdc,0xde,0xe0,0xe2,0xe4,0xe6,0xe8,0xea,0xec,0xed,0xef,0xf0,0xf2,0xf3,0xf5,
 0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfc,0xfd,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,
 0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xfd,0xfc,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,
 0xf6,0xf5,0xf3,0xf2,0xf0,0xef,0xed,0xec,0xea,0xe8,0xe6,0xe4,0xe2,0xe0,0xde,0xdc,
 0xda,0xd8,0xd5,0xd3,0xd1,0xce,0xcc,0xc9,0xc7,0xc4,0xc1,0xbf,0xbc,0xb9,0xb6,0xb3,
 0xb0,0xae,0xab,0xa8,0xa5,0xa2,0x9f,0x9c,0x98,0x95,0x92,0x8f,0x8c,0x89,0x86,0x83,
 0x80,0x7c,0x79,0x76,0x73,0x70,0x6d,0x6a,0x67,0x63,0x60,0x5d,0x5a,0x57,0x54,0x51,
 0x4f,0x4c,0x49,0x46,0x43,0x40,0x3e,0x3b,0x38,0x36,0x33,0x31,0x2e,0x2c,0x2a,0x27,
 0x25,0x23,0x21,0x1f,0x1d,0x1b,0x19,0x17,0x15,0x13,0x12,0x10,0x0f,0x0d,0x0c,0x0a,
 0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x03,0x02,0x01,0x01,0x00,0x00,0x00,0x00,0x00,
 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x05,0x06,0x07,0x08,
 0x09,0x0a,0x0c,0x0d,0x0f,0x10,0x12,0x13,0x15,0x17,0x19,0x1b,0x1d,0x1f,0x21,0x23,
 0x25,0x27,0x2a,0x2c,0x2e,0x31,0x33,0x36,0x38,0x3b,0x3e,0x40,0x43,0x46,0x49,0x4c,
 0x4f,0x51,0x54,0x57,0x5a,0x5d,0x60,0x63,0x67,0x6a,0x6d,0x70,0x73,0x76,0x79,0x7c
};

/* MPU基本設定 */
static void initMPU(void)
{
 DDRA = 0b00000001;
 DDRB = 0b00101010;
}

/* PWM(timer1)設定 */
static void initPWM(void)
{
 /* PLL有効 IntRC8MHz * 8 = 64MHz */
 PLLCSR = 0b00000110;
 
 /* 3出力とも高速PWM動作 */
 TCCR1A = 0b10100011;
 TCCR1B = 0b00000001;
 TCCR1C = 0b10101001;
 TCCR1D = 0b00000000;
 
 /* PWMデューティのデフォルト値 */
 OCR1A = 128;
 OCR1B = 128;
 OCR1D = 128;
}

/* Timer0設定 */
static void initTimer0()
{
 TCCR0A = 0b00000001;
 TCCR0B = 0b00000001;
 TIMSK = 0b00010000;
 
 /* DDS処理割り込み周期決定 */
 /* 24.576MHz / 170 > About 6.917317us */
 OCR0A = 170 - 1;
}

/* DDS処理割り込み */
ISR (TIMER0_COMPA_vect)
{
 /* 位相ポインタ加算 */
 acc1 += adder1;
 /* SIN波形テーブル参照 3相波形出力 > 位相シフト120deg */
 OCR1A = sinewave[acc1 >> 24];
 OCR1B = sinewave[(acc1 + 1431655765) >> 24];
 OCR1D = sinewave[(acc1 + (1431655765 * 2)) >> 24];
}

/* 周波数設定 */
static void setFrq(uint16_t af1, uint16_t af2, uint16_t af3)
{
 adder1 = af1 / DDS_RES;
 //adder2 = af2 / DDS_RES;
 //adder3 = af3 / DDS_RES;
}


int main(void)
{
 uint16_t f1, f2, f3;
  
 initMPU();
 initPWM();
 initTimer0();
 
 sei();
 
 /* 60Hz */
 f1 = 600;
 setFrq(f1, f2, f3);
 
 while (1) 
 {
  /* 割り込み負荷測定用 */
  PORTA = 0x00;
  PORTA = 0x01;
 }
}


0 件のコメント:

コメントを投稿