Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: led blinking
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
i.dmitry
Привет всем.
после темы 'bit set' решил помигать диодами. Вот что получилось:
Код
#include <iom16v.h>

//----------------------------------------------------------
// interrupt on verflow
//----------------------------------------------------------
#pragma interrupt_handler timer0_overflow: iv_TIMER0_OVF
void timer0_overflow () {
  int i;
  while (i<8) {
    i++;
    switch (i) {
      case 0: PORTD = 0x00;
      case 1: PORTD = 0x80;
      case 2: PORTD = 0xC0;
      case 3: PORTD = 0xE0;
      case 4: PORTD = 0xF0;
      case 5: PORTD = 0xF8;
      case 6: PORTD = 0xFC;
      case 7: PORTD = 0xFE;
      default : PORTD = 0x00;
    }
  if (i==8) i=0;     
    
    
  };  
  //PORTD ^= 0xFF; //toggle all pins
    
};
//----------------------------------------------------------

void init_portd (void) {
  DDRD = 0xFF;   //define all pins as outputs
  PORTD = 0x00;  //initially all LEDs are HIGHLIGHTED
}

void init_timer0(void) {
  SREG |= 0x80; //enable all interrupts
  TCCR0 = (1<<CS00) | (1<<CS02); //timer clk = system clk / 1024
  TIMSK = 0x01; //enable Timer0 overflow interrupt
}

void main (void) {
  
  init_portd();
  init_timer0();
  
  while (1) {
  
  };
}


Но есть проблема - не работет.
Отдельми диодами и всеми сразу мигать могу, а вот чобы было последовательное отключение диодом - не получается.
Использую STK500 + ICC7.

Подскажите плиз как исправить.
defunct
Код
typedef unsigned char U8

#pragma interrupt_handler timer0_overflow: iv_TIMER0_OVF
void timer0_overflow ()
{
    static U8 CurrVal = 0;
  
    CurrVal = (CurrVal == 0) ? 1 : CurrVal << 1;
    PORTD = CurrVal;
};


вот еще вариант:

Код
#pragma interrupt_handler timer0_overflow: iv_TIMER0_OVF
void timer0_overflow ()
{
    static U8 CurrVal = 0xFF;
  
    CurrVal = (CurrVal == 0) ? 0xFF : CurrVal << 1;
    PORTD = CurrVal;
};


Как вы уже вероятно догадались, в вашем варианте нехватает слова "static" при объявлении переменной i, и вместо while поставить if
i.dmitry
спасибо - работает!!!!!!!

Цитата
extern - если переменная объявляется во внешнем файле - например в хидере delay.h приведенном выше.

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

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


я еще не знаю отличий между extern, static and volatile.
стоит ли верить выше изложенному (нашел в гугле, сайте [banned])
-------------
Если это не соывсем точно, разъясните плиз вкратце.

Цитата(i.dmitry @ Jul 26 2007, 22:51) *
спасибо - работает!!!!!!!
я еще не знаю отличий между extern, static and volatile.
стоит ли верить выше изложенному (нашел в гугле, сайте [banned])
-------------
Если это не соывсем точно, разъясните плиз вкратце.

Вот что нашел:
Цитата
When you use static to declare a variable inside a function, that variable is initialized at startup (like other global variables) and retains its value between calls to that function. It is not reinitialized on entry to the function.


а если вместо static char я использую просто char - у меня не работет. это значит что при выходе из функции обр прерывания - она (переменная) обнуляется что-ли?
=GM=
Цитата(i.dmitry @ Jul 26 2007, 17:49) *
while (i<8) {
i++;
switch (i) {
case 0: PORTD = 0x00;
case 1: PORTD = 0x80;
case 2: PORTD = 0xC0;
case 3: PORTD = 0xE0;
case 4: PORTD = 0xF0;
case 5: PORTD = 0xF8;
case 6: PORTD = 0xFC;
case 7: PORTD = 0xFE;
default : PORTD = 0x00;
}
if (i==8) i=0;
};
Но есть проблема - не работает.
Отдельми диодами и всеми сразу мигать могу, а вот чобы было последовательное отключение диодом - не получается. Использую STK500 + ICC7. Подскажите плиз как исправить.

В конце каждого варианта (case) поставьте оператор break, чтобы выполнялся только это вариант. А так у вас выходит, что при переходе на case 2 выполняются варианты 2, 3, 4 , 5, 6, 7 и default, результат работы которого (горят все диоды) остаётся до следующего прерывания.
i.dmitry
в такомслучае у меня горит постоянно только один диод, а остальные еле-еле заметно что они вообще горят, но видно чот мигают.
Код
void timer0_overflow () {
  static char i;
  for (i=0; i<8; i++) {
    switch (i) {
      case 0:  { PORTD = 0x00; break; }
      case 1:  {PORTD = 0x80; break; }
      case 2: { PORTD = 0xC0; break; }
      case 3: { PORTD = 0xE0; break; }
      case 4: { PORTD = 0xF0; break; }
      case 5: { PORTD = 0xF8; break; }
      case 6: { PORTD = 0xFC; break; }
      case 7:  { PORTD = 0xFE; break; }
      default : {PORTD = 0x00; break; }
    }
  }    
  if (i==8) i=0;    
    
    
    
  //PORTD ^= 0xFF; //toggle all pins
    
};
Сергей Борщ
Цитата(i.dmitry @ Jul 26 2007, 22:22) *
в такомслучае у меня горит постоянно только один диод, а остальные еле-еле заметно что они вообще горят, но видно чот мигают.
Естественно. Он в цикле быстро-быстро перебирает все варианты, после последнего case 7: выходит из цикла и этот светодиод вы видете включенным до следующего прерывания. Выкиньте цикл а в switch() напишите switch(++i);
i.dmitry
Цитата(Сергей Борщ @ Jul 26 2007, 23:43) *
Естественно. Он в цикле быстро-быстро перебирает все варианты, после последнего case 7: выходит из цикла и этот светодиод вы видете включенным до следующего прерывания. Выкиньте цикл а в switch() напишите switch(++i);

спасибо работает
defunct
Цитата
Цитата
static - если переменная локальная т.е. объявлена в какой либо функции и не должна сохранять свое значение до следующего вызова этой функции.

стоит ли верить выше изложенному (нашел в гугле, сайте [banned])

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

Цитата
а если вместо static char я использую просто char - у меня не работет. это значит что при выходе из функции обр прерывания - она (переменная) обнуляется что-ли?

Если не поставить static, то место под переменную будет выделяться в стеке автоматически при каждом входе в функцию, и освобождаться перед выходом из функции. Тобиш переменная существует только внутри функции - вышли из функции - переменная пропала, память которая под нее выделалась, будет использоваться для чего-то другого.
rezident
Цитата(i.dmitry @ Jul 27 2007, 00:56) *
я еще не знаю отличий между extern, static and volatile.
стоит ли верить выше изложенному (нашел в гугле, сайте [banned])
-------------
Если это не соывсем точно, разъясните плиз вкратце.
Вот что нашел:
а если вместо static char я использую просто char - у меня не работет. это значит что при выходе из функции обр прерывания - она (переменная) обнуляется что-ли?

Не нужно читать "запрещенные" курсы, читайте авторов СИ Кернигана и Ричи wink.gif
Вкратце: переменные в Си бывают автоматические (локальные), регистровые, глобальные и статические.
Автоматические переменные располагаются на стеке, но по выбору компилятора могут и в регистрах.
Регистровые переменные теоретически должны располагаться в регистрах, но реально компиляторы чаще всего игнорируют тип register и используют их как локальные переменные т.к. для локальных те же регистры используются.
Глобальные и статические переменные размещаются в ОЗУ. Различие у них в области "видимости". Статические переменные "видны" только в той функции в которой они объявлены. К тому же глобальные переменные объявляются вне функций, а статические внутри функций. И глобальные и статические переменные в соответствии со стандартом ANSI C компилятор обязан обнулить еще до вызова main(). Для локальных и регистровых такой привилегии не предусмотрено, поэтому они требуют явной инициализации до их использования в операциях. Ибо без инициализации (присвоения им определенного значения) значение такой переменной не определено.
Например, вы можете в каждой функции иметь переменную типа static с одинаковым именем cntr, которая будет сохранять свое значение при выходе из функции, но в то же время значения cntr будет свое собственное в каждой функции.

Код
void funcNum1(void)
{ static unsigned cntr=10;
   if (cntr!=0)
   { ....
      cntr--;
   }
}

void funcNum2(void)
{ static unsigned cntr=1;
   if (cntr<1000)
   { ....
     cntr++;
   }
}


volatile это не тип переменной, а квалификатор, который указывает компилятору, что значение переменной может изменяться в любой момент и/или вне данной функции/модуля. Поэтому компилятор при операциях с volatile-переменной обязан каждый раз считывать ее значение, а не копировать его в локальную или регистровую переменную и не работать с ее копией.
i.dmitry
[Убрал ненужное цитирование, хотя и весь пост можно было удалить как неинформативный]
thanks a lot
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.