Страница 108 из 132
Re: ВСЁ по прошивке и программированию AT90S2313/ATTiny2313
Добавлено: Пт авг 10, 2012 00:36:12
zero648
x8973 писал(а):С программированием прерывания INT1, вроде как, разобрался. Но теперь "внимание, вопрос". Можно ли использовать для управления кнопками ноги T0 и T1(OC0B)? А то я по незнанию две кнопки из трех на них развел...
Если кнопки на PD3, PD4, PD5, можно все три проверять на одном прерывани INT1.
Re: ВСЁ по прошивке и программированию AT90S2313/ATTiny2313
Добавлено: Пт авг 10, 2012 08:14:19
shadivl
zero648
Принципиально на PD0 кнопку нужно?
Нет, не принципиально, просто я понять хочу, почему он так реагирует.
Re: ВСЁ по прошивке и программированию AT90S2313/ATTiny2313
Добавлено: Пт авг 10, 2012 08:41:26
x8973
zero648 писал(а):Если кнопки на PD3, PD4, PD5
Да, они на PD4 и PD5. Но, честно говоря, я понятия не имею, как это замутить.
А было бы неплохо, а то с опросом кнопок код вырос, и памяти контроллера только-только на два эффекта хватило)
Re: ВСЁ по прошивке и программированию AT90S2313/ATTiny2313
Добавлено: Пт авг 10, 2012 08:50:35
Gudd-Head
Не очень понимаю кому что надо с кнопками, но можно замутить вызов прерывания при нажатия ЛЮБОЙ кнопки, если развязаться диодами (и если нога внешнего прерывания свободна, естессно). В обработчике прерывания уже смотреть какая кнопка нажата.
Re: ВСЁ по прошивке и программированию AT90S2313/ATTiny2313
Добавлено: Пт авг 10, 2012 08:54:02
x8973
Gudd-Head писал(а):если развязаться диодами
Если развязываться диодами, то значит - перекраивать плату. А если уже на то пошло, то я лучше кнопки по новой разведу.
Re: ВСЁ по прошивке и программированию AT90S2313/ATTiny2313
Добавлено: Пт авг 10, 2012 08:57:00
Gudd-Head
Ну это так, на будущее. Может, пригодится...
Re: ВСЁ по прошивке и программированию AT90S2313/ATTiny2313
Добавлено: Пт авг 10, 2012 09:18:27
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) {делаем третье}
}
Re: ВСЁ по прошивке и программированию AT90S2313/ATTiny2313
Добавлено: Пт авг 10, 2012 09:24:39
zero648
x8973 писал(а):Если развязываться диодами, то значит - перекраивать плату. А если уже на то пошло, то я лучше кнопки по новой разведу.
Зачем плату перекраивать, подпаял диоды и все, или вообще SMD-шные, они на дорожки хорошо приделываются.
Re: ВСЁ по прошивке и программированию AT90S2313/ATTiny2313
Добавлено: Пт авг 10, 2012 10:48:38
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
Re: ВСЁ по прошивке и программированию AT90S2313/ATTiny2313
Добавлено: Пт авг 10, 2012 10:57:08
x8973
Не вышло. Все три кнопки работают как одна.
Re: ВСЁ по прошивке и программированию AT90S2313/ATTiny2313
Добавлено: Пт авг 10, 2012 11:02:09
zero648
x8973 писал(а):Не вышло. Все три кнопки работают как одна.
Ну покаж код, посмотрим
Re: ВСЁ по прошивке и программированию AT90S2313/ATTiny2313
Добавлено: Пт авг 10, 2012 11:06:15
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;
}
Re: ВСЁ по прошивке и программированию AT90S2313/ATTiny2313
Добавлено: Пт авг 10, 2012 12:06:57
zero648
Попробуй подтянуть portd, это исключит генерацию прерывания при рестарте, хотя и без подтяжки работает, но при рестарте срабатывает одно прерывание с INT1, попробуй подтяни хотя бы PD3.

Твой код здесь пока ни при чем, проверял на своем коде.
Re: ВСЁ по прошивке и программированию AT90S2313/ATTiny2313
Добавлено: Пт авг 10, 2012 12:21:09
x8973
Все три кнопки изначально подтянуты на Vcc резюками по 10 кОм.
Re: ВСЁ по прошивке и программированию AT90S2313/ATTiny2313
Добавлено: Пт авг 10, 2012 12:24:08
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(); //Инициализация ШИМ
Re: ВСЁ по прошивке и программированию AT90S2313/ATTiny2313
Добавлено: Пт авг 10, 2012 12:30:11
x8973
Хммм... А разве мы вот этим
Код: Выделить всё
unsigned int status_pinD = PIND&((1<<PD5)|(1<<PD4)|(1<<PD3));
не делаем то же самое?
Re: ВСЁ по прошивке и программированию AT90S2313/ATTiny2313
Добавлено: Пт авг 10, 2012 12:38:10
zero648
x8973 писал(а):Хммм... А разве мы вот этим
Код: Выделить всё
unsigned int status_pinD = PIND&((1<<PD5)|(1<<PD4)|(1<<PD3));
не делаем то же самое?
Нет, этим мы проверяем состояние порта
Re: ВСЁ по прошивке и программированию AT90S2313/ATTiny2313
Добавлено: Пт авг 10, 2012 14:03:05
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(); //Глобальное разрешение прерываний
}
Re: ВСЁ по прошивке и программированию AT90S2313/ATTiny2313
Добавлено: Пт авг 10, 2012 16:33:46
x8973
Да, вот теперь работает как надо) Эх, невнимательность моя - такую ошибку тупую пропустил)
Re: ВСЁ по прошивке и программированию AT90S2313/ATTiny2313
Добавлено: Вс авг 19, 2012 11:05:26
x8973
Народ, а подскажет кто-нибудь контроллер AVRовский, так же, с четырьмя каналами ШИМ, но с объемом памяти побольше? А то оптимизация не помогает - не хватает памяти для трех и более эффектов...