Jump to content
~Vad~

Прошу Совета По Оптимизации(Программный Шим)

Recommended Posts

Добрый день, стоит задача: формирование импульсов для управления тиристорным выпрямителем. Используем МК attiny2313. Написал программный шим, аттини немного не справляется с формированием(за все время формирования импульсов может пропустить 1-5 импульсов). Подскажите как можно оптимизировать код, чтобы облегчить жизнь тиньки :)

#define F_CPU 8000000L
#define start_timer 65490;
#define Start 3 // ПУСК
#define Rect 0
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#define sm -40
//
static int sync_idx = 0;
const int PIN_NUM = 6;
const int SYNC_NUM = 2;
const int LEN = 2;
int timer[sYNC_NUM] = {0,0};
int flag_sync;
int pulses[sYNC_NUM][PIN_NUM][LEN]={
{ {200,210},
{267,277},
{334,344},
{400,410},
{467,477},
{533,544}},
{
{199,210},
{266,277},
{333,344},
{399,410},
{466,477},
{532,544}}
};
int idx[sYNC_NUM][PIN_NUM]={{LEN,LEN,LEN,LEN,LEN,LEN},{LEN,LEN,LEN,LEN,LEN,LEN}};//{{{LEN,LEN},{LEN,LEN},{LEN,LEN},{LEN,LEN},{LEN,LEN},{LEN,LEN}},{{LEN,LEN},{LEN,LEN},{LEN,LEN},{LEN,LEN},{LEN,LEN},{LEN,LEN}}};
const char pinMask[PIN_NUM][LEN] ={{0x04,0x08},{0x01,0x04},{0x10,0x01},{0x02,0x10},{0x20,0x02},{0x08,0x20}};//{0x0C, 0x05,0x11,0x12,0x22,0x28}; // TCK TBA TAK TCA TBK TAA
const int pinMaskFlag[PIN_NUM][LEN]={{2,3},{0,2},{4,0},{1,4},{5,1},{3,5}};	 // 0 01 1 02 2 04 3 08 4 010 5 020
//int flag[PIN_NUM]={0,0,0,0,0,0};
void init() //функция инициализации
{
// Конфигурируем порты на вход/выход
//Порт Б DDRB 00111111
DDRB=0x3f;
PINB=0x00;
PORTB=0x00;
//Порт D DDRD 00000001
DDRD=0x01;
PIND=0x00;
PORTD=0x00;
//
//конфигурируем прерывания
TCCR1B = (0<<CS12)|(1<<CS11)|(0<<CS10); //xtall/8
TIMSK |= (1<<TOIE1);
TCNT1 = start_timer;
PCMSK |= (1<<PIND2);
MCUCR = (1<<ISC01) | (0<<ISC00);
GIMSK |= (1<<INT0);
//sei();
}

// главная функция
int main(void)
{
init();
pulses[0][0][0]=200+sm; pulses[0][0][1]=210+sm;
pulses[0][1][0]=267+sm; pulses[0][1][1]=277+sm;
pulses[0][2][0]=334+sm; pulses[0][2][1]=344+sm;
pulses[0][3][0]=400+sm; pulses[0][3][1]=410+sm;
pulses[0][4][0]=467+sm; pulses[0][4][1]=477+sm;
pulses[0][5][0]=533+sm; pulses[0][5][1]=544+sm;
for(int i=0;i<PIN_NUM;i++){
pulses[1][i][0]=pulses[0][i][0]-1;
pulses[1][i][1]=pulses[0][i][1];}
while(1)
{

if(PIND & 1<<Start)
{
PORTD &= ~(1<<Rect);
for(int p=0;p<PIN_NUM;p++)
{
PORTB &=~ pinMask[p][0];
PORTB &=~ pinMask[p][1];
}
pulses[0][0][0]=200+sm; pulses[0][0][1]=210+sm;
pulses[0][1][0]=267+sm; pulses[0][1][1]=277+sm;
pulses[0][2][0]=334+sm; pulses[0][2][1]=344+sm;
pulses[0][3][0]=400+sm; pulses[0][3][1]=410+sm;
pulses[0][4][0]=467+sm; pulses[0][4][1]=477+sm;
pulses[0][5][0]=533+sm; pulses[0][5][1]=544+sm;
for(int i=0;i<PIN_NUM;i++){
pulses[1][i][0]=pulses[0][i][0]-1;
pulses[1][i][1]=pulses[0][i][1];
}
sync_idx=0;
timer[0]=0;
timer[1]=0;
for(int i=0;i<SYNC_NUM;i++)
for(int j=0;j<PIN_NUM;j++)
idx[i][j]=LEN;
}

if(!(PIND & 1<<Start)){//на схеме обратная логика
_delay_us(10);// исключение дребезга
//sync_idx=0;
sei();
}

while(!(PIND & 1<<Start))
{
//if(flag_sync>0){
for (int s = 0; s < SYNC_NUM; s++){
 for (int p = 0; p < PIN_NUM; p++){
 if (idx[s][p] < LEN){
 if (timer[s] >= pulses[s][p][idx[s][p]]){

	 if (idx[s][p]&1 ){
	 if(pulses[0][0][0]>100)
	 PORTB &=~ pinMask[p][0];
	 PORTB &= ~pinMask[p][1];

	 }
	 else{
	 PORTB |= pinMask[p][0];
	 if(pulses[0][0][0]>100)
	 PORTB |= pinMask[p][1];
	 pulses[s][p][idx[s][p]]--;
	 }
	 idx[s][p] ++;
 }
 }

 }
}
if(pulses[1][0][0]<=1)
{
 cli();
 PORTD |= (1<<Rect);
 for(int p=0;p<PIN_NUM;p++)
 {
 PORTB |= pinMask[p][0];
 PORTB |= pinMask[p][1];
 }
}
//}
}
}
return 0;
}
// прерывание по вектору INT0 (прерывание по синхронизации - спад из 1 в 0
ISR(INT0_vect){
timer[sync_idx] =0;
for (int p = 0; p < PIN_NUM; p++)
idx[sync_idx][p] = 0;
if (++sync_idx >= SYNC_NUM) sync_idx = 0;
}
ISR( TIMER1_OVF_vect )
{
TCNT1 = start_timer;
{timer[0]++; timer[1]++;}
}

ekbZT-n8PoY.jpg

Share this post


Link to post
Share on other sites

Что то не вкурю.... А зачем тут такие "жирные" массивы? Да и вообще, зачем они? :)

Share this post


Link to post
Share on other sites

В массиве я храню время начала формирования импульса, и время его закрытия. Получается 2 массива данных для двух пачек импульса. Сначала формируется первая пачка от момента спадающего импульса синхронизации, пока первая формируется - уже наступает второй импульс синхронизации, и начинается формироваться вторая пачка. Таким образом они чередуются(чет-нечет). Понимаю что алгоритм использован дубовый, пытался несколько иначе сделать, но этот - наиболее работающий.

Edited by ~Vad~

Share this post


Link to post
Share on other sites

Особенности схемотехники и трассировки печатных плат для STM32WB55

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

Читать статью

Слишком избыточно... так работать корректно не будет... Я когда разрабатывал в Полуавтомат управление - делал все без использования массива. И диодно-тиристорный мост работает идеально. И симистор тоже идеально :)

Share this post


Link to post
Share on other sites

Я понимаю, что избыточно- МК постоянно прогоняет весь массив, чтобы включить только одну пару импульсов. Отказаться от массивов хорошая идея, попробую ее реализовать. Если вернуться к моему коду, подскажите пожалуйста идея правильная(если не брать в расчет массивы), или алгоритм надо строить совершенно по другому? Если Вам не сложно, подскажите алгоритм, хотя бы на пальцах.

Edited by ~Vad~

Share this post


Link to post
Share on other sites
                     

Видеокурс Работаем с микроконтроллерами STM32G0. Впервые на русском языке.

В цикле видеокурсов по работе с STM32G0 от компании STMicroelectronics показаны архитектура, периферия (особенности процессорного ядра, режимов пониженного питания, векторов прерываний, DMA и мультиплексора DMA, схемы тактирования и сброса, и.т.д.) и даны практические примеры. Материал дает наглядное понимание того, как начать работу на новых микроконтроллерах STM32G0

Подробнее

У меня алгоритм такой:

при захвате перехода через ноль , запускаемых таймер на время равное настроенной мощности Р - 100.

При событии прерывания - даем импульс на тиристоры.

Импульс сбрасываем через 1мс. или при следующем переходе через ноль. И никаких массивов! У меня ещё и динамическая индикация крутится , и все успевает :)

ПС : исправьте предыдущие посты! Не цитируйте целиком пред. сообщение!

Вот статья и схема: cxem.net/house/1-269.php

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Similar Content

    • By Timu4en Jin
      Значит в чем суть, по всем параметрам сгорела микросхема, и она без маркировки, может кто то уже чинил подобный блок, и знает что там и чем заменить, буду благодарен. Я бы загрузил больше фото но больше 10 мб нельзя. Стрелками указал что заменил. Высоковольтный диод c3d100, 10ом резистор, конденсатор на 100пф 630в, рядом с этой микросхемой была перемычка, нулевой резистор и она имела Сопротивление в 102ом,после всего этого что заменил никаких результатов. Помогите кто знает


    • By Павел Лопатин
      Добрый день!
      Подскажите, пожалуйста, можно ли вынести переменный резистор 16K1-B10K, L20KC, 10 кОм с ШИМ регулятора на отдельную плату? 
      Какие провода лучше использовать? На какое расстояние можно вынести (длина провода) и изменятся ли от этого характеристики? (все-таки, как я понимаю, появится дополнительное сопротивление от провода)
      ШИМ покупной в RDC2-0024 - фото и схема в аттаче
      DOC002726141.pdf
    • By Kirillius Labutin
      Добрый день!
      Имеется готовый лазерный модуль с драйвером (стабилизатор тока и, наверное, напряжения). 
      Хочу регулировать яркость лазера с помощью ШИМ с МК, гугл сказал что лучший вариант - шунтирование лазера. Но драйвер устроен таким образом, что в нём с питанием напрямую не связан ни "+" ни земля лазера. Набросал такую схемку, чтобы реализовать это через оптопару.

      Внимание, вопрос)
      1. Заработает ли такая схема?
      2. Какой посоветуете транзистор Q1 и оптопару? Макс. напряжение в цепи - 5В, ток - 0.5А Я думаю что-нибудь вроде IRLL014TRPBF
      3. Какой выбрать номинал резистора R1 для разряда Q1? Частота ШИМ планируется в районе 1кгц.
    • By 1 111
      Здравствуйте форумчане! Проверьте пожалуйста данную принципиальную схему на ошибки

    • By SigmA
      Доброго времени суток всем. Для своей новой жены захотелось мне сделать сердечко на atmega8, с кучей эффектов и т.д. Так вот, разные мигалки-переключалки св-диодов я написал, использовал delay. Но мне этого стало мало и я решил подключить шим программный. Отдельно от всей программы шим работает как нужно, так же и переключалки работают отдельно от шим, но вот когда я соединяю это всё воедино то работает только шим и не переходит дальше по коду.Я так понимаю, что таймеры и delay вместе работать не могут? Но если могут, то как?
      #include <mega8.h> #include <delay.h> #define GREEN PORTC.1=PORTC.2=PORTC.3=PORTC.0 unsigned char i, s,; unsigned char green=255; unsigned char green_b; //переменные, для буферизации значений скважности ШИМ unsigned char count; //переменная- счетчик вызовов обработчика прерываний unsigned char temp=1; interrupt [TIM0_OVF] void timer0_ovf_isr(void) { count++; if (count == 0){ //если счетчик переполнился и принял значение 0 green_b = green; GREEN = 1; } if (green_b == count) { GREEN = 0;} } void main(void) { PORTC=0x0F; //конфигурируем порт DDRC=0x0F; TCCR0=0x01; //настраиваем таймер TCNT0=0x00; TIMSK=0x01; //разрешаем генерацию прерывания по переполнению таймера T0 #asm("sei") //глобально разрешаем прерывания while (1) { for (i=0;i<3;i++) { if (temp==1) {if (green < 255) green += 1; else temp = 2;} if (temp==2) {if (green > 0) green -= 1; else temp = 1;} delay_ms(1000); }; s=7; for (i=0;i<=s;i++) { PORTC.0=1; delay_ms(200); PORTC.0=0; PORTC.1=1; delay_ms(200); PORTC.1=0; PORTC.2=1; delay_ms(200); PORTC.2=0; PORTC.3=1; delay_ms(200); PORTC.3=0; } for (i=0;i<=s;i++) { PORTC.3=1; delay_ms(200); PORTC.3=0; PORTC.2=1; delay_ms(200); PORTC.2=0; PORTC.1=1; delay_ms(200); PORTC.1=0; PORTC.0=1; delay_ms(200); PORTC.0=0; } for (i=0;i<=s;i++) { PORTC.3=1; delay_ms(200); PORTC.2=1; delay_ms(200); ; PORTC.1=1; delay_ms(200); PORTC.0=1; delay_ms(200); PORTC.3=0; delay_ms(200); PORTC.2=0; delay_ms(200); PORTC.1=0; delay_ms(200); PORTC.0=0; delay_ms(200); } for (i=0;i<=s;i++) { PORTC.0=1; delay_ms(200); PORTC.1=1; delay_ms(200); ; PORTC.2=1; delay_ms(200); PORTC.3=1; delay_ms(200); PORTC.0=0; delay_ms(200); PORTC.1=0; delay_ms(200); PORTC.2=0; delay_ms(200); PORTC.3=0; delay_ms(200); } for (i=0;i<=s;i++) { PORTC=0x01; delay_ms(200); PORTC=0x02; delay_ms(200); PORTC=0x04; delay_ms(200); PORTC=0x08; delay_ms(200); PORTC=0x09; delay_ms(200); PORTC=0x0A; delay_ms(200); PORTC=0x0C; delay_ms(200); PORTC=0x0D; delay_ms(200); PORTC=0x0E; delay_ms(200); PORTC=0x0F; delay_ms(200); PORTC=0x07; delay_ms(150); PORTC=0x0B; delay_ms(200); PORTC=0x03; delay_ms(250); PORTC=0x05; delay_ms(300); PORTC=0x09; delay_ms(350); PORTC=0x01; delay_ms(400); PORTC=0x02; delay_ms(200); PORTC=0x04; delay_ms(200); PORTC=0x08; delay_ms(200); PORTC=0x00; delay_ms(200); } for (i=0;i<=5;i++) { PORTC=0x0f; delay_ms(100); PORTC=0x00; delay_ms(100); PORTC=0x0f; delay_ms(100); PORTC=0x00; delay_ms(100); PORTC=0x0f; delay_ms(100); PORTC=0x00; delay_ms(150); PORTC=0x0f; delay_ms(300); PORTC=0x00; delay_ms(100); PORTC=0x0f; delay_ms(300); PORTC=0x00; delay_ms(100); PORTC=0x0f; delay_ms(300); PORTC=0x00; delay_ms(150); PORTC=0x0f; delay_ms(100); PORTC=0x00; delay_ms(100); PORTC=0x0f; delay_ms(100); PORTC=0x00; delay_ms(100); PORTC=0x0f; delay_ms(100); PORTC=0x00; delay_ms(1000); } } }  
×
×
  • Create New...