Skocz do zawartości

Zapis pola struktury w przerwaniu


davidpi

Pomocna odpowiedź

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ć??

Link do komentarza
Share on other sites

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ść.

Link do komentarza
Share on other sites

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.

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

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.

Link do komentarza
Share on other sites

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.

Link do komentarza
Share on other sites

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.

Link do komentarza
Share on other sites

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ę »
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.