:? Чудеса с Atmega8 и Proteus

Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Закрыто
sun
Первый раз сказал Мяу!
Сообщения: 32
Зарегистрирован: Ср окт 07, 2009 10:07:02
Откуда: Минск

Сообщение sun »

Всем привет. Пишу тут первый раз, так что не царапайте, если не там написал (не в той теме). Контроллеры программировать начал недавно. Первым моим эксперементом была ATMEGA16, которая программировалась на ура и в протеусе программа эмулировалась аналогично. Но для экономии места решил попробовать ATMEGA8... Вроде похожие, тока фунционала поменьше. Получился у меня такой вот полтергейст: Написанная элементарнейшая программка не хочет нормально отрабатывать в эмуляторе. Вот текст:

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

#include <avr>
#include <util>
#include <avr>

void Init(void)
{
  DDRC  = 0xFF;
  PORTC = 0x00;
  DDRD  = 0xFF;
  PORTD = 0x00;

  //Global
  TIFR  = 0xC1;
  TIMSK = 0xC1;
  //Timer2
  TCCR2 = 0x42;
  TCNT2 = 0x02;

}

ISR(SIG_OVERFLOW2)
{
  cli();
  char pc = PORTC;
  pc = pc + 1;
  if (pc == 0)
    pc = 1;
  PORTC = pc;
  sei();
}


int main (void)
{
  Init();
  Init();
  sei();
  while (1){
  };
  return 0;
}

Всё до смеха просто... В протеусе просто повесил атмегу, указал программу (elf|hex) и подключил на порт C осцилограф из виртуал инструментс. НО! сигнал есть только на PC1. Объясните, может что-то я не так делаю? собираюсь юзать внутренние 1MHz, так что в проекте WinAVR установлено 1000000Hz.

На

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

pc = pc + 1;
не смотрите, это уже от безысходности написал, так было

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

 char pc = PORTC << 1;
Контактная информация:
Реклама
Мучитель микросхем
Сообщения: 459
Зарегистрирован: Вс июн 01, 2008 12:16:38

Сообщение smac »

sun писал(а):Всем привет. ... НО! сигнал есть только на PC1. Объясните, может что-то я не так делаю? ...
Дык а чего ожидаете то?
Во-первых изменяемую в прерываниях переменную нужно как минимум с квалификатором volatile объявлять.
Во-вторых SIG_OVERFLOW2 -устаревшее определение вектора прерывания, лучше использовать TIMER2_OVF_vect.
В-третьих неплохо бы на дизассемблер посмотреть.
Реклама
sun
Первый раз сказал Мяу!
Сообщения: 32
Зарегистрирован: Ср окт 07, 2009 10:07:02
Откуда: Минск

Сообщение sun »

smac писал(а): Во-первых изменяемую в прерываниях переменную нужно как минимум с квалификатором volatile объявлять.
Переменная внутренняя (НЕ ГЛОБАЛЬНАЯ).
Во-вторых SIG_OVERFLOW2 -устаревшее определение вектора прерывания, лучше использовать TIMER2_OVF_vect.
В-третьих неплохо бы на дизассемблер посмотреть.
Это из iom8.h

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

/* Timer/Counter2 Overflow */
#define TIMER2_OVF_vect			_VECTOR(4)
#define SIG_OVERFLOW2			_VECTOR(4)
И повторюсь, на Atmega16 всё прекрасно работало. Вопрос, почему на Atmega8 такая фигня?
Контактная информация:
Мучитель микросхем
Сообщения: 459
Зарегистрирован: Вс июн 01, 2008 12:16:38

Сообщение smac »

sun писал(а): И повторюсь, на Atmega16 всё прекрасно работало. Вопрос, почему на Atmega8 такая фигня?
Повторюсь, хотелось бы дизассемблер глянуть и схемку подключения.
Реклама
Эиком - электронные компоненты и радиодетали
sun
Первый раз сказал Мяу!
Сообщения: 32
Зарегистрирован: Ср окт 07, 2009 10:07:02
Откуда: Минск

Сообщение sun »

Спасибо, но сам разобрался (почти)...
Всего добился изменением регистра прерываний таймера и WaveForm.

Схемы небыло вообще, просто мк в протеусе и к нему осцилограф.
Последний раз редактировалось sun Чт окт 08, 2009 22:43:55, всего редактировалось 1 раз.
Контактная информация:
Реклама
sun
Первый раз сказал Мяу!
Сообщения: 32
Зарегистрирован: Ср окт 07, 2009 10:07:02
Откуда: Минск

Сообщение sun »

Закрываеть - это я погарячился...
всё заработало..... собрал вот такую схему, тока без светодиодов....
Индикатор был сдвоенный, но выводы цифр на нём для каждой отдельные... тоесть я их просто пермкнул паралельно. собрал вот в такой схеме - не хочет работать... потребляет атмега как-то странно мало - 2mA, при нажатии кнопки 2.5mA.... Я думал, она в районе 6 ток держать будет..... но на индикаторе пусто..... может я что не так сделал? по даташиту написано, что можно подключать светодиоды прямо к выводам, да и так об этом в нете читал, а семисегментники - это и есть 8 светодиодов )) вот только они не хотят гореть по какой-то причине...

вот код, чуть не забыл )))

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

#include <avr>
#include <util>
#include <avr>

#define Dig_0 0b11000000;
#define Dig_1 0b11111001;
#define Dig_2 0b10100100;
#define Dig_3 0b10110000;
#define Dig_4 0b10011001;
#define Dig_5 0b10010010;
#define Dig_6 0b10000010;
#define Dig_7 0b11111000;
#define Dig_8 0b10000000;
#define Dig_9 0b10010000;

volatile char ValA    = 0x00;
volatile char ValB    = 0x00;
volatile char Counter = 0x00;

char CharToDigit(char c)
{
 while (c > 9)
   c -= 10;
 if (c == 1)
   return Dig_1;
 if (c == 2)
   return Dig_2;
 if (c == 3)
   return Dig_3;
 if (c == 4)
   return Dig_4;
 if (c == 5)
   return Dig_5;
 if (c == 6)
   return Dig_6;
 if (c == 7)
   return Dig_7;
 if (c == 8)
   return Dig_8;
 if (c == 9)
   return Dig_9;
 if (c == 0)
   return Dig_0;
 return 0xFF;
}

void Init(void)
{
  DDRB  = 0xFF;
  PORTB = 0x00;
  
  DDRC  = 0x00;
  PORTC = 0x00;
  
  DDRD  = 0xFF;
  PORTD = 0x00;

  //Global
  TIFR  = 0x41;
  TIMSK = 0x41;
  //Timer0
  TCCR0 = 0x05;
  TCNT0 = 0x40;
  //Timer2
  TCCR2 = 0x03;
  TCNT2 = 0x40;

}

ISR(SIG_OVERFLOW0)
{
  Counter++;
  if (Counter > 9)
    Counter = 0x00;
  char pb = 0x00;
  if (((ValA + 1) > Counter) && (ValA > 0))
    pb |= 0x01;
  if (((ValB + 1) > Counter) && (ValB > 0))
    pb |= 0x02;
  PORTB = PORTB & 0xC0;
  PORTB |= pb;
}

ISR(SIG_OVERFLOW2)
{
  char pb = (PORTB >> 6) <<1> 2))
    pb = 1;
  PORTB = (PORTB & 0x3F) | pb <<6>> 2)) & 0x0F;
    if ((pressed == 0x00) && (pc != 0x00))
    {
      _delay_ms(50);
	  pressed = 1;
      switch (pc)
      {
        case 0x01 : if (ValA <9> 0) ValA--; break;
        case 0x04 : if (ValB <9> 0) ValB--; break;
      }
    }
    if (pc == 0x00)
	{
      pressed = 0;
	  _delay_ms(50);
    }
  }
  return 0;
}
Вложения
.jpg
(77.79 КБ) 515 скачиваний
Контактная информация:
Реклама
Закрыто

Вернуться в «Микроконтроллеры и ПЛИС»