реклама на сайте
подробности

 
 
> Помогите разобраться, мега 128 и внешние прервывания
Старый Бабай
сообщение May 20 2006, 10:48
Сообщение #1


Частый гость
**

Группа: Свой
Сообщений: 104
Регистрация: 5-12-05
Из: Екатеринбург
Пользователь №: 11 823



Народ помогите разобраться где грабли.
Устройство должно отвечать на длинный(12us) и коротрий(4us) старты. На которкий старт отвечает нормально а на длинный ну не хочт никак




#include <io.h>
#include <interrupt.h>
#include <sig-avr.h>
//#include <avr\signal.h>
#include <ina90.h> // _NOP();_SLEEP();
#include <eeprom.h>


typedef unsigned char u08;
typedef char s08;
typedef unsigned short u16;
typedef short s16;
typedef unsigned long u32;
typedef long s32;



volatile u08 Fw=0;

/*****************************************************************************

******************************************************************************/
INTERRUPT(SIG_INTERRUPT0)
//SIGNAL(SIG_INTERRUPT0)
{
/*
// 6 us compare(8us)
//TCCR0 = 0x89;
TCCR0 = 1;
TCNT0 = 0x00;
//OCR0 = 0x20;
TIFR = (1<<OCF0);
while(bit_is_clear(TIFR,1));

if(bit_is_clear(PIND,0)) Fw=2;
else
if(bit_is_set(PIND,0)) Fw=1;

TCCR0 = 0x00;
TCNT0 = 0x00;
//OCR0 = 0x00;
sbi(TIFR,OCF0);

while(bit_is_clear(PIND,0));
*/
TCCR0 = 1;
while(!(PIND&0x01)&&!(TIFR&2));
if(TIFR&2) Fw=2; else Fw=1;
TCCR0 = 0;
TCNT0 = 0;
TIFR |= 1;
while(!(PIND&0x01));
}
/*****************************************************************************

******************************************************************************/
int main(void)
{
DDRA = 0x00;
PORTA = 0x00;
DDRB = 0x00;
PORTB = 0x00;
DDRC = 0xDF;
PORTC = 0x40;
DDRD = 0x00;
PORTD = 0xFF;
DDRE = 0x0F;
PORTE = 0xC8;
DDRF = 0x00;
PORTF = 0x00;
DDRG = 0x00;
PORTG = 0x00;

ACSR = 0x80;

if(bit_is_set(PIND,1))
{
SPI_Init();
/* init Timer0 */
//TCCR0 = 0x89; // old
OCR0 = 0x20;
/* init interrupt */
MCUCR = 0x00;
//MCUCR = 0x30; // SLEP - Power Down
//MCUCSR = (1<<PORF);
MCUCSR = 0x00;
EICRA = 0x00;
EICRB = 0x00;
EIMSK = (1<<INT0);
sei();

for(;;)
{
if(Fw==1)
{
ReadDataSensor();
Fw=0;
}
else
if(Fw==2)
{
ReadDataEEPROM();
Fw=0;
}
//_SLEEP();
}
}
else
{

for(;;)
{
_NOP();
}
}
}
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 5)
beer_warrior
сообщение May 20 2006, 11:50
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 065
Регистрация: 8-10-05
Из: Kiev, UA
Пользователь №: 9 380



Ну мне кажеться, что это хозяйство не успевает отрабатывать столь короткие импульсы. Это тот случай, когда прерывание стоит писать на
ассемблере. Посмотрите листинг и попробуйте посчитать такты, имхо будет
многовато, особенно в части цикла while, там может быть пролет.
Еще добвлю что стоит подумать о том чтобы убрать обработку в основной контекст, а в прерывании только оставить флажок или хэндлер на соответствующую функцию.


--------------------
Вони шукають те, чого нема,
Щоб довести, що його не існує.
Go to the top of the page
 
+Quote Post
Yura_K
сообщение May 20 2006, 19:44
Сообщение #3


Частый гость
**

Группа: Свой
Сообщений: 185
Регистрация: 5-05-06
Из: Ekaterinburg, Russia
Пользователь №: 16 821



Если я правильно понимаю, в прерывании INT0 ожидаем либо 0 на PIND.1 - старт 12us, либо срабатывания компаратора OCR0 - старт 4us (Fclk=32/4us=8 MHz). Тогда реакции на PIND.1=0 никогда не будет. Потому как компаратор сработает раньше. Если наоборот, то тогда какая частота МК, вроде получается: Fclk=32/12us=2.66 MHz, как-то странно smile.gif . Если все таки Fclk=8 MHz, то поменяйте реакцию компаратора на длинный старт 12us, при этом OCR0=8MHz*12us=96. А вообще, лучше все-таки поменять логику программы и, как было сказано beer_warrior, вынести циклы while из обработчика прерывания.


--------------------
Чудес не бывает - бывает мало знаний и опыта!
Go to the top of the page
 
+Quote Post
Старый Бабай
сообщение May 21 2006, 05:36
Сообщение #4


Частый гость
**

Группа: Свой
Сообщений: 104
Регистрация: 5-12-05
Из: Екатеринбург
Пользователь №: 11 823



Спасибо за советы
Буду пробовать
а в код влупил заремленыый кусок
Go to the top of the page
 
+Quote Post
Старый Бабай
сообщение May 22 2006, 03:48
Сообщение #5


Частый гость
**

Группа: Свой
Сообщений: 104
Регистрация: 5-12-05
Из: Екатеринбург
Пользователь №: 11 823



Цитата(Yura_K @ May 20 2006, 22:44) *
Если я правильно понимаю, в прерывании INT0 ожидаем либо 0 на PIND.1 - старт 12us, либо срабатывания компаратора OCR0 - старт 4us (Fclk=32/4us=8 MHz). Тогда реакции на PIND.1=0 никогда не будет. Потому как компаратор сработает раньше. Если наоборот, то тогда какая частота МК, вроде получается: Fclk=32/12us=2.66 MHz, как-то странно smile.gif . Если все таки Fclk=8 MHz, то поменяйте реакцию компаратора на длинный старт 12us, при этом OCR0=8MHz*12us=96. А вообще, лучше все-таки поменять логику программы и, как было сказано beer_warrior, вынести циклы while из обработчика прерывания.




Частота 8 МГц . Старты приходят на INT0 . Короткий 4, длинный 12 мкс. А на PIND.1 происходит переход и вывор режима работы "МАРШ" или "КАЛИБРОВКА"
Go to the top of the page
 
+Quote Post
Старый Бабай
сообщение May 22 2006, 05:06
Сообщение #6


Частый гость
**

Группа: Свой
Сообщений: 104
Регистрация: 5-12-05
Из: Екатеринбург
Пользователь №: 11 823



Переписал прерывание

SIGNAL(SIG_INTERRUPT0)
{
TCCR0 = 1;
while(bit_is_clear(PIND,0));
TCCR0 = 0;
if(TCNT0<40) Fw=1; else Fw=2;
TCNT0 = 0;
while(!(PIND&0x01));
}

Теперь вроде работает
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 16:45
Рейтинг@Mail.ru


Страница сгенерированна за 0.01379 секунд с 7
ELECTRONIX ©2004-2016