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

dm37

Members
  • Постов

    252
  • Зарегистрирован

  • Посещение

Электроника

  • Стаж в электронике
    Более 20 лет

Посетители профиля

1 665 просмотров профиля

Достижения dm37

Экспериментатор

Экспериментатор (5/14)

  • Неделя на форуме
  • Месяц на форуме
  • Год на форуме
  • 10 постов на форуме

Последние значки

56

Репутация

Одно обновление статуса

Смотреть все обновления от dm37

  1. ;tv

    Приветствую вас DM37!     Говорите код у вас сработал???  Я обращаюсь к вам с просьбой, подскажите в чем ошибка в моем коде? Однозначно вы что-то скоректировали иначе и у меня она бы заработала. Просмотрите пожалуйста еще раз код, обратите внимание на комментарии и подскажите отличие от вашего рабочего кода.

     

    /*
     * Atmega8_decoder_zvonok.c
     *
     * Created: 14.09.2016 21:42:57
     *  Author: SUN 
     */ 

    #define F_CPU8000000UL                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
    #include <avr/io.h>
    #include <avr/interrupt.h>

    //**********************************************************************8                                                      
                                          
                                            
    void int0_set(void)
    {
    MCUCR &= ~( (1<<ISC11)|(1<<ISC10)|(1<<ISC01)|(1<<ISC00) );   //сбрасываем все биты ISCxx
    MCUCR |= (1<<ISC01)|(1<<ISC00);                              //настраиваем на срабатывание INT0 по переднему фронту
    GICR |= (1<<INT0);                                           //разрешаем глобальное прерывание 
    GIFR|=(1<<INTF0);                                            //опрос вектора на разрешения запрета прерывания
                                                         
    }

    void pauza_set (void)
    {
        TCNT2=50;                    //число/старт отсчета до числа OCR2
        TIMSK|=(1<<OCIE2);          // по совпадению
        OCR2=150;                   // число по совпадению TCNT2=OCR2
        TCCR2|=(1<<WGM21);          // режим CTC;
        TCCR2|=(1<<CS20);           // prescaler                             
    }

     void puls_set(void)
     {
        
        TCNT2=0;                    //число/старт отсчета до числа OCR2    
        TIMSK|=(1<<OCIE2);          // по совпадению
        OCR2=200;                   // число по совпадению TCNT2=OCR2
        TCCR2|=(1<<WGM21);          // режим CTC;
        TCCR2|=(1<<CS20);           // prescaler    
     }
                                                 
    ISR( INT0_vect )
    {                     
        pauza_set ();                   // инициировали и запустили условия pauza_set();        
    }
     
     ISR(TIMER2_COMP_vect)               //при pauza_set=0; т.е. по истечении времени обусловленного pauza_set();
     {
        PORTC|=(1<<1);                   // тестовый импульс на ПИНС0 для контроля срабатывания INT0 (на форуме высказали сомнение)
        PORTC&=~(1<<1);                     //"------------------------------------------------------------------------------------"
        unsigned char pauza;             // инициализация локалной переменной  (иначе ругается)!
        if (!pauza)                      // если pauza=0
        {
            PORTC|=(1<<0);               // лог"1"
            pauza++;                     // pauza=1;
            puls_set();                     // запускаем условия puls_set; (отсчитав обусловленное время, возврашается к условию if)
        } 
        else
        {
            PORTC&=~(1<<0);              // проверив условие if, т.к.pauza=1, сработает условие else. (НЕ СРАБАТЫВАЕТ!!!!)        
        }    
          TCCR2=0;                         
          TIMSK=0;                                                                       
     }
          
    int main(void)
    {  
        DDRD&=0x00;                                       //0;//все пины на вход, в том числе и пин на котором прерывание
        PORTD&=0x00;
        PORTD|=(1<<2);                                    //подтягивоющий резистор.
        DDRB|=0xFF;
        PORTB&=0x00;
        DDRC|=0xFF;
        PORTC&=0x00;
        int0_set();                                         //запустили инициализацию прерывания.
        sei();                                             //глобально разрешили прерывания
        
        while(1)
        {            
                asm("nop");
        }
        
    }
     

     Тут ниже для наглядности картинка с протеуса. INT0-работает, pauza_set(); отрабатывает свое время(ПИНС.1)

     

     

    Снимок.PNG

    1. dm37

      dm37

      Привет,

      ну что сразу бросилось в глаза это

       unsigned char pauza;             // инициализация локалной переменной  (иначе ругается)!

      эта переменная должна определятся как глобальная, т.е. должна быть здесь

       /*
       * Atmega8_decoder_zvonok.c
       *
       * Created: 14.09.2016 21:42:57
       *  Author: SUN 
       */ 
      #define F_CPU8000000UL                                                                                                                             #include <avr/io.h>
      #include <avr/interrupt.h>
      
      //**********************************************************************8                                                      
      volatile unsigned char pausa;

      надо поставить volatile, чтобы компилятор не выбросил операции с этой переменной из кода после оптимизации (так надо поступать со всеми переменными, которые меняются в прерываниях). Когда вы объявили переменную внутри прерывания, да ещё и не присвоили ей значение вы при сравнении в переменной pausa, в лучшем случае будет всегда получать 0, а обычно там разный мусор (т.к. для локальных переменных компилятор старается использовать регистры, которые при этом не инициализирует). Глобальные переменные, по умолчанию, всегда инициализируются 0.

      Попробуйте сначала изменить это, потом дальше посмотрим

      можно немного оптимизировать функции pauza_set() и pulse_set():
      вынести настройку режима CTC (выполнять только один раз в main()), а оставить только настройку задержек, т.е.
      - останавливаем таймер (prescaler = 0)
      - устанавливаем новое значение задержки
      - запускаем таймер

×
×
  • Создать...