Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: ШИМ в ATtiny13
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > MCS51, AVR, PIC, STM8, 8bit
dominator
Добрый вечер!

Пытаюсь сделать светящийся кристал, который был не так давно описан на хабре: http://habrahabr.ru/blogs/DIY/111671/ (там код для ATtiny13, снизу страницы ссылки на две другие части описания). Общая идея в том, что при прикосновении человека должен постепенно разгораться светодиод, потом - гаснуть. Все вроде бы просто, исходный код программы есть, но почему-то не работает ШИМ.
Работаю в связке AVR Studio 4.16+WinAVR 2008-12-05+Proteus VSM. При отладке заметил, что при прохождении строки кода TCCR0A=0x83 вместо значения 0х83 (COM0A1, WGM01, WGM00) этому параметру присваивается значение 0х30 (COM0B1, COM0B0). Может, кто подскажет, почему такое может быть? Рад буду любым идеям.

skyled
Про Proteus ничего не скажу, не пользуюсь. Нет смысла. Вы посимулируйте в AVRStudio. Tiny13 симулируется полностью, включая вчдог.
dominator
Цитата(skyled @ Feb 8 2011, 12:07) *
Про Proteus ничего не скажу, не пользуюсь. Нет смысла. Вы посимулируйте в AVRStudio. Tiny13 симулируется полностью, включая вчдог.


Я в так и делаю, просто там еще Proteus прикручен: http://s61.radikal.ru/i174/0903/ef/af557db03d96.jpg. АВРка почему-то неправильно присваивает значение TCCR0A...
skyled
Код
void SetTimer(char Mod)         //Функция для быстрой переинициализации таймера с режима сенсора на ШИМ
{
    if(Mod)            //1,  проверка сенсора
    {    
        TCCR0A=0x00;
        TCCR0B=0x00;
        TCNT0=0x00;
    }
else            //0,  ШИМ
    {
        TCCR0A=0x83;
        TCCR0B=0x00;
        TCNT0=0x00;
    }
}
Это единственное место, где упоминается этот регистр. При (Mod==0) должно присваивать 0x83. А у Вас что? Заново вречную при латинской раскладке наберите строчку и ту же строчку выше.

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

Смените опцию оптимизации.
dominator
Вот часть кода, где происходит сбой
Код
        case M_SENSOR_RECHECK: //проверка сенсора
        cli();        
            Delay++;            
            if(Delay>0x0010) //0x0010    
            {                
                
                if(!CheckSensor())  //проверяем сенсор
                {
                    Mode= M_WAITING_SENSOR; //если не активен - спим
                    Delay=0x0000;
                }
                else
                {    
                    Delay=0x0000;
                    Mode= M_GLOW;    //если активен - начинаем разгораться                
                    SetTimer(0);  //вот здесь TCCR0A присваивается вместо 0x83  значение 0х30
                    PWM=0x00;
                    OCR0A=PWM;
                    TCCR0B|=0x01;                    
                }
            }


Ставил TCCR0A=0x83 в начале программы, устанавливается нормально. Может, есть какой-то связанный с ним параметр, который тоже нужно поменять?

dominator
Цитата(skyled @ Feb 8 2011, 16:27) *
Смените опцию оптимизации.


Спасибо! Поменял оптимизацию с -Os на -O1 значение TCCR0A стало нормально устанавливаться.

Но теперь не работает строчка OCR0A=PWM. OCR0A постоянно равна 0, хотя PWM меняет свое значение. Рад буду любым идеям. Может, кто-то уже сталкивался с чем-то подобным?
dominator
Сюдя по всем проблема возникает после прохождения вот этих строчек кода:
Код
                //Здесь инициализируется вотчдог таймер и режим энергосбережения
                //В процессе отладки пользовался ассемблером, и не стал менять обратно
                //То же самое можно написать и с использованием библиотечных функций
                sei();        
                __asm__ __volatile__("in   r16, 0x21");
                __asm__ __volatile__("ori r16, 0b00011000");
                __asm__ __volatile__("out 0x21 ,r16");
                __asm__ __volatile__("ldi r16, 0b01000111");
                __asm__ __volatile__("out 0x21 ,r16");
                __asm__ __volatile__("ldi r16 ,0b00110000");
                __asm__ __volatile__("out 0x35 ,r16");
                __asm__ __volatile__("sleep");            
                           //сюда мы вернемся уже через 1 секунду, из прерывания

Быть может, кто-то подскажет какие флаги оптимизации должны стоять, чтобы этот код нормально обрабатывался. Сейчас что-то вроде этого:

Код
## Compile options common for all C compilation units.
CFLAGS = $(COMMON)
CFLAGS += -Wall -gdwarf-2 -std=gnu99 -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
CFLAGS += -MD -MP -MT $(*F).o -MF dep/$(@F).d

## Assembly specific flags
ASMFLAGS = $(COMMON)
ASMFLAGS += $(CFLAGS)
ASMFLAGS += -x assembler-with-cpp -Wa,-gdwarf2


dominator
Хм, о чудо. TCCR0A почему-то брал значение из регистра r16, которому в этом коде присваивалось значение 0х30:
Код
                __asm__ __volatile__("ldi r16 ,0b00110000");
                __asm__ __volatile__("out 0x35 ,r16");

Удивительно...
sigmaN
я бы выбросил эти асм вставки на мороз! они там нужны так-же, как зайцу стоп-сигнал )))
dominator
Цитата(sigmaN @ Feb 21 2011, 16:45) *
я бы выбросил эти асм вставки на мороз! они там нужны так-же, как зайцу стоп-сигнал )))


Да, уже выбросил нафик. sm.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.