Witam,
bazując na kilku kodach znalezionych w sieci popełniłem takie oto coś
#define USART_BAUDRATE 57600
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)
#define MAX_INTS 100 // number of interrupts to be done
volatile int counter = 0;
volatile int ms_counter = 0; // number of seconds / 10000
volatile int s_counter = 0; // number of seconds
volatile int ms[MAX_INTS];
volatile unsigned char s[MAX_INTS];
void UART_init(void)
{
UBRR0H = (unsigned char)(BAUD_PRESCALE >> 8);
UBRR0L = (unsigned char)BAUD_PRESCALE;
UCSR0A = 0;
/* Enable receiver and transmitter */
UCSR0B = (1<<RXEN)|(1<<TXEN);
/* Set frame format: 8data, 2stop bit */
UCSR0C = (1<<USBS)|(3<<UCSZ0);
}
void USART_Transmit( unsigned char data )
{
/* Wait for empty transmit buffer */
while ( !( UCSR0A & (1<<UDRE0)) )
;
/* Put data into buffer, sends the data */
UDR0 = data;
}
void USART_Transmit_String(char* string){
int len;
unsigned char i;
len = strlen(string);
for(i=0; i<len; i++){
USART_Transmit(string[i]);
}
}
void USART_Transmit_Measures(){
int i = 0;
char ms_buf[4]= {0,0,0,0};
char s_buf[3] = {0,0,0};
for(i = 0; i < MAX_INTS; i++){
itoa(ms[i], ms_buf, 10);
itoa(s[i], s_buf, 10);
USART_Transmit_String(s_buf);
USART_Transmit_String("s ");
USART_Transmit_String(ms_buf);
USART_Transmit_String("ms\r\n");
}
}
int main(void)
{
// serial port initialization
UART_init();
DDRD = 0;
DDRD |= (1 << 1); // Set PD1 as ACK output
TCCR1B |= (1 << WGM12); // Configure timer 1 for CTC mode
TIMSK |= (1 << OCIE1A); // Enable CTC interrupt
PORTD = 0; // int0
EIMSK |= (1 << 0); //enable int0
OCR1A = 1600; // Set CTC compare value to 0,001Hz at 16MHz AVR clock, with a prescaler of 1
TCCR1B |= ((1 << CS10) | (0 << CS11) | (0 << CS12)); // Set up timer at Fcpu
USART_Transmit_String ("Welcome on board, sir!\n\r");
sei(); // Enable global interrupts
PORTD = (0 << 1); //
PORTD = (1 << 1); // send ACK
PORTD = (0 << 1); //
while(1) {}
}
ISR(TIMER1_COMPA_vect)
{
if(ms_counter <10000)
ms_counter ++;
else{
ms_counter = 0;
s_counter ++;
}
}
ISR(INT0_vect)
{
if(counter < MAX_INTS ){
ms[counter ] = ms_counter ;
s[counter ] = s_counter ;
counter ++;
USART_Transmit('+');
}
else{
USART_Transmit_Measures();
counter = 0;
_delay_ms(500);
}
_delay_ms(10);
PORTD = (0 << 1); //
PORTD = (1 << 1); // send ACK
PORTD = (0 << 1); //
ms_counter = 0;
s_counter = 0;
OCR1A = 1600;
}
Jak widać zależy mi na serii pomiarów czasu obsługi przerwania na porcie LPT. Program obsługi przerwania napisany jest po stronie systemu QNX (po wykryciu przerwania na porcie LPT wysyłany jest sygnał na STROBE [INT0 na AVR] ) i działa.
Problem polega na tym, że raz na jakiś czas nie jest zgłaszane przerwanie, więc całość (polegająca na interakcji - przerwanie -> odpowiedź) wisi.
Dodałem nawet opóźnienie pomiędzy obliczeniem czasu reakcji a wywołaniem kolejnego przerwania, ale i to nic nie dało.
Wydaje mi się, że wina leży po stronie AVR, ponieważ gdy w momencie "zwisu" zresetuję płytkę pomiary znowu ruszają.
Niestety nie mam pojęcia, co może powodować tak dziwne zachowanie.