2016年3月14日月曜日

DDS

-- DDS処理メモ --
割り込みのオーバヘッド割合が大きいため、サンプリング周波数を高くできない・・・

■仕様
MPU: ATtiny2313@24.576MHz
出力: 2CH PWM (MAX 4CH)
サンプリング周波数: 約125kHz
垂直分解能: 8bit
波形テーブル: 正弦波256サンプル


出力波形例

配線(ん)


以下参考ソース

/*
 * softwareDDS.c
 *
 * Created: 2016/03/05 18:59:42
 * Author : kingyoZAL1
 */ 

#include <avr/io.h>
#define F_CPU 24.576E6
#include <util/delay.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>

/* Global val */
volatile uint32_t acc1 = 0, acc2 = 0;
volatile uint32_t adder1, adder2;

/* (1 / 2^32) / (7.97526 * 10^-6) */
#define DDS_RES 0.0002919411

/* MPU初期化 */
static void InitMPU (void)
{
 DDRD = 0x01;
 PORTD = 0;
 
 /* デバッグ用 */
 DDRD |= 1 << 4;
}

/* PWM設定 */
static void InitPWM (void)
{
 /* Duty = 50% */
 OCR0A = 0x80;
 OCR0B = 0x80;
 
 /* OC0A, OC0B */
 DDRB |= 1 << 2;
 DDRD |= 1 << 5;
 TCCR0A = 0b10100011;
         // ||||||++--- WGM01, WGM00
         // ||||++----- Reserved(0)
         // ||++------- COM0B1, COM0B0
         // ++--------- COM0A1, COM0A0
 TCCR0B = 0b10000001;
         // |||||+++--- CS02, CS01, CS00
         // ||||+------ WGM02
         // ||++------- Reserved(0)
         // ++--------- FOC0A, FOC0B
#if 0
 /* OC1A, OC1B */
 DDRB |= 1 << 3;
 DDRB |= 1 << 4;
 TCCR1A = 0b10100001;
         // ||||||++--- WGM11, WGM10
         // ||||++----- Reserved(0)
         // ||++------- COM1B1, COM1B0
         // ++--------- COM1A1, COM1A0
 TCCR1B = 0b10001001;
         // |||||+++--- CS02, CS01, CS00
         // ||||+------ WGM12
         // |||+------- WGM13
         // ||+-------- Reserved(0)
         // ++--------- ICNC1, ICES1
#endif
}

/* 正弦波波形テーブル */
const uint8_t sinewave[] PROGMEM =
{
 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,
};

/* DDS処理 */
ISR (TIMER1_COMPA_vect)
{
 acc1 += adder1;
 OCR0A = pgm_read_byte(&sinewave[acc1 >> 24]);
 acc2 += adder2;
 OCR0B = pgm_read_byte(&sinewave[acc2 >> 24]);
}

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

/* MAIN */
int main (void)
{
 uint16_t f1, f2;

 InitMPU();
 InitPWM();
 
 /* 定周期DDS処理用タイマ1設定 */
 TCCR1A = 0b00000000;
 TCCR1B = 0b00001001;
 TIMSK = 0b01000000;
 OCR1A = 196 - 1; // 196 -> About 7.97526us
 
 sei ();
 
 f1 = 10000;
 f2 = 2000;
 setFrq(f1, f2);
 
 while (1) 
 {
  /* 波形観測用トリガ信号 */
  PORTD |= 1 << 4;
  PORTD &= ~(1 << 4);
  
  /* 周波数切替てすと */
  setFrq(2000, 5000);
  _delay_ms(2);
  
  setFrq(10000, 2000);
  _delay_ms(2);
 }
}
Let's キモい波形生成!

~ おわり ~

3 件のコメント:

  1. 初めまして。
    ブラシレスモータについて勉強していたところ、youtubeであなたの動画を見つけ、ブログまでたどり着きました。
    https://www.youtube.com/watch?v=XBKd1TVE-JA

    もしよろしければ、こちらの回路図とプログラムについて教えていただけないでしょうか?
    ホールセンサを使って回すことは出来ているのですが、センサレスでブラシレスモータを綺麗に回すことが出来なくて困っています。
    よろしくお願いします。

    返信削除
  2. mumuさん
    動画を見ていただきありがとうございます。
    実は私自身もセンサレスブラシレスモータを上手に制御する方法はまだ理解できておらず、投稿してる動画はやっつけで適当に作ったものだったりします。
    停止状態からスムーズに起動させることや、回転数の可変はまだ実現できてません。。
    海外の安いラジコン用ブラシレスアンプを分解して見るとイロイロ勉強になるかもしれません。
    また近いうちにこちらのブログで自身の勉強兼ねて紹介します。
    少々お待ち下さい・・・

    返信削除
  3. お返事ありがとうございます。
    なるほど、ESCの分解ですか。確かに勉強になりそうです。
    金魚さんの記事を楽しみに待ちながら、私も勉強しておきます。

    返信削除