среда, 11 апреля 2012 г.

Распределенная Bit Angle Modulation

Часто, для управления мощностью нагрузки используется широтно-импульсная модуляция. То есть энергия поступает в нагрузку периодами и потребляемая мощность зависит от соотношения периодов включения и выключения.
Описание BAM.
Как видно из описания, периоды включения распределены неравномерно. Попробуем это исправить. Я попробовал поменять местами старшие и младшие биты адреса.

Javascript:

// Bit Angle Modulation
// Альтернатива ШИМ

var out = [];
var inp = 208;
var maxBit = 7;
for(var i=0; i<256; i++)
{

  for(var bit=maxBit, mask, mask2; bit >=0; --bit)
  {
    mask = 1 << bit;
    mask2 = 1 << (maxBit - bit);
    if(i & mask2)
    {
      out.push(+(!!(inp & mask)))
      break;               
    }        
  }
    
}
console.log(out);

На выходе получил такую последовательность:
1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, ...

Неплохо, но видно что последовательность неоднородна.
Решил попробовать использовать алгоритм Брезенхема, код на C:
/*
  Программный эмулятор распределенной Bit Angle модуляции базируется на алгоритме Брезенхема
  Равномерно распределяет нули и единицы на протяжении периода
*/

#include <stdio.h>

// длительность импульса (максимальное значение)
#define LENGTH 255

unsigned char brezen(unsigned char value){
  static unsigned char out[LENGTH];

  unsigned char oldVal = LENGTH/2;
  unsigned char newVal;
  unsigned char i=0;
 
  for(; i<LENGTH; ++i)
  {
    if(value >= LENGTH)
    {
      out[i] = 1;
    }
    else
    {
        newVal = (oldVal + value) % LENGTH;
        out[i] = newVal < oldVal ? 1 : 0;
        oldVal = newVal;
   
    }
    printf("%d", out[i]);
  }
  printf("\n");
  return out;
}


int main()
{
  brezen(0);
  brezen(5);
  brezen(25);
  brezen(254);
  brezen(255);
  return 0;
}

Получается последовательность с равномерно распределенными нулями и единицами.
Но, есть БОЛЬШОЕ "но" - эти алгоритмы реализованы программно и отнимают процессорное время. Алгоритмы можно реализовать в "железе"

4 комментария:

  1. Этот комментарий был удален автором.

    ОтветитьУдалить
  2. Смысл этого метода в том, чтобы уменьшить затраты ресурсов Мк в пользу увеличения полезных функций, а вы предложили обратно свести на нет все преимущества.
    Я честно говоря не понял как вы собираетесь самый большой бит делить опять городить кипу прерываний?
    И еще я не понял из вашего кода как будет выглядеть алгоритм управления множеством нагрузок.

    ОтветитьУдалить
    Ответы
    1. Целью этого алгоритма является уменьшение низкочастотной составляющей спектра для упрощения фильтрации. Я реализовал подобный алгоритм для МК PIC16 http://vitaliy-rudik.blogspot.com/2012/05/blog-post.html. Данный алгоритм генерирует последовательности в основном цикле. Предполагается что микроконтроллер используется только для генерации последовательности в качестве сопроцессора, а по прерыванию в него записываются новые значения выходных уровней. Да, так искажаются формы выходных импульсов, но я думаю несущественно. Если генерацию импульсов посадить на прерывание по таймеру, то частота будет значительно ниже, так как требуются дополнительные такты для сохранения и восстановления рабочего регистра и программного счетчика.

      Удалить
  3. Почему не:

    ...
    var offset = 0;
    var next = 0;
    var del = 255/inp;
    for( var offset=0; offset<256; offset++)
    {
    if (offset >= next)
    {
    next = (int) next + del;
    out.push(1);
    }
    else
    {
    out.push(0);
    }
    }

    ???

    ОтветитьУдалить