-
1. Data: 2010-05-14 19:22:40
Temat: WinAVR - Pytanie do znawcow C
Od: "roxy" <k...@o...pl>
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
-
2. Data: 2010-05-18 23:53:22
Temat: Re: WinAVR - Pytanie do znawcow C
Od: MrWebsky <m...@p...onet.pl>
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:
> 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
-
3. Data: 2010-05-18 23:59:37
Temat: Re: WinAVR - Pytanie do znawcow C
Od: Konop <k...@g...pl>
> 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
-
4. Data: 2010-05-19 21:09:10
Temat: Re: WinAVR - Pytanie do znawcow C
Od: Adam Dybkowski <a...@4...pl>
W dniu 2010-05-19 01:53 MrWebsky napisał(a):
> 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.
-
5. Data: 2010-05-22 14:13:41
Temat: Re: WinAVR - Pytanie do znawcow C
Od: "roxy" <k...@o...pl>
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.
-
6. Data: 2010-05-22 16:01:18
Temat: Re: WinAVR - Pytanie do znawcow C
Od: "Artur M. Piwko" <m...@b...pl>
In the darkest hour on Sat, 22 May 2010 16:13:41 +0200,
roxy <k...@o...pl> screamed:
> 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.
>
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.