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

Работа с T/C2


;tv

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

 

 

 

 

 

                                   Приветствую вас! 

                       Пытаюсь подружиться с таймером, не поддается . Для примера поставил себе задачу,   при прерывании INT0 сделать паузу, т.е. установить  лог"0" на ПИНС0,  при прерывании по        совпадению (TCNT=OCR)  установить  ПИНС0 в  лог "1",  и сохранять ее до следующего прерывания по совпадению.

Код  не работает в части инициализации установки и сохранения лог"1".   Подскажите пожалуйста ошибку!    Среда ATMEL STUDIO 6.   Камень  Atmega8   Язык  "СИ".

 

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

#define F_CPU1000000UL                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
#include <avr/io.h>
#include <avr/interrupt.h>
volatile unsigned char zero,one;
//**********************************************************************8                                                      
                                      
                                        
void int_set(void)
{
MCUCR &= ~( (1<<ISC11)|(1<<ISC10)|(1<<ISC01)|(1<<ISC00) );   //сбрасываем все биты ISCxx
MCUCR |= (1<<ISC01)|(1<<ISC00);                              //настраиваем на срабатывание INT0 по переднему фронту
GICR |= (1<<INT0);                                           //разрешаем глобальное прерывание 
}                                        
ISR( INT0_vect )
{
    PORTC&=~(1<<0);                  //  установили ПИНС0 в лог"0"
    pauza_set ();                   //    инициировали и запустили условия pauza_set();
}

void pauza_set (void)
{
    zero=5;                     //  условие для истины в if
    TCNT2=0;                  //число/старт отсчета до числа OCR2
    TCCR2|=(1<<WGM21);         // режим CTC;
    TCCR2|=(1<<CS20);          // prescaler
    TIMSK|=(1<<OCIE2);         // по совпадению
    OCR2=250;                   // число по совпадению TCNT2=OCR2
    asm("sei");                // глобальное прерывание
    
}
 
 void puls_set(void)
 {
     one=5;                    // условие для истины в if
    TCNT2=0;                  //число/старт отсчета до числа OCR2
    TCCR2|=(1<<WGM21);         // режим CTC;
    TCCR2|=(1<<CS20);          // prescaler
    TIMSK|=(1<<OCIE2);         // по совпадению
    OCR2=250;                   // число по совпадению TCNT2=OCR2
    asm("sei");                // глобальное прерывание
    
     
 }
 ISR(TIMER2_COMP_vect)
 {
     if (zero==5)                   // условие истины при котором запускается условие void pauza_set (void)
     {
         
         TCCR2=0;                   // 
         TIMSK=0;                    //
         puls_set ();               // инициализация и запуск условия puls_set (); !!!!!!!!!!!!!!!  НЕ ЗАПУСКАЕТСЯ !!!!!!!!!!!!!!!!!!!!!!!!!
         PORTC|=(1<<0);             //  начало импульса /  старт лог"1"
     }
     
     if (one==5);                     // условие истины при котором запускается условие void puls_set (void)
     {
         TCCR2=0;                     //
         TIMSK=0;                     //
         PORTC&=~(1<<0);              // конец импульса /лог"0"
     }
    
 }

int main(void)
{  
    DDRD&=0x00;                                       //0;//все пины на вход, в том числе и пин на котором прерывание
    PORTD&=0x00;
    PORTD|=(1<<2);                                    //подтягивоющий резистор.
    DDRB|=0xFF;
    PORTB&=0x00;
    DDRC|=0xFF;
    PORTC&=0x00;
    int_set();                                         //запустили инициализацию прерывания.
    sei();                                             //глобально разрешили прерывания
    
    while(1)
    {            
            asm("nop");
    }
    
}

    

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

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

GIFR |= (1<<INT0);    // Сбросить флаг

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

Сравнительное тестирование аккумуляторов EVE Energy и Samsung типоразмера 18650

Инженеры КОМПЭЛ провели сравнительное тестирование аккумуляторов EVE и Samsung популярного для бытовых и индустриальных применений типоразмера 18650. 

Для теста были выбраны аккумуляторы литий-никельмарганцевой системы: по два образца одного наименования каждого производителя – и протестированы на двух значениях тока разряда: 0,5 А и 2,5 А. Испытания проводились в нормальных условиях на электронной нагрузке EBD-USB от ZKEtech, а зарядка осуществлялась от лабораторного источника питания в режиме CC+CV в соответствии с рекомендациями в даташите на определенную модель. Подробнее>>

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

               Приветствую вас!

           В вышеуказанный код внес подсказанные DmitryS коррективы, задача все равно не решилось!   Для наглядности задачи предлагаю посмотреть два графика работы кода.  С протеуса реальный график, в paint-е запланированный, но не выполняемый выше представленным кодом.    P.S. DmitryS благодарю за помощь.

Снимок.PNG

Безымянный.png

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

Новый аккумулятор EVE серии PLM для GSM-трекеров, работающих в жёстких условиях (до -40°С)

Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре. 

Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств. Подробнее параметры и результаты тестов новой серии PLM по ссылке.

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

 

Попробуй так, правда код переделал под IAR, думаю не трудно будет обратно под Atmel Studio восстановить

 

#include <ina90.h>
#include <iom8.h>

volatile unsigned char pause;

void pauza_set (void);

void int_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)
{
  TCCR2 = 0;
  TCCR2 |= (1<<WGM21) | (0<<WGM20); // режим CTC;
  TCCR2 |= (0<<CS22) | (1<<CS21) | (0<<CS20);          // prescaler
  TIMSK |= (1<<OCIE2);         // по совпадению
  OCR2 = 250;                   // число по совпадению TCNT2=OCR2
  TIFR &= ~(0<<OCF2);
}

void puls_set(void)
{
  TCCR2 = 0;
  TCCR2 |= (1<<WGM21) | (0<<WGM20); // режим CTC;
  TCCR2 |= (0<<CS22) | (1<<CS21) | (0<<CS20);          // prescaler
  TIMSK |= (1<<OCIE2);         // по совпадению
  OCR2 = 150;                   // число по совпадению TCNT2=OCR2
  TIFR &= ~(0<<OCF2);
}

#pragma vector = INT0_vect
__interrupt void INT0Vector(void)
{
  PORTC &= ~(1<<0);                  //  установили ПИНС0 в лог"0"
  pauza_set();                   //    инициировали и запустили условия pauza_set();
}

#pragma vector = TIMER2_COMP_vect
__interrupt void Timer2CompVector(void)
{
  if(!pause)
  {
    PORTC |= (1<<0);             //  начало импульса /  старт лог"1"
    pause++;
    puls_set();               // инициализация и запуск условия puls_set (); !!!!!!!!!!!!!!!  НЕ ЗАПУСКАЕТСЯ !!!!!!!!!!!!!!!!!!!!!!!!!
  }
  else
  {
    PORTC &= ~(1<<0);              // конец импульса /лог"0"
    TCCR2 = 0;                     //
    TIMSK = 0;                     //
  }
}

int main(void)
{  
  DDRD = 0x00;                                       //0;//все пины на вход, в том числе и пин на котором прерывание
  PORTD = (1<<2);                                    //подтягивоющий резистор.
  DDRB = 0xFF;
  PORTB = 0x00;
  DDRC = 0xFF;
  PORTC = 0x00;
  int_set();                                         //запустили инициализацию прерывания.
  _SEI();
  
  while(1)
  {            
  }
}

 

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

Литиевые батарейки и аккумуляторы от мирового лидера  EVE в Компэл

Компания Компэл, официальный дистрибьютор EVE Energy, бренда №1 по производству химических источников тока (ХИТ) в мире, предлагает продукцию EVE как со склада, так и под заказ. Компания EVE широко известна в странах Европы, Америки и Юго-Восточной Азии уже более 20 лет. Недавно EVE была объявлена поставщиком новых аккумуляторных элементов круглого формата для электрических моделей «нового класса» компании BMW.

Продукция EVE предназначена для самого широкого спектра применений – от бытового до промышленного. Подробнее>>

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

                           DM37, спасибо за вариант, но он у меня все равно не заработал. Может я не так перевел? Вот вариант перевода:

/*
 * _8_zvinok_2.c
 *
 * Created: 20.09.2016 19:19:28
 *  Author: SUN
 */ 

#define F_CPU1000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
volatile unsigned char pause;

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)
{
    TCCR2 = 0;
    TCCR2 |= (1<<WGM21) | (0<<WGM20); // режим CTC;
    TCCR2 |= (0<<CS22) | (1<<CS21) | (0<<CS20);          // prescaler
    TIMSK |= (1<<OCIE2);         // по совпадению
    OCR2 = 250;                   // число по совпадению TCNT2=OCR2
    TIFR=(1<<OCF2);
}

void puls_set(void)
{
    TCCR2 = 0;
    TCCR2 |= (1<<WGM21) | (0<<WGM20); // режим CTC;
    TCCR2 |= (0<<CS22) | (1<<CS21) | (0<<CS20);          // prescaler
    TIMSK |= (1<<OCIE2);         // по совпадению
    OCR2 = 150;                   // число по совпадению TCNT2=OCR2
    TIFR |=(1<<OCF2);
}

ISR(INT0_vect)
{
    PORTC &= ~(1<<0);                  //  установили ПИНС0 в лог"0"
    pauza_set();                   //    инициировали и запустили условия pauza_set();
}

ISR(TIMER2_COMP_vect)
{
    if(!pause)
    {
        PORTC |= (1<<0);             //  начало импульса /  старт лог"1"
        pause++;
        puls_set();               // инициализация и запуск условия puls_set (); !!!!!!!!!!!!!!!  НЕ ЗАПУСКАЕТСЯ !!!!!!!!!!!!!!!!!!!!!!!!!
    }
    else
    {
     

/*
 * _8_zvinok_2.c
 *
 * Created: 20.09.2016 19:19:28
 *  Author: SUN
 */ 

#define F_CPU1000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
volatile unsigned char pause;

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)
{
    TCCR2 = 0;
    TCCR2 |= (1<<WGM21) | (0<<WGM20); // режим CTC;
    TCCR2 |= (0<<CS22) | (1<<CS21) | (0<<CS20);          // prescaler
    TIMSK |= (1<<OCIE2);         // по совпадению
    OCR2 = 250;                   // число по совпадению TCNT2=OCR2
    TIFR=(1<<OCF2);
}

void puls_set(void)
{
    TCCR2 = 0;
    TCCR2 |= (1<<WGM21) | (0<<WGM20); // режим CTC;
    TCCR2 |= (0<<CS22) | (1<<CS21) | (0<<CS20);          // prescaler
    TIMSK |= (1<<OCIE2);         // по совпадению
    OCR2 = 150;                   // число по совпадению TCNT2=OCR2
    TIFR |=(1<<OCF2);
}

ISR(INT0_vect)
{
    PORTC &= ~(1<<0);                  //  установили ПИНС0 в лог"0"
    pauza_set();                   //    инициировали и запустили условия pauza_set();
}

ISR(TIMER2_COMP_vect)
{
    if(!pause)
    {
        PORTC |= (1<<0);             //  начало импульса /  старт лог"1"
        pause++;
        puls_set();               // инициализация и запуск условия puls_set (); !!!!!!!!!!!!!!!  НЕ ЗАПУСКАЕТСЯ !!!!!!!!!!!!!!!!!!!!!!!!!
    }
    else
    {
        PORTC &= ~(1<<0);              // конец импульса /лог"0"
        TCCR2 = 0;                     //
        TIMSK = 0;                     //
    }
}


int main(void)

    DDRD = 0x00;                                       //0;//все пины на вход, в том числе и пин на котором прерывание
    PORTD = (1<<2);                                    //подтягивоющий резистор.
    DDRB = 0xFF;
    PORTB = 0x00;
    DDRC = 0xFF;
    PORTC = 0x00;
    int0_set();                                         //запустили инициализацию прерывания.
    sei();
    
    
    while(1)
    {
       asm("nop");
    }
}

              //
    }
}


int main(void)

    DDRD = 0x00;                                       //0;//все пины на вход, в том числе и пин на котором прерывание
    PORTD = (1<<2);                                    //подтягивоющий резистор.
    DDRB = 0xFF;
    PORTB = 0x00;
    DDRC = 0xFF;
    PORTC = 0x00;
    int0_set();                                         //запустили инициализацию прерывания.
    sei();
    
    
    while(1)
    {
       asm("nop");
    }
}

  В таком варианте, ПИНС0 при INT0 уходит в лог "0" и там остается.  Тут мне не понятна смысл логики функции " if ". Я прочитал ее так:

 if(!pauza), -pauza по умолчанию "0", и условие значит: если пауза истина, т.е. (=1) выполнится часть "тела"  


        PORTC &= ~(1<<0);              // конец импульса /лог"0"
        TCCR2 = 0;                     //
        TIMSK = 0;  

 и далее условие в " if ()" никак не поменяется. В результате и получается лог"0" по условию ISR(TIMER2_COMP_vect).

 Надеюсь кто поправит мое понимание кода или подскажет правильное решение!!!

                          PS. код второпях прописал дважды, надеюсь не создаст больших проблем! Пардон!

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

Если вы пытаетесь эмулировать данный код в протеусе, то я столкнулся с тем, что у меня не работала подтяжка входа к питанию (у вас это PORTD |= (1<<2)), приходилось в коде подтяжку отключать и вешать на вход резистор 30кОм.
Похоже, что у вас не срабатывает прерывание INT0.
я ваш код проверял в отладчике AVR Studio 4.18 - всё работало

Т.е. если я правильно понял вашу задачу:
- при прерывании от кнопки вы попадаете в  ISR(INT0_vect), где запускается таймер на время Tpause (pauza_set()). PC0 = 0;
- после окончания времени Tpause вы попадаете в ISR(TIMER2_COMP_vect), где если pause = 0, то запускается таймер на время Tpuls (puls_set()). PC0 = 1. Увеличиваем pause (pause = 1);
- после окончания времени Tpuls вы попадаете в ISR(TIMER2_COMP_vect) второй раз, но со значением pause = 1 и выполняется код из блока else, в котором работа таймера останавливается. PC0 = 0.

наверно переменную pause надо переименовать в pulse, было бы более правильно, в любом случае это флаг для переключения с паузы на импульс

if(!pause)		// если pause = 0,
{			// то
  PORTC |= (1<<0);	// PC0 = 1
  pause++;		// pause = 1
  puls_set();		// запускаем таймер на Tpuls
}
else			// если pause = 1,
{			// то
  PORTC &= ~(1<<0);	// PC0 = 0
  TCCR2 = 0;		// останавливаем таймер
  TIMSK = 0;		//	-//-
}

Это конечно при условии, что вы не будете дергать прерывание INT0 до окончания работы таймера.

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

в прерывании INT0 в обработчике, нету антидребезга. в настройках таймера нужно сначала все настроить и в самую последнюю очередь настраивать прескаллер, после чего соответственно разрешить глобально прерывания. все обработчики прирываний поднимите в самый верх программы, сразу после объявления переменных, а то читать неудобно.

в подпрограммах, таких как пауза, нужно выключать таймер, делать изменения, и потом рпять включать таймер. это делается битами CSxx, он же прескаллер. тогда будет корректно работать

СНАЧАЛА ВЫКЛЮЧАЕМ, ПОТОМ МЕНЯЕМ ЧТО НУЖНО, ПОТОМ ОПЯТЬ ВКЛЮЧАЕМ,

 

Изменено пользователем Viktor26

Не знаеш как? Спроси у Google'а !!!

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

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

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

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

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

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

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

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

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

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

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

    • В былые годы запрещалось размещать на форуме бессмысленные темы. Видать, с тех пор правила существенно изменились.
    • скачай новый архив. там есть важные изменения в комповой программе, по сравнению с той, что я отправлял в личке. исправлены недоделки и добавлены проверки на некорректные действия.
    • Здесь все индивидуально, точного ответа нет. Тип фоторезиста, качество фотошаблона, расстояние и время засветки, длина волны св.диодов, "полоскание" в химии ... Надо все пробовать самому, ручками, опыт придет со временем, ничего сложного там нет. На форуме есть ветка, почитайте.
    • Привет.  Хочу попробовать поработать с фоторезистом. Есть пару десятков ультрафиолетовых светодиодов, общей мощностью 4 вата. Хватит ли этой мощности для обработки платок размером 10 на 10 см или надо искать что-то дополнительно? 
    • Чтобы меньше было излучения, нужно мотать тороидальную. Возможно для повышения добротности по омическому сопротивлению лучше этот ТОР мотать в пару слоев. Если ее намотать на шило, то она вряд ли будет вообще работать как катушка.   Индуктивность прямо пропорциональна площади сечения, которая в свою очередь прямо пропорциональна квадрату диаметра. К тому же индуктивность в обратной пропорции с длиной намотки.
    • Я в ходе отладки выяснил, что сбоит в функции:  void w25qWritingByUSB(uint32_t dpagenum, uint8_t *bufByUSB) При чем поведение очень странное. Отладочные сообщения даже не выводятся в начале функции. В ходе экспериментов понял что связано это с объявлением массивов и решил объявить большие буферы которые на 4КБ и 0.25КБ: uint8_t current_sector_buf[4096]; uint8_t buf[256]; глобально. В оригинале, буферы объявлялись локально в функции. После изменения буквально двух строчек кода, все заработало. Также, в оригинальном проекте было сильно напутано из функциями. Я решил функции выкинуть из main.c и вставить в w25q.c Эти функции: void w25qEraseSector(uint16_t sector) void w25qWritingByUSB(uint32_t dpagenum, uint8_t *bufByUSB) Поиск данной проблемы реально отобрало кучу времени. На будущее буду знать что и такое бывает...
×
×
  • Создать...