Страница 25 из 386

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

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

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

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

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

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

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

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

Добавлено: Вт май 10, 2011 19:00:21
shurikss123
ARV писал(а):
DX168B писал(а):Я обычно пишу хейдеры, в которых просто пишу свои функции.
вы делаете неправильно. в хидерах не должно быть реализаций функций, должны быть только заголовки (прототипы, описания). разве что inline-функции или макросы-функции могут там быть в виде исключения...
вот пасибо, а то тоже задавался вопросом как все организовать :idea:

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

Добавлено: Ср май 11, 2011 20:05:16
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 по переполнению.

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

Добавлено: Ср май 11, 2011 21:38:50
O-LED
Общем так. Если OCR2=0xff (макс значение) то прерывание по переполнению Т2 не срабатывает. При этом прерывание Т2 по совпадению - прекрасно работает. Почему так?

Я понимаю так. Когда OCR2=0xff и TCNT2=0xff то одновременно наступают события для генерации и по совпадению Т2, и по переполнению Т2. Так как у прерывания по совпадению вектор выше, то первым обрабатывается оно, а после выхода из этого прерывания должно сразу же начать обрабатываться по переполнению.
Что подскажите?

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

Добавлено: Ср май 11, 2011 22:12:50
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 в асинхронном режиме

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

Добавлено: Ср май 11, 2011 22:43:32
O-LED
Мега8А. Асинхронный режим.
и что ничего нельзя сделать??
пробовал так - внутри обработчика по совпадению пишу if (OCR2==0xfе) OCR2=0; - всё работает, но теряется одно прерывание по совпадению.
пробовал принудительно подымать флаг прерывания по переполнению Т2 - if (OCR2==0xff) TIFR|=0b01000000; ничего не помогает.
:(

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

Добавлено: Ср май 11, 2011 23:11:30
md5sum
Если между прерываниями достаточно времени (несколько тактов таймера), то проще сделать проверку перед изменениями регистров типа такой

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

while ((TCNT2==0) || (TCNT2==0xff)) {/* ждем пока счетчик не станет >0 и <255 */}
OCR2=....

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

Добавлено: Ср май 11, 2011 23:42:47
O-LED
у меня прерывания идут каждый тик таймера :(

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

interrupt [TIM2_COMP] void timer2_comp_isr(void)
{
OCR2++;
<<<ОБРАБОТЧИК ПРЕРЫВАНИЯ>>>
}

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

Добавлено: Чт май 12, 2011 01:24:21
avreal
Если прерывания OCR идут все, то, может, как-то так?

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

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

    if (OCR2 == 0) { // или 1, смотря какая фаза нужна, может как раз и нужно когда _стало_ 1, было 0
        sei(); // следующее прерывание по compare сможет прервать это,
               // сюда второй раз все равно не зайдёт.
        // тут  как бы обработка прерывания «overflow», то, что было на том векторе
        // а вектор overflow и не трогать вообще
    }
}

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

Добавлено: Чт май 12, 2011 03:45:23
O-LED
avreal так не пойдёт. «overflow» включен постоянно, а «compare» включается периодически .........

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

Добавлено: Чт май 12, 2011 09:37:01
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. Да, это немного затратнее по коду и времени, зато будет работать.

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

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

ЗЫ: Тема как-бы "Вопросы по С/С++ (СИ)", а тут ... Может стоит перенести?

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

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

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

Добавлено: Чт май 12, 2011 12:54:03
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)) {/*набежала секунда - выполняем код считающий секунды*/}
/*тут код динамической индикации*/
Зато не надо постоянно менять регистры таймера

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

Добавлено: Чт май 12, 2011 13:13:49
O-LED
Спасибо.
я думал над таким вариантом, но тогда выйдет что при питании от батарее мы будем иметь в секунду 256 прерываний вместо одного. а это сильно увеличит потребление. :)

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

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

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

static uint8_t issecond=0;
if (!(++issecond)) {/*набежала секунда - выполняем код считающий секунды*/}
/*тут код динамической индикации*/
Зато не надо постоянно менять регистры таймера
в таком то коде похоже можно и T0 обойтись:) - ещё на PWM таймер останется.

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

Добавлено: Чт май 12, 2011 13:28:19
vitalik_1984
O-LED писал(а):Спасибо.
я думал над таким вариантом, но тогда выйдет что при питании от батарее мы будем иметь в секунду 256 прерываний вместо одного. а это сильно увеличит потребление. :)
А слабо при переходе в ждущий режим поменять код?:) (сменить делитель и прерывания)

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

Добавлено: Чт май 12, 2011 13:55:14
O-LED
в таком то коде похоже можно и T0 обойтись:) - ещё на PWM таймер останется.
Да на Т0 уже сделал, эт не проблема.... :) А хоцца только на Т2. :roll:
А слабо при переходе в ждущий режим поменять код?:) (сменить делитель и прерывания)
нет, не слабо. попробую. :beer:

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

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

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

Добавлено: Вс май 15, 2011 16:28:27
Ратмир
Всем привет! Может кто подскажет нашел пример программы для индикатора (7-сегментного) с общим катодом, как переделать прогаммку для индикатора с общим анодом? Я так понимаю, что подаю +5В с обоих сторон.