реклама на сайте
подробности

 
 
> tiny13 не выходит из idle по прерыванию
Arvenen
сообщение Jun 1 2008, 17:15
Сообщение #1





Группа: Новичок
Сообщений: 5
Регистрация: 1-06-08
Пользователь №: 37 963



Tiny13 не выходит из idle режима по прерыванию от компаратора таймера, хотя в документации сказано, что он должен выходитьиз него по любому внутреннему или внешнему прерыванию. Подобная проблема у меня была с mega16, но там она как-то сама собой решилась... Компилятор WinAVR... Да, я пишу на Си... Знаю, для микроконтроллеров со столь малым размером памяти программы это не очень хорошо, но ассемблер я не знаю вовсе, так что буду оптимизировать программу, пока она не поместится в память. Вот программа:

Код
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>

#define ADC_VREF_TYPE 0x00

// Вектор прерывания компаратора таймера:
ISR(TIM0_COMPA_vect)
{
    TCNT0 = 0x0;
    
    // Мигание лампочки:
    PORTB ^= 0b00001000;
}

int main(void)
{
    // Начальная инициализация, сгенерирована CodeVisionAVR
    
    // Input/Output Ports initialization
    // Port B initialization
    // Func5=In Func4=In Func3=Out Func2=In Func1=In Func0=In
    // State5=T State4=T State3=0 State2=T State1=T State0=T
    PORTB=0x00;
    DDRB=0x08;

    // Timer/Counter 0 initialization
    // Clock source: System Clock
    // Clock value: 150,000 kHz
    // Mode: Normal top=FFh
    // OC0A output: Disconnected
    // OC0B output: Disconnected
    TCCR0A=0x00;
    TCCR0B=0x03;
    TCNT0=0x00;
    OCR0A=0x99;
    OCR0B=0x00;

    // External Interrupt(s) initialization
    // INT0: Off
    // Interrupt on any change on pins PCINT0-5: Off
    GIMSK=0x00;
    MCUCR=0x00;

    // Timer/Counter 0 Interrupt(s) initialization
    TIMSK0=0x04;

    // Analog Comparator initialization
    // Analog Comparator: Off
    ACSR=0x80;
    ADCSRB=0x00;

    // ADC initialization
    // ADC Clock frequency: 75,000 kHz
    // ADC Bandgap Voltage Reference: Off
    // ADC Auto Trigger Source: None
    // Digital input buffers on ADC0: On, ADC1: On, ADC2: On, ADC3: On
    DIDR0&=0x03;
    DIDR0|=0x00;
    ADMUX=ADC_VREF_TYPE & 0xff;
    ADCSRA=0x8F;

    sei();

    while (1)
    {
        //строки, переводящие контроллер в idle режим
        
        //set_sleep_mode(SLEEP_MODE_IDLE);
        //sleep_mode();    
        
    }
    
    return 0;
}


Так все нормально, лампочка на PB3 начинает подавать признаки жизни, но если раскомментировать строки, переводящие контроллер в idle, то лампочка не загорается... Скажите, пожалуйста, что я делаю не так?

На всякий случай:
Код
Fuses:
  OSCCAL = 5D, 5C
  EESAVE = 1
  WDTON = 1
  CKDIV = 1
  SUT = 2
  CKSEL = 2
  SELFPRGEN = 1
  DWEN = 1
  BODLEVEL = 3
  RSTDISBL = 1
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Arvenen
сообщение Jun 5 2008, 18:26
Сообщение #2





Группа: Новичок
Сообщений: 5
Регистрация: 1-06-08
Пользователь №: 37 963



Цитата
Скажите только, это хекс именно того кода, что приведен в начале темы?

Вот этого обещать не могу... Я там столько раз уже пробовала все поменять... Постаралась вернуть все назад, на всякий случай, вот код на си и соответствующий ему hex:

Код
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <avr/wdt.h>
#include <util/delay.h>

#define ADC_VREF_TYPE 0x00

ISR(TIM0_COMPA_vect)
{
    TCNT0 = 0x0;
    
    PORTB ^= 0b00001000;
}

int main(void)
{
    // Input/Output Ports initialization
    // Port B initialization
    // Func5=In Func4=In Func3=Out Func2=In Func1=In Func0=In
    // State5=T State4=T State3=0 State2=T State1=T State0=T
    PORTB=0x00;
    DDRB=0x08;

    // Timer/Counter 0 initialization
    // Clock source: System Clock
    // Clock value: 150,000 kHz
    // Mode: Normal top=FFh
    // OC0A output: Disconnected
    // OC0B output: Disconnected
    TCCR0A=0x00;
    TCCR0B=0x03;
    TCNT0=0x00;
    OCR0A=0x99;
    OCR0B=0x00;

    // External Interrupt(s) initialization
    // INT0: Off
    // Interrupt on any change on pins PCINT0-5: Off
    GIMSK=0x00;
    MCUCR=0x00;

    // Timer/Counter 0 Interrupt(s) initialization
    TIMSK0=0x04;

    // Analog Comparator initialization
    // Analog Comparator: Off
    ACSR=0x80;
    ADCSRB=0x00;

    // ADC initialization
    // ADC Clock frequency: 75,000 kHz
    // ADC Bandgap Voltage Reference: Off
    // ADC Auto Trigger Source: None
    // Digital input buffers on ADC0: On, ADC1: On, ADC2: On, ADC3: On
    DIDR0&=0x03;
    DIDR0|=0x00;
    ADMUX=ADC_VREF_TYPE & 0xff;
    ADCSRA=0x8F;

    sei();

    while (1)
    {
        set_sleep_mode(SLEEP_MODE_IDLE);
        sleep_mode();    
    }
    
    return 0;
}


Код
:1000000009C022C021C020C01FC01EC01EC01CC00D
:100010001BC01AC011241FBECFE9CDBF10E0A0E65F
:10002000B0E0EEEBF0E003C0C89531960D92A0363B
:10003000B107D1F710E0A0E6B0E001C01D92A036F4
:10004000B107E1F715D03AC0DBCF1F920F920FB680
:100050000F9211248F939F9312BE88B398E0892743
:1000600088BB9F918F910F900FBE0F901F90189596
:1000700018BA88E087BB1FBC83E083BF12BE89E942
:1000800086BF19BC1BBE15BE84E089BF80E888B955
:1000900013B884B3837084BB84B384BB17B88FE870
:1000A00086B9789485B7877E886085BF85B780627A
:0E00B00085BF889585B78F7D85BFF4CFFFCFC4
:00000001FF


И... спасибо вам огромнейшее! Это моя вторая поделка с микроконтроллером... Я правда не знаю, с какого боку можно подойти к решению возникшей проблемы...
Go to the top of the page
 
+Quote Post
smac
сообщение Jun 5 2008, 19:08
Сообщение #3


Частый гость
**

Группа: Участник
Сообщений: 149
Регистрация: 2-06-08
Из: Москва
Пользователь №: 38 003



Цитата(Arvenen @ Jun 5 2008, 22:26) *
Вот этого обещать не могу... Я там столько раз уже пробовала все поменять... Постаралась вернуть все назад, на всякий случай, вот код на си и соответствующий ему hex: ...

И... спасибо вам огромнейшее! Это моя вторая поделка с микроконтроллером... Я правда не знаю, с какого боку можно подойти к решению возникшей проблемы...


Как мне кажется, проблема в прерываниях от АЦП. Согласно хекса ацп установлен в режим непрерывного преобразования, прерывания от ацп разрешены, а программа их обработки в конечном счете совершает переход на адрес 0х000. как я понял, явно обработка прерываний в данном исходнике на С не описана, хотя я могу ошибаться (С я не знаю), тем не менее она происходит. Вполне возможно, что прерывания от АЦП приходят раньше чем от таймера, поэтому таймер просто не успевает вывести МК из режима Слип. Т. Е. из режима слип МК выводят прерывания АЦП, затем таймер переинициализуруется и цикл повторяется.
Как вариант выяснения так ли это, нужно попробовать временно исключить из исходника действия с АЦП и посмотреть выводит ли таймер из режима СЛИП.
Как вариант нужно в исходнике на С изменить строку ADCSRA=0x8F; на ADCSRA=0x83; что запретит прерывания от АЦП, но позволит отслеживать флаг прерываний полингом. В общем я не знаю как описать это на С, но попробуйте предложенный вариант.
Кстати, как я понимаю симптомы того, что МК не выходит из СЛИПА проявляются в отсутствии мигания светодиода, который мигает с малой частотой.
Если это так то проблема скорее всего именна та, что я описал.
Вообще если программа не сложная легче ее на АСМЕ написать, могу взяться если опишете алгоритмы подробно.

З. Ы. Частота мигания светодиода (лампочки) 500 Гц?

Сообщение отредактировал smac - Jun 5 2008, 19:26
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 04:55
Рейтинг@Mail.ru


Страница сгенерированна за 0.01402 секунд с 7
ELECTRONIX ©2004-2016