Witam, mam dziwny problem, pomoże mi ktoś go rozwiązać?
Chodzi o to, że buduję urządzenie, które na żądanie będzie mierzyło temperaturę układem DS18B20. Żądanie odbywa się poprzez naciśnięcie odpowiedniego przycisku na pilocie RC5. Całe moje urządzenie to dwa AVR:
Atmega8 (jako dekoder RC5, który wysyła odebrany adres i komendę poprzez USART do drugiego uC)
Atmega32 (jako właściwy procesor) - tu odbywa się odbiór USART, sprawdzenie warunków na komendę (funkcja switch).
Do Atmegi32 mam też podłączone diody, które się włączają po wciśnięciu odpowiednich klawiszy, oraz fotorezystor w układzie dzielnika napięcia, po wciśnięciu klawisza na pilocie istnieje możliwość pomiaru napięcia (ADC) na tym czujniku oświetlenia. Te elementy działają bezproblemowo. Jednak podczas żądania pomiaru temperatury dzieją się dziwne rzeczy.
Urządzenie mierzy temperaturę, wysyła ją przez UART (FT232 > USB) do komputera, po czym się resetuje. Nie zaobserwowałem takiego zjawiska podczas ciągłego pomiaru w nieskończonej pętli main()... while(1)...
Niezależnie jakie dam opóźnienie po odczycie temperatury, nawet 10s, to po tym czasie procesorek się resetuje. Wiem to, ponieważ po resecie wysyłane jest powitanie na UART. Podłączony mam też na przerwaniu INT0 zegarek DS1307. On działa dobrze. A dlaczego poruszam sprawę jego istnienia - bo zauważyłem, że Atmega nie resetuje się całkiem. Po resecie w odstępie ok. 100ms rysują się na LCD (HD44780) krateczki - taki jakby pasek postępu. Zauważyłem, że po tym śmiesznym resecie po pomiarze temperatury układ przerwanie INT0 dalej jest aktywne bo zegarek je inicjuje - co przerywa proces rysowania ładowania paska. Dlaczego ten program się tak dziwnie zachowuje, że w zależności gdzie i kiedy wywołam funkcję odczytu temperatury z DS18B20 to albo układ się resetuje albo nie. Poniżej zamieszczam parę funkcji. Funkcje do obsługi czujnika DS18B20 zapożyczyłem z XYZ Hobby Robot - kurs AVR
gettemp - funkcja odczytu temperatury
funkcja przerwania od odbioru USART oraz funkcja rozp - rozpoznająca otrzymany komunikat
A oto co dostaję na komputerze w terminalu
Początkowo wciśnięto klawisz 1, by zaświecić jedną z diodek LED, później klawisz pomiary temperatury.
Chodzi o to, że buduję urządzenie, które na żądanie będzie mierzyło temperaturę układem DS18B20. Żądanie odbywa się poprzez naciśnięcie odpowiedniego przycisku na pilocie RC5. Całe moje urządzenie to dwa AVR:
Atmega8 (jako dekoder RC5, który wysyła odebrany adres i komendę poprzez USART do drugiego uC)
Atmega32 (jako właściwy procesor) - tu odbywa się odbiór USART, sprawdzenie warunków na komendę (funkcja switch).
Do Atmegi32 mam też podłączone diody, które się włączają po wciśnięciu odpowiednich klawiszy, oraz fotorezystor w układzie dzielnika napięcia, po wciśnięciu klawisza na pilocie istnieje możliwość pomiaru napięcia (ADC) na tym czujniku oświetlenia. Te elementy działają bezproblemowo. Jednak podczas żądania pomiaru temperatury dzieją się dziwne rzeczy.
Urządzenie mierzy temperaturę, wysyła ją przez UART (FT232 > USB) do komputera, po czym się resetuje. Nie zaobserwowałem takiego zjawiska podczas ciągłego pomiaru w nieskończonej pętli main()... while(1)...
Niezależnie jakie dam opóźnienie po odczycie temperatury, nawet 10s, to po tym czasie procesorek się resetuje. Wiem to, ponieważ po resecie wysyłane jest powitanie na UART. Podłączony mam też na przerwaniu INT0 zegarek DS1307. On działa dobrze. A dlaczego poruszam sprawę jego istnienia - bo zauważyłem, że Atmega nie resetuje się całkiem. Po resecie w odstępie ok. 100ms rysują się na LCD (HD44780) krateczki - taki jakby pasek postępu. Zauważyłem, że po tym śmiesznym resecie po pomiarze temperatury układ przerwanie INT0 dalej jest aktywne bo zegarek je inicjuje - co przerywa proces rysowania ładowania paska. Dlaczego ten program się tak dziwnie zachowuje, że w zależności gdzie i kiedy wywołam funkcję odczytu temperatury z DS18B20 to albo układ się resetuje albo nie. Poniżej zamieszczam parę funkcji. Funkcje do obsługi czujnika DS18B20 zapożyczyłem z XYZ Hobby Robot - kurs AVR
gettemp - funkcja odczytu temperatury
void gettemp(void)
{
double temperature = 0;
//unsigned char ds18b20_pad[9];
uint8_t ds18b20_pad[9];
if(ds18b20_ConvertT())
{
_delay_ms(750);
ds18b20_Read(ds18b20_pad);
temperature = ((ds18b20_pad[1] << 8) + ds18b20_pad[0]) / 16.0 ;
dtostrf(temperature,3,2,temperaturenapis);
USART_Write("POMIAR TEMPERATURY\r\n");
}
}
funkcja przerwania od odbioru USART oraz funkcja rozp - rozpoznająca otrzymany komunikat
ISR(USART_RXC_vect)
{
//gettemp();
cli();
i++;
odbior[i] = USART_Receive();
if (odbior[i] == 13)
{
rozp(odbior);
i = 0;
}
sei();
}
void rozp(unsigned char* odbior)
{
char tekst[32];
adres = ((odbior[2]-48)*10+odbior[3]-48);
komenda = ((odbior[6]-48)*10+odbior[7]-48);
USART_Write("--> ");
for (j = 1; j <= i; j ++) USART_Transmit(odbior[j]);
sprintf(tekst,"Adres: %d, Komenda: %d\r", adres, komenda);
USART_Write(tekst);
if (adres == 0)
{
switch (komenda)
{
case 1:
PORTC ^= 1 << PC7;
USART_Write("Zmieniono wyjście 1\r\n");
break;
case 2:
PORTC ^= 1 << PC6;
USART_Write("Zmieniono wyjście 2\r\n");
break;
case 3:
PORTC ^= 1 << PC5;
USART_Write("Zmieniono wyjście 3\r\n");
break;
case 4:
PORTC ^= 1 << PC4;
USART_Write("Zmieniono wyjście 4\r\n");
break;
case 5:
PORTC ^= 1 << PC3;
USART_Write("Zmieniono wyjście 5\r\n");
break;
case 6:
PORTC ^= 1 << PC2;
USART_Write("Zmieniono wyjście 6\r\n");
break;
case 11:
USART_Write("Resetowanie AVR...\r\n");
_delay_ms(10);
Reset_AVR();
break;
case 54:
ac_read();
USART_Write("Aktualne oświetlenie: ");
USART_Write(ac);
USART_Write("V\r\n");
break;
case 60:
gettemp();
USART_Write("Aktualna temperatura: ");
USART_Write(temperaturenapis);
USART_Write("°C\r\n");
break;
case 63:
gettemp();
_delay_ms(10000);
break;
default:
USART_Write("Komenda nierozpoznana! \r\n");
}
} else USART_Write("Adres nierozpoznany! \r\n");
}
A oto co dostaję na komputerze w terminalu
[RESET]
--> A00,K01
Adres: 0, Komenda: 1
Zmieniono wyjście 1
--> A00,K60
Adres: 0, Komenda: 60
POMIAR TEMPERATURY
Aktualna temperatura: 25.06°C
[RESET]
Początkowo wciśnięto klawisz 1, by zaświecić jedną z diodek LED, później klawisz pomiary temperatury.