Обсуждаем контроллеры компании Atmel.
Ответить

Re: Параллельные задачи в ATmega8

Ср авг 21, 2019 14:11:56

BOB51 писал(а):Нафига мозг по дурному морочить?
из принципа :))

Re: Параллельные задачи в ATmega8

Ср авг 21, 2019 14:16:19

Ну ужшш ....
Тогда усложним задачку:
на одном выводе единовременно и индикаторный светик светиться (с + питания на вывод) и кнопа висит на GND.
Изображение
Воть так реально польза будет.
кнопой и зажигаем и гасим тот светик.
Ну и чего-то еще в основной прожке делаем.
:twisted:

Re: Параллельные задачи в ATmega8

Ср авг 21, 2019 14:42:24

ARV, хоть бы мигнули светодиодом для приличия, а не просто вывели единицу в бит порта )))
1. Команды в AVR не прерываются. Так что до 2 тактов ожидания завершения команды.
2. Только вход в прерывание занимает 4 такта (2 такта на сохранение PC в стеке и два такта на RJMP).
3. Комада IRET выполняется 4 такта.
4. Для мигания, даже 10 тактов может не хватить, так как потребуется сохранять и восстанавливать из стека или SREG и/или рабочий регистр. Комп далеко, проверить не могу.

Добавлено after 9 minutes 48 seconds:
А что это за "мигание" в 100ГЦ???
Чей глаз его узрит-то?

Легко, если это стробоскоп. Может быть ТС тахометр нужен на 6000 оборотов в минуту?

Re: Параллельные задачи в ATmega8

Ср авг 21, 2019 14:53:39

там запись в пин, а не в порт — это тоггл, .т.е. будет мигание
если сделать вместо пинб=1; асм сет пинб.0 , то регистров не понадобится и в стек можно ничего не пихать...
про остальное навскидку не скажу...

Добавлено after 1 minute 52 seconds:
кстати в исходнике было пинб|=1;
"или" там лишнее...

Добавлено after 49 seconds:
если стробоскоп — то меандр ему не в кайф, нужны короткие вспышки

Re: Параллельные задачи в ATmega8

Ср авг 21, 2019 15:06:30

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

С каких это пор команда SBI не устанавливает бит, а инвертирует?
Порты в AVR тупые. Или считай байт, инвертируй бит и запиши обратно, или воспользуйся командами SBIC/SBIS

Изображение

Добавлено after 4 minutes 38 seconds:
если стробоскоп — то меандр ему не в кайф, нужны короткие вспышки

Почему не в кайф? Скважность лучше иметь порядка 10. Но помню, стробоскопы в проигрывателях грампластинок, со скважностью 2 работали на неонках, что совершенно не мешало их использовать )
Последний раз редактировалось ПростоНуб Ср авг 21, 2019 15:11:14, всего редактировалось 1 раз.

Re: Параллельные задачи в ATmega8

Ср авг 21, 2019 15:11:51

нет, тут всё правильно, прошу обратить внимание, что пишем в регистр ПИН, а не ПОРТ

Добавлено after 2 minutes 22 seconds:
я сейчас не помню, как у пластинок... там обе полуволны светили?

Добавлено after 2 minutes 46 seconds:
если на вал я нанесу тонкую риску, то при оборотах 6000 и скважности = 2, у меня полкруга зарисует... это не страшно если нужно оценить скорость, но неприемлемо для определения фазы (например зажигание с такой скважностью не настроить)

Re: Параллельные задачи в ATmega8

Ср авг 21, 2019 15:12:00

Ivanoff-iv, обе полуволны. Неонки то неполярные )
Нет такой команды в AVR. Уточнил выше.

Фаза то зачем, если нужно только регулировать обороты? Важно только чтобы эта размазня на месте стояла, а не вращалась.

Re: Параллельные задачи в ATmega8

Ср авг 21, 2019 15:15:37

ПростоНуб писал(а):хоть бы мигнули светодиодом для приличия
ладно, пусть будет не 6 тактов, а 12, т.е. 1,5 мкс джиттер - это ничто для IR-команд. или не согласны?
ПростоНуб писал(а):так как потребуется сохранять и восстанавливать из стека или SREG и/или рабочий регистр
не потребуется - листинг обработчика я вам привел
Ivanoff-iv писал(а):"или" там лишнее...
к сожалению, не всякая версия компилятора AVR-GCC согласна с вами :) в 6.3.0 генерируется кошмар хоть с ИЛИ, хоть без. а вот версия 9.1.0 на ИЛИ родила обработчик из 2 команд :))) который я и показал. не ожидал я, честно говоря, такого подвоха от 6-ки... даже 3-ка понимала, что ИЛИ порта с константой из 1 единичного бита это SBI...
ПростоНуб писал(а):С каких это пор команда SBI не устанавливает бит, а инвертирует?
с тех, когда она над портом PINx - "особенность архитектуры" :)))

Re: Параллельные задачи в ATmega8

Ср авг 21, 2019 15:20:17

ARV, 12 тактов на вывод единицы в порт. Вы мигание напишите, тогда поговорим )))

Re: Параллельные задачи в ATmega8

Ср авг 21, 2019 15:29:44

BOB51 писал(а):кнопой и зажигаем и гасим тот светик
злостный оффтоп: а давайте я нажму кнопу, а вы программно погасите светик :))) в общем виде поставленная вами задача не решаема.

Добавлено after 7 minutes 51 second:
ARV, 12 тактов на вывод единицы в порт. Вы мигание напишите, тогда поговорим )))
вот вы нудный :))) это не переход на личности, это просто к слову :)))
Изображение
это из даташита на attiny13
Вложения
Screenshot_2.png
(41.36 KiB) Скачиваний: 477

Re: Параллельные задачи в ATmega8

Ср авг 21, 2019 15:55:59

ARV, спасибо за информацию. Этого я не знал.

Re: Параллельные задачи в ATmega8

Ср авг 21, 2019 15:57:42

Да на здоровье.

Re: Параллельные задачи в ATmega8

Чт авг 22, 2019 08:13:26

Это не у всех изначально имелось - появилась та строчка в даташитах чуток попозже.
В любом случае всегда надо удостовериться, что в конкретном даташите к конкретному МК прописано.
Особо после проглощения атмеля микрощипом....
:wink:

Re: Параллельные задачи в ATmega8

Чт авг 22, 2019 16:35:28

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

Протокол НЕК - базируется на тайминге 560 мкс, все остальные тайминги кратны ему.
С учетом конских допусков в протоколе - базовый тайминг предлагаю сделать 555 мкс.

Принимаем, что тактирование меги 8 МГц
Тогда настраиваем таймер 1 в режим СТС, с коэффициентом пересчета 8*555 = 4440; предделитель = 1.

Далее основная программа:
пустой цикл, ожидающий появление флага TOV1 в регистре TIFR. Это значит, что оттикало наши 555 мкс.
сбрасываем этот флаг, записав в TIFR.TOV1 единичку.

Теперь 2 машины состояний.
Первая - простая, через каждые 9 циклов переключаем состояние выхода 100 гц. 555*9 = 4995 мкс или частота на выходе будет 100.1001 Гц
Вторая - более сложная, которая будет дергать второй выход в режиме отправки команды по НЕК-протоколу.
Скорее всего, при инициализации нужно в какой то массив записать последовательность таймингов по переключению состояния выхода в количествах циклов. Напомню, 1 цикл - 555 мкс.
По большому счету, это дело взлетит даже без особой оптимизации и на том же Си. Каждый цикл длится 555 мкс. 555*8 = 4440 машинных циклов. Этого с головой хватит, еще и останется...

Вот как то так....
Погрешность генерации 100 гц - 0.1%, погрешность генерации НЕК - 0.89%
Плюс будет некий джиттер. Но тут никуда от него...

Re: Параллельные задачи в ATmega8

Чт авг 22, 2019 17:00:25

goldenandy, Вы забыли о несущей частоте (например, 38 КГц) при передаче по NEC протоколу.

Re: Параллельные задачи в ATmega8

Чт авг 22, 2019 17:26:01

Несущая делается задержками, уже говорил. Можно и без прерываний сделать, если на спор :) , взяв за дискрету полупериод несущей. Все можно, делали же на Спектруме ФМ-музычку параллельно основной игре вообще без прерываний!
Сделать можно, но зачем?!

Re: Параллельные задачи в ATmega8

Чт авг 22, 2019 17:58:14

ПростоНуб, Каюсь, забыл.
Но!...
Люди, у вас мега8!!
в ней три таймера!!!
(Ну два нормальных и один кастрированный....)

Таймер2.
СТС режим. Предделитель = 1, коэф. персчета 8МГц/(2*38кГц) = 105.
OCR2 = 0. Режим OC2(PORTB3) - Toggle OC2 on Compare Match: COM2[1:0]=01.
Объединить выход PORTB3 и выход NEC-огибающей элементом И (можно 2 диода и резистор), далее усилятельный транзистор и светодиод.

Добавлено after 9 minutes 15 seconds:
ARV, Сделать можно, но зачем?!
Ну вот курсовик студенту нарисовали почти.... Или лабораторку решили... (Я хз чему сейчас прикладников учат)

Re: Параллельные задачи в ATmega8

Чт авг 22, 2019 18:08:08

goldenandy писал(а):Ну вот курсовик студенту нарисовали почти.... Или лабораторку решили...
знаете, студент, который справится с поставленной задачей без применения прерваний, это будет гений какой-то! :) если так сейчас учат студентов, что рискуют им подобные "курсовые" задавать - нас ждет великое будущее, как программистской сверхдержавы :)))

Re: Параллельные задачи в ATmega8

Чт авг 22, 2019 18:39:51

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

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

Re: Параллельные задачи в ATmega8

Чт авг 22, 2019 18:42:51

ARV писал(а):
BOB51 писал(а):кнопой и зажигаем и гасим тот светик
злостный оффтоп: а давайте я нажму кнопу, а вы программно погасите светик :))) в общем виде поставленная вами задача не решаема.
А мне все было интересно, имеет ли эта схема право на жизнь.
Давайте я попробую погасить светик.
Спойлер
Код:
#define F_CPU 8000000

#define service_DDR      DDRB
#define service_PIN      PINB

#define pin        PORTB0

#define SetBit(reg, bit)        reg |= (1<<(bit))   
#define ClearBit(reg, bit)      reg &= (~(1<<(bit)))
#define BitIsSet(reg, bit)      ((reg & (1<<(bit))) != 0)
#define BitIsClear(reg, bit)    ((reg & (1<<(bit))) == 0)
#define InvBit(reg, bit)        reg ^= (1<<(bit))


volatile uint8_t kn_n=0; 
volatile uint8_t kn_temp=0;   
volatile uint8_t kn_count=0;


// Timer 0 overflow interrupt service routine
ISR(TIMER0_OVF_vect){

 switch (kn_count) {
 
 case 0: ClearBit(service_DDR,pin); break;
 case 2: {
   if((BitIsClear(service_PIN,pin))&&(BitIsClear(kn_temp,pin))){
    InvBit (kn_n,pin);     
    SetBit (kn_temp,pin);
  } else {
    if(BitIsSet(service_PIN,pin))
   ClearBit (kn_temp,pin);
   }
 } break;
 case 3: {
   if(BitIsSet(kn_n,pin)){
   SetBit(service_DDR,pin);   
   }
 } break;
 
 }
 
 if(kn_count++ == 5) kn_count=0;
 
 
}



int main(void)
 {
// Input/Output Ports initialization
// Port B initialization
DDRB=(0<<DDB7) | (0<<DDB6) | (0<<DDB5) | (0<<DDB4) | (0<<DDB3) | (0<<DDB2) | (0<<DDB1) | (1<<DDB0);
PORTB=(0<<PORTB7) | (0<<PORTB6) | (0<<PORTB5) | (0<<PORTB4) | (0<<PORTB3) | (0<<PORTB2) | (0<<PORTB1) | (0<<PORTB0);

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 1000,000 kHz
TCCR0=(0<<CS02) | (1<<CS01) | (0<<CS00);
TCNT0=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=(0<<OCIE2) | (0<<TOIE2) | (0<<TICIE1) | (0<<OCIE1A) | (0<<OCIE1B) | (0<<TOIE1) | (1<<TOIE0);

// Global enable interrupts
sei();

while (1)
      {
      // Place your code here

      }
 }
Таймер 256us
kn_count 0 = 38 тактов (4.75us)
1 = 37 тактов (4.63)
2 = 47 тактов (5.87)
3 = 43 тактов (5.38)
4 = 37 тактов (4.63)
5 = 38 тактов (4.75)

Светик:
Период 1,56ms (640Гц)
Длительность 0,78
Скважность 2
Ответить