Не нашел примера использования PCINT для Attiny13

Обсуждаем контроллеры компании Atmel.
Ответить
Аватара пользователя
c2n
Сверлит текстолит когтями
Сообщения: 1193
Зарегистрирован: Ср июл 25, 2012 21:40:09
Откуда: Самара
Контактная информация:

Не нашел примера использования PCINT для Attiny13

Сообщение c2n »

Доброго дня.На третий день празднеств решил побаловаться с Тини13, переработать код товарисча, в более компактную форму.
Решил за одно изучить использование прерываний PCINT, на практике. До этого с такой мелюзгой и этим прерыванием не работал.
Изображение

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

#include <avr/io.h>
#include <avr/interrupt.h>

int Counter=1;

ISR(PCINT0_vect) //Прерывание на PCINT
{
	sei(); //Запретить прерывания...дабы неповадно было
	if (Counter >=4) // если переменная 4 и более
	{
	Counter = 1;	// приравниваем к 1.
	} else // иначе
	{
	Counter++;	// инкремент счетчика	
	}
	cli(); //Разрешить прерывание
}

int main(void)
{
	sei(); //Запретил прерывания, дабы не повадно было
	DDRB = 0b00111; //установил пол порта на вход, половину на выход
	PORTB = 0b00111; //включил порт 
	GIMSK = GIMSK|(1<<PCIE); //разрешил прерывание PCINT0
	PCMSK = PCMSK|(1<<PCINT4); //Разрешил вызов прерывания при изменении наа порту 4
	cli(); //Разрешил прерывания
    while(1)
    {
		PORTB = Counter; //вывожу некую переменную в порт.
    }
}
Ну и как результат - не работает :(
Понятно что ошибка в ДНК, да и отравление еще не прошло. Подскажите...
Вложения
Т13.jpg
(104.58 КБ) 4840 скачиваний
Реклама
codenamehawk
Вымогатель припоя
Сообщения: 528
Зарегистрирован: Вт фев 09, 2010 17:52:26

Re: Не нашел примера использования PCINT для Attiny13

Сообщение codenamehawk »

Ошибки в :
sei(); //Запретить прерывания...дабы неповадно было
sei(); Разрешает прерывания.

cli(); //Разрешить прерывание -- запрещает.

Они вообще не нужны в прерывании, там все автоматом делается.

При изменении переменной в прерывании необходимо добавить квалификатор volatile.
Примерно так.
volatile int Counter=1;

Остального не смотрел.
Последний раз редактировалось codenamehawk Пт янв 03, 2014 20:53:59, всего редактировалось 1 раз.
Реклама
Аватара пользователя
c2n
Сверлит текстолит когтями
Сообщения: 1193
Зарегистрирован: Ср июл 25, 2012 21:40:09
Откуда: Самара
Контактная информация:

Re: Не нашел примера использования PCINT для Attiny13

Сообщение c2n »

http://radiokot.ru/forum/viewtopic.php? ... 2#p1188562
Тут мои догадки "подтвердились", только комрады плавно перешли с Сей на АСМу :( а я на этом диалекте пока не очень...
codenamehawk писал(а):Они не нужны в прерывании, там все автоматом делается.
Но во многоих источниках пишут - пользуй RETI, или з-апрещай прерывания делай что надо и потом разрешай т.к. SREG при возникновении прерывания обнуляется...
=======

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

CLI();
SEI();


местами поменял. Не помогло :(
Последний раз редактировалось c2n Пт янв 03, 2014 21:04:47, всего редактировалось 1 раз.
codenamehawk
Вымогатель припоя
Сообщения: 528
Зарегистрирован: Вт фев 09, 2010 17:52:26

Re: Не нашел примера использования PCINT для Attiny13

Сообщение codenamehawk »

Компилятор сам запретит прерывания при входе в прерывание и разрешит при выходе.
(Это относится к языку С, на АСМ все ручками)
Реклама
Эиком - электронные компоненты и радиодетали
codenamehawk
Вымогатель припоя
Сообщения: 528
Зарегистрирован: Вт фев 09, 2010 17:52:26

Re: Не нашел примера использования PCINT для Attiny13

Сообщение codenamehawk »

Создайте проект в протеус, посмотрю.
Реклама
Аватара пользователя
pyzhman
Друг Кота
Сообщения: 7016
Зарегистрирован: Вс июл 12, 2009 19:15:29
Откуда: Ижевск
Контактная информация:

Re: Не нашел примера использования PCINT для Attiny13

Сообщение pyzhman »

codenamehawk писал(а):Компилятор сам запретит
И даже сам камень.
Docendo discimus
Реклама
codenamehawk
Вымогатель припоя
Сообщения: 528
Зарегистрирован: Вт фев 09, 2010 17:52:26

Re: Не нашел примера использования PCINT для Attiny13

Сообщение codenamehawk »

pyzhman писал(а): И даже сам камень.

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

Re: Не нашел примера использования PCINT для Attiny13

Сообщение zero648 »

codenamehawk писал(а):И где тут смеяться?
Зачем смеяться? Глобальные прерывания аппаратно запрещаются при входе в прерывание, и разрешаются ком-ой RETI при выходе.
Аватара пользователя
c2n
Сверлит текстолит когтями
Сообщения: 1193
Зарегистрирован: Ср июл 25, 2012 21:40:09
Откуда: Самара
Контактная информация:

Re: Не нашел примера использования PCINT для Attiny13

Сообщение c2n »

протеус - зло!
а отладчик системы драгон у меня помер :(

Код - рабочий.
Спойлер

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

#include <avr/io.h>
#include <avr/interrupt.h>

int Counter=1;

ISR(PCINT0_vect) //Прерывание на PCINT
{
	
	if (Counter >=4) // если переменная 4 и более
	{
		Counter = 1;   // приравниваем к 1.
	} else // иначе
	{
		Counter++;   // инкремент счетчика
	}
	
}

int main(void)
{
	cli(); //Запретил прерывания, дабы не повадно было
	DDRB = 0b00111; //установил пол порта на вход, половину на выход
	PORTB = 0b00111; //включил порт
	GIMSK = GIMSK|(1<<PCIE); //разрешил прерывание PCINT0
	PCMSK = PCMSK|(1<<PCINT4); //Разрешил вызов прерывания при изменении наа порту 4
	sei(); //Разрешил прерывания
	while(1)
	{
		PORTB = Counter; //вывожу некую переменную в порт.
	}
}
Теперь осталось разобраться, как определить On_Button_Down и On_Button_Up, но это другая песня

Спасибо. надеюсь новичкам поможет.
а мне - закусывать нада :beer: всех с новым годом

=====
Ну да

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

volatile
- указывает компилятору не проводить оптимизацию...
Думаю в моем случае это не существенно, но по хорошему - надо.
Последний раз редактировалось c2n Пт янв 03, 2014 22:14:32, всего редактировалось 2 раза.
codenamehawk
Вымогатель припоя
Сообщения: 528
Зарегистрирован: Вт фев 09, 2010 17:52:26

Re: Не нашел примера использования PCINT для Attiny13

Сообщение codenamehawk »

zero648 писал(а): Зачем смеяться? Глобальные прерывания аппаратно запрещаются при входе в прерывание, и разрешаются ком-ой RETI при выходе.
Это я уже написал выше, но при чем тут "сам камень"?
Камень выполнит то, что ему прикажет программа.
codenamehawk
Вымогатель припоя
Сообщения: 528
Зарегистрирован: Вт фев 09, 2010 17:52:26

Re: Не нашел примера использования PCINT для Attiny13

Сообщение codenamehawk »

То c2n
Выбросите cli(); и sei(); из обработчика прерывания.

В прерывании используют sei(); , только если необходимо отловить следующее прерывание, находясь в другом прерывании.
И то это надо очень осторожно применять, программа может зациклиться.
Аватара пользователя
oleg110592
Друг Кота
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Re: Не нашел примера использования PCINT для Attiny13

Сообщение oleg110592 »

codenamehawk писал(а):Это я уже написал выше, но при чем тут "сам камень"?
Камень выполнит то, что ему прикажет программа.
человек хотел сказать
что если МК начал выполнять программу прерывания, то вход в другие прерывания "блокируется" (автоматически) сбросом флага I регистра статуса, и другие прерывания если произошла установка их флагов, будут ожидать пока флаг I не будет установлен. Флаг I устанавливается при выходе из прерывания командой reti
это делает сам "камень" без "приказов" и компилятор Си такого никогда не делает:
codenamehawk писал(а):Компилятор сам запретит прерывания при входе
достаточно листинг посмотреть и в ассемблерной программе "ручками" совсем не надо этого делать.
для примера тестовый код:
Спойлер

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

// -----------------------------------------
// cpu:     ATmega8
// speed:   8 mhz (max: 16 mhz)
// -----------------------------------------
#include <avr/io.h>
#include <avr/interrupt.h>

#if !defined (__AVR_ATmega8__)
#error __AVR_ATmega8__ not defined !
#endif

#if !defined (F_CPU)
#define F_CPU 8000000
#endif

#define RAMSTART 0x0060
#define RAMSIZE (RAMEND-RAMSTART)

ISR(TIMER0_OVF_vect) // Timer/Counter0 Overflow
{
	TCNT0 = 178;
	// ... ;
}
// --------------
// --- Timer0 ---
// --------------
void Timer0_Init(void)
{
	// Timer0 settings: ~ 79872 ticks (9984 us / 9,984 ms / 0,009984 sec)
	TCCR0 = (1<<CS02) | (1<<CS00); // CLK/1024
	TIMSK = (1 << TOIE0); // Timer/Counter0 Overflow Interrupt Enable
	TCNT0 = 178;
}
// --------------
// --- main() ---
// --------------
int main()
{
	Timer0_Init();
	sei(); // enable interrupts
	for (;;)
	return 0;
}
листинг обработчика прерывания после компиляции:
Спойлер

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

ISR(TIMER0_OVF_vect) // Timer/Counter0 Overflow
{
  38:	1f 92       	push	r1
  3a:	0f 92       	push	r0
  3c:	0f b6       	in	r0, 0x3f	; 63
  3e:	0f 92       	push	r0
  40:	11 24       	eor	r1, r1
  42:	8f 93       	push	r24
	TCNT0 = 178;
  44:	82 eb       	ldi	r24, 0xB2	; 178
  46:	82 bf       	out	0x32, r24	; 50
	// ... ;
}
  48:	8f 91       	pop	r24
  4a:	0f 90       	pop	r0
  4c:	0f be       	out	0x3f, r0	; 63
  4e:	0f 90       	pop	r0
  50:	1f 90       	pop	r1
  52:	18 95       	reti
нет там команды cli
codenamehawk
Вымогатель припоя
Сообщения: 528
Зарегистрирован: Вт фев 09, 2010 17:52:26

Re: Не нашел примера использования PCINT для Attiny13

Сообщение codenamehawk »

"Компилятор сам запретит прерывания при входе в прерывание" тут я ошибся.
(Ожидал,что раз есть RET и RETI, то есть и два вызова по аналогии.)

Действительно, сам камень аппаратно запрещает прерывания.
Аватара пользователя
pyzhman
Друг Кота
Сообщения: 7016
Зарегистрирован: Вс июл 12, 2009 19:15:29
Откуда: Ижевск
Контактная информация:

Re: Не нашел примера использования PCINT для Attiny13

Сообщение pyzhman »

Фуф, а я то уже наглотался валидола и начал переосмыслять структуру прерываний... :))
:beer:
Docendo discimus
Alkul
Держит паяльник хвостом
Сообщения: 933
Зарегистрирован: Ср апр 13, 2011 11:09:20
Откуда: Екатеринбург

Re: Не нашел примера использования PCINT для Attiny13

Сообщение Alkul »

c2n писал(а):т.к. SREG при возникновении прерывания обнуляется...
С точностью до наоборот :)
В регистре SREG при вызове обработчика прерывания аппаратно сбрасывается только флаг I (флаг глобального запрета прерываний) Все остальные флаги не изменяются. А вот сам обработчик прерывания вполне может изменить какие-то флаги. Поэтому при использовании прерываний в обработчике обязательно нужно писать следующий код:

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

INTERRUPT:               ;Имя выбрано только для примера
  push R16               ;Сохранить на стеке регистр, который будет "испорчен" при сохранении регистра состояния
  in R16,SREG            ;Скопировать содержимое регистра состояний в регистр R16
  push R16               ;Сохранить на стеке содержимое регистра состояний

  push R17               ;Регистры выбраны для примера,
  push ZL                ;в котором показывается необходимость
  push ZH                ;сохранения регистров, использованных в обработчике прерывания

; ... Здесь расположено тело обработчика прерывания                             

  pop ZH                 ;Восстановить из стека
  pop ZL                 ;регистры, использованные
  pop R17                ;в обработчике прерывания

  pop R16                ;Восстановить из стека содержимое регистра состояний
  out SREG,R16           ;Восстановить регистр состояний
  pop R16                ;Восстановить "испорченный" при сохранении SREG регистр
  reti
Регистры R17, ZL и ZH взяты наугад. Предположим, что эти регистры используются в коде обработчика прерывания.
Смысл в том, что вызов обработчика прерывания не должен никак сказываться на работе основной программы после выхода из обработчика. Поэтому обязательно нужно после входа в обработчик прерывания сохранить, а перед выходом из обработчика восстановить SREG и все задействованные в обработчике регистры.
codenamehawk писал(а):Ожидал,что раз есть RET и RETI, то есть и два вызова по аналогии
Нет :)
Разница между RET и RETI лишь в том, что RET снимает со стека адрес возврата и переходит по нему, а RETI, кроме этого еще и глобально разрешает прерывания.
Valek174
Первый раз сказал Мяу!
Сообщения: 21
Зарегистрирован: Ср апр 24, 2013 19:33:05

Re: Не нашел примера использования PCINT для Attiny13

Сообщение Valek174 »

Здравствуйте!
Подскажите пожалуйста как определить какое из внешних прерываний PCINT4 или PCINT3 сработало?
Аватара пользователя
pyzhman
Друг Кота
Сообщения: 7016
Зарегистрирован: Вс июл 12, 2009 19:15:29
Откуда: Ижевск
Контактная информация:

Re: Не нашел примера использования PCINT для Attiny13

Сообщение pyzhman »

Считать состояние порта и определиться с нужным действием.
Docendo discimus
Ответить

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