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

Arsen

Members
  • Постов

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

  • Посещение

Информация

  • Город
    Симферополь

Электроника

  • Стаж в электронике
    1-2 года

Достижения Arsen

Новичок

Новичок (1/14)

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

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

0

Репутация

  1. тему можно закрывать всё вывел и сигнал на ножку кому надо скину исходник
  2. извините господа модераторы первый раз на этом сайте прошу сильно не пинать новечка
  3. тоесть мне надо помигать ножкой РС4 синхронно с точкой на индикаторе! когда останится менее 7ми секунд до отключения
  4. Доброго времени суток всем! Собираю таймер на меге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 //********************
×
×
  • Создать...