прошу помочь ускорить работу скетча программный шим 6 каналов

daniilguz
Offline
Зарегистрирован: 13.01.2020

Добрый день!

Прошу помощи в ускорении работы для реализации программного шим для частотного регулятора.

Собрал плату на irams10up60b. Управление хочу выполнить на ардуино нано v3.

Нужно синус на 6 каналов для управления трехфазным двигателем. Скетч сделал, полностью рабочий, но скорость только до 100 герц. Помогите построить более быстрый программный шим.

#include <avr/io.h>
#include <avr/interrupt.h>

#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))

byte prog_pwm=0;
byte prog_prev=0;
byte num=1;
byte mnogitel=0;
byte k=0;

int  steep1=32;
int  steep2=32;
int  steep3=32;
int  steep4=32;
int  steep5=32;
int  steep6=32;

int sensorValue ;
int flag_led_1=0;
int readsens=0;
int pinIn    = A0; // Пин аналогового входа

byte sin_1_h[36]={0  , 45, 88,128,164,196,221,240,252,255,252,240,221,196,164,128, 88, 45,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0};
byte sin_2_h[36]={221,196,164,128, 88, 45,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 45, 88,128,164,196,221,240,252,255,252,240};
byte sin_3_h[36]={0  ,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 45, 88,128,164,196,221,240,252,255,252,240,221,196,164,128, 88, 45,  0,  0,  0,  0,  0,  0};
byte sin_1_l[36]={0  ,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 45, 88,128,164,196,221,240,252,255,252,240,221,196,164,128, 88, 45};
byte sin_2_l[36]={0  ,  0,  0,  0,  0,  0,  0, 45, 88,128,164,196,221,240,252,255,252,240,221,196,164,128, 88, 45,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0};
byte sin_3_l[36]={221,240,252,255,252,240,221,196,164,128, 88, 45,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 45, 88,128,164,196};

//byte sin_1_h[13]={ 0  ,127,221,255,221,127, 0 , 0 , 0 , 0 , 0 , 0 , 0 };
//byte sin_2_h[13]={ 221,127,  0,  0, 0 , 0 , 0 , 0 , 0 ,127,221,255,221};
//byte sin_3_h[13]={ 0  ,  0,  0,  0, 0 ,127,221,255,221,127, 0 , 0 , 0 };
//byte sin_1_l[13]={ 0  ,  0,  0,  0, 0 , 0 , 0 ,127,221,255,221,128, 0 };
//byte sin_2_l[13]={ 0  ,  0,  0,127,221,255,221,127, 0 , 0 , 0 , 0 , 0 };
//byte sin_3_l[13]={ 221,255,221,127, 0 , 0 , 0 , 0 , 0 ,  0,  0,127,221};


ISR (TIMER1_COMPA_vect  )
{
  
  flag_led_1++; 
  prog_pwm++;
}
void setup() {
  pinMode(pinIn, INPUT);
    ADCSRA |= (1 << ADPS1);                     //Биту ADPS2 присваиваем единицу - коэффициент деления 16
    ADCSRA &= ~ ((1 << ADPS2) | (1 << ADPS0));  //Битам ADPS1 и ADPS0 присваиваем нули
   pinMode(2, OUTPUT);  
   pinMode(3, OUTPUT); 
   pinMode(4, OUTPUT); 
   pinMode(5, OUTPUT);  
   pinMode(6, OUTPUT); 
   pinMode(7, OUTPUT); 
 
               cli(); // отключить глобальные прерывания
    TCCR1A = 0x00;
    TCCR1B = (0 << CS12)| (1 << CS11)|(0 << CS10)|(1 << WGM12); //предделитель clk/0, режим таймера СТС
    TCNT1 = 0x00;
    OCR1A =10; // максимальный предел счета
    TIMSK1 |= (1 << OCIE1A); // разрешение прерывания по совпадению


              sei();
   
}

void loop() {
 
    if (prog_pwm>=32){prog_pwm=0;}
     if (flag_led_1>=1){flag_led_1=0;}
           steep1=(sin_1_h[num]/4)-prog_pwm-k;if (steep1> prog_pwm){PORTD |= 1<<2;}else{PORTD &= ~(1<<2);}
           steep2=(sin_2_h[num]/4)-prog_pwm-k;if (steep2> prog_pwm){PORTD |= 1<<3;}else{PORTD &= ~(1<<3);}
           steep3=(sin_3_h[num]/4)-prog_pwm-k;if (steep3> prog_pwm){PORTD |= 1<<4;}else{PORTD &= ~(1<<4);}
           steep4=(sin_1_l[num]/4)-prog_pwm-k;if (steep4> prog_pwm){PORTD |= 1<<5;}else{PORTD &= ~(1<<5);}
           steep5=(sin_2_l[num]/4)-prog_pwm-k;if (steep5> prog_pwm){PORTD |= 1<<6;}else{PORTD &= ~(1<<6);}
           steep6=(sin_3_l[num]/4)-prog_pwm-k;if (steep6> prog_pwm){PORTD |= 1<<7;}else{PORTD &= ~(1<<7);}
        mnogitel++;
    
    if ( mnogitel>=(9+sensorValue/8)){mnogitel=0;num++;if (num>=36){num=0;sensorValue=analogRead(pinIn);if (sensorValue>=500){k=sensorValue/16;}else{k=0;} }
     }
}


   

      
   

 

asam
asam аватар
Онлайн
Зарегистрирован: 12.12.2018

А чем аппаратный (на таймерах) ШИМ не устраивает?

-NMi-
Offline
Зарегистрирован: 20.08.2018

Может конечно я что и не непонял, но, первое - как на аврке сделать аппаратный синус через шим? Это непонятно вообще.

И второе, как??? сделать програмный шим??? И тем более, как его ускорить? Это вооще нипанятьчиго.

**********  занавес  ***********

Лично я делал синус-шим на авр таким способом: 0-м таймером генерим синхру (тобишь скорость). 1 и 2 таймеры по 8 бит в фасте оба. 0-м таймером "бегаем" по таблице синуса со сдвигом в 120гр. и "кормим" таймеры 1 и 2.                             Всё.

daniilguz
Offline
Зарегистрирован: 13.01.2020

может я и ошибаюсь ноу ардуино нано всего три таймера на каждом по две ноги. Если использовать один для прерываний то остается 2 таймера,  4 канала шим,  а нужно 6. на мегу я скется уже написал все отлично работает. Идея сделать дешевое устройство плавного пуска электродвигателя. 2 доллара ардуино нано, 4 доллара игбт модуль, и на 4 доллара деталей. Всего 10 долларов и насосная станция или другой асинхронный двигатель стартует плавно.

Дешевое устройство плавного пуска.

nik182
Онлайн
Зарегистрирован: 04.05.2015

1.8 доллара блюпилл. Из коробки с одним первым таймером шестифазный генератор с дедтаймами и простой удобной регулировкой.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

nik182, сюда постоянно приходют много людей, хотящих странного, и не слушающих ничьих советов.  Им говорят, что железо надо подбирать под задачу, а оне всеми копытами упираются, мол, нет, у меня уже есть вот это, как бы мне теперь это поудобнее натянуть, как глаз на жопу. 

daniilguz
Offline
Зарегистрирован: 13.01.2020

Может конечно я что и не непонял, но, первое - как на аврке сделать аппаратный синус через шим? Это непонятно вообще.

Отвечаю: я не просил помочь сделать аппаратный синус. сам не пойму что это такое :)

И второе, как??? сделать програмный шим???

Ответ: сделать программный шим на ногах без поддержки аппаратного шим. Он уже реализован в скетче и работает например на PD 2,3,4,5,6,7 порту.

И тем более, как его ускорить? Это вооще нипанятьчиго. Согласен очепятался .Прошу помощи в ускорении работы скетча.

____________________________________________________________

Лично я делал синус-шим на авр таким способом: 0-м таймером генерим синхру (тобишь скорость). 1 и 2 таймеры по 8 бит в фасте оба. 0-м таймером "бегаем" по таблице синуса со сдвигом в 120гр. и "кормим" таймеры 1 и 2. 

На меге я так и сделал там таймеров и ног с запасом. Но идея сделать дешевое устройство плавного пуска ценой до 10-12 долларов.

0 и 2 таймер на нане 8 бит. на каждом по две ноги = 4 канала шим. ШИМ: 3, 5, 6,  и 11. поскольку таймером 1 мы бегаем по таблице синуса каналы 9, 10, не могут быть задействованы? или я ошибаюсь?

"бегаем" по таблице синуса со сдвигом в 120гр. В данном скетче я  сделал шесть массивов, что бы в скетче не пересчитывать сдвиг, это занимает время.

daniilguz
Offline
Зарегистрирован: 13.01.2020

не нужна регулировка. Это устройство плавного пуска.

Дедтайм реализован аппаратно в модуле игбт.

daniilguz
Offline
Зарегистрирован: 13.01.2020

так ведь работает уже, почему не получится? могу видео работы снять. Прошу помощи в ускорении работы скетча а не неестественных задач.

sadman41
Онлайн
Зарегистрирован: 19.10.2016
(0 << CS12)| (1 << CS11)|(0 << CS10)

Это предделитель /8

Для /1 (no prescaling) нужно выставлять CS10, а не CS11

daniilguz
Offline
Зарегистрирован: 13.01.2020

nik182 пишет:
1.8 доллара блюпилл. Из коробки с одним первым таймером шестифазный генератор с дедтаймами и простой удобной регулировкой.

 

не нужна регулировка это устройство плавного пуска, дедтайм реализован аппаратно в игбт модуле.

b707
Offline
Зарегистрирован: 26.05.2017

daniilguz пишет:

На меге я так и сделал там таймеров и ног с запасом. Но идея сделать дешевое устройство плавного пуска ценой до 10-12 долларов.

Слушайте, Мега стоит 480 руб, Нано - 180. Вы свое устройство собираетесь выпускать миллионными тиражами, что для вас так принципиальна разница в 300 рублей?

Если да - я вас разочарую, на Али есть готовые частотные модули за копейки

rkit
Онлайн
Зарегистрирован: 23.11.2016

Плавный пуск делают на симисторах, а это уже частотный преобразователь.

За 10 долларов частотник не сделать, потому что в реальном мире против фантазии нужны защитные устройства, нужно охлаждение ключей, нужен не абы какой монтаж, нужно вложить много времени, и так далее.

daniilguz
Offline
Зарегистрирован: 13.01.2020

я пробовал менять предделитель, но форма сигнала искажается видимо потому, что прерывание наступает слишком часто , несколько раз пока идет скетч.

Поэтому прошу посмотреть void loop, что можно ускорить, оптимизировать, упростить.

daniilguz
Offline
Зарегистрирован: 13.01.2020

rkit пишет:

Плавный пуск делают на симисторах, а это уже частотный преобразователь.

За 10 долларов частотник не сделать, потому что в реальном мире против фантазии нужны защитные устройства, нужно охлаждение ключей, нужен не абы какой монтаж, нужно вложить много времени, и так далее.

1 почему на симисторах, это кто так решил?

2 вот вам частотник за 10 баксов: https://youtu.be/He5ISCiuVcw

daniilguz
Offline
Зарегистрирован: 13.01.2020

не заметил модулей на али за копейки, киньте пожалуйста ссылку в личку. Буду очень благодарен.

daniilguz
Offline
Зарегистрирован: 13.01.2020

Прошу Вас о помощи, увеличить скорость работы скетча, а именно цикла void loop

как его можно оптимизировать, ускорить, упростить?

Прошу тапками не кидать, все уже реализовано, все работает, хочется ускорить работу.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

а схема и полный скетч будет публиковаться?

daniilguz
Offline
Зарегистрирован: 13.01.2020

Только сейчас понял вы предлагаете сменить контроллер. В принципе так и думал сделать, даже купил, но пока только разбираюсь в самых основах программирования stm.

daniilguz
Offline
Зарегистрирован: 13.01.2020

это полный скетч.

вот схема, по ней все собрано, она простейшая. контроль температуры не реализован, en подтянуто к +5 В через 1 кОм резистор.

http://circuits.datasheetdir.com/200/IRAMS10UP60B-circuits.jpg

rkit
Онлайн
Зарегистрирован: 23.11.2016

1. Решили инженеры, которые гораздо умнее нас с вами, и отвечают за свою деятельность финансово.

2. Монтаж 380 на макетке - бомба замедленного действия. Моторы без нагрузки не испытывают.

daniilguz
Offline
Зарегистрирован: 13.01.2020

Все в принципе все получилось ветку можно закрывать.

Устройство плавного пуска собрано,  шим работает на частоте где-то 5 кГц. Что хорошо сказывается на модуле, он вообще холодный.

Решением проблемы стало: для ускорения работы скетча уменьшил таблицу синуса до 24 значений. для совсем ленивых могу выложить.

Соответственно скорость работы увеличилась в ущерб форме синуса.

Схема указана выше, будут вопросы спрашивайте.

Есть скетч под мегу могу выложить, если нужно.

 

b707
Offline
Зарегистрирован: 26.05.2017

daniilguz, позволил себе отформатировать ваш код, а глаза сломать можно.

 

#include <avr/io.h>
#include <avr/interrupt.h>

#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))

byte prog_pwm = 0;
byte prog_prev = 0;
byte num = 1;
byte mnogitel = 0;
byte k = 0;

int  steep1 = 32;
int  steep2 = 32;
int  steep3 = 32;
int  steep4 = 32;
int  steep5 = 32;
int  steep6 = 32;

int sensorValue ;
int flag_led_1 = 0;
int readsens = 0;
int pinIn    = A0; // Пин аналогового входа

byte sin_1_h[36] = {0  , 45, 88, 128, 164, 196, 221, 240, 252, 255, 252, 240, 221, 196, 164, 128, 88, 45,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0};
byte sin_2_h[36] = {221, 196, 164, 128, 88, 45,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 45, 88, 128, 164, 196, 221, 240, 252, 255, 252, 240};
byte sin_3_h[36] = {0  ,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 45, 88, 128, 164, 196, 221, 240, 252, 255, 252, 240, 221, 196, 164, 128, 88, 45,  0,  0,  0,  0,  0,  0};
byte sin_1_l[36] = {0  ,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 45, 88, 128, 164, 196, 221, 240, 252, 255, 252, 240, 221, 196, 164, 128, 88, 45};
byte sin_2_l[36] = {0  ,  0,  0,  0,  0,  0,  0, 45, 88, 128, 164, 196, 221, 240, 252, 255, 252, 240, 221, 196, 164, 128, 88, 45,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0};
byte sin_3_l[36] = {221, 240, 252, 255, 252, 240, 221, 196, 164, 128, 88, 45,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 45, 88, 128, 164, 196};

//byte sin_1_h[13]={ 0  ,127,221,255,221,127, 0 , 0 , 0 , 0 , 0 , 0 , 0 };
//byte sin_2_h[13]={ 221,127,  0,  0, 0 , 0 , 0 , 0 , 0 ,127,221,255,221};
//byte sin_3_h[13]={ 0  ,  0,  0,  0, 0 ,127,221,255,221,127, 0 , 0 , 0 };
//byte sin_1_l[13]={ 0  ,  0,  0,  0, 0 , 0 , 0 ,127,221,255,221,128, 0 };
//byte sin_2_l[13]={ 0  ,  0,  0,127,221,255,221,127, 0 , 0 , 0 , 0 , 0 };
//byte sin_3_l[13]={ 221,255,221,127, 0 , 0 , 0 , 0 , 0 ,  0,  0,127,221};


ISR (TIMER1_COMPA_vect  )
{

  flag_led_1++;
  prog_pwm++;
}
void setup() {
  pinMode(pinIn, INPUT);
  ADCSRA |= (1 << ADPS1);                     //Биту ADPS2 присваиваем единицу - коэффициент деления 16
  ADCSRA &= ~ ((1 << ADPS2) | (1 << ADPS0));  //Битам ADPS1 и ADPS0 присваиваем нули
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);

  cli(); // отключить глобальные прерывания
  TCCR1A = 0x00;
  TCCR1B = (0 << CS12) | (1 << CS11) | (0 << CS10) | (1 << WGM12); //предделитель clk/0, режим таймера СТС
  TCNT1 = 0x00;
  OCR1A = 10; // максимальный предел счета
  TIMSK1 |= (1 << OCIE1A); // разрешение прерывания по совпадению


  sei();

}

void loop() {

  if (prog_pwm >= 32) {
    prog_pwm = 0;
  }
  if (flag_led_1 >= 1) {
    flag_led_1 = 0;
  }
  steep1 = (sin_1_h[num] / 4) - prog_pwm - k; 
  if (steep1 > prog_pwm) {
    PORTD |= 1 << 2;
  } else {
    PORTD &= ~(1 << 2);
  }
  steep2 = (sin_2_h[num] / 4) - prog_pwm - k; 
  if (steep2 > prog_pwm) {
    PORTD |= 1 << 3;
  } else {
    PORTD &= ~(1 << 3);
  }
  steep3 = (sin_3_h[num] / 4) - prog_pwm - k; 
  if (steep3 > prog_pwm) {
    PORTD |= 1 << 4;
  } else {
    PORTD &= ~(1 << 4);
  }
  steep4 = (sin_1_l[num] / 4) - prog_pwm - k; 
  if (steep4 > prog_pwm) {
    PORTD |= 1 << 5;
  } else {
    PORTD &= ~(1 << 5);
  }
  steep5 = (sin_2_l[num] / 4) - prog_pwm - k; 
  if (steep5 > prog_pwm) {
    PORTD |= 1 << 6;
  } else {
    PORTD &= ~(1 << 6);
  }
  steep6 = (sin_3_l[num] / 4) - prog_pwm - k; 
  if (steep6 > prog_pwm) {
    PORTD |= 1 << 7;
  } else {
    PORTD &= ~(1 << 7);
  }
  mnogitel++;

  if ( mnogitel >= (9 + sensorValue / 8)) {
    mnogitel = 0; num++; 
    if (num >= 36) {
      num = 0;
      sensorValue = analogRead(pinIn);
      if (sensorValue >= 500) {
        k = sensorValue / 16;
      } else {
        k = 0;
      }
    }
  }
}

А теперь посмотрите внимательнее - вы точно не ошиблись? Переход к новой точке синуса num++ действительно должен происходить только внутри условия строки 115 ? -

 

daniilguz
Offline
Зарегистрирован: 13.01.2020

Это-ж макет? а на чем делают макеты?

Проверил с нагрузкой на насосной станции все работает.

1. Решили инженеры, которые гораздо умнее нас с вами, и отвечают за свою деятельность финансово.

Отвечаю: Плавный пуск можно реализовывать каким угодно способом, в том числе и тиристорами, почему нельзя игбт модулем это сделать если стоимость низкая?

https://eleksun.com.ua/ustroystvo-plavnogo-puska-serii-altistart-01-in3-moshchnost-odnofaznyy-220vtrehfaznyy-380v-03711-kvt

Вот покупайте у этих инженеров сами за 120 баксов.

b707
Offline
Зарегистрирован: 26.05.2017

daniilguz пишет:

Все в принципе все получилось ветку можно закрывать.

Устройство плавного пуска собрано,  шим работает на частоте где-то 5 кГц

Решением проблемы стало: для ускорения работы скетча уменьшил таблицу синуса до 24 значений

Да ну? - уменьшил таблицу с 36 до 24 значиний - и частота ШИМ сразу выросла со 100 Гц до 5 КГц?

А можете свой код немного пояснить?

 1. Зачем, например, на каждом шаге каждое значение таблицы синусов делить на 4? - может стоило сразу в таблицу положить уже поделенные значения? - сэкономили бы 6 делений на каждом шаге - а деление в АВР очень медленное...

2. Что такое к?

(update - один вопрос убрал, вроде сам разобрался)

daniilguz
Offline
Зарегистрирован: 13.01.2020

Простите я не понимаю сути вопроса.

В строке 115 уменьшать статический коэффициент 9?

daniilguz
Offline
Зарегистрирован: 13.01.2020

Вообще конструктивно сейчас все обдумаю.

b707
Offline
Зарегистрирован: 26.05.2017

daniilguz пишет:

Простите я не понимаю сути вопроса.

В строке 115 уменьшать статический коэффициент 9?

вопрос снимается. Постепенно разбираюсь, скетч очень не наглядно написан. имена переменных неинформативные... "Множитель" - на самом деле совсем не множитель, а шаг ШИМ, верно?

b707
Offline
Зарегистрирован: 26.05.2017

и еще совет - число точек и ШИМ и синуса лучше выбрать степенью двойки - тогда переход через ноль можно будет делать одной битовой операцией. избавившись от проверки условия на каждом шаге

daniilguz
Offline
Зарегистрирован: 13.01.2020

в таблице синуса делю на 4 потому, что эта талица синуса у меня осталась из скетча меги. переделывать было лень, не знал что деление долго идет. исправлю таблицу.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

daniilguz пишет:

в таблице синуса делю на 4 потому, что эта талица синуса у меня осталась из скетча меги. переделывать было лень, не знал что деление долго идет. исправлю таблицу.

выложи плс исправленный скетч...

b707
Offline
Зарегистрирован: 26.05.2017

daniilguz пишет:

 не знал что деление долго идет. исправлю таблицу.

Какая разница, долго оно идет или нет? - У вас скорость всего кода, насколько я понял - определяется именно временем вычисления в цикле ЛУП - а значит именно здесь надо оптимизировать каждую букву. А вы вместо этого зачем-то шесть раз делите то, что можно было бы поделить заранее.

Logik
Offline
Зарегистрирован: 05.08.2014

При такой архитектуре все содержимое лупа нужно переносить в обработчик прерывания или прямо в лупе ждать таймер при полном запрете всех прерываний. Я бы выбрал второе, т.к. не было бы издержек на вход/выход в прерывания.  Действительно ли steep1-steep6 ли должны быть инт? Однобайтовые переменные быстрей посчитает. analogRead - медленный, заменить на прямую работу с АЦП. Шесть массивов с пошти одинаковыми данными - плохо. Быстрей один массив со смещением с учетом #28. Деление исправляйте конечно.

 

daniilguz
Offline
Зарегистрирован: 13.01.2020

очень не наглядно написан. так точно

выкладываю две осцилограммы полученного программного шим и синуса.

https://photos.app.goo.gl/WXfSzNEsXLoBQjoLA

https://photos.app.goo.gl/mV4XQxtMzG4b2RiZ8

 

asam
asam аватар
Онлайн
Зарегистрирован: 12.12.2018

daniilguz пишет:

в таблице синуса делю на 4 потому, что эта талица синуса у меня осталась из скетча меги. переделывать было лень, не знал что деление долго идет. исправлю таблицу.

Деление на 4 идет быстро, потому что это просто сдвиг влево на 2 разряда, но да, зачем дополнительные операции. Еще

prog_pwm - k вычисляется 6 раз. По идее компилятор при оптимизации должен это учесть, но нужно посмотреть получившийся ассемблерный код. Может стоит его вычислить один раз

Вместо того, что бы 6 раз дергать РОRTD (а это на самом деле несколько операций) быстрее будет собрать все нужные биты в одну переменную а потом записать ее в PORTD

Ну и самое медленное это analogRead правда он вызывается не часто, но тем не менее его можно запускать в фоне

 

asam
asam аватар
Онлайн
Зарегистрирован: 12.12.2018

А в чем глубокий смысл манипулирования flag_led_1 если он все равно нигде не используется?

Logik
Offline
Зарегистрирован: 05.08.2014

asam пишет:

Деление на 4 идет быстро, потому что это просто сдвиг влево на 2 разряда

Но только у проца нет такой команды. Есть только на 1 разряд, поэтому повторяет 2 раза, а если надо на 3-6 разрядов то воще цикл. 

asam пишет:

Вместо того, что бы 6 раз дергать РОRTD (а это на самом деле несколько операций) быстрее будет собрать все нужные биты в одну переменную а потом записать ее в PORTD

Не. Не поможет.  Что сбор в переменную будет тоже что и в порт сразу.

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Если определить моменты переключения вывода, то можно через PINx выход тогглить - минус несколько операций.

daniilguz
Offline
Зарегистрирован: 13.01.2020

Блин всем вам большое спасибо... я очень благодарен Вам.  буду оптимизировать.

analogread ускорена - строка 47, 48.

steep1 заменю на byte

массив поделю сразу.

____________________

Вместо того, что бы 6 раз дергать РОRTD (а это на самом деле несколько операций) быстрее будет собрать все нужные биты в одну переменную а потом записать ее в PORTD

вот это не пойму как сделать, тоже об этом думал

_____________________

осцилограммы выложил

asam
asam аватар
Онлайн
Зарегистрирован: 12.12.2018

Logik пишет:

Цитата:
Вместо того, что бы 6 раз дергать РОRTD (а это на самом деле несколько операций) быстрее будет собрать все нужные биты в одну переменную а потом записать ее в PORTD

Не. Не поможет.  Что сбор в переменную будет тоже что и в порт сразу.

А вот нефига. Спорим на 1000р?

b707
Offline
Зарегистрирован: 26.05.2017

asam пишет:

Logik пишет:

Что сбор в переменную будет тоже что и в порт сразу.

А вот нефига. Спорим на 1000р?

вопрос интересный, хорошо б кто-нить проверил. Склоняюсь к мнению Логика - потому как при сборе в переменную будут ровно те же операции. как и в порт - не вижу. на чем собираетесь выиграть

asam
asam аватар
Онлайн
Зарегистрирован: 12.12.2018

daniilguz пишет:

analogread ускорена - строка 47, 48.

analogread запускает преобразование и ждет пока оно закончится. А можно запустить преобразование и продолжить выполнение основной программы. А как оно закончится - считать результат

sadman41
Онлайн
Зарегистрирован: 19.10.2016

b707 пишет:

при сборе в переменную будут ровно те же операции. как и в порт - не вижу. на чем собираетесь выиграть

Видимо на чтении из порта.

asam
asam аватар
Онлайн
Зарегистрирован: 12.12.2018

b707 пишет:

вопрос интересный, хорошо б кто-нить проверил. Склоняюсь к мнению Логика - потому как при сборе в переменную будут ровно те же операции. как и в порт - не вижу. на чем собираетесь выиграть

Ну можно посмотреть по ассемблерному коду, а можно замерять время выполнения. Ну что подключаешься к спору? Будет у меня 2000р

b707
Offline
Зарегистрирован: 26.05.2017

asam пишет:

 Ну что подключаешься к спору? Будет у меня 2000р

не-а, я люблю выигрывать :)

GarryC
Offline
Зарегистрирован: 08.08.2016

0. У Вас в программе есть ошибка - корректирующий член prog_pwm увеличивается в одном месте (в прерывании), прокручивается в другом (начале цикла), а используется в третьем (теле цикла). Если прерывание произойдет в теле цикла, то оставшиеся ШИМы отработают с значением 33, что явно не планировалось.

Теперь о быстродействии - Вы в теле цикла делаете много ненужной работы.
1. Прокручивание prog_pwm и flag_led_1 (кстати, а зачем он) следует убрать из цикла в прерывание.
2. В таблице сразу разместить синусы / 4
3. Изменить условие ШИМ - вместо
steep1=sin_1_h[num]-prog_pwm-k; if (steep1> prog_pwm) ...
сделать
border=2*-prog_pwm+k;
....
steep1=sin_1_h[num]; if (steep1> border) ...
4. Вместо / 8 лучше явно писать >> 3.
5. Следует быть уверенным, что операция сброса и установки бита выполняется за такт, иначе лучше воспользоваться советом из предыдущего коммента о группировке битов.
7. Вместо индекса лучше использовать указатель
8. Если массив реорганизовать по 6 байт одного отсчета рядом, то с указателем будет совсем быстро.

 

 

daniilguz
Offline
Зарегистрирован: 13.01.2020

короче мне еще работать и работать над кодом, спасибо всем, на неделю разбираться.

daniilguz
Offline
Зарегистрирован: 13.01.2020

и еще совет - число точек и ШИМ и синуса лучше выбрать степенью двойки - тогда переход через ноль можно будет делать одной битовой операцией. избавившись от проверки условия на каждом шаге

____________________________________

вот это не понял.

daniilguz
Offline
Зарегистрирован: 13.01.2020

asam пишет:

daniilguz пишет:

analogread ускорена - строка 47, 48.

analogread запускает преобразование и ждет пока оно закончится. А можно запустить преобразование и продолжить выполнение основной программы. А как оно закончится - считать результат

я новичок, суть я понял а как сделать не знаю.

daniilguz
Offline
Зарегистрирован: 13.01.2020

sadman41 пишет:

(0 << CS12)| (1 << CS11)|(0 << CS10)

Это предделитель /8

Для /1 (no prescaling) нужно выставлять CS10, а не CS11

 

я в курсе, но тогда пока один раз проходит луп 8 раз срабатывает прерывание.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

daniilguz пишет:

я новичок, суть я понял а как сделать не знаю.

Если ты новичок, какого ж хрена сразу за частотник схватился?