Вопросы по С/С++ (СИ)

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень

Сообщение vitalik_1984 »

demonchik писал(а):спасибки. я думал что есть какой-то выход из данной ситуации, объявив в одном месте
Можно так попробовать сделать, но если даже просто поменяешь местами

Код: Выделить всё

 #include <1.h>
#include <2.h>
Может возникнуть проблема, зачем рисковать?
Например в заголовочном файле util/atomic.h сделана запись

Код: Выделить всё

#include <interrupts.h>
при этом отпадает необходимость прописывать <interrupts.h>

Если вы в своём заголовочном файле пропишете, заголовочные файлы, что там использованы, потом в основном как раз не нужно будет думать о том что прописывать.
Вроде так.
В поисках истины человек развивается.
Контактная информация:
Реклама
Грызет канифоль
Аватара пользователя
Сообщения: 271
Зарегистрирован: Пн окт 25, 2010 20:47:04
Откуда: Казахстан, Астана

Сообщение shurikss123 »

ARV писал(а):
DX168B писал(а):Я обычно пишу хейдеры, в которых просто пишу свои функции.
вы делаете неправильно. в хидерах не должно быть реализаций функций, должны быть только заголовки (прототипы, описания). разве что inline-функции или макросы-функции могут там быть в виде исключения...
вот пасибо, а то тоже задавался вопросом как все организовать :idea:
Изображение
Мастер на все руки, кручу, кручу, кручу и матерюсь
Повелитель паяльной станции, лома, и пинцета!!!
Реклама
Мудрый кот
Аватара пользователя
Сообщения: 1800
Зарегистрирован: Вт окт 05, 2010 01:08:57

Сообщение O-LED »

Подскажите, почему не срабатывает прерывание по переполнению Т2??

Код: Выделить всё

interrupt [TIM2_OVF] void timer2_ovf_isr(void)
{
ОБРАБОТЧИК ПРЕРЫВАНИЯ
}
interrupt [TIM2_COMP] void timer2_comp_isr(void)
{
OCR2++;
ОБРАБОТЧИК ПРЕРЫВАНИЯ
}
ASSR=0x08;
TCCR2=0x05;
OCR2=0x01;

TIMSK=0xC0;  
Если отключить прерывание Т2 по совпадению, то начинает работать Т2 по переполнению.
KIT
Контактная информация:
Мудрый кот
Аватара пользователя
Сообщения: 1800
Зарегистрирован: Вт окт 05, 2010 01:08:57

Сообщение O-LED »

Общем так. Если OCR2=0xff (макс значение) то прерывание по переполнению Т2 не срабатывает. При этом прерывание Т2 по совпадению - прекрасно работает. Почему так?

Я понимаю так. Когда OCR2=0xff и TCNT2=0xff то одновременно наступают события для генерации и по совпадению Т2, и по переполнению Т2. Так как у прерывания по совпадению вектор выше, то первым обрабатывается оно, а после выхода из этого прерывания должно сразу же начать обрабатываться по переполнению.
Что подскажите?
KIT
Контактная информация:
Реклама
Эиком - электронные компоненты и радиодетали
Вымогатель припоя
Аватара пользователя
Сообщения: 672
Зарегистрирован: Вт окт 27, 2009 22:39:19
Откуда: Москва

Сообщение md5sum »

O-LED писал(а):Что подскажите?
Какая мега?
Для меги 8-32 rev L

Код: Выделить всё

ERRATA
Interrupts may be lost when writing the timer registers in the asynchronous timer
The interrupt will be lost if a timer register that is synchronous timer clock is written when the
asynchronous Timer/Counter register (TCNTx) is 0x00.
Problem Fix/Workaround
Always check that the asynchronous Timer/Counter register neither have the value 0xFF nor
0x00 before writing to the asynchronous Timer Control Register (TCCRx), asynchronous
Timer Counter Register (TCNTx), or asynchronous Output Compare Register (OCRx).
Не стоит менять указанные регистры при значениях счетчика 0x00 или 0xFF в асинхронном режиме
— Не говорите мне что делать и я не скажу куда Вам идти...
Реклама
Мудрый кот
Аватара пользователя
Сообщения: 1800
Зарегистрирован: Вт окт 05, 2010 01:08:57

Сообщение O-LED »

Мега8А. Асинхронный режим.
и что ничего нельзя сделать??
пробовал так - внутри обработчика по совпадению пишу if (OCR2==0xfе) OCR2=0; - всё работает, но теряется одно прерывание по совпадению.
пробовал принудительно подымать флаг прерывания по переполнению Т2 - if (OCR2==0xff) TIFR|=0b01000000; ничего не помогает.
:(
KIT
Контактная информация:
Реклама
Вымогатель припоя
Аватара пользователя
Сообщения: 672
Зарегистрирован: Вт окт 27, 2009 22:39:19
Откуда: Москва

Сообщение md5sum »

Если между прерываниями достаточно времени (несколько тактов таймера), то проще сделать проверку перед изменениями регистров типа такой

Код: Выделить всё

while ((TCNT2==0) || (TCNT2==0xff)) {/* ждем пока счетчик не станет >0 и <255 */}
OCR2=....
— Не говорите мне что делать и я не скажу куда Вам идти...
Мудрый кот
Аватара пользователя
Сообщения: 1800
Зарегистрирован: Вт окт 05, 2010 01:08:57

Сообщение O-LED »

у меня прерывания идут каждый тик таймера :(

Код: Выделить всё

interrupt [TIM2_COMP] void timer2_comp_isr(void)
{
OCR2++;
<<<ОБРАБОТЧИК ПРЕРЫВАНИЯ>>>
}
KIT
Контактная информация:
Опытный кот
Аватара пользователя
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна

Сообщение avreal »

Если прерывания OCR идут все, то, может, как-то так?

Код: Выделить всё

interrupt [TIM2_COMP] void timer2_comp_isr(void)
{
    ++OCR2;
    // тут обработка преывания «compare» как и был ораньше

    if (OCR2 == 0) { // или 1, смотря какая фаза нужна, может как раз и нужно когда _стало_ 1, было 0
        sei(); // следующее прерывание по compare сможет прервать это,
               // сюда второй раз все равно не зайдёт.
        // тут  как бы обработка прерывания «overflow», то, что было на том векторе
        // а вектор overflow и не трогать вообще
    }
}
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Контактная информация:
Мудрый кот
Аватара пользователя
Сообщения: 1800
Зарегистрирован: Вт окт 05, 2010 01:08:57

Сообщение O-LED »

avreal так не пойдёт. «overflow» включен постоянно, а «compare» включается периодически .........
KIT
Контактная информация:
Опытный кот
Аватара пользователя
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна

Сообщение avreal »

Можно попытаться выкрутиться.

Код: Выделить всё

uint8_t compare_processing_enable;

interrupt [TIM2_COMP] void timer2_comp_isr(void)
{
    ++OCR2;

    if (compare_processing_enable) {
        // тут обработка прерывания «compare» как и было раньше
    }

    if (OCR2 == 0) { // или 1, смотря какая фаза нужна, может как раз и нужно когда _стало_ 1, было 0
        sei(); // следующее прерывание по compare сможет прервать это,
               // сюда второй раз все равно не зайдёт.
        // тут  как бы обработка прерывания «overflow», то, что было на том векторе
        // а вектор overflow и не трогать вообще
    }
}
и вместо разрешения/запрещения прерывания по compare устанавливать/сбрасывать переменную compare_processing_enable. Да, это немного затратнее по коду и времени, зато будет работать.
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Контактная информация:
Вымогатель припоя
Аватара пользователя
Сообщения: 672
Зарегистрирован: Вт окт 27, 2009 22:39:19
Откуда: Москва

Сообщение md5sum »

O-LED писал(а):у меня прерывания идут каждый тик таймера :(
!!! Тогда опиши алгоритм - который пытаешься реализовать. Прерывания по совпадению каждый тик это что-то...
Может логику работы проще изменить, чем так изгаляться над таймером?

ЗЫ: Тема как-бы "Вопросы по С/С++ (СИ)", а тут ... Может стоит перенести?
— Не говорите мне что делать и я не скажу куда Вам идти...
Мудрый кот
Аватара пользователя
Сообщения: 1800
Зарегистрирован: Вт окт 05, 2010 01:08:57

Сообщение O-LED »

!!! Тогда опиши алгоритм - который пытаешься реализовать. Прерывания по совпадению каждый тик это что-то...
Может логику работы проще изменить, чем так изгаляться над таймером?
Общем так. Т2 в асинхронном режиме. Тактируется 256гц (32768\128) «overflow» наступает раз в секунду (отсчет времени). Также на Т2 решил сделать и динамическую индикацию на 4 разряда. если Т2 заставить срабатывать каждый тик («compare», OCR2++;) то имеем 256 сработок в секунду, (64 на каждую цифру, вполне подходит для динамической индикации). Если случится пропадание питание, то все прерывания кроме «overflow»Т2 выключаются и контроллер загоняется в power save.
В принципе дин индикацию можно и на Т0 или Т1 соорудить, но захотелось попробовать обойтись одним Т2 :roll: Так сказать, спортивный интерес :idea:
KIT
Контактная информация:
Вымогатель припоя
Аватара пользователя
Сообщения: 672
Зарегистрирован: Вт окт 27, 2009 22:39:19
Откуда: Москва

Сообщение md5sum »

O-LED писал(а):Общем так. Т2 в асинхронном режиме. Тактируется 256гц (32768\128) «overflow» наступает раз в секунду (отсчет времени). Также на Т2 решил сделать и динамическую индикацию на 4 разряда. если Т2 заставить срабатывать каждый тик («compare», OCR2++;) то имеем 256 сработок в секунду, (64 на каждую цифру, вполне подходит для динамической индикации). Если случится пропадание питание, то все прерывания кроме «overflow»Т2 выключаются и контроллер загоняется в power save.
В принципе дин индикацию можно и на Т0 или Т1 соорудить, но захотелось попробовать обойтись одним Т2 :roll: Так сказать, спортивный интерес :idea:
Предлагаю:
Таймер тактируется 32768 без делителя, режим CTC, OCR2=127
в прерывании:

Код: Выделить всё

static uint8_t issecond=0;
if (!(++issecond)) {/*набежала секунда - выполняем код считающий секунды*/}
/*тут код динамической индикации*/
Зато не надо постоянно менять регистры таймера
— Не говорите мне что делать и я не скажу куда Вам идти...
Мудрый кот
Аватара пользователя
Сообщения: 1800
Зарегистрирован: Вт окт 05, 2010 01:08:57

Сообщение O-LED »

Спасибо.
я думал над таким вариантом, но тогда выйдет что при питании от батарее мы будем иметь в секунду 256 прерываний вместо одного. а это сильно увеличит потребление. :)
KIT
Контактная информация:
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень

Сообщение vitalik_1984 »

md5sum писал(а):
O-LED писал(а): В принципе дин индикацию можно и на Т0 или Т1 соорудить, но захотелось попробовать обойтись одним Т2 :roll: Так сказать, спортивный интерес :idea:
Предлагаю:
Таймер тактируется 32768 без делителя, режим CTC, OCR2=127
в прерывании:

Код: Выделить всё

static uint8_t issecond=0;
if (!(++issecond)) {/*набежала секунда - выполняем код считающий секунды*/}
/*тут код динамической индикации*/
Зато не надо постоянно менять регистры таймера
в таком то коде похоже можно и T0 обойтись:) - ещё на PWM таймер останется.
В поисках истины человек развивается.
Контактная информация:
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень

Сообщение vitalik_1984 »

O-LED писал(а):Спасибо.
я думал над таким вариантом, но тогда выйдет что при питании от батарее мы будем иметь в секунду 256 прерываний вместо одного. а это сильно увеличит потребление. :)
А слабо при переходе в ждущий режим поменять код?:) (сменить делитель и прерывания)
В поисках истины человек развивается.
Контактная информация:
Мудрый кот
Аватара пользователя
Сообщения: 1800
Зарегистрирован: Вт окт 05, 2010 01:08:57

Сообщение O-LED »

в таком то коде похоже можно и T0 обойтись:) - ещё на PWM таймер останется.
Да на Т0 уже сделал, эт не проблема.... :) А хоцца только на Т2. :roll:
А слабо при переходе в ждущий режим поменять код?:) (сменить делитель и прерывания)
нет, не слабо. попробую. :beer:
KIT
Контактная информация:
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень

Сообщение vitalik_1984 »

O-LED писал(а):
в таком то коде похоже можно и T0 обойтись:) - ещё на PWM таймер останется.
Да на Т0 уже сделал, эт не проблема.... :) А хоцца только на Т2. :roll:
Зачем занимать такой функциональный таймер на решение такой простой задачи?Одного Т0 как раз хватит. Ведь там не нужно использовать прерывание по совпадению, а в Т0 его нет.
В поисках истины человек развивается.
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 8865
Зарегистрирован: Чт янв 20, 2011 19:54:19
Откуда: Уфа

Сообщение Ратмир »

Всем привет! Может кто подскажет нашел пример программы для индикатора (7-сегментного) с общим катодом, как переделать прогаммку для индикатора с общим анодом? Я так понимаю, что подаю +5В с обоих сторон.
Вложения
Пример.JPG
(115.32 КБ) 442 скачивания
"Мы так жить будем, что наши внуки нам завидовать будут" В.С. Черномырдин
Изображение
Ответить

Вернуться в «Разные вопросы по МК»