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

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