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

Помогите с инкрементом в операторе ветвления


Юстас

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

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

Всё не так. Так программы не пишутся.  Давайте без суеты. Для начала, создаёте на каком нибудь таймере прерывания каждые 40-60 мс. В обработчике пишите программу анализа состояния кнопок и складываете их в какие нибудь флаги. Там уже готовое всё должно лежать - такие то кнопки нажаты, такие то нет. Всё. Это самостоятельная программа, никаких rjmp, всё на прерываниях.

Никогда не спорьте с дураком - люди могут не заметить между вами разницы

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

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

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

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

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

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

Hongfa для различных применений в Компэл. Большой выбор в наличии!

Компания HONGFA - это не только крупнейший в мире производитель электромеханических реле, но также производитель конденсаторов, вакуумных прерывателей, трансформаторов и низковольтного коммутационного оборудования. На складе КОМПЭЛ регулярно поддерживаются около 100 самых популярных позиций электромеханических реле. Реле Hongfa могут заместить многие изделия производства недоступных брендов. Подробнее>>

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

Я бы немного подкорректировал совет Григория. В прерывании таймера поднимать флаг глобального разрешения, а все остальные функции вызывать в основном цикле (основываясь на поднятии флага). Таким образом проще распределять выполнение функций программы. 

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

Тренды и лучшие решения для разработки зарядных станций в России

К 2029 году в России прогнозируется увеличение числа зарядных станций до 40 000. При этом отечественный рынок электротранспорта имеет климатические, потребительские и географические особенности. Для успешной разработки и построения инфраструктуры станций заряда в России идеальным вариантом является использование решений и электронных компонентов китайских производителей – лидеров индустрии электротранспорта и возобновляемой энергетики, которые уже представлены в КОМПЭЛ. Подробнее>>

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

Цитата

ldi   temp, 0b00000000
out DDRC, temp           ; PORTC на вход
ser temp
out DDRD, temp

Забавно, что зануляете переменную через ldi (а не clr), а заполняете единицами через ser (а не ldi). Это не ошибка, просто смотрится странно

Цитата

;НАСТРОЙКА ТАМЕРА 0//
ldi   temp, 0b00000011   ; предделитель 64
out   TCCR0, temp
ldi temp, 0b00000001     ; прерывание по переполнению каждые 980 мкс
out   TIMSK, temp

С точки зрения форматирования кода лучше использовать сдвиги и логические операции, например ldi temp, (1<<CS01 | 1<<CS00)

Цитата

KNOPKI:
in temp, PINC        ; считываем PINC в переменную
cpi temp, 0b00000011 ; сравниваем с константой  

Зря вы подпустили Капитана Очевидность к исходному коду, он там комментарии оставил. Лучше сами написали чего хотите добиться этими командами, а не что они делают на самом деле. На первый взгляд константа 0b00000011 ни о чем не говорит

Цитата

 

cpi ANTDRBZG, 0x3c ; сравним переменую с 60 (примерно 60 мс)

ret ; если равно 60 мс, то...

rjmp SET_PORTD0 ; ... прыгаем установить 1 в PORTD.0

 

Вот тут серьезная ошибка или несоответствие кода комментарию: ret будет выполнен независимо от сравнения, поскольку команды условного перехода (хотя бы breq) нет

Цитата

;ОСНОВНЩЙ ЦИКЛ**********************************
tst flag           ; пповерим флаг
breq INKRIMENT     ; если поднят, прыгаем в INKRIMENT

Очевидно, просто опечатки.

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

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

Секреты депассивации литиевых батареек FANSO EVE Energy

Самыми лучшими параметрами по энергоемкости, сроку хранения, температурному диапазону и номинальному напряжению обладают батарейки литий-тионилхлоридной электрохимической системы. Но при длительном хранении происходит процесс пассивации. Разберем в чем плюсы и минусы, как можно ее избежать или уменьшить последствия и как проводить депассивацию батареек на примере продукции и рекомендаций компании FANSO EVE Energy. Подробнее>>

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

Обработчик я написал так для начала.

код:

Скрытый текст

;***********************************************
;*******ПРЕРЫВАНИЕ ПО ВЕКТОРУ TIMER0_OVF********
;***********************************************
TIMER0_OVF:
cli
in PINC, REG_PINC        ; прочтём PINC
cpi REG_PINC, 0b00000011 ; сравним с константой PINC биты 0 и 1
ldi FLAG_PINC_1_2, 1     ; если равно, то поднимем флаг PINC
sei
reti
;***********************************************

Скрытый текст

;***********************************************
;*******ПРЕРЫВАНИЕ ПО ВЕКТОРУ TIMER0_OVF********
;***********************************************
TIMER0_OVF:
cli
in PINC, REG_PINC        ; прочтём PINC
cpi REG_PINC, 0b00000011 ; сравним с константой PINC биты 0 и 1
ldi FLAG_PINC_1_2, 1     ; если равно, то поднимем флаг PINC
sei
reti
;***********************************************

 

 

14 минуты назад, COKPOWEHEU сказал:

Забавно, что зануляете переменную через ldi (а не clr), а заполняете единицами через ser (а не ldi). Это не ошибка, просто смотрится странно

Знал что кто нибудь да заметит)))

14 минуты назад, COKPOWEHEU сказал:

С точки зрения форматирования кода лучше использовать сдвиги и логические операции, например ldi temp, (1<<CS01 | 1<<CS00)

Знаю... больше не буду))

Ладно, хватит придираться к опечаткам, я начал новую жизнь, как говорится с чистого листа))) 

Подправил)

;НАСТРОЙКА ТАМЕРА 0//
ldi   temp, (1<<CS02 | 1<<CS00)   ; предделитель 1024
out   TCCR0, temp        ; прерывание по переполнению каждые 61 мс
ldi temp, 0b00000001     
out   TIMSK, temp
sei
;***********************************************

Обработчик

Скрытый текст

;***********************************************
;*******ПРЕРЫВАНИЕ ПО ВЕКТОРУ TIMER0_OVF********
;***********************************************
TIMER0_OVF:
cli
in REG_PINC, PINC       ; прочтём PINC
cpi REG_PINC, 0b00000011 ; сравним с константой PINC биты 0 и 1
ldi FLAG_PINC_1_2, 1     ; если равно, то поднимем флаг PINC
sei
reti
;***********************************************

 

 

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

Уберите из кода cli и sei, они сами сработают, как только вы войдёте в прерывание. А использование sei, как это использовано у вас даже опасно, можете при определенных обстоятельствах не выйти из данного прерывания.

После того как считали данные из порта, наложите маску по and для тех бит, которые используются. Если у вас только две кнопки на 0 и 1 разрядах, то это будет так

andi Key, 0b00000011

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

 

p.s.

если использовать прерывание таймера не по переполнению, а по сравнению (используя регистр OCR), то отпадёт необходимость каждый раз в прерывании инициализировать регистр TCCR0 (что у вас почему то отсутствует)

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

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

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

А в основном теле программы только анализирую флаги.

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

вы принципиально хотите на ассемблере? На Си будет быстрее и понятнее и примеров больше, а написав на Си код, вы всегда можете посмотреть его ассемблерный вариант

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

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

@Юстас в прерываниях для обработки кнопок нужно иметь по два флага на каждую кнопку. Если пин кнопки установлен, то проверяете первый флаг. Если он не установлен, поднимаете его. Если он установлен, то поднимаете второй. Этот второй и будет общедоступным состоянием кнопки. аналогично и с отпусканием кнопок.

Никогда не спорьте с дураком - люди могут не заметить между вами разницы

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

с Си всё намного проще, чем вы думаете.

Вот например весь код для динамической индикации, а во вложении есть файл проект (IAR EW) + proteus (симулятор).

Цитата

#include <ina90.h>
#include <iom168.h>
#include <stdint.h>

volatile unsigned char Vibor_Razrada;
volatile unsigned char LEDBuf[4];

const __flash unsigned char TableLEDRazrad[] = {0x01,0x02,0x04,0x08}; // лог.1 включает индикатор
const __flash unsigned char TableLEDDecode[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90}; // лог.0 зажигает сегмент (инверсия)

//==============================================================================
//
//==============================================================================
void main(void)
{
  TCCR0A = (1<<WGM01) | (0<<WGM00);           // режим CTC - сброс при совпадении
  TCNT0 = 0x00;                               // начальное значение счётчика
  OCR0A = 0x7C;                               // значение для сравнения
  TIMSK0 |= (1<<OCIE0A);                      // разрешаем прерывания от таймера 0 по сравнению
  TCCR0B = (0<<CS02) | (1<<CS01) | (1<<CS00); // делитель на 64

  DDRD = 0xFF;      // Порт D на вывод
  PORTD = 0xFF;     // начальное значение
  DDRB = 0x0F;      // Порт B на вывод
  PORTB = 0x00;     // начальное значение
 
// заполняем буфер для отображения
 
  LEDBuf[0] = TableLEDDecode[6];
  LEDBuf[1] = TableLEDDecode[7];
  LEDBuf[2] = TableLEDDecode[8];
  LEDBuf[3] = TableLEDDecode[9];

 
  _SEI();
 
  while(1)
  {
  }
}

//==============================================================================
// Прерывание каждую миллисекунду
//==============================================================================
#pragma vector = TIMER0_COMPA_vect
__interrupt void RefreshLcdKbd(void)    // опрос клавиатуры и регенерация дисплея
{
    Vibor_Razrada++;
    PORTB = 0;  // гасим все индикаторы
    PORTD = LEDBuf[Vibor_Razrada & 0x03];    // выводим наш символ
    PORTB = TableLEDRazrad[Vibor_Razrada & 0x03];  // включаем индикатор
}

 

dyn_ind.zip

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

Капец))) Как пыльным мешком по голове)) Что-то понятно, что-то не очень. Не прозрачно как-то. На асме я всё пальцами чувствую (в пределах моих знаний)

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

26 минут назад, dm37 сказал:

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

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

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

Как упоминал Григорий, алгоритм нужен.

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

в этом коде из того, что вы не знаете, наверно, так это только массивы, всё остальное вы пишите на ассемблере практически как есть (оформление прерывания я не считаю)

поверьте, ассемблер сложнее, чем си

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

Не поверю. Если хорошо знать МК, то не важно на чем писАть. Вот только на Си библы нужны и решение обычно "в лоб". На Ассме можно решить как угодно и библы не нужны.

Да и вопрос сейчас стоит не тот. Пишем на Ассме, учим Юстаса порядку в программе.

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

Генадий, да я всё понимаю, а вот начинаю код писать и такой вот огород получается)

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

Так где лучше считывать PINC в основной программе или в прерывании по таймеру?

 

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

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

Юстас, заюзайте один таймер с интервалом 1мс. Дальше посмотрим.

Вам не только антидребезг нужен, потребуется еще и функция одновибратора (один раз нажал - одно приращение получил).

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

4 минуты назад, Геннадий сказал:

Юстас, заюзайте один таймер с интервалом 1мс. Дальше посмотрим.

Вам не только антидребезг нужен, потребуется еще и функция одновибратора (один раз нажал - одно приращение получил).

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

Начнем с начала. 

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

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

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

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

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

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

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

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

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

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

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

  • Сообщения

    • Позвольте и я вставлю свои "пять копеек" Название темы - "Фотогалерея ваших усилителей + обсуждение корпусов" Разберём подробно: В название темы нет конкретного уточнения, что подрузомивается под названием - Фотогалерея ваших усилителей? Как я вижу - это усилитель какой/каким усилителем пользуется форумчанин и этим решил поделиться на форуме. Собрал ли он его сам или заказал готовые платы или модули. Да и вообще можно выложить заводской усилитель, т.к. нет в названии "Собранный своими руками" На куске доски или в корпусе он находится это уже другое, в название темы нет конкретики, всего лишь "+ обсуждение корпусов" т.е. корпус уже второстепенное как по мне. Предположим, кто то собрал усилитель на куске фанеры с кучей проводов и слушает музыку, его это устраивает. Он решил поделиться своими впечатлениями на форуме и выложил фото своего усилителя. Выложил фото усилителя? Как по мне - да! А в каком корпусе это лишь только обсуждение  
    • Я понял, спасибо. Закажу на али возможно. На данный момент все работает, но с резисторами 4.7к. Транзисторы не теплые даже, как при 12в. Наверное многовато 4.7к. Заменил резисторы так как страшно уже, задолбался менять транзисторы. Возможно они и Г, но на данный момент кроме али другие достать можно только по оверпрайсу что не хотелось бы. По звуку 24в намного лучше на высокой громкости. Вообще вот уменьшение наминала этих резисторов хоть как-то влияет на звук или нет?
    • или не важно какой сигнал подавать, надо усиление подбирать? только я не знаю какими резисторами задается коэффициент усиления..
    • Термостабильность показаний градусника это интересный момент Полный костыль выглядел смешнее - в цикле loop стоял "таймер" на миллис с измерением внутри и счётчиком, дабы сформировать семплрейт порядка 250 герц, каждые 100  выборок счётчик сбрасывается, значение усредняется и обновляется переменная, отправляемая в метод вывода на дисплей, который сам находится в своём "таймере" на миллис со временем обновления порядка раз в полсекунды. Уж не помню, зачем я конкретно эти тайминги делал, может для того чтобы подавить 50 герц наводки на проводах в пару метров... Возня с "таймерами" нужна была для того, чтобы не мешать работать основной части программы, т.е. чтобы код не блокировался.
    • Мне однажды попались 740-е с 10-ю омами. Я тогда знатно прифигел, т.к. обычно левак отличается максимум в 5 раз, а тут аж почти в 20. Но 18 ом, это конечно рекорд
    • @Nem0 извини, если повторяется вопрос..  какой сигнал подавать на вход для максимальной мощности? сейчас стоит NE5532p, но кажется сигнал слабоват, можно использовать такую схему?: Источник сигнала ->ne5532p->ne5532p-> УНЧ ОМ2? 
    • @Nem0 для моего уровня он очень сложен... мне реально проще собрать Натали(при наличии всех радиодеталей))  IRS2092 у меня была, как только пришёл на сайт(это мой второй аккаунт) у меня в подписи была IRS2092)) микросхема лежала годами но так и не собрал на ней ничего..
×
×
  • Создать...