Forum: Mikrocontroller und Digitale Elektronik Zufallszahlengenerator mit MSP430F2013


von Franz Peter Zantis (Gast)


Lesenswert?

Dieser Code arbeitet als Zufallszahlengenerator. Aber warum? Am Eingang 
des ADC16 (Pin 3 bzw. P1.1 über A4+) liegt eine konstante Spannung von 
300 mV an.




#include <msp430x20x3.h>
static unsigned int s;
unsigned int i;
unsigned int ptime = 1; // pulse time
unsigned int btime = 10; // break (pause) time





void main( void )
{
  WDTCTL = WDTPW + WDTHOLD;   // Stop watchdog timer to prevent time out 
reset


//clock (DCO) einstellen
BCSCTL1 = CALBC1_16MHZ;
DCOCTL=CALDCO_16MHZ;

//SMCLK ausgeben an Pin6 (P1.4) - nur zu Testzwecken
P1DIR |= 0x10;   //P1.4 als output
P1SEL = 0x10;   //P1.4 an SMCLK

P1DIR |= 0x01; //set P1.0 to output direction - zur Nutzung der LED an 
P1.0

//den AD-Wanlder vorbereiten
SD16CTL = SD16REFON + SD16SSEL_1 + SD16DIV_0;  // VREF=1.2V, 
Clock=SMCLK, Clock-Divider=1
P1SEL |= BIT3;  //interne Referenzspannung an P1.3 (Pin5) ausgeben
SD16INCTL0 = SD16INCH_4 + SD16GAIN_1; //Verwendung von Eingang A4 
(P1.1=A4+, P1.2=A4-), keine Verstärkung

SD16AE = SD16AE1; //negative inputs are internally connected to Vss 
(GND); P1.1 an A4+
SD16CCTL0 = SD16IE + SD16SNGL; // Interrupt + Single Conversion + 
bipolarer Input
_BIS_SR(GIE); //globale Interruptfreigabe


  SD16CCTL0 |= SD16SC;  //set bit to start conversion; Rücksetzen dieses 
Bits erfolgt automatisch


//Endlosschleife, damit der Takt läuft
while(1)
{

};

}





#pragma vector = SD16_VECTOR // Interrupt service routine for
__interrupt void SD16ISR(void) // conversion
{
  P1OUT ^= 0x01; // LED toggeln
  //for (i = 0; i < 65000; i++);
  s = SD16MEM0;
  SD16CCTL0 |= SD16SC;  //set bit to start conversion; Rücksetzen dieses 
Bits erfolgt automatisch
}

von Tobias K. (kurzschluss81)


Lesenswert?

möchtest du den Code nicht lieber in die Codesammlung stellen.
Einen Zufallsgenerator sucht bestimmt der eine oder andere.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Franz Peter Zantis schrieb:
> //Endlosschleife, damit der Takt läuft
Wie bitte?

> Dieser Code arbeitet als Zufallszahlengenerator. Aber warum?
Als was sollte er denn arbeiten? Und wie gut sind die Zufallszahlen?

von Franz Peter Zantis (Gast)


Lesenswert?

Also eigentlich sollte die Spannung, die an P1.1 (Pin3) anliegt, 
gemessen werden. Ich habe nun auf unipolare Betriebsart umgeschaltet. Da 
erhalte ich zwar keine Zufallszahlen, aber der Messbereich reicht nur 
von 0 bis 300 mV. Nach Datenblatt müssten es aber 0 bis 600 mV sein.


Ohne die Endlosschleife ist der Takt (SMCLK) nicht messbar.

von Stefan (Gast)


Lesenswert?

Die maximale Taktfrequenz für den SD16_A beträgt 1,1 MHz.
Teil die 16 MHz von SMCLK über SD16DIVx und SD16XDIVx auf einen 
zulässigen Wert herunter.

von Bernd N. (Gast)


Lesenswert?

Glaubst du wirklich das dieser Code irgend etwas produziert ? 
Zufallszahlen wohl eher noch nicht.

Damit man den Code mal ansehen kann...
1
#include <msp430x20x3.h>
2
3
static unsigned int s;
4
unsigned int i;
5
unsigned int ptime = 1;                             // pulse time
6
unsigned int btime = 10;                            // break (pause) time
7
8
void main (void)
9
{
10
    WDTCTL = WDTPW + WDTHOLD;                       // Stop watchdog timer to prevent time out reset
11
12
// clock (DCO) einstellen
13
14
    BCSCTL1 = CALBC1_16MHZ;
15
    DCOCTL=CALDCO_16MHZ;
16
17
// SMCLK ausgeben an Pin6 (P1.4) - nur zu Testzwecken
18
19
    P1DIR |= 0x10;                                  // P1.4 als output
20
    P1SEL  = 0x10;                                  // P1.4 an SMCLK
21
    P1DIR |= 0x01;                                  // set P1.0 to output direction - zur Nutzung der LED an P1.0
22
23
// den AD-Wanlder vorbereiten
24
25
    SD16CTL = SD16REFON + SD16SSEL_1 + SD16DIV_0;   // VREF=1.2V, Clock=SMCLK, Clock-Divider=1
26
    P1SEL |= BIT3;                                  // interne Referenzspannung an P1.3 (Pin5) ausgeben
27
    SD16INCTL0 = SD16INCH_4 + SD16GAIN_1;           // Verwendung von Eingang A4 (P1.1=A4+, P1.2=A4-), keine Verstärkung
28
    SD16AE = SD16AE1;                               // negative inputs are internally connected to Vss (GND); P1.1 an A4+
29
    SD16CCTL0 = SD16IE + SD16SNGL;                  // Interrupt + Single Conversion + bipolarer Input
30
31
    _BIS_SR(GIE);                                   // globale Interruptfreigabe
32
33
34
    SD16CCTL0 |= SD16SC;                            // set bit to start conversion; Rücksetzen dieses Bits erfolgt automatisch
35
36
// Endlosschleife, damit der Takt läuft
37
38
    while(1) {
39
40
    };
41
42
}

Die Idee soll sicherlich sein das der ADC wildes Rauschen messen soll 
und daraus eine Zufallszahl generiert wird aber derzeit macht dieser 
Code das noch nicht.

Beschreibe mal was du glaubst was hier derzeit passiert ?

von holger (Gast)


Lesenswert?

>Die Idee soll sicherlich sein das der ADC wildes Rauschen messen soll
>und daraus eine Zufallszahl generiert wird

Völliger Blödsinn. Ein ADC tendiert bei offenem Eingang
immer in irgendeine Richtung. Je nach Mondphase und Luftfeuchtigkeit.
Ich hatte auch schon ADCs die bei offenem Eingang die zuletzt
gemessene Spannung im Samplekondensator an den Ausgang geliefert
haben. Wenn vor dem ADC also ein Mux sitzt könnte es sein das
der Wert aus einem anderen Kanal noch einmal gemessen wird;)

von Bernd N. (Gast)


Lesenswert?

>> Völliger Blödsinn.

Das war nur eine Vermutung da der gegeben Code eh keinen Sinn ergibt.

Daher sollte Peter ja erklären was er so in seinem Code sieht :-)

Der Code läßt sich ja nicht mal kompilieren... nur so am Rande bemerkt. 
Ich weiß schon das es keinen Sinn ergibt aber derartige Versuche einen 
Zufallsgenerator zu bauen sehe ich nicht zum ersten mal.

von Stefan (Gast)


Lesenswert?

Abgesehen von einer Warnung (Warning[Pe550]: variable "s" was set but 
never used...) lässt sich der Code mit dem IAR problemlos kompilieren.
Die ISR darf man dabei allerdings nicht weglassen, das ist der einzige 
Programmteil wo etwas passiert
Allerdings macht der Code nicht ganz das was er soll, es sollte aber 
wohl nie ein Zufallsgenerator werden:

Franz Peter Zantis schrieb:
> Also eigentlich sollte die Spannung, die an P1.1 (Pin3) anliegt,
> gemessen werden.

Eigentlich schon erstaunlich, dass bei fast 15facher Übertaktung nach 
einer kleinen Programmänderung schon "fast richtige" Werte herauskommen:

> Ich habe nun auf unipolare Betriebsart umgeschaltet. Da
> erhalte ich zwar keine Zufallszahlen, aber der Messbereich reicht nur
> von 0 bis 300 mV. Nach Datenblatt müssten es aber 0 bis 600 mV sein.

von Franz Peter Zantis (Gast)


Lesenswert?

Ich habe nun den Clock-Divider für den ADU auf 16 eingestellt:
SD16CTL = SD16REFON + SD16SSEL_1 + SD16DIV_2;  // VREF=1.2V, 
Clock=SMCLK, Clock-Divider=16

Jetzt scheint es zu funktionieren. Das muss ich aber noch genauer 
testen.
Hat noch jemand einen Tipp, wie ich
- den Inhalt des SD16MEMO-Registers online sehen kann (also während des 
Programmlaufs)
- bipolare Werte messen kann (-600mV .... +600mV)

Viele Grüße und schon mal Danke vor allem an Stefan mit dem Tipp zur 
Takfrequenzänderung für den ADC!


Franz Peter

von Bernd N. (Gast)


Lesenswert?

Welche Hardware verwendest du ? Wenns ein Launchpad ist könntest du die 
Daten über den USB Anschluß / UART senden. Ansonsten brauchst du einen 
Pegelwandler.

>> - bipolare Werte messen kann (-600mV .... +600mV)

Das geht nicht.

von Franz Peter Zantis (Gast)


Lesenswert?

Es geht nur um die Programmentwicklung. Da möchte ich gerne den Inhalt 
des SD16MEM0 live sehen. Ich verwende IAR Kickstart. Man kann zwar 
verschiedene Watch-Fenster öffnen, aber den Status der Variablen erhält 
man da nur wenn man das Programm anhält. Es gibt auch einen Menüeintrag 
Live Watch Window. Dieser ist aber ausgegraut und das verstehe ich 
nicht.

Wenn bipolare Messungen nicht gehen, warum kann man den MSP430F2013 denn 
auf bipolare Messung einstellen?

SD16CCTL0 |& ~SD16UNI;

Also durch Nullsetzen des SD16UNI-Bits.

von Bernd N. (Gast)


Lesenswert?

Du kannst schon bipolar messen aber durch das Umschalten wird der 
Bereich nicht zu +/- 600 mV. Desweiteren darf der (-) Anschluß nicht 
unter GND gehen.

Auch wenn der ADC Differenzeingänge hat, so darf ADC- nicht negativ (< 0 
Volt) werden.

von Wilhelm F. (Gast)


Lesenswert?

Franz Peter Zantis schrieb:

> Es geht nur um die Programmentwicklung. Da möchte ich gerne den Inhalt
> des SD16MEM0 live sehen.

Mach die serielle Schnittstelle an einen PC, wo du ein Terminalprogramm 
wie bspw. TeraTerm drauf hast.

Beispiele für Ringbuffer an seriellen Schnittstellen, wo man im Programm 
blitzschnell Werte hinein schreiben kann, und auf die serielle 
Kommunikation dann gar nicht weiter achten muß, gibts im Internet auch 
genug.

So haben wir früher debugt, und das geht heute auch noch.

von Bernd N. (Gast)


Angehängte Dateien:

Lesenswert?

>> Es gibt auch einen Menüeintrag Live Watch Window. Dieser ist aber
>> ausgegraut und das verstehe ich nicht.

This window repeatedly samples and displays the value of expressions 
while your application is executing. Variables in the expressions must 
be statically located, such as global variables.

http://www.ece.uah.edu/~jovanov/msp430/GettingStartedWithMSP430_IAR_EW.pdf

>> den Inhalt des SD16MEMO-Registers online sehen kann (also während des
>> Programmlaufs)

So richtig erschließt sich mir das auch nicht aber dennoch kann man die 
Werte brauchbar mittels Debugger verfolgen (siehe Screenshot, Ausgabe 
deiner Variable + SD16MEM0).

Ich habe mal ne Ausgabe dazu gebastelt und das Ganze auf TeraTerm 
ausgegeben (nicht dein Code) daher sieht man auch die Ausgabe der 
Spannung gleich in Volt.

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.