WinAvr в вопросах и ответах

Обсуждаем контроллеры компании Atmel.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение ARV »

я вообще ничего не понял, как связаны программные извраты с количеством внешних прерываний...
но дам вам пару советов:
1. когда пишите код - будьте внимательны и анализируйте то, что вы НАПИСАЛИ, а не то, ЧТО ХОТИТЕ получить, т.к. часто это не одно и то же.
2. наплюйте на "черточки" в протеусе - раз компилятор что-то выкинул, значит, оно было лишним. случаев, чтобы компилятор выкинул то, что нельзя, не замечено. зато полно случаев, когда написанное ведет себя не так, как хотелось - см.п.1
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
TICLIR
Встал на лапы
Сообщения: 134
Зарегистрирован: Вс авг 01, 2010 16:05:25

Re: WinAvr в вопросах и ответах

Сообщение TICLIR »

ARV писал(а):но дам вам пару советов:

С Новым Годом ВСЕМ!!! Я за всегда рад выслушать совет. А вот мысли свои выложить не могу. Но то чего я хотел у меня получилось, может кому надо:

int fol=0x0F;
ISR(TIMER0_OVF_vect){ // Timer/Counter0 Overflow
wip=PIND|fol;
if(wip==0X1F){
PORTD&=~(1<<0);
fol|=(1<<5);
_delay_ms(50);PORTD|=(1<<0);
}
if(PIND&0X20) fol&=~(1<<5);
wip=PIND|fol;
if(wip==0X2F){
PORTD&=~(1<<0);
fol|=(1<<4);
_delay_ms(50);PORTD|=(1<<0);
}
if(PIND&0X10) fol&=~(1<<4);
Это для двух кнопок. А вот только на счёт задержки сомневаюсь,надо ли она.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение ARV »

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

Мой уютный бложик... заходите!
R_ura
Грызет канифоль
Сообщения: 293
Зарегистрирован: Сб май 29, 2010 00:08:48
Откуда: Харьков

Re: WinAvr в вопросах и ответах

Сообщение R_ura »

Начал переходить с асма на Си и тут же уперся в нежелание незатейливой программки работать.
В отладчике командой sei флаг прерываний не устанавливается, в тоже время программа крутится не в главном цикле, а вокруг прерывания.. Собственно не работает прерывание..
Что здесь может не работать - ума не приложу??

Код: Выделить всё

 
#include <util/delay.h>
#include <avr/io.h> 
#include <avr/interrupt.h>
 
#include <stdlib.h>     // 
//#include "bits_macros.h"     // 
 
 unsigned int  cnt_S;
//XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
 
int main (void)
{
 // ____ Configuration of ports _____
  DDRA  = 0b11111111;   //; PA0-7=Out
  PORTA = 0b00000000;   //; PA0-7=low
  DDRB  = 0b00010000;   //; PB4-????? ??? ???????? ???????????
  PORTB = 0b11100011;   //; pin3-????????? R-r
  DDRC  = 0b11100000;   //; PC6,7,8=out, PC0,1,2,3,4,5=In
  PORTC = 0b00011111;   //; PC6,7,8= no R-rs, PC0,1,2,3,4,5= set R-rs 
  DDRD  = 0xFC;         //  for LCD
 
//_______ Init. interrupt timer0 _____
  TIMSK =(1<<TOIE0);  // Timer0 overflow interrupt enable
  TCCR0 = 3; //     ;Prescaller > ;0=STOP; 2=F/8; 3=F/64 4=F/256;
  cnt_S = 0;
  sei() ;                       // установить флаг I 
//SREG |= (1<<(7));    // установить флаг I   
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
 while(1)
     {
     if (cnt_S >= 1000)        //  проверить состояние счетчика
      {
          PORTC ^= (1<<(5));   //  инвертировать вывод
          cnt_S = 0;                  //  обнулить счетчик
      };
     }; 
   return (0);
}
//*****************************************************************

 ISR (TIMER0_OVF_vect)         //  прерывание переполнения Т0
    { 
     cnt_S ++ ;
     TCNT0 = (0xff - 0x83);  //  прерывание каждую мс
    };   
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение ARV »

вы совершили традиционную для начинающих ошибку. avr-gcc (оно же WinAVR) не прощает вольностей по отношению к стандарту языка Си. ваша переменная cnt_S используется и в обработчике прерывания и в главной функции, а значит, она обязательно должна объявляться volatile-переменной! иначе компилятор считает, что эта переменная внутри основного цикла никогда не изменит свое значение, а значит, ни на что повлиять не сможет. бесполезные переменные и код для их обслуживания компилятор выбрасывает - у вас получается черти что: есть прерывание, но оно ничего не делает!
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
R_ura
Грызет канифоль
Сообщения: 293
Зарегистрирован: Сб май 29, 2010 00:08:48
Откуда: Харьков

Re: WinAvr в вопросах и ответах

Сообщение R_ura »

ARV писал(а): она обязательно должна объявляться volatile-переменной! иначе компилятор считает, что эта переменная внутри основного цикла никогда не изменит свое значение, а значит, ни на что повлиять не сможет. !

Спасибо, буду знать !!
Объявил как volatile unsigned int cnt_S; - не помогло...
Пернес проверку счетчика в само прерывание - тоже не работает..

Код: Выделить всё

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 
 while(1)
     {
    /* if (cnt_S >= 1000)      //
      {
          PORTA ^= (2<<(5)); // 
          cnt_S = 0;         // 
      };*/
     }; 
   return (0);
}
//*****************************************************************

 ISR (TIMER0_OVF_vect)  //
    { 
     cnt_S ++ ;
     TCNT0 = (0xff - 0x83);  //
     if (cnt_S >= 1000)      //
      {
          PORTA ^= (1<<(5)); // 
          cnt_S = 0;         // 
      };
    };

)))) что-то мудреный этот Си..
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение ARV »

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

Мой уютный бложик... заходите!
R_ura
Грызет канифоль
Сообщения: 293
Зарегистрирован: Сб май 29, 2010 00:08:48
Откуда: Харьков

Re: WinAvr в вопросах и ответах

Сообщение R_ura »

ARV писал(а):ничего там мудреного. вы что хотите сделать?

Да у меня есть прогграмма, написанная на асме. Я ее решил переписмать на Си, для изучения последнего. Вот попытался вести в программу прерывание - не работает. Теперь просто хочу его запустить - помигать хотя бы светодиодом.. ))) Ничего не выходит. Где-то что-то упускаю.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение ARV »

просто помигать можно вот так, без прерываний:

Код: Выделить всё

#include <avr/io.h>
#include <util/delay.h>

int main(void){
   DDRB = 1;
   while(1){
      PORTB ^= 1;
      _delay_ms(500);
   }
}
или так, с прерываниями:

Код: Выделить всё

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

ISR(TIMER0_OVF_vect){
   PORTB ^= 1;
}

int main(void){
   DDRB = 1;
   TIMSK = _BV(TOIE0);
   TCCR0 = _BV(CS02)  | _BV(CS00);
   sei();
   while(1);
}

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

Мой уютный бложик... заходите!
R_ura
Грызет канифоль
Сообщения: 293
Зарегистрирован: Сб май 29, 2010 00:08:48
Откуда: Харьков

Re: WinAvr в вопросах и ответах

Сообщение R_ura »

Спасибо, разберу ваши примеры. Но мне мигание нужно для того в данный момент, чтобы включить прерывание. А в рабочем варианте в прерывании у меня выставляется флаг 1мс, по которому в основном цикле уже отсчитываются всевозможные интервалы..
Прошу прощения, а какая частота мигания будет в вашем варианте с прерыванием?? Мне кажется туда счетчик все-равно надо вводить.. Иначе частота будет намного выше визуально видимой..
Последний раз редактировалось R_ura Пн янв 03, 2011 23:49:52, всего редактировалось 1 раз.
Аватара пользователя
radio-kot
Собутыльник Кота
Сообщения: 2584
Зарегистрирован: Вт сен 14, 2010 10:27:19

Re: WinAvr в вопросах и ответах

Сообщение radio-kot »

Посмотрите в PROTEUS :beer:
Будете проходить мимо- проходите!
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение ARV »

R_ura писал(а):Прошу прощения, а какая частота мигания будет в вашем варианте с прерыванием?? Мне кажется туда счетчик все-равно надо вводить.. Иначе частота будет намного выше визуально видимой..
откуда ж мне знать. какая у вас тактовая частота? для таймера я включил делитель на 1024, переполнение возникнет спустя 256 этих тиков, т.е. итоговое деление тактовой частоты получается на 262144... если тактовая 1 МГц, то период мигания будет почти 8 секунд... ну а при тактовой 8 МГц - соответственно, 1 секунда (почти)... глазом ОООООЧЕНЬ заметно будет :)))

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

Мой уютный бложик... заходите!
R_ura
Грызет канифоль
Сообщения: 293
Зарегистрирован: Сб май 29, 2010 00:08:48
Откуда: Харьков

Re: WinAvr в вопросах и ответах

Сообщение R_ura »

ARV писал(а):
R_ura писал(а):Прошу прощения, а какая частота мигания будет в вашем варианте с прерыванием?? Мне кажется туда счетчик все-равно надо вводить.. Иначе частота будет намного выше визуально видимой..
откуда ж мне знать. какая у вас тактовая частота? для таймера я включил делитель на 1024, переполнение возникнет спустя 256 этих тиков, т.е. итоговое деление тактовой частоты получается на 262144... если тактовая 1 МГц, то период мигания будет почти 8 секунд... ну а при тактовой 8 МГц - соответственно, 1 секунда (почти)... глазом ОООООЧЕНЬ заметно будет :)))

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

Прошу прощения, я не хотел вас уколоть. Я не думал, что на 8 битном таймере можно организовать секундные задержки.. Спасибо, вы правы..
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение ARV »

я толстокожий, об меня не один ёжик иголки обломал (типа лицар) :))) так что ваши опасения напрасны.
просто тонкости настройки таймеров не имеют прямого отношения к WinAVR... а по сути WinAVR вы пока не сильно вопросы задаете...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
R_ura
Грызет канифоль
Сообщения: 293
Зарегистрирован: Сб май 29, 2010 00:08:48
Откуда: Харьков

Re: WinAvr в вопросах и ответах

Сообщение R_ura »

ARV писал(а):я толстокожий, об меня не один ёжик иголки обломал (типа лицар) : .

Так то ж вы в одном месте толстокожий - для їжаків)))))
Задам еще, дай бог прерывание включить.. Создам проект заново, а то и ваш пример не работает нифига..((
TICLIR
Встал на лапы
Сообщения: 134
Зарегистрирован: Вс авг 01, 2010 16:05:25

Re: WinAvr в вопросах и ответах

Сообщение TICLIR »

ARV писал(а):всегда плохо, когда в обработчике прерываний делаются задержки... так же не хорошо, когда из обработчика прерывания вызываются сторонние функции (не статические, а библиотечные). не знаю, какая у вас конкретная задача, но лично я никогда в прерываниях кнопки не обслуживаю - нет нужды. по мне, так самое простое - это в главном цикле время от времени проверять состояние кнопок, вот и все.

Спасибо. Вы не первый кто мне это говорит, но я не понимаю, ведь программа дойдя до замкнутого цикла стоит там ждёт прерываний, она же не может вернутся в начало.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение ARV »

а вы продумайте алгоритм своей программы так, чтобы она в цикле не стояла, а что-то делала. и как раз опрос кнопок тут самое подходящее занятие. я уже не раз говорил: для чего нужно прерывание? для немедленной и мгновенной реакции на какое-то событие. а кнопка, которую нажимает человек, ну никак не может требовать такой реакции, ибо человек не в состоянии заметить задержку в реакции на свое действие, если эта задержка менее 0,02 секунды, а его тело вообще не в состоянии совершить какое-то действие быстрее, чем за 0,15 секунды - и то такая скорость реакции у специально тренированных людей. а 0,15 секунд для МК - это дико много, и строить работу с кнопками по прерываниям от них - это нелогично. практически любая программа любительского уровня может делаться по такому скелету:

Код: Выделить всё

uint8_t get_key(void); // эта функция опрашивает порт с кнопками и возвращает код, соответствующий комбинации нажатых кнопок
void indicate(uint8_t mode); // эта функция обеспечивает индикацию в соответствии с режимом работы mode
static void init(void); // эта функция инициализирует всю аппаратуру МК

int main(void){
   uint8_t mode = 0;
   uint8_t key;
   init();
   while(1){
      indicate(mode);
      key = get_key();
      switch(key){
      case KEY1 : // тут обрабатываем нажатие первой кнопки
            // если нужно - переключаем режим mode
            break;
      case KEY2 : // тут обрабатываем нажатие второй кнопки
            // и так далее все возможные комбинации нажатий кнопок
      }
   }
}

как видите, основной цикл занят делом: он работает с кнопками и занимается изменением режима индикации. а вот все прочие функции могут делаться и по прерываниям - особенно хорошо укладывается в это динамическая индикация. можно проводить какие-товычисления и т.п. работу, а в прерываниях делать только то, что требует МГНОВЕННОЙ НЕЗАМЕДЛИТЕЛЬНОЙ реакции - например, принимать ИК-команды с пульта, следить за переходом сети через 0, принимать из USART и т.п. кстати, принимать из USART так же далеко не всегда требуется по прерываниям - иной раз проще делать это в основном цикле.

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

Мой уютный бложик... заходите!
R_ura
Грызет канифоль
Сообщения: 293
Зарегистрирован: Сб май 29, 2010 00:08:48
Откуда: Харьков

Re: WinAvr в вопросах и ответах

Сообщение R_ura »

ARV писал(а):
я вам просто показал, как помигать, раз у вас даже это не выходило. а счетчик и т.п. - это уже от вашей задачи зависит...


Хе-хе.. Сделал новый проект - не пашет это прерывание.. Светодиоды не то что не мигают, а вообще не горят..)

Код: Выделить всё

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

ISR(TIMER0_OVF_vect){
   PORTA ^= 0xFF;
}

int main(void){
   DDRA = 0xFF;
   TIMSK = _BV(TOIE0);
   TCCR0 = _BV(CS02)  | _BV(CS00);
   sei();
   while(1);

}

А вот такой вариант работает. Стало быть с портом все в порядке...

Код: Выделить всё

  #include <avr/io.h>
#include <util/delay.h>

int main( void )
{
  DDRA = 0xFF;
  while(1)
  {
    _delay_ms(500);
    PORTA ^= 0xFF;
  }
  return 0;
}


Что за чертовщина с этим прерыванием - никак не хочет работать?
В программе на Паскале работает нормально, значит проц рабочий..
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение ARV »

и вправду, чертовщина у вас какая-то... пригласите попа с кадилом, пусть освятит вашу лабораторию, ибо я вот только что в студии просимулировал этот код (только поменял PORTA на PORTB, т.к. у меня заточено на atmega8) - работает, ё! как и было обещано. так что это у вас лыжи неправильные :)))
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
radio-kot
Собутыльник Кота
Сообщения: 2584
Зарегистрирован: Вт сен 14, 2010 10:27:19

Re: WinAvr в вопросах и ответах

Сообщение radio-kot »

Вот проекты то и надо цеплять, а не голые исходники :beer: и версию указывать.
Будете проходить мимо- проходите!
Ответить

Вернуться в «AVR»