WinAVR - Pytanie do znawcow C

Mam pytanie dlaczego zmienna Ki oraz Kp (s->Ki oraz s->Kp) wchodzaca w sklad struktury s_pid przyjmuje losowe warosci wewnatrz funkcji RegulatorNextStep; Przedstawiam ponizej zawartosc plikow zrodlowych

Dodam tylko ze problem rozwiazalem ale nie moge sobie wytlumaczyc tak dziwnego zachowania kompilatora. Rozwiazanie problemu polegalo na przeniesieniu tworzenia struktury (struct s_pid pid;) z wnetrza funkcji main() na zewnatrz jej (globalna).

******** plik main.c ********

#include "pid.h" ... main(1); { ... struct s_pid pid; // jezeli przeniose to strukture na zewnatrz funkcji main // to program wykonuje sie prawidlowo ... InitReg(&pid,40,1,0); ... while(1); { ... err=RegulatorNextStep(&pid,i_set,current); ... }// end while }// end main

*************************** plik pid.h *************************** #ifndef _PID_H_ #define _PID_H_

struct s_pid { signed int Kp; signed int Ki; signed int Kd; signed long sigma; signed int delta; };

void InitReg(struct s_pid *s, signed int Kp, signed int Ki, signed int Kd); signed int RegulatorNextStep(struct s_pid *s,signed int set,signed int mes); void RegulatorReset(struct s_pid *s);

#endif

***************************** plik pid.c ************************** #include "pid_flt.h" ... signed int RegulatorNextStep(struct s_pid *s,signed int set_value,signed int measure_value) { ...

p_term=(s->Kp) * error; i_term= (s->Ki * s->sigma)/8; ... lcd(s->Kp); // !!!!!! dla czego mam losowe wartosci??? lcd(s->Ki); ... return (signed int)out; }

void InitReg(struct s_pid *s, signed int Kp, signed int Ki, signed int Kd) { s->Kp=Kp; s->Ki=Ki; s->Kd=Kd; s->sigma=0; s->delta=0; }

******************************************************************************

__________ Informacja programu ESET NOD32 Antivirus, wersja bazy sygnatur wirusow 5103 (20100510) __________

Wiadomosc zostala sprawdzona przez program ESET NOD32 Antivirus.

formatting link
lub
formatting link

Reply to
roxy
Loading thread data ...

Szczerze mówiąc to napisanie czegoś takiego "main(1)" powinno zostać oprotestowane prez kompilator bo składnia main w C jest taka int main(int arg,char* argv[]) niemniej kompilatory są na ogół wyrozumiałe.

Natomiast

while(1); { }

to już ewidentny błąd. Dla kompilatora taki zapis oznacza, że program ma stać w pustej pętli i nie robić nic a instrukcje z bloku otoczonego klamrami w ogóle nie zostaną wykonane. Kompilator może wtedy potraktować strukturę s_pid jak nieużywaną i usunać ją.

Zapis powinien wyglądać tak:

while(1) // Bez średnika!!! { }

Wtedy procesor ma wykonywac w kółko instrukcje zawarte w bloku.

Jeśli miałbym się tutaj jeszcze czego przyczepić, to nie wiem jak kompilator reaguje na wyznaczanie adresu struktury w locie operatorem & Załóż dodatkową zmienną wskaźnikową typu struct s_pid* zainicjalizują ją adresem struktury pid i podaj do funkcji zamiast &pid. Możliwe, że coś źle działa operator & i podstawia do funkcji zły adres structury powodując przekłamania.

A tak w ogóle jaki to proc i kompilator?

roxy wrote:

Reply to
MrWebsky

Jeśli pytający napisał w temacie "WinAVR", to myślę, że chodzi o proca z rodziny AVR :)... kompilator - zapewne gcc, bo ten wchodzi w skład WinAVR ;)... Chyba, że pytasz dokładniej (jaka wersja, jaki konkretny układ), to niestety, nie wiadomo...

Reply to
Konop

W dniu 2010-05-19 01:53 MrWebsky napisał(a):

BTW: Czasem niektóre kompilatory (nie wiem akurat tu o jaką wersję avr-gcc chodzi) narzekają przy takiej konstrukcji na stały warunek w pętli while. Dlatego w przenośnym kodzie dużo lepiej jest pisać:

for(;;)

zamiast

while(1)

Reply to
Adam Dybkowski

In the darkest hour on Sat, 22 May 2010 16:13:41 +0200, roxy snipped-for-privacy@o2.pl screamed:

Właśnie po to wymyślono snprintf.

Reply to
Artur M. Piwko

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.