logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[Atmega16][C]Przerwanie wywołuje sie samoistnie

PrzemyslawK 05 Gru 2010 14:26 866 1
REKLAMA
  • #1 8829180
    PrzemyslawK
    Poziom 1  
    Witam,
    Napisalem gdzie zaczyna sie problem, uk wywołuje przerwanie samoistnie, zaraz po globalnym zezwoleniu na przerwania sei() sam przechodzi do przerwania i je wykonuje. Chce mieć możliwość przerwania pętli while w jakimkolwiek momencie. Sposób jaki zastosowałem uważam za mało efektywny ale nie wiem jak inaczej się za to zabrać. Pozdrawiam
    #define F_CPU 16000000L
    #include <avr/io.h>
    #include <util/delay.h>
    #include <inttypes.h>
    #include <avr/interrupt.h>
    #include "HD44780.h"
    #include "HD44780.c"
    
    uint8_t volatile wyjscie;
    
    //obsługa przerwania
    ISR(SIG_INTERRUPT0)
    {
    _delay_ms(50);
    wyjscie=0;
    }
    
    //---------------------------------------------------------------------------
    
    void main (void)
    {
    
    GICR|=(1<<INT0);
    MCUCR&=0xf0;
    MCUCR|=(1<<ISC01);
    
    
    uint8_t menu;
    menu=2;
    uint8_t scratch_pad[2]={0x00,0x00};
    uint8_t temperatura[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
    uint8_t temperatura_pamiec[8];
    uint8_t a=0;
    
    int j=0;
    
    PORTD|=0x0c;
    DDRD &=0xf3; 
    
    while(1)
    {
    wyjscie=1;
    if(!(PIND&0x04))
    	{
    		_delay_ms(50);
    		menu+=1;
    		j=0;
    		if(menu==3)
    			{
    			menu=0;
    			}
    		while(!(PIND&0x04)){}
    		_delay_ms(50);
    
    	switch(menu)
    		{
    		case 0:
    			LCD_Clear();
    			LCD_WriteText("1-Pojedynczy");
    			LCD_GoTo(0,1);
    			LCD_WriteText("pomiar");
    			break;
    		case 1:
    			LCD_Clear();
    			LCD_WriteText("2- Poprzedni");
    			LCD_GoTo(0,1);
    			LCD_WriteText("pomiar");
    			break;
    		case 2:
    			LCD_Clear();
    			LCD_WriteText("3- Ciagly");
    			LCD_GoTo(0,1);
    			LCD_WriteText("pomiar");
    			break;
    		}
    	}
    
    
    
    if(!(PIND&0x08))
    	{	
    	_delay_ms(50);
    	j=0;
    	while(!(PIND&0x08)){}
    	_delay_ms(50);	
    
    	switch(menu)
    	{
    
    	case 0:
    
    		LCD_Clear();
    		LCD_GoTo(1,0);
    		LCD_WriteText("Trwa pomiar...");
    		for(uint8_t j=0;j<7;j++)
    			{
    			temperatura_pamiec[j]=temperatura[j];
    			}
    		ustabilizowanie_temp(scratch_pad);
    		temperatura_lcd(scratch_pad,temperatura);
    		a=0;						
    		LCD_Clear();
    		LCD_WriteText("Temp= ");
    		LCD_WriteText(temperatura);	
    		LCD_WriteData(0);
    		LCD_WriteText("C");
    		break;
    
    	case 1:
    
    		a^=0xff;
    		if(a)
    			{
    			if(!(temperatura_pamiec[0]))
    				{	
    				LCD_Clear();
    				LCD_WriteText("Brak pomiaru");
    				}
    			else
    				{
    				LCD_Clear();
    				LCD_WriteText("Poprzedni pomiar");
    				LCD_GoTo(0,1);
    				LCD_WriteText("Temp= ");
    				LCD_WriteText(temperatura_pamiec);
    				LCD_WriteData(0);
    				LCD_WriteText("C");
    				}
    			}
    		else
    			{	
    			if(!(temperatura[0]))
    				{	
    				LCD_Clear();
    				LCD_WriteText("Brak pomiaru");
    				}
    			else
    				{
    				LCD_Clear();
    				LCD_WriteText("Aktualny pomiar");
    				LCD_GoTo(0,1);
    				LCD_WriteText("Temp= ");
    				LCD_WriteText(temperatura);
    				LCD_WriteData(0);
    				LCD_WriteText("C");
    				}
    			}
    		break;
    //POCZATEK PROBLEMU
    
    	case 2:
    		sei();
    		while(wyjscie)
    			{
    			
    			if(reset_1wire())
    				{
    				zapis_bajtu(0xcc);
    				zapis_bajtu(0x44);
    				while(!odczyt_bitu()){} 
    				if(reset_1wire())
    					{	
    					zapis_bajtu(0xcc);
    					zapis_bajtu(0xbe);
    					for( i=0; i<2; i++)
    						{
    						scratch_pad[i]=odczyt_bajtu();
    						}
    					}	
    				temperatura_lcd(scratch_pad,temperatura);	
    				LCD_Clear();
    				LCD_WriteText("Temp= ");
    				LCD_WriteText(temperatura);	
    				LCD_WriteData(0);
    				LCD_WriteText("C");
    				}
    			else
    				{
    				LCD_Clear();
    				LCD_WriteText("NIE WYKRYTO");
    				LCD_GoTo(0,1);
    				LCD_WriteText("1WIRE");
    				
    				}
    			}
    		cli();	
    		break;
    	}
    }
    //KONIEC PROBLEMU
    }
    }


    ]
  • REKLAMA
  • #2 8829293
    rpal
    Poziom 27  
    Mnie też się kompletnie nie podoba twoje przerwanie, od kiedy to w przerwaniach stosuje się procedury opóźniajace? Program postawiłeś na głowie inna sprawa że jak skasujesz flagę wystąpienia przerwania w rejestrze GIFR a potem zezwolisz na wykonanie przez SEI to program obsłuży je tylko wtedy kiedy ono wystąpi. Tylko że jak obsługa będzie taka jaką ją zrobiłeś za długo to nie pochodzi bez wykrzaczenia się.
REKLAMA