RTV forum PL | NewsGroups PL

Dziwne zachowanie zmiennych Kp i Ki w strukturze s_pid w WinAVR - co może być przyczyną?

WinAVR - Pytanie do znawcow C

NOWY TEMAT

elektroda NewsGroups Forum Index - Elektronika Polska - Dziwne zachowanie zmiennych Kp i Ki w strukturze s_pid w WinAVR - co może być przyczyną?

roxy
Guest

Fri May 14, 2010 7:22 pm   



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.

http://www.eset.pl lub http://www.eset.com

MrWebsky
Guest

Tue May 18, 2010 11:53 pm   



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:

Quote:
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.

http://www.eset.pl lub http://www.eset.com


Konop
Guest

Tue May 18, 2010 11:59 pm   



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

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

--
Pozdrawiam
Konop

Adam Dybkowski
Guest

Wed May 19, 2010 9:09 pm   



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

Quote:
Zapis powinien wyglądać tak:

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

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

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)


--
Adam Dybkowski
http://dybkowski.net/

Uwaga: przed wysłaniem do mnie maila usuń cyfry z adresu.

roxy
Guest

Sat May 22, 2010 2:13 pm   



Wiadomosc na grupe pisalem z glowy, to nie sa fragmenty listingu wiec
wkradly sie bledy ktore zauwazyl kolwga MrWebsky.
Ale powodem problemu bylo cos innego a mianowicie instrikcja sprintf_P.
Dochodziło do niekontrolowanego nadpisywania ramu.
Mialem cos takiego:

char str[8];
...
...
sprintf_P(str,SPTR("U=%dV "),x);
lcd_write(str);
....

Przy wiekszej wartosci x dochodziło do pisania poza rozmiarem zadeklarowanej
tablicy znakow str.

Artur M. Piwko
Guest

Sat May 22, 2010 4:01 pm   



In the darkest hour on Sat, 22 May 2010 16:13:41 +0200,
roxy <kicak@o2.pl> screamed:
Quote:
Wiadomosc na grupe pisalem z glowy, to nie sa fragmenty listingu wiec
wkradly sie bledy ktore zauwazyl kolwga MrWebsky.
Ale powodem problemu bylo cos innego a mianowicie instrikcja sprintf_P.
Dochodzio do niekontrolowanego nadpisywania ramu.
Mialem cos takiego:

char str[8];
..
..
sprintf_P(str,SPTR("U=%dV "),x);
lcd_write(str);
...

Przy wiekszej wartosci x dochodzio do pisania poza rozmiarem zadeklarowanej
tablicy znakow str.


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

--
[ Artur M. Piwko : Pipen : AMP29-RIPE : RLU:100918 : From == Trap! : SIG:222B ]
[ 18:01:01 user up 12445 days, 5:56, 1 user, load average: 0.75, 0.61, 0.84 ]

I love being me, but I can't recommend it.

elektroda NewsGroups Forum Index - Elektronika Polska - Dziwne zachowanie zmiennych Kp i Ki w strukturze s_pid w WinAVR - co może być przyczyną?

NOWY TEMAT

Regulamin - Zasady uzytkowania Polityka prywatnosci Kontakt RTV map News map