Forum: PC-Programmierung Adresse einer Variablen in ein String schreiben


von Dennis M (Gast)


Lesenswert?

Hallo zusammen, kann mir eventuell einer sagen wie ich mit AVR Studio 
Adresse einer Variablen in einen String kopieren kann.
z.B.
1
char testvariable;
2
printf("%p",&testvariable);    //ausgabe der Adresse auf dem Bildschirm.
ich möchte jetzt aber diese Adresse in ein String kopieren, vorzugsweise 
ohne "printf" zu benutzen.

habe eventuell dran gedacht

char adresse[];

adresse=&testvariable;

bin mir aber net sicher.

Gruß

Dennis

von Karl H. (kbuchegg)


Lesenswert?

Dennis M schrieb:
> Hallo zusammen, kann mir eventuell einer sagen wie ich mit AVR Studio

Du meinst: in C

C ist das Auto, AVR-Studio ist die Garage

> Adresse einer Variablen in einen String kopieren kann.
> z.B.
>
>
1
> char testvariable;
2
> printf("%p",&testvariable);    //ausgabe der Adresse auf dem Bildschirm.
3
>
> ich möchte jetzt aber diese Adresse in ein String kopieren, vorzugsweise
> ohne "printf" zu benutzen.

sprintf macht genaus dasselbe wie printf, nur dass es sein Ergebnis in 
einen String schreibt anstelle auf ein Ausgabegerät


> habe eventuell dran gedacht
>
> char adresse[];

Nope.
Du musst schon eine Länge vorgeben
1
  char  adrString[20];
2
3
  sprintf( adrString, "%p", &testvariable );

von Dennis M (Gast)


Lesenswert?

Danke schonma, jetzt mal ne andere Frage.
Normalerweise, wenn ich das Board vom Strom nehme und wieder anschliesse 
(starte) sollten eigentlich alle Variablen die nicht im EEPROM 
gespeichert sind, eine neue Adresse zugewiesen bekommen. Ist das 
richtig?

D.h. wenn ich die Adrese meiner "testvariable" auslese, sollten sich die 
Adressen unterscheiden. Oder habe ich was missverstanden?

Gruß

Dennis

von Peter (Gast)


Lesenswert?

Dennis M schrieb:
> D.h. wenn ich die Adrese meiner "testvariable" auslese, sollten sich die
> Adressen unterscheiden. Oder habe ich was missverstanden?

wenn der Prozessor immer das gleiche macht, gibt  es auch immer die 
gleichen Adressen. Es ist ja kein Zufallsgenerator eingebaut.

von Uwe .. (uwegw)


Lesenswert?

Wenn es um einen AVR oder anderen µC geht: die Adressen von 
nicht-dynamisch angelegten Varaiblen werden vom Linker festgelegt und 
sind somit bei jedem Programmstart gleich.
Bei dynamisch genutzem Speicher können sich die Adressen ändern, 
allerdings nicht nur bei jedem neustart, sondern teilweise auch zwischen 
zwei Funktionsaufrufen, wenn lokale Variablen benutzt werden.
Und auf einem PC wird der Speicherbereich für dein Programm vom OS 
zugewiesen, die Adressen ändern sich also teilweise bei jedem 
Programmstart.

von Dennis M (Gast)


Lesenswert?

Schade, wollte die Adressen als Parameter für einen 
Zuffalszahlengenerator einbauen, wird aber wohl nix draus.

Danke nochma.

Gruß

Dennis

von Klaus W. (mfgkw)


Lesenswert?

Ich überlege seit einer halben Stunde, was du mit der
Adresse in einem String willst.
Aber darauf wäre ich nun nicht gekommen.

von Dennis M (Gast)


Lesenswert?

Hallo nochmals,

hab jetzt an eine andere Lösung für meinen Zufallsgenerator gedacht.
Möchte jetzt den Timer benutzen. Und zwar solange man im ConfigMenue ist 
soll der Timer laufen. Ist man draussen, stoppt dieser. Die Zeit wird 
dann in ms. als unsigned long an eine Variable zugewiesen. Diese benutze 
ich dann zur generierung der Zufallszahlen.

hier der code,
1
volatile unsigned int  millisekunden;
2
volatile unsigned int sekunde;
3
4
sei();
5
6
load_settings();
7
if (!CONFIG)
8
     configmode();
9
uart_init(UART_BAUD_SELECT(uart_baud, F_CPU));
10
rf12_config(rf_baud, channel, 0, nvironment_1,threshold_1,bandwidth_1);  
11
  
12
TCCR0 = (0<<CS01);   //timer stopt, wenn raus aus configmode
13
14
#else
15
    
16
uart_init(UART_BAUD_SELECT(UART_BAUDRATE, F_CPU));
17
rf12_config(RF_BAUDRATE, CHANNEL, 0, QUIET,THRESHOLD,_BANDWIDTH_);  
18
19
...
20
void configmode(void)
21
{  unsigned char c;
22
  uart_init(UART_BAUD_SELECT(CONFIG_BAUD, F_CPU));
23
24
  TCCR0 = (1<<CS01); // Prescaler 8
25
    
26
  // Overflow Interrupt erlauben
27
  TIMSK |= (1<<TOIE0);
28
29
  for(;;)
30
  {  
31
    
32
33
34
    //threshold_1=THRESHOLD;
35
    uart_puts_P("\r\n\r\n");
36
    uart_puts_P("RFM12 RS232 bridge v1.2\r\n");
37
...
38
//ConfigMenue
39
40
...
41
42
43
//schleife mit Zufallszahlen
44
45
do
46
{
47
            
48
  txbuf[tx_cnt]=(timer_1%10)+48;
49
  wert=wert/10;
50
  tx_cnt++;
51
              }while(tx_cnt<(test_pointer_length+5));
52
53
...
54
55
ISR(SIG_OUTPUT_COMPARE1A)              // 500Hz Interrupt
56
{  
57
  //if (delaycnt)
58
  //  delaycnt--;
59
  
60
  millisekunden++;
61
    if(millisekunden == 1000)
62
    {
63
        sekunde++;
64
        millisekunden = 0;
65
  if(sekunde==60)
66
    sekunde=0;
67
  }
68
  timer_1=(millisekunden+sekunde*1000);
69
}


nur funktionieren tut es noch net richtig, habe ich da irgendwo einen 
Denkfehler?

Gruß

Dennis

von Klaus W. (mfgkw)


Lesenswert?

Pluspunkt: Der Code ist mit [c]... formatiert.

Sonst: Quelltext unvollständig, Beschreibung mies("funktionieren
tut es noch net richtig" muß man sich wie vorstellen?).

von Dennis M (Gast)


Lesenswert?

also ich komme nicht mehr in die
1
for(;;)

Schleife. Lasse ich den timercode weg, funktioniert das Menue 
einwandfrei.

von Karl H. (kbuchegg)


Lesenswert?

Dennis M schrieb:

> hab jetzt an eine andere Lösung für meinen Zufallsgenerator gedacht.

Zunächst mal sollten wir klären, warum es so wichtig ist, dass du bei 
jedem Einschalten eine andere Folge von Zufallszahlen bekommst.

Wenn dieser Punkt im Grunde völlig unwichtig ist, dann benutze ganz 
einfach die C-Funktion rand(). Die liefert dir einen Zufallswert nach 
dem anderen. Bei jedem Aufruf einen.

Nun macht rand() das natürlich nicht wirklich zufällig. Sondern es hat 
eine Funktion mit, die aus dem vorhergehenden Wert eine neue Zufallszahl 
errechnen kann.
Mit dem Zufall ist das nämlich so eine Sache. 'Zufall' ist eine 
statistische Eigenschaft einer Folge von Zahlen. Und wenn man da nicht 
vorsichtig ist und naiv ran geht, dann erzeugt man 'Zufallszahlen' die 
alles andere als irgendwelche statistischen Eigenschaften von 
Zufallszahlen haben.

Wenn es daher auf die Qualität der Zufallszahlen ankommt, dann solltest 
du ohne Not nicht selbst etwas erfinden, sondern lieber rand() 
verwenden. Dessen Formel ist nämlich so ausgelegt, dass es eine Folge 
von Zahlen generieren kann, die zumindest die meisten statistischen 
Tests auf Zufallszahlen übersteht.

Nun erzeugt rand() natürlich bei jedem erneuten Einschalten des Geräts 
immer dieselbe Folge von Zufallszahlen, weil es ja immer mit demselben 
ersten Wert beginnt und sich alle anderen Werte daraus ja ergeben.

Allerdings kann man rand() mittels der Funktion srand() einen ersten 
Wert vorgeben. Wenn man jetzt nur dafür sorgt, dass der bei jedem 
Einschalten ein wenig anders ist, dann ist man genau dort wo man sein 
möchte.

Dafür sorgen kann man zb, in dem man die Zeit bis zum ersten Tastendruck 
des Benutzers nimmt. Oder man könnte diesen ersten Wert auch ganz 
einfach im EEPROM ablegen und bei jedem Einschalten 1 dazu zählen und 
den neuen Wert an srand() übergeben und gleichzeitig auch wieder ins 
EEPROM ablegen. Da gibts mehrere Möglichkeiten.

Wovon ich dir aber auf jeden Fall abraten würde:
Dir selbst jetzt eine windige Generierung von Zufallszahlen einfallen zu 
lassen. Das ist nämlich viel schwieriger als man gemeinhin denkt.
rand() ist zwar meistens auch nicht der beste aller möglichen 
Zufallszahlengenerator, aber zumindest schafft er einige der 
statistischen Zufallszahlentests. Was man von den meisten 
schnell-schnell selbst erstellten Generatoren nicht gerade behaupten 
kann.

von Dennis M (Gast)


Lesenswert?

Also es geht um folgendes, ich habe hier zwei Boards ligen. Jedes Board 
soll eine ID bekommen. Beide Boards haben denselben Code, d.h. wenn ich 
rand oder srand benutzen würde, dann würden ja die IN-nummern dieselben 
sein für beide Bauteile. Deswegen wollte ich den Timer als ein Parameter 
für eine Zuffalszahl nehmen und dann mittels

(timer_1%10)+48;

die Zuffalszehl berechnen.

Gruß

Dennis

von Karl H. (kbuchegg)


Lesenswert?

Dennis M schrieb:
> Also es geht um folgendes, ich habe hier zwei Boards ligen. Jedes Board
> soll eine ID bekommen. Beide Boards haben denselben Code, d.h. wenn ich
> rand oder srand benutzen würde, dann würden ja die IN-nummern dieselben
> sein für beide Bauteile.

Das kannst du so sowieso nie ausschliessen

> Deswegen wollte ich den Timer als ein Parameter
> für eine Zuffalszahl nehmen und dann mittels
>
> (timer_1%10)+48;
>
> die Zuffalszehl berechnen.

d.h. du brauchst nur 1 Zahl, die einfach nur irgendwo herkommt und 
irgendwie variiert wird.

Dann ist das ok.

(Wenn du aber sowieso ein Config Menü hast, warum lässt du dann nicht 
einfach den Benutzer die ID einstellen? Ich würde dir schön was husten, 
wenn ich draufkomme, dass ein Aufbau nur deswegen nicht geht, weil der 
Zufallsgenerator zufällig auf beiden Boards mit derselben ID 
hochgekommen ist und vor allen Dingen: wenn ich als Benutzer das nicht 
ändern kann)

von Karl H. (kbuchegg)


Lesenswert?

Dennis M schrieb:
> also ich komme nicht mehr in die
>
>
1
> for(;;)
2
>
>
> Schleife. Lasse ich den timercode weg, funktioniert das Menue
> einwandfrei.



Und das sollen wir jetzt anhand von
1
//ConfigMenue
2
3
...
4
5
6
//schleife mit Zufallszahlen
7
8
do
9
{
10
            
11
  txbuf[tx_cnt]=(timer_1%10)+48;
12
  wert=wert/10;
13
  tx_cnt++;
14
              }while(tx_cnt<(test_pointer_length+5));
15
16
...
erraten?

Die +5 kommen mir da Spanisch vor.

Warum machst du das alles so seltsam?
Lern doch endlich mit den String Funktionen zu arbeiten!
Die sind zwar auch nicht trivial, aber immer noch besser als wenn du dir 
da selber immer wieder ein Bein mit Buffer Overflows und seltsam 
formulierten Schleifenabbruchbedingungen stellst.

von Dennis M (Gast)


Lesenswert?

Später wird das Bauteil keine serielle schnittstelle habe, d.h. man hat 
nen Knopf. Wird dieser gedrückt so werden die Einstellungen automatisch 
durchgeführt, unter anderem auch die ID Vergabe.

gruß

von Klaus W. (mfgkw)


Lesenswert?

Du kannst doch beim Flashen gleich eins EEPROM den ersten Wert
vorgeben. Mit jedem Neustart wird der Wert dann gelesen,
geändert und wieder gespeichert.

Jetzt brauchst du nur noch zu Beginn den beiden Dingern einen
unterschiedlichen Startwert einplfanzen, und schon bist du aus dem
Schneider.
Oder bei einem fünf Mal öfter Reset drücken...

von Grrrr (Gast)


Lesenswert?

Ich möchte raten, eher einigen Aufwand zu treiben,
als die Möglichkeit zuzulassen, dass eine Gerätekombination beim Kunden 
aus "Zufall" nicht geht. Das ist letztlich nur eine Verlegenheitslösung 
weil das eigentliche Problem nicht ausreichend analysiert wurde.

Das Problem heisst: "Satz von n Geräten/jedem eine einmalige Id"
(Warum ist das ein Problem)?

(Dazu wäre es vielleicht besser einen eigenen Thread dafür aufzumachen. 
Mit dem ursprünglichen Problem, hat das ja jetzt garnichst mehr zu tun).

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.