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

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

Сообщение zero648 »

x8973 писал(а):С программированием прерывания INT1, вроде как, разобрался. Но теперь "внимание, вопрос". Можно ли использовать для управления кнопками ноги T0 и T1(OC0B)? А то я по незнанию две кнопки из трех на них развел...
Если кнопки на PD3, PD4, PD5, можно все три проверять на одном прерывани INT1.
Реклама
Открыл глаза
Аватара пользователя
Сообщения: 76
Зарегистрирован: Пт май 28, 2010 13:41:16
Откуда: Мариинск, Томск

Сообщение shadivl »

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

Сообщение x8973 »

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

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

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

Сообщение x8973 »

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

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

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

Сообщение 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 раз.
Вымогатель припоя
Аватара пользователя
Сообщения: 650
Зарегистрирован: Пн июн 18, 2012 12:01:04
Откуда: Челябинская область, Копейск

Сообщение zero648 »

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

Сообщение 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

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

Сообщение x8973 »

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

Сообщение zero648 »

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

Сообщение 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;
}
Вымогатель припоя
Аватара пользователя
Сообщения: 650
Зарегистрирован: Пн июн 18, 2012 12:01:04
Откуда: Челябинская область, Копейск

Сообщение zero648 »

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

Сообщение x8973 »

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

Сообщение 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(); //Инициализация ШИМ
Встал на лапы
Сообщения: 99
Зарегистрирован: Чт мар 08, 2012 18:05:49
Откуда: Пермь

Сообщение x8973 »

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

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

unsigned int status_pinD = PIND&((1<<PD5)|(1<<PD4)|(1<<PD3));
не делаем то же самое?
Вымогатель припоя
Аватара пользователя
Сообщения: 650
Зарегистрирован: Пн июн 18, 2012 12:01:04
Откуда: Челябинская область, Копейск

Сообщение zero648 »

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

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

unsigned int status_pinD = PIND&((1<<PD5)|(1<<PD4)|(1<<PD3));
не делаем то же самое?
Нет, этим мы проверяем состояние порта
Вымогатель припоя
Аватара пользователя
Сообщения: 650
Зарегистрирован: Пн июн 18, 2012 12:01:04
Откуда: Челябинская область, Копейск

Сообщение 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(); //Глобальное разрешение прерываний
}

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

Сообщение x8973 »

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

Сообщение x8973 »

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

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