davidpi Napisano Listopad 24, 2012 Udostępnij Napisano Listopad 24, 2012 Witam. Mam pewien problem przy pisaniu programu. Mam dwie Atmegi 8 połączone za pomocą TWI. W jednej z nich jest stworzona struktura z kilkoma polami typu char. TWI jest obsługiwany w przerwaniach. Chciałbym aby do tej struktury wpisywane były dane odebrane przez TWI. Jednak nie mogę tego zrobić. Do zwykłej zmiennej da się wpisać, ale do pola struktury już nie. Program sie kompiluje ale cały czas jest tam stara wartość. Nie chcę wklejać całego kodu bo jest długi. Deklaracja struktury i funkcja która wpisuje dane. Funkcja OdbierzDane wywoływana jest w przerwaniu. volatile struct sZawor { unsigned char u_cAdres; unsigned char u_cCisnienie; unsigned char u_cPozycja; }volatile ZaworTab[IL_ZAWOROW]; void OdbierzDane() { switch (PozDanej) { case 1: { ZaworTab[PozDanej].u_cCisnienie=TWDR; TWI_ACK(ACK); break; } case 2: { ZaworTab[PozDanej].u_cPozycja=TWDR; TWI_ACK(NACK); TWI_M_Stop(); break; } default: break; } if(++PozDanej > IL_DANYCH) PozDanej=1; } Kombinowałem różnie z volatile ale i tak nie działa. Może macie jakiś pomysł jak to zrobić??
BlackJack Listopad 25, 2012 Udostępnij Listopad 25, 2012 Jeżeli dobrze pamiętam to adresy (indexy) do tablic w C zaczynają się od zera nie od 1. Nie wiem czy nie trzeba tez przekazać, struktury do funkcji ?
davidpi Listopad 25, 2012 Autor tematu Udostępnij Listopad 25, 2012 Struktura jest zadeklarowana jak zmienna globalna więc chyba nie trzeba przekazywać do funkcji. Na indeksy proszę nie zwracać uwagi bo nie są tu istotne. Chodzi o to, że ta linijka nie działa: ZaworTab[PozDanej].u_cCisnienie=TWDR; Natomiast jeżeli napiszę: dana=TWDR; to wtedy w zmiennej dana jest odczytana wartość.
kling Listopad 25, 2012 Udostępnij Listopad 25, 2012 void OdbierzDane() { unsigned char dana; dana = TWDR; switch (PozDanej) { case 1: { ZaworTab[PozDanej].u_cCisnienie=dana; TWI_ACK(ACK); break; } case 2: { ZaworTab[PozDanej].u_cPozycja=dana; TWI_ACK(NACK); TWI_M_Stop(); break; } default: break; } if(++PozDanej > IL_DANYCH) PozDanej=1; } Może taki zabieg pomoże;) Ja już parę razy przechejałem się na 'optymalizacji' kompilatora i jego podejście do struktur.
davidpi Listopad 25, 2012 Autor tematu Udostępnij Listopad 25, 2012 Niestety nic to nie pomogło. Spróbowałem też różnych rodzajów optymalizacji i nic się nie zmienia. Nie ogarniam tego.
kling Listopad 25, 2012 Udostępnij Listopad 25, 2012 A jesteś pewien, że tak funkcja się wywołuje albo, że którykolwiek z tych 'case'ow' się spełnia?
davidpi Listopad 25, 2012 Autor tematu Udostępnij Listopad 25, 2012 Tak funkcja działa prawidłowo. Zadeklarowałem zmienną globalną Dana i zmieniłem funkcje na taką: void OdbierzDane() { switch (PozDanej) { case 1: { Dana=TWDR; TWI_ACK(ACK); break; } case 2: { Dana=TWDR TWI_ACK(NACK); TWI_M_Stop(); break; } default: break; } if(++PozDanej > IL_DANYCH) PozDanej=1; } Następnie wyświetliłem zmienną Dana na LCD i wszystko było ok. Więc wychodzi na to że da się zapisać do zmiennej, ale nie da się zapisać do pola struktury.
kamil4u Listopad 25, 2012 Udostępnij Listopad 25, 2012 Nie mam pojęcia dlaczego to Twoje nie działa. Spróbuj jednak tak: typedef struct{ unsigned char u_cAdres; unsigned char u_cCisnienie; unsigned char u_cPozycja; } ZaworTab[IL_ZAWOROW]; Jeżeli nadal nie zadziała to staraj się to debugować "ręcznie", czyli: 1. Na początek sprawdzić czy gdybyś tam nie dał tablicy, a samą strukturę to czy będzie działać 2. Sprawdzić co jest pod zmienną, czyli: ZaworTab[PozDanej].u_cCisnienie=dana; // wyświetl zawartość ZaworTab[PozDanej].u_cCisnienie przez jakieś rs232 czy coś takiego // ew. zapalaj diody w zależności od tego co jest w zmiennej Opisz nam rezultaty tych dwóch punktów.
davidpi Listopad 25, 2012 Autor tematu Udostępnij Listopad 25, 2012 Uhh chyba coś sknociłem m w tamtym programie Założyłem nowy projekt i wpisałem taki kod: /* * A.c * * Created: 2012-11-25 21:54:43 * Author: David */ #include <avr/io.h> #include <util/delay.h> #include <stdlib.h> #include <avr/interrupt.h> struct SZawor { unsigned char u_cCisnienie; }Zawor[1]; volatile int d=0; void TimerInit() { OCR1A = 5000; TIMSK |= (1<<OCIE1A); TCCR1B |= (1<<WGM12) | (1<<CS10) | (1<<CS11); } void LCD(int dana) { char buf[8]; LCD_Clear(); itoa(dana,buf,10); LCD_WriteText(buf); } ISR(TIMER1_COMPA_vect) { Zawor[0].u_cCisnienie++; } int main(void) { LCD_Initalize(); TimerInit(); sei(); while(1) { LCD(Zawor[0].u_cCisnienie); _delay_ms(2); } } I tutaj wszystko działa. W przerwaniu od timera pole struktury się zmienia i jest ok. Muszę teraz prześledzić tamten program i sprawdzić co się dzieje, że tam nie działa. [ Dodano: 25-11-2012, 23:08 ] Dobra. Sorry chłopaki, że w ogóle zawracam głowę. Wygłupiłem się jak nigdy (albo jak zawsze). Na początku napisałam, że indeksy w tablicy struktur są dobre i żeby sie nimi nie przejmować. A oczywiście one były złe. volatile struct sZawor { unsigned char u_cAdres; unsigned char u_cCisnienie; unsigned char u_cPozycja; }volatile ZaworTab[IL_ZAWOROW]; void OdbierzDane() { switch (PozDanej) { case 1: { ZaworTab[PozDanej].u_cCisnienie=TWDR; TWI_ACK(ACK); break; } case 2: { ZaworTab[PozDanej].u_cPozycja=TWDR; TWI_ACK(NACK); TWI_M_Stop(); break; } default: break; } if(++PozDanej > IL_DANYCH) PozDanej=1; } IL_ZAWOROW wynosi 1. Więc tablica struktur ma jeden element. A ja sie w funkcji odwoływałem do ZaworTab[1].u_cCisnienie i do ZaworTab[w].u_cPozycja. Więc nie miało prawa działać. Szkoda trochę, że kompilator nie ostrzega przed wychodzeniem poza zakres tablicy. Dzięki serdeczne za pomoc.
Pomocna odpowiedź
Bądź aktywny - zaloguj się lub utwórz konto!
Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony
Utwórz konto w ~20 sekund!
Zarejestruj nowe konto, to proste!
Zarejestruj się »Zaloguj się
Posiadasz własne konto? Użyj go!
Zaloguj się »