Перейти к содержанию

Примеры кода для AVR


Duhas

Рекомендуемые сообщения

вот так работает

lcd_gotoxy(0,0);
		lcd_putstring("i love M");
		lcd_gotoxy(40,0);
		lcd_putstring("aria");

надо теперь написать если больше 8 символов то адрес перескакивает на 40

Ссылка на комментарий
Поделиться на другие сайты

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

В библиотеке Peter Fleury, которую я рекомендовал, есть возможность настроить области памяти ЖКИ по-своему.

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

Ссылка на комментарий
Поделиться на другие сайты

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

03.12.2019 в 16:35, Дмитрий Вас сказал:

но вот беда в железе так и отказывается работать

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

а ты, по-прежнему, используешь 4-битный режим и передаешь по 2 байта - 1 байт со старшей тетрадой и 1 байт с младшей тетрадой.

а должен передавать один раз (8-битный режим, 1 байт) только со старшей тетрадой.

и 3 раза нужно передать 0х30, а не 0х03

и только когда в четвертый раз 8-битной командой передашь 0х20 (а не 0х02), можно переходить на 4-битный режим, начиная с команды 0х28.

Мудрость приходит вместе с импотенцией...

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

Ссылка на комментарий
Поделиться на другие сайты

Выбираем схему BMS для заряда литий-железофосфатных (LiFePO4) аккумуляторов

Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ очень важен контроль процесса заряда и разряда для избегания воздействия внешнего зарядного напряжения после достижения 100% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

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

Ссылка на комментарий
Поделиться на другие сайты

  • 3 недели спустя...

Сравнительное тестирование аккумуляторов EVE Energy и Samsung типоразмера 18650

Инженеры КОМПЭЛ провели сравнительное тестирование аккумуляторов EVE и Samsung популярного для бытовых и индустриальных применений типоразмера 18650. 

Для теста были выбраны аккумуляторы литий-никельмарганцевой системы: по два образца одного наименования каждого производителя – и протестированы на двух значениях тока разряда: 0,5 А и 2,5 А. Испытания проводились в нормальных условиях на электронной нагрузке EBD-USB от ZKEtech, а зарядка осуществлялась от лабораторного источника питания в режиме CC+CV в соответствии с рекомендациями в даташите на определенную модель. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

хочу рассказать, как легко и просто можно из 8-битного таймера (таймер2 в atmega8) сделать 16-битный таймер.
вот такой код я придумал (с подробными комментариями):

   ; объявляем регистр флагов
.def flags         = R19   ; различные флаги
   ; объявляем флаг
.equ timer2_ready   = 4      ; таймер отработал заданное время

   ; объявляем "старший байт" таймера2
.def count_256      = R20   ; старший байт для Таймера2, счетчик "полных оборотов" таймера
   ; объявляем регистры, где будет находится требуемое время таймера (задержка)
.def delayL         = R21   ; задержка, младший байт
.def delayH         = R22   ; задержка, старший байт

   ; прерывание таймера2, режим СТС
timer2_CTC:

   ; сохраним регистры, которые использует прерывание

sbrc flags, timer2_ready
   ; если задержка выполнена, то идем на выполнение "тела" прерывания
rjmp work

   ; тестируем байты задержки
test_delay:
   ; проверяем старший байт на ноль
tst delayH
   ; если старший байт задержки равен нулю, то сразу идем на задание младшего байта задержки
breq set_delayL
   ; сравним счетчик "полных оборотов" со старшим байтом задержки
cp count_256, delayH
   ; если меньше, то идем на задание "полного оборота"
brlo set_256
   ; счетчик "полных оборотов" стал равен старшему байту, проверяем младший байт на ноль
tst delayL
   ; если младший байт равен нулю, то задержка состоит только из старшего байта и выполнена полностью
   ; поэтому идем на выполнение "тела" прерывания
breq work
   ; иначе сбрасываем счетчик "полных оборотов"
clr count_256
   ; и идем на задание младшего байта задержки
rjmp set_delayL

   ; задание "полного оборота"
set_256:
   ; увеличиваем счетчик "полных оборотов"
inc count_256
ser R16
   ; задаем 255 - "полный оборот"
out OCR2, R16
   ; и выходим из прерывания
rjmp end_timer2

   ; задание младшего байта задержки
set_delayL:
out OCR2, delayL
   ; поставим бит (флаг), что задержка выполнена. точнее, будет выполнена после отработки младшего байта
sbr flags, 1<<timer2_ready

   ; конец прерывания таймера2
end_timer2:
   ; восстановим регистры, которые использует прерывание
reti

work:
   ; сбросим бит (флаг) готовности задержки
cbr flags, 1<<timer2_ready

   ; "тело" прерывания

   ; идем на задание задержки для следующего цикла таймера
rjmp test_delay

при необходимости, для очень больших задержек точно так же можно расширить 16-битный таймер1 до трех байт.
однажды один человек заказал мне прошивку для генератора импульсов с изменяемой частотой, от 1 Герца (период 1 секунда). там я ему, как раз, расширил таймер1 до трех байтов.

Мудрость приходит вместе с импотенцией...

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

Ссылка на комментарий
Поделиться на другие сайты

Литиевые аккумуляторы EVE Energy и решения для управления перезаряжаемыми источниками тока (материалы вебинара)

Опубликованы материалы вебинара Компэл, посвященного литиевым аккумуляторам EVE Energy и решениям для управления перезаряжаемыми источниками тока.

На вебинаре мы представили информацию не только по линейкам аккумуляторной продукции EVE, но и по решениям для управления ею, что поможет рассмотреть эти ХИТ в качестве дополнительной альтернативы для уже выпускающихся изделий. Также рассмотрели нюансы работы с производителем и сервисы, предоставляемые Компэл по данной продукции. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

14 часов назад, Starichok сказал:

вот такой код я придумал (с подробными комментариями):

Замечательный пример! И на универсальном языке это будет выглядеть примерно так:

if(timer2_ready) goto work;
if(delayH == 0) goto set_delayL;
if(count_256 < delayH) goto set_256;
if(delayL == 0) goto work;
count_256 = 0;

set_256:
count_256 ++;
setOCR2(0xFF);
reti();

set_delayL:
setOCR2(delayL);
timer2_ready = 1;
reti();

work:
timer2_ready = 0;
...

И тогда эту технику достаточно легко (хоть и вручную) транслировать на любой ассемблер.

Отсюда, например, сразу видно что переменную "count_256" можно исключить из алгоритма если применить декремент значения "delayH:delayL" (что лично я предпочитаю в таких случаях),

а функции: 

reti();

setOCR2(х);

зависят от архитектуры таймера на заданной платформе (процессоре).

Изменено пользователем ruhi
опечатка

Можно сделать все! Но чем больше можно, тем больше нельзя!

Ссылка на комментарий
Поделиться на другие сайты

Литиевые батарейки и аккумуляторы от мирового лидера  EVE в Компэл

Компания Компэл, официальный дистрибьютор EVE Energy, бренда №1 по производству химических источников тока (ХИТ) в мире, предлагает продукцию EVE как со склада, так и под заказ. Компания EVE широко известна в странах Европы, Америки и Юго-Восточной Азии уже более 20 лет. Недавно EVE была объявлена поставщиком новых аккумуляторных элементов круглого формата для электрических моделей «нового класса» компании BMW.

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

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

глядя на твой код, сейчас я обнаружил у себя одну ошибку и у тебя другую ошибку.

у меня написано:

brlo set_256
   ; счетчик "полных оборотов" стал равен старшему байту, проверяем младший байт на ноль
tst delayL
   ; если младший байт равен нулю, то задержка состоит только из старшего байта и выполнена полностью
   ; поэтому идем на выполнение "тела" прерывания
breq work
   ; иначе сбрасываем счетчик "полных оборотов"
clr count_256
   ; и идем на задание младшего байта задержки
rjmp set_delayL

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

иначе уйдем в тело прерывания с не сброшенным счетчиком.

то есть, должно быть так:

brlo set_256
   ; счетчик "полных оборотов" стал равен старшему байту
   ; сбрасываем счетчик "полных оборотов"
clr count_256
   ; и проверяем младший байт на ноль
tst delayL
   ; если младший байт равен нулю, то задержка состоит только из старшего байта и выполнена полностью
   ; поэтому идем на выполнение "тела" прерывания
breq work
   ; и идем на задание младшего байта задержки
rjmp set_delayL

а у тебя ошибка здесь:

if(delayL == 0) goto work;
count_256 = 0;

set_256:

после count_256 = 0 нет нужного перехода и программа идет на установку полного оборота.

7 часов назад, ruhi сказал:

переменную "count_256" можно исключить из алгоритма если применить декремент значения "delayH:delayL"

по-моему, ты тут сильно ошибаешься. или поясни свою мысль.

а на счет архитектуры я ясно указал - АТМега8.

Мудрость приходит вместе с импотенцией...

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

Ссылка на комментарий
Поделиться на другие сайты

15 часов назад, Starichok сказал:

глядя на твой код, сейчас я обнаружил у себя одну ошибку и у тебя другую ошибку.

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

15 часов назад, Starichok сказал:

после count_256 = 0 нет нужного перехода

да просмотрел, так должно быть:

if(timer2_ready) goto work;
if(delayH == 0) goto set_delayL;
if(count_256 < delayH) goto set_256;
if(delayL == 0) goto work;
count_256 = 0;

set_delayL:
setOCR2(delayL);
timer2_ready = 1;
reti();
                      
set_256:
count_256 ++;
setOCR2(0xFF);
reti();

work:
timer2_ready = 0;
...

 

Изменено пользователем ruhi
опечатка

Можно сделать все! Но чем больше можно, тем больше нельзя!

Ссылка на комментарий
Поделиться на другие сайты

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

помогите разобраться с этим битом. PLOCK судя по схеме бит-результат, судя по описанию его нужно ставить. и как перевод вообще трактовать

скрин.jpg

Ссылка на комментарий
Поделиться на другие сайты

15 часов назад, Starichok сказал:

по-моему, ты тут сильно ошибаешься. или поясни свою мысль.

вот так намного проще = эффективнее:

if(timer2_ready == 1)
{
  work:
stopTimer();
  timer2_ready = 0;
  setAgain(delayH, delayL);//или setNew();
  ...//processEndTimerEvent();
startTimer();
}
else
{
  if(delayH == 0)
  {
      timer2_ready = 1;
      setOCR2(delayL);
  }
  else
  {
      delayH--;
      setOCR2(0xFF);
  }
}
reti();

всего два условия вместо непонятно скольки.

Невозможное - возможно под Новый Год.

С наступающим!

6 минут назад, Дмитрий Вас сказал:

помогите разобраться с этим битом. PLOCK

PLL включается не сразу! он какое то время не стабильный, и его нельзя использовать - этот бит надо проверять чтобы определить момент когда PLL уже можно использовать,

в программе надо ожидание поставить (вроде нуля) на этом бите после включения PLL, после этого PLL можно использовать в качестве источника тактов.

Изменено пользователем ruhi
опечатка

Можно сделать все! Но чем больше можно, тем больше нельзя!

Ссылка на комментарий
Поделиться на другие сайты

в предыдущем твоем сообщении так и остался сброс счетчика после перехода к работе прерывания.

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

но то, что переставил блок "set_delayL", это хорошо, не нужно делать переход на этот блок.

сейчас, чисто для развлечения, я делаю программу управления шаговыми двигателями.

чтобы одновременно управлять двумя двигателями, использую два таймера. поэтому мне понадобилось расширить таймер2 до 16 бит.

но МК общается с компом, и на компе я сделал тестовую программу, где я вижу текущую задержку шага. поэтому мне нельзя изменять сам старший байт задержки (delayH) и я использую дополнительный регистр (count_256).

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

 но и тут, в последнем коде, ты потерял проверку младшего байта (delayL) на ноль. а нужно сначала проверить delayL на на ноль, и при нуле уйти в работу. а у тебя безусловно выполнится "setOCR2(delayL)".

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

Мудрость приходит вместе с импотенцией...

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

Ссылка на комментарий
Поделиться на другие сайты

Только что, Starichok сказал:

ты потерял проверку младшего байта (delayL) на ноль.

я не потерял - я в детали не вникал, я рад что общая идея понятна.

Можно сделать все! Но чем больше можно, тем больше нельзя!

Ссылка на комментарий
Поделиться на другие сайты

и более того, применив два старших байта (регистра) можно расширить таймер2 до 24 бит с точностью до 1 такта таймера.

и вот тут уже можно применить два старших регистра, которые поддерживают команду sbiw.

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

Дмитрий Вас, эта тема называется "Примеры Кода Для Avr", а не обсуждение общих вопросов.

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

Мудрость приходит вместе с импотенцией...

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

Ссылка на комментарий
Поделиться на другие сайты

1 час назад, ruhi сказал:

всего два условия вместо непонятно скольки.

что значит непонятно скольки?

у меня всего 3 условия. и как я сказал выше, третье условие ты потерял...

Мудрость приходит вместе с импотенцией...

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

Ссылка на комментарий
Поделиться на другие сайты

подсмотрел кусок кода где написано 

#define Start_pll_64_mega()   (PLLCSR = 0x06) 

вопрос. почему после mega скобки. почему нельзя без них обойтись?

Ссылка на комментарий
Поделиться на другие сайты

9 минут назад, Дмитрий Вас сказал:

подсмотрел кусок кода где написано 


#define Start_pll_64_mega()   (PLLCSR = 0x06) 

вопрос. почему после mega скобки. почему нельзя без них обойтись?

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

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

Ссылка на комментарий
Поделиться на другие сайты

1 минуту назад, ARV сказал:

но на вызов функции это совсем не будет похоже.

тото меня и смутило что дальше он не используется как функция 

void mc_init_pwm()
{
  Start_pll_32_mega();
  Wait_pll_ready();

 

Ссылка на комментарий
Поделиться на другие сайты

5 часов назад, Starichok сказал:

и как я сказал выше, третье условие ты потерял...

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

Можно сделать все! Но чем больше можно, тем больше нельзя!

Ссылка на комментарий
Поделиться на другие сайты

1 час назад, Дмитрий Вас сказал:

тото меня и смутило что дальше он не используется как функция 


void mc_init_pwm()
{
  Start_pll_32_mega();
  Wait_pll_ready();

 

Так Start_pll_32_mega(); - это абсолютно естественная форма обращения к функции, и если бы вы не знали, что это марос, никогда бы не отличили от функции! Именно об этом "эффекте" я и говорил.

Согласитесь, что в "базовом синтаксисе" языка Си запись

Start_pll_32_mega;

выглядит слишком неоднозначно: это может быть макрос, а может быть и обращение к volatile-переменной, а еще так может быть описана переменная int... И, глядя только на эту строку никогда нельзя однозначно понять, что именно это означает. В случае со скобками мы можем быть на 100% уверены, что тут какое-то действие происходит, т.к. функция используется именно для однострочной записи какого-то (вероятно, сложного) действия.

Изменено пользователем ARV

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

Ссылка на комментарий
Поделиться на другие сайты

25.12.2019 в 21:52, Starichok сказал:

вот такой код я придумал...

А так?

; прерывание таймера2, режим СТС
timer2_CTC:

; сохраним регистры, которые использует прерывание
		cbi		PORTD,0
		sbrc flags, timer2_ready
; если задержка выполнена, то идем на выполнение "тела" прерывания
		rjmp work

; тестируем байты задержки
test_delay:
		subi		delayH,1
		brne		set_256
		rjmp		set_delayL
work:
; сбросим бит (флаг) готовности задержки
		cbr flags, 1<<timer2_ready
		ldi		delayH,timer2_ready
		sbi		PORTD,0
; "тело" прерывания
; ..............
; ..............
; задание "полного оборота"
set_256:
		ser R16
; задаем 255 - "полный оборот"
		out OCR2, R16
; и выходим из прерывания
		rjmp end_timer2

; задание младшего байта задержки
		set_delayL:
		out OCR2, delayL
; поставим бит (флаг), что задержка выполнена. точнее, будет выполнена после отработки младшего байта
		sbr flags, 1<<timer2_ready

; конец прерывания таймера2
		end_timer2:
; восстановим регистры, которые использует прерывание
		reti

 

Ссылка на комментарий
Поделиться на другие сайты

Геннадий

я выше написал, почему я не могу изменять регистр delayH. ты разве этого не читал?

а какая разница инкрементировать или декрементировать регистр? результат будет одинаковый.

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

 а это что за фигня

ldi delayH,timer2_ready

?

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

и если тело прерывания длинное, то твой условный переход

brne set_256

не сможет работать, так как по условию переход делается только "короткий"

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

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

Мудрость приходит вместе с импотенцией...

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

Ссылка на комментарий
Поделиться на другие сайты

13 часов назад, Starichok сказал:

Геннадий

 а это что за фигня

ldi delayH,timer2_ready

и если тело прерывания длинное, то твой условный переход

brne set_256

не сможет работать, так как по условию переход делается только "короткий"

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

Это я взял по ошибке, как константу для задания интервала. Извиняюсь. Хотя Ваши, @Starichok , пляски с бубном тоже сложно понять. Вы свой алгоритм проверяли? И какой смысл наворачивать в прерывании кучу проверок и переходов, если можно решить все гораздо лаконичнее (а именно таким должен быть обработчик прерывания). Если Вам кажется, что Вы придумали оригинальное решение, то на мой взгляд - это навороченная путаница (без обид). Во всяком случае, мне она именно так видится. Давайте разберемся по порядку.

Ваше представление о 16-битном таймере заключается в отработке delayH кол-ва полных циклов (OCR2=0xFF) и одного delayL (OCR2=delayL). Заметьте, у Вас delayL отрабатывает ОДИН РАЗ и проверять его на 0 нет смысла.

Объясню. Когда count_256 достигает значения delayH,  происходит его сброс (clr   count_256), потом проверка delayL на 0, с последующим ветвлением либо на work, либо на set_delayL (в котором Вы поднимаете флаг timer2_ready  и меняете значение OCR2 на delayL). Ну ладно, delayL не равно нулю и перехода на work быть не должно (как и происходит). Однако флаг Вы поднимаете и при следующем вызове обработчика (сразу же по флагу) переходите на work, никак не работая со счетчиком delayL. Так для чего он и его проверка на 0 нужны? 

Ссылка на комментарий
Поделиться на другие сайты

я не просто проверял алгоритм, он у меня работает.

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

да, можно сократить код, если декрементировать старший байт (delayH), но тогда все равно нужно где-то хранить значение задержки.

по используемым ресурсам то на то и выйдет - тот же дополнительный регистр (count_256) придется переназначить для хранения старшего байта. младший байт остается без изменения и его дополнительно нигде хранить не надо.

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

1 час назад, Геннадий сказал:

у Вас delayL отрабатывает ОДИН РАЗ и проверять его на 0 нет смысла.

заблуждаешься.

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

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

вот так это будет выглядеть в оптимальном виде:

; объявляем регистр флагов
.def flags            = R19    ; различные флаги
; объявляем флаг
.equ timer2_ready    = 4        ; таймер отработал заданное время

; объявляем регистры, где будет находится требуемое время таймера (задержка)
.def delayL            = R20    ; задержка, младший байт
.def delayH            = R21    ; задержка, старший байт

; прерывание таймера2, режим СТС
timer2_CTC:

; сохраним регистры, которые использует прерывание

sbrc flags, timer2_ready
    ; если задержка выполнена, то идем на выполнение "тела" прерывания
rjmp work

    ; тестируем байты задержки
test_delay:
    ; проверяем старший байт на ноль
tst delayH
    ; если старший байт задержки равен нулю, то идем на задание младшего байта задержки
breq set_delayL
    ; иначе уменьшаем старший байт
dec delayH
    ; и задаем 255 - "полный оборот" таймера2
ser R16
out OCR2, R16
    ; и выходим из прерывания
rjmp end_timer2

    ; задание младшего байта задержки
set_delayL:
    ; старший байт задержки равен нулю, проверяем младший байт на ноль
tst delayL
    ; если младший байт равен нулю, то задержка состоит только из старшего байта и выполнена полностью
    ; поэтому идем на выполнение "тела" прерывания
breq work
    ; иначе идем на задание младшего байта задержки
out OCR2, delayL
    ; поставим бит (флаг), что задержка выполнена. точнее, будет выполнена после отработки младшего байта
sbr flags, 1<<timer2_ready

    ; конец прерывания таймера2
end_timer2:
    ; восстановим регистры, которые использует прерывание
reti

work:
    ; сбросим бит (флаг) готовности задержки
cbr flags, 1<<timer2_ready

    ; "тело" прерывания

    ; загружаем в delayH:delayL значение задержки
    ; и идем на тестирование задержки для следующего цикла таймера2
rjmp test_delay

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

Мудрость приходит вместе с импотенцией...

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

Ссылка на комментарий
Поделиться на другие сайты

сейчас на Радиокоте мне подсказали о крупном дефекте моего алгоритма.

если "довесок" в младшем байте (delayL) будет очень маленьким, то таймер просто не сможет его отработать с точностью до 1 такта таймера, так как само прерывание на свою работу по анализу задержки и загрузке младшего байта потратит больше времени, чем содержится в младшем байте.

и решение тоже подсказали.

нужно задержку пересчитать так, чтобы число "полных оборотов" в старшем байте было кратно 128 (а не 256). тогда в младшем байте останется число от 127 до 254, и такая задержка уже будет прекрасно работать.

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

Мудрость приходит вместе с импотенцией...

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

Ссылка на комментарий
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу

×
×
  • Создать...