Skocz do zawartości

Problem z programowaniem Texas instruments MSP430 launchPad.


white88

Pomocna odpowiedź

Witam serdecznie,
mam nadzieje że ktoś z drogich forumowiczów pomoże z problemem z jakim się borykam.Otóż jestem w trakcje budowy (a w zasadzie budowę mam ukończoną i jestem w fazie programowej) robota mobilnego 3 kołowego.Moje doświadczenie w programowaniu uC nie jest złe aczkolwiek zdarzają się problemy. Jeden polega na tym że wykorzystuję wymienioną w temacie płytkę uruchomieniową (nie pytać dlaczego) z procesorem MSP-EXPG2553.

Idea mojego robota jest prosta.Jeździ sobie prosto gdy wykrywa przeszkodę zmienia tor ruchu.typowy robocik wykrywający przeszkody.

Przejdę może odrazu do samego problemu i oprogramowania niejako liczę się z tym że pewnie mało ludzi spotkało się z tym układem więc nie będę tłumaczył szczegółów a myślę że osoby rozumiejące temat pomogą.

Mając napisany szkielet programu :

void setup(void)
{
     WDTCTL = WDTPW + WDTHOLD;           	  // Stop watchdog timer
  P1DIR |= 0xBF;                     	  // GPIO
  P2DIR |= 0x11;					      // GPIO
  P1OUT= 0x40; 						 	  // GPIO
  P2OUT= 0x0F;

  BCSCTL1 = CALBC1_8MHZ; 		// Ustawiam zegar uC
  BCSCTL2 &= ~(DIVS_3);         // Ustawienia zegara


  BCSCTL3 |= LFXT1S_2;  		// Ustawienia zegara
  IFG2 &= ~OFIFG;
  BCSCTL2 |= SELM_0 + DIVM_0;

  P1IE |= 0x40; 				// Przerwanie dla P1
  P2IE |= 0x2E; 				// Przerwanie dla P2


  P1IFG &= ~(0x40); 				//  Flaga wyzerowana od P1
  P2IFG &= ~(0x2E); 				//  Flaga wyzerowana od P2

 // P1IES ^= 0x40;					// zbocze dla P1
  //P2IES ^= 0x2E;					// zbocze dla P2


  CCTL0 = CCIE;
  TACTL = TASSEL_2 + MC_1; 		// Timer praca - Up mode,
  CCR0 =111;					// liczy do 111
}



int main(void)
{

setup();
__enable_interrupt(); // enable all interrupts
enkoder_p = 0;
_BIS_SR(GIE);
while(1)
{
while(enkoder_p < 5 )
{

P1OUT |= 0x01;
_delay_cycles(8000000);
P1OUT &= 0xFE;
_delay_cycles(8000000);



}
while(enkoder_p >= 5 )
{
P1OUT |=0x01;
_delay_cycles(16000000);
P1OUT &= 0xFE;
_delay_cycles(16000000);
enkoder_p = 0;

}

}

}

#pragma vector=PORT2_VECTOR
__interrupt void Port_2(void)
{

if ( 0x20 & P2IFG )			// ODBIORNIK IR
{
enkoder_p = enkoder_p + 1;
P2IFG&= ~(0x20);

}


if ( 0x04 & P2IFG )			// ENKODER I LEWA
	{
//	jazda_tyl();
	//P2IFG&= ~(0x04);

	}


if ( 0x02 & P2IFG )			// ENKODER II LEWA
	{
//	jazda_tyl();
//	P2IFG&= ~(0x02);

	}


if ( 0x08 & P2IFG )			// ENDKODER II PRAWA
	{
//	jazda_tyl();
//	P2IFG&= ~(0x08);

	}


}


#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void)
{

if ( 0x40 & P1IFG )			// ENKODER I PRAWA
		{
//	jazda_tyl();
	//	P1IFG&= ~(0x40);

		}


}

Funkcja void setup wszystkie ustawienia, main ,oraz obsługa przerwania od portu. Problem jest taki gdy przed pętlą while włącze przerwania __enable_interrupt to przerwanie zostaje wykryte jednak nie wykonuję się program w pętli while.Gdy wywalę to zezwolenie na przerwanie to oczywiście wszystko pracuje normalnie tyle że brak przerwań.

Chce żeby w pętli głównej była funkcja poruszania się narazie prosta bazująca na odliczaniu np.1s. a gdy zostanie wygenerowanie przerwanie ma zostać wykonana funkcja stop po czym ma wrócić spowrotem do petli while.

Czy ktoś ma jakis pomysł jak poprawnie powinny być zdefioniowane włączania przerwań i czego jeszcze brakuje? Ciężko to wszystko opisać słowami.

Przykłądowa funkcja ruchu :

void jazda_przod(void)
{

zasilanie_on;
enable_A_on;
enable_B_on;
silnik_l_przod();
silnik_p_przod();
_delay_cycles(8000000);
enable_A_off;
enable_B_off;
silnik_l_stop();
silnik_p_stop();

}

Nie wiem dlaczego coś się blokuje w tym całym programie. W kodzie który wrzuciłem jest takie działanie że normalnie dioda miga co 1s a gdy przyjdzie przerwanie zwiększy wartość licznika dioda miga co 0,5s.Jednak tak nie jest.A przerwanie działa na pewno dobrze ponieważ gdy pętla while jest pusta a miganie diody napisane jest w obsłudze przerwania to miga.

Jak ktoś zrozumiał co napisałem i ma coś do dodania z wielką chęcią wysłucham.W razie niejasności dopowiem gdybym wszystko wypisał to zajęło by to 10 stron.

Robot:

Dziękuje za uwage pozdrawiam.

Link do komentarza
Share on other sites

Mało osób programuje te procesory chociaż są dość ciekawe. Zwykle takie objawy są przyczyną:

- ciągle występującego przerwania (przykładowo przerwanie wykonuje się 1 ms a występuje co 0.9ms)

- zapętlaniem się w przerwaniu

- nie kasowaniu flagi przerwania (po wyjściu procesor myśli że w trakcie przerwania zostało zgłoszone nowe)

Spróbuj dać do przerwania tylko jedną prostą operacje np: dodaj 2 zmienne, zapal leda i zobacz czy działa. Jak dalej będą problemy to poczytaj jak powinno się obsługiwać przerwania: kasowanie flag, odpowiednie ustawienie źródła itp.

Napisz czy funkcja przerwania wykonuje się tylko raz czy w kółko.

Link do komentarza
Share on other sites

Napisałem trochę niewyraźnie ale tak właśnie jest. Przerwanie działa prawidłowo. Gdy wrzucę tam operację zapalania i gaszenia diody operacja wykonuję się pojedynczo. Przerwanie jest wywoływanie gdy odbiorę sygnał z IR. Gdy pilotem lub innym IR zaświecę dioda zapali sie i zgaśnie tak jak powinno to być. Na samym początku main po ustawieniach flagi wszystkie są kasowane ponadto zaraz po wykonaniu jakiejś operacji w przerwaniu tam też jest FLAGA kasowana. Co jest najgorsze gdy zostawię funkcje przerwania pustą a w pętli while zrobię operacja migania ledem to efekt jest taki że dioda ta zapali się ale nie miga tak jak powinna.A nawet jeżeli miga bardzo szybko(czego nie wiem bo świeci ciągle - bezwładność oka) to dlaczego skoro daje jej czas zwłoki 1s który w moim przypadku wynosi 8000000 cykli procka.

Link do komentarza
Share on other sites

Co jest najgorsze gdy zostawię funkcje przerwania pustą a w pętli while zrobię operacja migania ledem to efekt jest taki że dioda ta zapali się ale nie miga tak jak powinna.A nawet jeżeli miga bardzo szybko(czego nie wiem bo świeci ciągle - bezwładność oka) to dlaczego skoro daje jej czas zwłoki 1s który w moim przypadku wynosi 8000000 cykli prock

Czyli led miga dopóki procek nie wejdzie w przerwanie?

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

W zasadzie udało mi się znaleść przyczynę problemu.

Brakowało linijki :

	  _bis_SR_register(SCG1 + SCG0);

Przez co przerwania działały pętla główna też niby działała ale nie wykonywały się żadne funkcje czasowe bo zegar był zatrzymany SCG1 oraz SCG0 za to odpowiedzialne. Teraz wszystko działa prawidłowo tzn. robot jeździ sobie prosto wykrywa przeszkodę i następuje funkcja stop. Dziękuje za zainteresowanie. Jak zakończę prace nad robotem z chęcią podzielę się obszerną dokumentacja zarówno dot. samego robota jak i msp430 launch pad. Forbota przeglądam od dawna nie miałem nigdy jakoś okazji się zarejestrować. Program gotowy też udostępnię może komuś się przyda.Ale to dopiero jak skończę.

Jeszcze raz pozdrawiam serdecznie.

Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Gość
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • 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.