ВСЁ по прошивке и программированию AT90S2313/ATTiny2313

Обсуждаем контроллеры компании Atmel.
Аватара пользователя
zero648
Вымогатель припоя
Сообщения: 650
Зарегистрирован: Пн июн 18, 2012 12:01:04
Откуда: Челябинская область, Копейск

Re: ВСЁ по прошивке и программированию AT90S2313/ATTiny2313

Сообщение zero648 »

x8973 писал(а):С программированием прерывания INT1, вроде как, разобрался. Но теперь "внимание, вопрос". Можно ли использовать для управления кнопками ноги T0 и T1(OC0B)? А то я по незнанию две кнопки из трех на них развел...

Если кнопки на PD3, PD4, PD5, можно все три проверять на одном прерывани INT1.
Аватара пользователя
shadivl
Открыл глаза
Сообщения: 76
Зарегистрирован: Пт май 28, 2010 13:41:16
Откуда: Мариинск, Томск

Re: ВСЁ по прошивке и программированию AT90S2313/ATTiny2313

Сообщение shadivl »

zero648
Принципиально на PD0 кнопку нужно?

Нет, не принципиально, просто я понять хочу, почему он так реагирует.
x8973
Встал на лапы
Сообщения: 99
Зарегистрирован: Чт мар 08, 2012 18:05:49
Откуда: Пермь

Re: ВСЁ по прошивке и программированию AT90S2313/ATTiny2313

Сообщение x8973 »

zero648 писал(а):Если кнопки на PD3, PD4, PD5

Да, они на PD4 и PD5. Но, честно говоря, я понятия не имею, как это замутить.
А было бы неплохо, а то с опросом кнопок код вырос, и памяти контроллера только-только на два эффекта хватило)
Аватара пользователя
Gudd-Head
Друг Кота
Сообщения: 20092
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

Re: ВСЁ по прошивке и программированию AT90S2313/ATTiny2313

Сообщение Gudd-Head »

Не очень понимаю кому что надо с кнопками, но можно замутить вызов прерывания при нажатия ЛЮБОЙ кнопки, если развязаться диодами (и если нога внешнего прерывания свободна, естессно). В обработчике прерывания уже смотреть какая кнопка нажата.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
x8973
Встал на лапы
Сообщения: 99
Зарегистрирован: Чт мар 08, 2012 18:05:49
Откуда: Пермь

Re: ВСЁ по прошивке и программированию AT90S2313/ATTiny2313

Сообщение x8973 »

Gudd-Head писал(а):если развязаться диодами

Если развязываться диодами, то значит - перекраивать плату. А если уже на то пошло, то я лучше кнопки по новой разведу.
Аватара пользователя
Gudd-Head
Друг Кота
Сообщения: 20092
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

Re: ВСЁ по прошивке и программированию AT90S2313/ATTiny2313

Сообщение Gudd-Head »

Ну это так, на будущее. Может, пригодится...
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Аватара пользователя
zero648
Вымогатель припоя
Сообщения: 650
Зарегистрирован: Пн июн 18, 2012 12:01:04
Откуда: Челябинская область, Копейск

Re: ВСЁ по прошивке и программированию AT90S2313/ATTiny2313

Сообщение zero648 »

x8973 писал(а):Да, они на PD4 и PD5. Но, честно говоря, я понятия не имею, как это замутить.
А было бы неплохо, а то с опросом кнопок код вырос, и памяти контроллера только-только на два эффекта хватило)

Схема подключения 3-х кнопок на одно внешнее прерывание:

Изображение

Опрос в прерывании INT1:

status_pinD=PIND&((1<<PB5)|(1<<PB4)|(1<<PB3)); // Опросим и сразу промаскируем порт D

// Проверяем status_pinD:

0x38 - кнопки не нажаты;
0x30 - нажата кнопка PD3;
0x20 - нажата кнопка PD4;
0x10 - нажата кнопка PD5;

if (status_pinD!=0x38)
{
if (status_pinD==0x30) {делаем первое}
if (status_pinD==0x20) {делаем второе}
if (status_pinD==0x10) {делаем третье}
}
Последний раз редактировалось zero648 Сб авг 11, 2012 08:51:18, всего редактировалось 1 раз.
Аватара пользователя
zero648
Вымогатель припоя
Сообщения: 650
Зарегистрирован: Пн июн 18, 2012 12:01:04
Откуда: Челябинская область, Копейск

Re: ВСЁ по прошивке и программированию AT90S2313/ATTiny2313

Сообщение zero648 »

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

Зачем плату перекраивать, подпаял диоды и все, или вообще SMD-шные, они на дорожки хорошо приделываются.
Аватара пользователя
zero648
Вымогатель припоя
Сообщения: 650
Зарегистрирован: Пн июн 18, 2012 12:01:04
Откуда: Челябинская область, Копейск

Re: ВСЁ по прошивке и программированию AT90S2313/ATTiny2313

Сообщение zero648 »

shadivl писал(а):Нет, не принципиально, просто я понять хочу, почему он так реагирует.

Если не разобрался со своим кодом, могу предложить такой вариант, кнопка на PD6, юзаем внешнее прерывание таймера:
Спойлер

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

            .include "tn2313def.inc"  ; Используем ATtiny2313

; ROM ===============

            .CSEG                     ; ROM

            .org $000
            rjmp RESET                ; External Pin, Power-on Reset, Brown-out Reset and Watchdog Reset
            reti                      ; INT0          Внешнее прерывание 0
            reti                      ; INT1          Внешнее прерывание 1
            rjmp TIMER1_CAPT          ; TIMER1 CAPT   Захват таймера/счетчика Т1

; ---------- R E S E T ----------

            .ORG   INT_VECTORS_SIZE   ; Конец таблицы прерываний

RESET:
            cli
            ldi     r16, RAMEND       ; Set Stack Pointer to top of RAM
            out     SPL, r16          ;

; ---------- M A I N  P R O G R A M M ----------

PORTS_Init:
            ldi   r16, 0b0000000
            out   DDRD, r16
            ldi   r16, 0b1111111
            out   PORTD, r16
            ldi   r16, 0b11111111
            out   DDRB, r16
            ldi   r16, 0b11111111
            out   PORTB, r16
OCR1_Init:
            ldi   r16, (1<<ICIE1)     ; Включаем прерывания по сигналу ICP1
            out   TIMSK, r16
            sei

            clr   r20
            ser   r21

MAIN_loop:
            in    r16, MCUCR
            ori   r16, (1<<SE)
            out   MCUCR, r16
taste_push: sbis  PIND, 6
            rjmp  taste_push
            sleep                     ; Отдыхаем пока не началось
            rjmp  MAIN_loop           ; Go again               


; ---------- E X T E R N A L  I N T E R R U P T S ----------

TIMER1_CAPT:
            eor   r20, r21
            ori   r20, 0b10111111
            in    r16, PIND
            ori   r16, 0x80
            com   r16
            eor   r16, r20
            sbrc  r16, 6
            ldi   r16, 0xff
            sbrs  r16, 6
            ldi   r16, 0x00
            out   PORTB, r16
            reti

x8973
Встал на лапы
Сообщения: 99
Зарегистрирован: Чт мар 08, 2012 18:05:49
Откуда: Пермь

Re: ВСЁ по прошивке и программированию AT90S2313/ATTiny2313

Сообщение x8973 »

Не вышло. Все три кнопки работают как одна.
Аватара пользователя
zero648
Вымогатель припоя
Сообщения: 650
Зарегистрирован: Пн июн 18, 2012 12:01:04
Откуда: Челябинская область, Копейск

Re: ВСЁ по прошивке и программированию AT90S2313/ATTiny2313

Сообщение zero648 »

x8973 писал(а):Не вышло. Все три кнопки работают как одна.

Ну покаж код, посмотрим
x8973
Встал на лапы
Сообщения: 99
Зарегистрирован: Чт мар 08, 2012 18:05:49
Откуда: Пермь

Re: ВСЁ по прошивке и программированию AT90S2313/ATTiny2313

Сообщение x8973 »

Спойлер

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

#include <avr/io.h> //Библиотека ввода/вывода
#include <math.h> //Библиотека математических функций
#include <avr/interrupt.h> //Библиотека прерываний

//Переменные
unsigned short int stage = 1; //Номер сцены для эффектов
unsigned short int t = 1000; //Величина задержки для эффектов
unsigned short int mode = 1; //Номер текущего эффекта
unsigned short int pin4hold = 0; //Блокировка многократного срабатывания кнопки "+"
unsigned short int pin5hold = 0; //Блокировка многократного срабатывания кнопки "-"

SIGNAL (SIG_INTERRUPT1)//Программа-обработчик прерывания INT1
{
   cli(); //Глобальный запрет прерываний
   unsigned int status_pinD = PIND&((1<<PD5)|(1<<PD4)|(1<<PD3));
   if (status_pinD!=0x38)
   {
      if (status_pinD=0x30) //Нажата кнопка MODE (PD3)
      {
         if (mode < 2) //2 - количество эффектов
         {
            mode++;
         }
         else
         {
            mode = 1;
         }
      }
      if (status_pinD=0x20) //Нажата кнопка "+" (PD4)
      {
         if (t >= 100)
         {
            t = t - 100; //Уменьшаем задержку
         }
      }
      if (status_pinD=0x10) //Нажата кнопка "-" (PD5)
      {
         t = t + 100; //Увеличиваем задержку
      }
   }   
   sei(); //Глобальное разрешение прерываний
}

//Подпрограмма задержки
void pause(unsigned int a)
{
   unsigned int i;
   for (i=a; i>0; i--);
}

//Подпрограмма инициализации ШИМ
void pwm_init(void)
{
   TCCR0A = (1<<WGM01)|(1<<WGM00); //Режим FastPWM
      TCCR1A = (1<<WGM10); //Режим FastPWM 8 bit
      TCCR1B = (1<<WGM12); //Режим FastPWM 8 bit

      TCCR0A = TCCR0A|(1<<COM0A1)|(1<<COM0A0); //Инвертированный выход
      TCCR1A = TCCR1A|(1<<COM1A1)|(1<<COM1A0);
      TCCR1A = TCCR1A|(1<<COM1B1)|(1<<COM1B0);
   
      TCCR0B = TCCR0B|(1<<CS00); //Предделители
      TCCR1B = TCCR1B|(1<<CS10);

      OCR0A = 0xff; //Начальная яркость нулевая
      OCR1AL = 0xff;
      OCR1BL = 0xff;
}

/*------Подпрограммы световых эффектов------*/

//Эффект "Непрерывного спектра"
void eff_inf_spectr(unsigned int delay)
{
   if (stage == 1){if (OCR1A > 0){OCR1A--;}else{stage = 2;}} //Увеличиваем зеленый
   if (stage == 2){if (OCR1B < 255){OCR1B++;}else{stage = 3;}} //Уменьшаем красный
   if (stage == 3){if (OCR0A > 0){OCR0A--;}else{stage = 4;}} //Увеличиваем синий
   if (stage == 4){if (OCR1A < 255){OCR1A++;}else{stage = 5;}} //Уменьшаем зеленый
   if (stage == 5){if (OCR1B > 0){OCR1B--;}else{stage = 6;}} //Увеличиваем красный
   if (stage == 6){if (OCR0A < 255){OCR0A++;}else{stage = 1;}} //Уменьшаем синий
   pause(delay);
}

//Эффект "Случайный цвет"
void eff_rand_color(unsigned int delay)
{
   stage = rand() / 4096; //Случайное число от 0 до 8 (rand() возвращает целое число от 0 до 32768)
   switch (stage)
   {
      case 1:
      {
         OCR1BL = 0x00; //Красный полная яркость
         OCR1AL = 0xff; //Зеленый погашен
         OCR0A = 0xff; //Синий погашен
         break;
      }
      case 2:
      {
         OCR1BL = 0x88; //Половина красного
         OCR1AL = 0x88; //Половина зеленого
         OCR0A = 0xff; //Синий погашен
         break;
      }
      case 3:
      {
         OCR1BL = 0xff; //Красный погашен
         OCR1AL = 0x00; //Зеленый полная яркость
         OCR0A = 0xff; //Синий погашен
         break;
      }
      case 4:
      {
         OCR1BL = 0xff; //Красный погашен
         OCR1AL = 0x88; //Половина зеленого
         OCR0A = 0x88; //Половина синего
         break;
      }
      case 5:
      {
         OCR1BL = 0xff; //Красный погашен
         OCR1AL = 0xff; //Зеленый погашен
         OCR0A = 0x00; //Синий полная яркость
         break;
      }
      case 6:
      {
         OCR1BL = 0x88; //Половина красного
         OCR1AL = 0xff; //Зеленый погашен
         OCR0A = 0x88; //Половина синего
         break;
      }
   }
   pause(delay);
}

//Основная подпрограмма
int main(void)
{
   DDRB=(1<<PB2)|(1<<PB3)|(1<<PB4); //Инициализация порта B
   //DDRD&=~(1<<PD4)|(1<<PD5); //Инициализация порта D
   //PORTD|=(1<<PD4)|(1<<PD5); //Настройка ног PD4 и PD5 на ввод (Кнопки "+" и "-")
   GIMSK = (1<<INT1); //Разрешение прерывания int1 (Кнопка MODE)
   MCUCR = (1<<ISC11) | (1<<ISC10); //Прерывание по появлению низкого уровня
   sei(); //Глобальное разрешение прерываний
   pwm_init(); //Инициализация ШИМ
   while (1)
   {
      /*if(!(PIND & (1<<PIND4))) //Нажатие на кнопку "+"
      {
         if (!pin4hold)
         {
            if (t >= 100)
            {
               t = t - 100; //Уменьшаем задержку
            }
            pin4hold = 1;
         }
      }
      else
      {
         pin4hold = 0;
      }
      if(!(PIND & (1<<PIND5))) //Нажатие на кнопку "-"
      {
         if (!pin5hold)
         {
            t = t + 100; //Увеличиваем задержку
            pin5hold = 1;
         }
      }
      else
      {
         pin5hold = 0;
      }*/
      switch (mode) //Выбор текущего эффекта
      {
         case 1:
         {
            eff_inf_spectr(t); //"Непрерывный спектр"
            break;
         }
         case 2:
         {
            eff_rand_color(t); //"Случайный цвет"
            break;
         }
      }
   }
    return 1;
}
Аватара пользователя
zero648
Вымогатель припоя
Сообщения: 650
Зарегистрирован: Пн июн 18, 2012 12:01:04
Откуда: Челябинская область, Копейск

Re: ВСЁ по прошивке и программированию AT90S2313/ATTiny2313

Сообщение zero648 »

Попробуй подтянуть portd, это исключит генерацию прерывания при рестарте, хотя и без подтяжки работает, но при рестарте срабатывает одно прерывание с INT1, попробуй подтяни хотя бы PD3.
Изображение
Твой код здесь пока ни при чем, проверял на своем коде.
x8973
Встал на лапы
Сообщения: 99
Зарегистрирован: Чт мар 08, 2012 18:05:49
Откуда: Пермь

Re: ВСЁ по прошивке и программированию AT90S2313/ATTiny2313

Сообщение x8973 »

Все три кнопки изначально подтянуты на Vcc резюками по 10 кОм.
Аватара пользователя
zero648
Вымогатель припоя
Сообщения: 650
Зарегистрирован: Пн июн 18, 2012 12:01:04
Откуда: Челябинская область, Копейск

Re: ВСЁ по прошивке и программированию AT90S2313/ATTiny2313

Сообщение zero648 »

C инициализацией портов и прерываний были косячки :))

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

//Основная подпрограмма
int main(void)
{
   DDRB=(1<<PB2)|(1<<PB3)|(1<<PB4); //Инициализация порта B
   DDRD=~((1<<PD5)|(1<<PD4)|(1<<PD3)); //Инициализация порта D
   PORTD|=(1<<PD5)|(1<<PD4)|(1<<PD3); //Настройка ног PD4 и PD5 на ввод (Кнопки "+" и "-")
   GIMSK = (1<<INT1) ; //Разрешение прерывания int1 (Кнопка MODE)
   MCUCR = (1<<ISC11); //Прерывание по появлению низкого уровня
   sei(); //Глобальное разрешение прерываний
   pwm_init(); //Инициализация ШИМ
x8973
Встал на лапы
Сообщения: 99
Зарегистрирован: Чт мар 08, 2012 18:05:49
Откуда: Пермь

Re: ВСЁ по прошивке и программированию AT90S2313/ATTiny2313

Сообщение x8973 »

Хммм... А разве мы вот этим

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

unsigned int status_pinD = PIND&((1<<PD5)|(1<<PD4)|(1<<PD3));

не делаем то же самое?
Аватара пользователя
zero648
Вымогатель припоя
Сообщения: 650
Зарегистрирован: Пн июн 18, 2012 12:01:04
Откуда: Челябинская область, Копейск

Re: ВСЁ по прошивке и программированию AT90S2313/ATTiny2313

Сообщение zero648 »

x8973 писал(а):Хммм... А разве мы вот этим

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

unsigned int status_pinD = PIND&((1<<PD5)|(1<<PD4)|(1<<PD3));

не делаем то же самое?

Нет, этим мы проверяем состояние порта
Аватара пользователя
zero648
Вымогатель припоя
Сообщения: 650
Зарегистрирован: Пн июн 18, 2012 12:01:04
Откуда: Челябинская область, Копейск

Re: ВСЁ по прошивке и программированию AT90S2313/ATTiny2313

Сообщение zero648 »

Вот этот кусок еще поправь:

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

SIGNAL (SIG_INTERRUPT1)//Программа-обработчик прерывания INT1
{
   cli(); //Глобальный запрет прерываний
   unsigned int status_pinD = PIND&((1<<PD5)|(1<<PD4)|(1<<PD3));
      if (status_pinD == 0x30) //Нажата кнопка MODE (PD3)
          {
         if (mode == 2) {mode = 1;} else {mode = 2;} //2 - количество эффектов
          }
      if (status_pinD == 0x20) //Нажата кнопка "+" (PD4)
          {
         if (t >= 100) {t = t - 100;} //Уменьшаем задержку
          }
      if (status_pinD == 0x10) //Нажата кнопка "-" (PD5)
                       {t = t + 100;} //Увеличиваем задержку
   sei(); //Глобальное разрешение прерываний
}

x8973
Встал на лапы
Сообщения: 99
Зарегистрирован: Чт мар 08, 2012 18:05:49
Откуда: Пермь

Re: ВСЁ по прошивке и программированию AT90S2313/ATTiny2313

Сообщение x8973 »

Да, вот теперь работает как надо) Эх, невнимательность моя - такую ошибку тупую пропустил)
x8973
Встал на лапы
Сообщения: 99
Зарегистрирован: Чт мар 08, 2012 18:05:49
Откуда: Пермь

Re: ВСЁ по прошивке и программированию AT90S2313/ATTiny2313

Сообщение x8973 »

Народ, а подскажет кто-нибудь контроллер AVRовский, так же, с четырьмя каналами ШИМ, но с объемом памяти побольше? А то оптимизация не помогает - не хватает памяти для трех и более эффектов...
Ответить

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