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

не могу вывести сигнал на ножку PC4


Arsen

Рекомендуемые сообщения

      Доброго времени суток всем! Собираю таймер на меге8 вот этот:  http://c2.at.ua/load/avr/tajmer_na_atmega8/17-1-0-25  прошивка с архива работает идеально,

но когда компилирую текст с исходника полученная прошивка не работает как должно, а именно не выводдится индикация секунд если остаётся менее часа до отключения

и нет сигнала на РС4 когда остаётся 20 секунд до завершения! Индикацию секунд я вывел и сигнал на РС4 тоже только не мигает светодиод ! Помогите!!

Вот собственно код исправленный мною;

/*
 * tim.c
 *
 * Created: 04.04.2017 17:37:57
 *  Author: ARSEN
 */ 


#include <avr/io.h>              // Most basic include files
#include <avr/interrupt.h>       // Add the necessary ones
//#include <avr/signal.h>        // here
//#define __AVR_ATmega8__
#include <avr/pgmspace.h>
#include <string.h>


//******************************************************************************
//  Определение констант
//******************************************************************************
#define IND_PORT  PORTD
#define IND_DDR  DDRD

#define IND_COM PORTB
#define IND_CDDR DDRB
#define IND_PIN PINB

#define IND_CA1   PB1   // Левый индикатор
#define IND_CA2   PB2
#define IND_CA3   PB3
#define IND_CA4   PB4   // Правый

#define KEY_PORT  PORTC
#define KEY_DDR DDRC
#define KEY_PIN PINC

#define KEY_HOURS PC0
#define KEY_MINUTES PC1
#define KEY_RUN PC2
#define KEY_RESET PC3

#define JUMPER PB0      // Джампер, определяющий работу после пропадания питания
#define CHECK_POWER PB5 // Вход для контроля наличия питания

#define SIGNAL_OUT PC4  // Выход для контрольного светодиода или пищалки

#define LOAD   PC5   // Выход управления нагрузкой

// Значения для таймеров
#define T0_VALUE (255-78)

#define KEY_DEBOUNCE 100

// Флаги
#define f_WholeSec 0   // Флаг указывает, что отсчитана целая секунда.
                        // Используется для мигающей точки, переключается
                        // каждые 0.5 секунд
#define f_CountDown 1  // Флаг, указывающий на то, что происходит обратный
                        // отсчет. Используется для гашения ведущих нулей в
                        // индикации часов.
#define f_TimerRunning 2 // Флаг, указывающий на то, что таймер был запущен

#define f_Power 3 // Флаг наличия общего питания

#define f_Signal 4 // Флаг работы сигнализации (звуковой или световой)


#define IND_OA 1  // Общий анод


const unsigned char DIGITS_OA[] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90};

//******************************************************************************
//  Глобальные переменные
//******************************************************************************
//typedef struct {
//   unsigned char Seconds;
//   unsigned char Minutes;
//   unsigned char Hours;
//} time;

//volatile time Time;
volatile unsigned char m_ucSecOnes = 0;
volatile unsigned char m_ucSecTens = 0;

volatile unsigned char m_ucMinOnes = 0;
volatile unsigned char m_ucMinTens = 0;

volatile unsigned char m_ucHrsOnes = 0;
volatile unsigned char m_ucHrsTens = 0;


volatile unsigned char sm_ucIndNum = 0;

volatile unsigned char m_ucFlags = 0;

volatile unsigned char ucKey_Run_Timeout = 0;
volatile unsigned char ucKey_Hours_Timeout = 0;
volatile unsigned char ucKey_Mins_Timeout = 0;


//******************************************************************************
//  Прерывания
//******************************************************************************
// Прерывание по переполнению таймера Т0, здесь мы выводим часы и минуты на
// индикатор, а также опрашиваем кнопки.
ISR(TIMER0_OVF_vect, ISR_NOBLOCK){ // Разрешены вложенные прервания
volatile unsigned char ucTemp = 0;  //


//volatile unsigned char ucKey_Run_Timeout;
   TCNT0 = T0_VALUE; // Перезагрузка таймера
   sm_ucIndNum++;
       if (sm_ucIndNum > 3){
          sm_ucIndNum = 0;
        }
    IND_COM &= ~((1<<IND_CA1)|(1<<IND_CA2)|(1<<IND_CA3)|(1<<IND_CA4));
    IND_PORT = 0xFF;
   // Во время работы таймера, когда идет отсчет, убираем ведущие ноли.
   // Если пропало питание (очищен флаг питания) индикация отключена
     
   switch (sm_ucIndNum){
      case 0:  {IND_COM |= (1<<IND_CA1);  // Индикация десятков часов
                ucTemp = DIGITS_OA[m_ucHrsTens];
                break;}
      case 1:  {IND_COM |= (1<<IND_CA2);  // Индикация единиц часов
                ucTemp = DIGITS_OA[m_ucHrsOnes];
                // Здесь мы мигаем точкой! если таймер запущен
                if (m_ucFlags & (1 << f_TimerRunning))
                if (m_ucFlags & (1 << f_WholeSec)){
                    ucTemp &= 0x7F;
                }
                break;}
      case 2:  {IND_COM |= (1<<IND_CA3);  // Индикация десятков минут
                ucTemp = DIGITS_OA[m_ucMinTens];
                break;}
      case 3:  {IND_COM |= (1<<IND_CA4);  // Индикация единиц минут
                ucTemp = DIGITS_OA[m_ucMinOnes];
                break;}
   
   }   
                     // А это мои изменения
                if (m_ucFlags & (1 << f_TimerRunning)){                            // Если таймер запущен  
   if(( m_ucHrsOnes<1)&&( m_ucHrsTens==0 )){ // и осталось менее одного часа,
                 switch (sm_ucIndNum){           // то на индикаторы выодятся минуты и секунды, индикатор приобретает форму формата ММ.СС 
      case 0:  {IND_COM |= (1<<IND_CA1);  // Индикация десятков минут
                ucTemp = DIGITS_OA[m_ucMinTens];
                break;}
      case 1:  {IND_COM |= (1<<IND_CA2);  // Индикация единиц минут
                ucTemp = DIGITS_OA[m_ucMinOnes];
                // Здесь мы мигаем точкой!
                if (m_ucFlags & (1 << f_TimerRunning)) // если таймер запушен
                if (m_ucFlags & (1 << f_WholeSec)){    // то мигаем точкой
                    ucTemp &= 0x7F;
                }
                break;}
      case 2:  {IND_COM |= (1<<IND_CA3);  // Индикация десятков секунд
                ucTemp = DIGITS_OA[m_ucSecTens];
                break;}
      case 3:  {IND_COM |= (1<<IND_CA4);  // Индикация единиц секунд
                ucTemp = DIGITS_OA[m_ucSecOnes];
                break;}
                 }
   }                            
   }                
                
                                                 
   
   if (IND_PIN & (1 << CHECK_POWER)){    // Если пропало питание
       IND_PORT = ucTemp;
    }
    else{
        IND_PORT = 0xFF;                 // отключаем индикацию
    }

   // Опрос кнопки Пуск/Пауза (KEY_RUN)
   if((m_ucSecOnes==0)&&(m_ucSecTens==0)&&(m_ucMinOnes==0)&&(m_ucMinTens==0)&&(m_ucHrsOnes==0)&&(m_ucHrsTens==0)){
       m_ucFlags &= ~(1 << f_CountDown);
       m_ucFlags &= ~(1 << f_TimerRunning);
      KEY_PORT &= ~(1 << LOAD);
     KEY_PORT&=~(1 << SIGNAL_OUT);} 
   if (!(KEY_PIN & (1 << KEY_RUN))){
      if (ucKey_Run_Timeout == 0){
         // Установка флага работы таймера
         // Этот флаг служит для блокировки кнопок и очищается
         // в обработчике прерывания таймера Т2
         m_ucFlags ^= (1 << f_CountDown);
         m_ucFlags |= (1 << f_TimerRunning);
         ucKey_Run_Timeout = 2*KEY_DEBOUNCE;
         // Устанавливаем флаг питания
         m_ucFlags |= (1 << f_Power);

         // Переключаем нагрузку
         if (m_ucFlags & (1 << f_CountDown)) KEY_PORT |= (1 << LOAD); 
         else KEY_PORT &= ~(1 << LOAD);
         
         KEY_PORT&=~(1 << SIGNAL_OUT);
      }
   }
   // Опрос кнопки настройки Часов
   // Только если не установлен флаг работы таймера
   if (!(m_ucFlags & (1 << f_TimerRunning))){
      if (!(KEY_PIN & (1 << KEY_HOURS))){
         if (ucKey_Hours_Timeout == 0){
            m_ucHrsOnes ++;
            if (m_ucHrsOnes > 9){
               m_ucHrsOnes = 0;
               m_ucHrsTens ++;
               if (m_ucHrsTens > 9) m_ucHrsTens = 0;
            }
            ucKey_Hours_Timeout = KEY_DEBOUNCE;
         }
      }
   }

   // Опрос кнопки настройки минут
   // Те же условия
   if (!(m_ucFlags & (1 << f_TimerRunning))){
      if (!(KEY_PIN & (1 << KEY_MINUTES))){
         if (ucKey_Mins_Timeout == 0){
            m_ucMinOnes ++;
            if (m_ucMinOnes > 9){
               m_ucMinOnes = 0;
               m_ucMinTens++;
               if (m_ucMinTens > 5) m_ucMinTens = 0;
            }
            ucKey_Mins_Timeout = KEY_DEBOUNCE;
         }
      }
   }

   // Опрос кнопки останова таймера
   if (!(KEY_PIN & (1 << KEY_RESET))){
      m_ucFlags &= ~(1 << f_CountDown);   // Очистка флагов
      m_ucFlags &= ~(1 << f_TimerRunning);
      KEY_PORT&=~(1 << SIGNAL_OUT); // отключаем сигнал с РС4
      
      m_ucHrsTens = 0; // это тоже мои изменения если нажать на сброс то очищаем и время
      m_ucHrsOnes = 0;
      m_ucMinTens = 0;
      m_ucMinOnes = 0;
      m_ucSecTens = 0;
      m_ucSecOnes = 0;
      // Отключаем нагрузку
      KEY_PORT &= ~(1 << LOAD);
      //

   }

   // Проверка наличия питания проводится только, если таймер в работе
   if (m_ucFlags & (1 << f_TimerRunning)){
   if (IND_PIN & (1 << CHECK_POWER)){ // power ok
      // Проверяем состояние джампера
      // и в зависимости от состояния флага питания делаем следующее
      if (!(m_ucFlags & (1 << f_Power))){ // Если питание пропадало
         if (IND_PIN & (1 << JUMPER)){
            // Если джампер не замкнут Останавливаем отсчет
            // нагрузка отключена
            m_ucFlags &= ~(1 << f_CountDown);
            KEY_PORT &= ~(1 << LOAD);
         }
         else{
            // Если джампер замкнут на 0
            // Продолжаем отсчет, включаем нагрузку
            m_ucFlags |= (1 << f_CountDown);
            KEY_PORT |= (1 << LOAD);
         }
         // Снова выставляем флаг, что с питанием все ок.
         if (IND_PIN & (1 << CHECK_POWER))
            m_ucFlags |= (1 << f_Power);
      }
   }
   else{ //power fail
      m_ucFlags &= ~(1 << f_Power);
      // Отключаем нагрузку
      KEY_PORT &= ~(1 << LOAD);
      // Выставляем флаг паузы отсчета
      m_ucFlags &= ~(1 << f_CountDown);
   }
   }

   if (ucKey_Run_Timeout > 0) ucKey_Run_Timeout--;
   if (ucKey_Hours_Timeout > 0) ucKey_Hours_Timeout--;
   if (ucKey_Mins_Timeout > 0) ucKey_Mins_Timeout--;

 
}


// Таймер Т2 работает все время, останавливается или запускается
// только отсчет времени.
// Прерывание по переполнению таймера Т2
ISR(TIMER2_OVF_vect){
    
 
 
 // сбрасываем счетный регистр таймера/счетчика T0

        
      
        
            
    
   m_ucFlags ^= (1 << f_WholeSec); // Переключаем флаг
if (m_ucFlags & (1 << f_CountDown)){
   if (m_ucFlags & (1<<f_WholeSec)){
       
     if((m_ucSecOnes==7)&&( m_ucSecTens==0)&&( m_ucMinOnes==0)&&( m_ucMinTens==0)&&( m_ucHrsOnes==0)&&( m_ucHrsTens==0 ))
KEY_PORT|=(1 << SIGNAL_OUT);          // здесь мы выводим сигнал на порт PC4 когда остаётся менее 7ми секунд до отключения
      
      m_ucSecOnes --;
      if (m_ucSecOnes > 9){
         m_ucSecOnes = 9;
         m_ucSecTens --;
         if (m_ucSecTens > 5){
            m_ucSecTens = 5;
            m_ucMinOnes --;
            if (m_ucMinOnes > 9){
               m_ucMinOnes = 9;
               m_ucMinTens --;
               if (m_ucMinTens > 5){
                  m_ucMinTens = 5;
                  m_ucHrsOnes --;
                  if(m_ucHrsOnes > 9){
                    m_ucHrsOnes = 9;
                     m_ucHrsTens --;
                     if(m_ucHrsTens > 9){
                                             // Здесь мы дошли до конца отсчета
                        m_ucHrsTens = 0;
                        m_ucHrsOnes = 0;
                        m_ucMinTens = 0;
                        m_ucMinOnes = 0;
                        m_ucSecTens = 0;
                        m_ucSecOnes = 0;
                        // Очищаем флаг отсчета
                        m_ucFlags &= ~(1 << f_CountDown);
                        m_ucFlags &= ~(1 << f_TimerRunning);
                        
                        KEY_PORT &= ~(1 << LOAD);    // отключаем нагрузку
                       KEY_PORT&=~(1 << SIGNAL_OUT); // отключаем сигнал РС4                  
                                                                                                           
                     }                                                 
                     }                  
               }
            }
         }
      }
   }
}
};

//******************************************************************************
//  Функции
//******************************************************************************


//******************************************************************************
//  Main program
//******************************************************************************

int main(void) {
   //***************************************************************************
   // Инициализация периферии
   //***************************************************************************

//int temp0, temp1;

   // Настройка порта для сегментов индикатора
   #ifdef IND_OA
      IND_PORT = 0xFF;
   #else
      IND_PORT = 0x00;
   #endif
   IND_DDR = 0xFF;
   // Настройка порта для общих выводов индикатора
   IND_CDDR = 0x00;
   IND_COM = 0x00;

   IND_CDDR = (1<<IND_CA1)|(1<<IND_CA2)|(1<<IND_CA3)|(1<<IND_CA4);
   IND_COM |= (1<<JUMPER)|(1<<CHECK_POWER)|(0<<IND_CA1)|(0<<IND_CA2)|(0<<IND_CA3)|(0<<IND_CA4);

   // Настройка порта для кнопок
   KEY_DDR &= ~((1<<KEY_HOURS)|(1<<KEY_MINUTES)|(1<<KEY_RUN)|(1<<KEY_RESET)); // input
   KEY_DDR |= (1<<SIGNAL_OUT)|(1<<LOAD);  // output
   KEY_PORT |=(1<<KEY_HOURS)|(1<<KEY_MINUTES)|(1<<KEY_RUN)|(1<<KEY_RESET);

   // Настройка таймера Т2, который работает в Асинхронном режиме
   // и тактируется от часового кварца на 32768 Гц
///// Ждем пока не стабилизируется работа внешнего кварца
//   for(temp0=0;temp0<0x0040;temp0++)   // Wait for external clock crystal to stabilize
//   {
//       for(temp1=0;temp1<0xFFFF;temp1++);
//   }
   TIMSK &=~((1<<TOIE2)|(1<<OCIE2));   // Запрещаем TC2 прерывания
   ASSR |= (1<<AS2);                   // Режим таймера - асинхронный
                                       // тактирование от внешн. кварца (32,768kHz)
   while (ASSR & (1 << TCN2UB)){};
   TCNT2 = 0x00;
   while (ASSR & (1 << TCR2UB)){};
   TCCR2 = 0x04;           //Делитель таймера / 64 для получения
                           // переполнения каждые 0.5 секунд

   TIMSK |= (1<<TOIE2);        //set 8-bit Timer/Counter2 Overflow Interrupt Enable
////////

   // Настройка таймера Т0, который используется для динамической индикации
   // и опроса кнопок. МК работает на частоте 1 МГц без внешнего кварца
   // Загрузка регистра таймера Т0
   TCNT0 = T0_VALUE;
   // Разрешение прерываний по переполнению таймера Т0
   TIMSK |= (1<<TOIE0);
   // Пуск таймера Т0
   TCCR0 = (0<<CS02)|(1<<CS01)|(1<<CS00);

   // Разрешение глобальных прерываний
   sei();
   while(1) {             // Infinite loop; define here the
      asm ("nop");                       // system behaviour
   }

}

//******************************************************************************
//  END of File
//********************

Ссылка на комментарий
Поделиться на другие сайты

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

1 час назад, Arsen сказал:

      Доброго времени суток всем! Собираю таймер на меге8 вот этот:  http://c2.at.ua/load/avr/tajmer_na_atmega8/17-1-0-25  прошивка с архива работает идеально,

но когда компилирую текст с исходника полученная прошивка не работает как должно, а именно не выводдится индикация секунд если остаётся менее часа до отключения

и нет сигнала на РС4 когда остаётся 20 секунд до завершения! Индикацию секунд я вывел и сигнал на РС4 тоже только не мигает светодиод ! Помогите!!

Вот собственно код исправленный мною;

/*
 * tim.c
 *
 * Created: 04.04.2017 17:37:57
 *  Author: ARSEN
 */ 


#include <avr/io.h>              // Most basic include files
#include <avr/interrupt.h>       // Add the necessary ones
//#include <avr/signal.h>        // here
//#define __AVR_ATmega8__
#include <avr/pgmspace.h>
#include <string.h>


//******************************************************************************
//  Определение констант
//******************************************************************************
#define IND_PORT  PORTD
#define IND_DDR  DDRD

#define IND_COM PORTB
#define IND_CDDR DDRB
#define IND_PIN PINB

#define IND_CA1   PB1   // Левый индикатор
#define IND_CA2   PB2
#define IND_CA3   PB3
#define IND_CA4   PB4   // Правый

#define KEY_PORT  PORTC
#define KEY_DDR DDRC
#define KEY_PIN PINC

#define KEY_HOURS PC0
#define KEY_MINUTES PC1
#define KEY_RUN PC2
#define KEY_RESET PC3

#define JUMPER PB0      // Джампер, определяющий работу после пропадания питания
#define CHECK_POWER PB5 // Вход для контроля наличия питания

#define SIGNAL_OUT PC4  // Выход для контрольного светодиода или пищалки

#define LOAD   PC5   // Выход управления нагрузкой

// Значения для таймеров
#define T0_VALUE (255-78)

#define KEY_DEBOUNCE 100

// Флаги
#define f_WholeSec 0   // Флаг указывает, что отсчитана целая секунда.
                        // Используется для мигающей точки, переключается
                        // каждые 0.5 секунд
#define f_CountDown 1  // Флаг, указывающий на то, что происходит обратный
                        // отсчет. Используется для гашения ведущих нулей в
                        // индикации часов.
#define f_TimerRunning 2 // Флаг, указывающий на то, что таймер был запущен

#define f_Power 3 // Флаг наличия общего питания

#define f_Signal 4 // Флаг работы сигнализации (звуковой или световой)


#define IND_OA 1  // Общий анод


const unsigned char DIGITS_OA[] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90};

//******************************************************************************
//  Глобальные переменные
//******************************************************************************
//typedef struct {
//   unsigned char Seconds;
//   unsigned char Minutes;
//   unsigned char Hours;
//} time;

//volatile time Time;
volatile unsigned char m_ucSecOnes = 0;
volatile unsigned char m_ucSecTens = 0;

volatile unsigned char m_ucMinOnes = 0;
volatile unsigned char m_ucMinTens = 0;

volatile unsigned char m_ucHrsOnes = 0;
volatile unsigned char m_ucHrsTens = 0;


volatile unsigned char sm_ucIndNum = 0;

volatile unsigned char m_ucFlags = 0;

volatile unsigned char ucKey_Run_Timeout = 0;
volatile unsigned char ucKey_Hours_Timeout = 0;
volatile unsigned char ucKey_Mins_Timeout = 0;


//******************************************************************************
//  Прерывания
//******************************************************************************
// Прерывание по переполнению таймера Т0, здесь мы выводим часы и минуты на
// индикатор, а также опрашиваем кнопки.
ISR(TIMER0_OVF_vect, ISR_NOBLOCK){ // Разрешены вложенные прервания
volatile unsigned char ucTemp = 0;  //


//volatile unsigned char ucKey_Run_Timeout;
   TCNT0 = T0_VALUE; // Перезагрузка таймера
   sm_ucIndNum++;
       if (sm_ucIndNum > 3){
          sm_ucIndNum = 0;
        }
    IND_COM &= ~((1<<IND_CA1)|(1<<IND_CA2)|(1<<IND_CA3)|(1<<IND_CA4));
    IND_PORT = 0xFF;
   // Во время работы таймера, когда идет отсчет, убираем ведущие ноли.
   // Если пропало питание (очищен флаг питания) индикация отключена
     
   switch (sm_ucIndNum){
      case 0:  {IND_COM |= (1<<IND_CA1);  // Индикация десятков часов
                ucTemp = DIGITS_OA[m_ucHrsTens];
                break;}
      case 1:  {IND_COM |= (1<<IND_CA2);  // Индикация единиц часов
                ucTemp = DIGITS_OA[m_ucHrsOnes];
                // Здесь мы мигаем точкой! если таймер запущен
                if (m_ucFlags & (1 << f_TimerRunning))
                if (m_ucFlags & (1 << f_WholeSec)){
                    ucTemp &= 0x7F;
                }
                break;}
      case 2:  {IND_COM |= (1<<IND_CA3);  // Индикация десятков минут
                ucTemp = DIGITS_OA[m_ucMinTens];
                break;}
      case 3:  {IND_COM |= (1<<IND_CA4);  // Индикация единиц минут
                ucTemp = DIGITS_OA[m_ucMinOnes];
                break;}
   
   }   
                     // А это мои изменения
                if (m_ucFlags & (1 << f_TimerRunning)){                            // Если таймер запущен  
   if(( m_ucHrsOnes<1)&&( m_ucHrsTens==0 )){ // и осталось менее одного часа,
                 switch (sm_ucIndNum){           // то на индикаторы выодятся минуты и секунды, индикатор приобретает форму формата ММ.СС 
      case 0:  {IND_COM |= (1<<IND_CA1);  // Индикация десятков минут
                ucTemp = DIGITS_OA[m_ucMinTens];
                break;}
      case 1:  {IND_COM |= (1<<IND_CA2);  // Индикация единиц минут
                ucTemp = DIGITS_OA[m_ucMinOnes];
                // Здесь мы мигаем точкой!
                if (m_ucFlags & (1 << f_TimerRunning)) // если таймер запушен
                if (m_ucFlags & (1 << f_WholeSec)){    // то мигаем точкой
                    ucTemp &= 0x7F;
                }
                break;}
      case 2:  {IND_COM |= (1<<IND_CA3);  // Индикация десятков секунд
                ucTemp = DIGITS_OA[m_ucSecTens];
                break;}
      case 3:  {IND_COM |= (1<<IND_CA4);  // Индикация единиц секунд
                ucTemp = DIGITS_OA[m_ucSecOnes];
                break;}
                 }
   }                            
   }                
                
                                                 
   
   if (IND_PIN & (1 << CHECK_POWER)){    // Если пропало питание
       IND_PORT = ucTemp;
    }
    else{
        IND_PORT = 0xFF;                 // отключаем индикацию
    }

   // Опрос кнопки Пуск/Пауза (KEY_RUN)
   if((m_ucSecOnes==0)&&(m_ucSecTens==0)&&(m_ucMinOnes==0)&&(m_ucMinTens==0)&&(m_ucHrsOnes==0)&&(m_ucHrsTens==0)){
       m_ucFlags &= ~(1 << f_CountDown);
       m_ucFlags &= ~(1 << f_TimerRunning);
      KEY_PORT &= ~(1 << LOAD);
     KEY_PORT&=~(1 << SIGNAL_OUT);} 
   if (!(KEY_PIN & (1 << KEY_RUN))){
      if (ucKey_Run_Timeout == 0){
         // Установка флага работы таймера
         // Этот флаг служит для блокировки кнопок и очищается
         // в обработчике прерывания таймера Т2
         m_ucFlags ^= (1 << f_CountDown);
         m_ucFlags |= (1 << f_TimerRunning);
         ucKey_Run_Timeout = 2*KEY_DEBOUNCE;
         // Устанавливаем флаг питания
         m_ucFlags |= (1 << f_Power);

         // Переключаем нагрузку
         if (m_ucFlags & (1 << f_CountDown)) KEY_PORT |= (1 << LOAD); 
         else KEY_PORT &= ~(1 << LOAD);
         
         KEY_PORT&=~(1 << SIGNAL_OUT);
      }
   }
   // Опрос кнопки настройки Часов
   // Только если не установлен флаг работы таймера
   if (!(m_ucFlags & (1 << f_TimerRunning))){
      if (!(KEY_PIN & (1 << KEY_HOURS))){
         if (ucKey_Hours_Timeout == 0){
            m_ucHrsOnes ++;
            if (m_ucHrsOnes > 9){
               m_ucHrsOnes = 0;
               m_ucHrsTens ++;
               if (m_ucHrsTens > 9) m_ucHrsTens = 0;
            }
            ucKey_Hours_Timeout = KEY_DEBOUNCE;
         }
      }
   }

   // Опрос кнопки настройки минут
   // Те же условия
   if (!(m_ucFlags & (1 << f_TimerRunning))){
      if (!(KEY_PIN & (1 << KEY_MINUTES))){
         if (ucKey_Mins_Timeout == 0){
            m_ucMinOnes ++;
            if (m_ucMinOnes > 9){
               m_ucMinOnes = 0;
               m_ucMinTens++;
               if (m_ucMinTens > 5) m_ucMinTens = 0;
            }
            ucKey_Mins_Timeout = KEY_DEBOUNCE;
         }
      }
   }

   // Опрос кнопки останова таймера
   if (!(KEY_PIN & (1 << KEY_RESET))){
      m_ucFlags &= ~(1 << f_CountDown);   // Очистка флагов
      m_ucFlags &= ~(1 << f_TimerRunning);
      KEY_PORT&=~(1 << SIGNAL_OUT); // отключаем сигнал с РС4
      
      m_ucHrsTens = 0; // это тоже мои изменения если нажать на сброс то очищаем и время
      m_ucHrsOnes = 0;
      m_ucMinTens = 0;
      m_ucMinOnes = 0;
      m_ucSecTens = 0;
      m_ucSecOnes = 0;
      // Отключаем нагрузку
      KEY_PORT &= ~(1 << LOAD);
      //

   }

   // Проверка наличия питания проводится только, если таймер в работе
   if (m_ucFlags & (1 << f_TimerRunning)){
   if (IND_PIN & (1 << CHECK_POWER)){ // power ok
      // Проверяем состояние джампера
      // и в зависимости от состояния флага питания делаем следующее
      if (!(m_ucFlags & (1 << f_Power))){ // Если питание пропадало
         if (IND_PIN & (1 << JUMPER)){
            // Если джампер не замкнут Останавливаем отсчет
            // нагрузка отключена
            m_ucFlags &= ~(1 << f_CountDown);
            KEY_PORT &= ~(1 << LOAD);
         }
         else{
            // Если джампер замкнут на 0
            // Продолжаем отсчет, включаем нагрузку
            m_ucFlags |= (1 << f_CountDown);
            KEY_PORT |= (1 << LOAD);
         }
         // Снова выставляем флаг, что с питанием все ок.
         if (IND_PIN & (1 << CHECK_POWER))
            m_ucFlags |= (1 << f_Power);
      }
   }
   else{ //power fail
      m_ucFlags &= ~(1 << f_Power);
      // Отключаем нагрузку
      KEY_PORT &= ~(1 << LOAD);
      // Выставляем флаг паузы отсчета
      m_ucFlags &= ~(1 << f_CountDown);
   }
   }

   if (ucKey_Run_Timeout > 0) ucKey_Run_Timeout--;
   if (ucKey_Hours_Timeout > 0) ucKey_Hours_Timeout--;
   if (ucKey_Mins_Timeout > 0) ucKey_Mins_Timeout--;

 
}


// Таймер Т2 работает все время, останавливается или запускается
// только отсчет времени.
// Прерывание по переполнению таймера Т2
ISR(TIMER2_OVF_vect){
    
 
 
 // сбрасываем счетный регистр таймера/счетчика T0

        
      
        
            
    
   m_ucFlags ^= (1 << f_WholeSec); // Переключаем флаг
if (m_ucFlags & (1 << f_CountDown)){
   if (m_ucFlags & (1<<f_WholeSec)){
       
     if((m_ucSecOnes==7)&&( m_ucSecTens==0)&&( m_ucMinOnes==0)&&( m_ucMinTens==0)&&( m_ucHrsOnes==0)&&( m_ucHrsTens==0 ))
KEY_PORT|=(1 << SIGNAL_OUT);          // здесь мы выводим сигнал на порт PC4 когда остаётся менее 7ми секунд до отключения
      
      m_ucSecOnes --;
      if (m_ucSecOnes > 9){
         m_ucSecOnes = 9;
         m_ucSecTens --;
         if (m_ucSecTens > 5){
            m_ucSecTens = 5;
            m_ucMinOnes --;
            if (m_ucMinOnes > 9){
               m_ucMinOnes = 9;
               m_ucMinTens --;
               if (m_ucMinTens > 5){
                  m_ucMinTens = 5;
                  m_ucHrsOnes --;
                  if(m_ucHrsOnes > 9){
                    m_ucHrsOnes = 9;
                     m_ucHrsTens --;
                     if(m_ucHrsTens > 9){
                                             // Здесь мы дошли до конца отсчета
                        m_ucHrsTens = 0;
                        m_ucHrsOnes = 0;
                        m_ucMinTens = 0;
                        m_ucMinOnes = 0;
                        m_ucSecTens = 0;
                        m_ucSecOnes = 0;
                        // Очищаем флаг отсчета
                        m_ucFlags &= ~(1 << f_CountDown);
                        m_ucFlags &= ~(1 << f_TimerRunning);
                        
                        KEY_PORT &= ~(1 << LOAD);    // отключаем нагрузку
                       KEY_PORT&=~(1 << SIGNAL_OUT); // отключаем сигнал РС4                  
                                                                                                           
                     }                                                 
                     }                  
               }
            }
         }
      }
   }
}
};

//******************************************************************************
//  Функции
//******************************************************************************


//******************************************************************************
//  Main program
//******************************************************************************

int main(void) {
   //***************************************************************************
   // Инициализация периферии
   //***************************************************************************

//int temp0, temp1;

   // Настройка порта для сегментов индикатора
   #ifdef IND_OA
      IND_PORT = 0xFF;
   #else
      IND_PORT = 0x00;
   #endif
   IND_DDR = 0xFF;
   // Настройка порта для общих выводов индикатора
   IND_CDDR = 0x00;
   IND_COM = 0x00;

   IND_CDDR = (1<<IND_CA1)|(1<<IND_CA2)|(1<<IND_CA3)|(1<<IND_CA4);
   IND_COM |= (1<<JUMPER)|(1<<CHECK_POWER)|(0<<IND_CA1)|(0<<IND_CA2)|(0<<IND_CA3)|(0<<IND_CA4);

   // Настройка порта для кнопок
   KEY_DDR &= ~((1<<KEY_HOURS)|(1<<KEY_MINUTES)|(1<<KEY_RUN)|(1<<KEY_RESET)); // input
   KEY_DDR |= (1<<SIGNAL_OUT)|(1<<LOAD);  // output
   KEY_PORT |=(1<<KEY_HOURS)|(1<<KEY_MINUTES)|(1<<KEY_RUN)|(1<<KEY_RESET);

   // Настройка таймера Т2, который работает в Асинхронном режиме
   // и тактируется от часового кварца на 32768 Гц
///// Ждем пока не стабилизируется работа внешнего кварца
//   for(temp0=0;temp0<0x0040;temp0++)   // Wait for external clock crystal to stabilize
//   {
//       for(temp1=0;temp1<0xFFFF;temp1++);
//   }
   TIMSK &=~((1<<TOIE2)|(1<<OCIE2));   // Запрещаем TC2 прерывания
   ASSR |= (1<<AS2);                   // Режим таймера - асинхронный
                                       // тактирование от внешн. кварца (32,768kHz)
   while (ASSR & (1 << TCN2UB)){};
   TCNT2 = 0x00;
   while (ASSR & (1 << TCR2UB)){};
   TCCR2 = 0x04;           //Делитель таймера / 64 для получения
                           // переполнения каждые 0.5 секунд

   TIMSK |= (1<<TOIE2);        //set 8-bit Timer/Counter2 Overflow Interrupt Enable
////////

   // Настройка таймера Т0, который используется для динамической индикации
   // и опроса кнопок. МК работает на частоте 1 МГц без внешнего кварца
   // Загрузка регистра таймера Т0
   TCNT0 = T0_VALUE;
   // Разрешение прерываний по переполнению таймера Т0
   TIMSK |= (1<<TOIE0);
   // Пуск таймера Т0
   TCCR0 = (0<<CS02)|(1<<CS01)|(1<<CS00);

   // Разрешение глобальных прерываний
   sei();
   while(1) {             // Infinite loop; define here the
      asm ("nop");                       // system behaviour
   }

}

//******************************************************************************
//  END of File
//********************

тоесть мне надо помигать ножкой РС4 синхронно с точкой на индикаторе! когда останится менее 7ми секунд до отключения

Ссылка на комментарий
Поделиться на другие сайты

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов

 Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Присоединяйтесь к обсуждению

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

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
  • Сообщения

    • Сабсоник 3 порядка потом усилитель на Оу. Далее все на столе отстроить и все 
    • Вот и я думаю сделать на сдвоенном операционнике входной усилитель и сабсоник. 
    • Я всегда подозревал, что эта схема была содрана кЕтайцами с какого-то старого и хорошо известного (но не у нас) блока питания, и что в оригинале использовались именно 741 операционники. И вот тому подтверждение... Все равно те микросхемы и транзисторы что они используют в наборах, чаще всего подделки. Мне например, пришлось заменить D1047 транзистор что шел в наборе на пару таких же, но нормальных (выдраных с дохлого усилка). Транзистор из набора (маркировка явно "левая", без какого-либо намека на изготовителя) сильно грелся даже на 1,5А. Такой же транзистор D1047, но из усилка грелся раза в два меньше, да и маркировка "нормальная".  Подозреваю что и TL081 что в наборе идут тоже возможно что перемаркированные 741 (они супердешевые, сравнимо с 358). 741 операционники выпускали все кому не лень, аналогов было выпущено очень много за полвека.  Были и на плюс-минус 22в, надо смотреть конкретный даташит и производителя, даже от буквы в конце это зависит.  Например, есть такой аналог uA741 от ST ("микро-А741"). ua741-957400.pdf ua741.pdf MA741.PDF
    • Нет. Эта модель TRI для 3фаз. Да и вся разводка сделана для 3х фаз. EVOLUTION Mono ➞ 1~ 230V ± 10% 50/60Гц EVOLUTION Tri ➞ 3~ 400V ± 10% 50/60Гц В конце второй минуты есть внутренности, подключение и включение пульта. Можно заметить, что платы идентичные. 
    • У меня такой усь был, он никакой. 
    • Приветствую , вопрос по светодиодам HL5-10 .  В схеме они по 1.65в каждый , автор на вегалабе упомянул суммарное напряжение в каждом плече 4.7в и что допустимо применение стабилитронов.   Вопрос какое напряжение допустимо и за что отвечает? В наличии светики только 1.7в.  Насколько оправданно установка стабилитронов ?  Схему прилагаю
    • Привет народ! В общем оставил на балконе в том виде, только как писали панели параллельно соединил. Сейчас солнце жарит и все работает) Отдельно аттини85 купил, только не понятно какой стороной в тот программатор пихать её.
×
×
  • Создать...