Kann ich aus INTOSC vs Crystal Zufallszahlen auf PIC generieren?

7

Das Erzeugen wirklich zufälliger Zahlen auf einem Mikrocontroller ist eine bekannte schwierige Aufgabe.

Eine Möglichkeit besteht darin, zwei verschiedene Uhren zu betreiben und die Zeitverschiebung zwischen ihnen zu messen.

Der PIC16F1783, den ich benutze, hat zwei Uhren. Eine mit einem externen Kristall und dem LFINTOSC, der den Watchdog antreibt.

Gibt es eine Möglichkeit, an den LFINTOSC zu gelangen, während Sie von der externen Kristalluhr aus laufen?

Eine Idee, die ich hatte, war, den Watchdog ablaufen zu lassen und den Wert von TMR2 zu überprüfen, aber es funktioniert nicht, weil TMR2 durch Watchdog-Resets zurückgesetzt wird.

Man könnte einen Zähler in einer engen Schleife in das EEPROM schreiben und den Watchdog ablaufen lassen und dann den Inhalt des EEPROM überprüfen, aber dies scheint sehr unelegant zu sein. Bearbeiten: Es ist viel besser, in den Arbeitsspeicher zu schreiben, wie in einem der Kommentare vorgeschlagen.

Gibt es einen besseren Weg? Ohne externe Schaltkreise und ohne ADC-Rauschen (das möglicherweise nicht immer vorhanden ist)?

Datenblatt: http://ww1.microchip.com/downloads/en/DeviceDoc/40001579E.pdf

Bearbeiten: Ich möchte, dass die Zufallszahl eine GUID generiert, damit mehrere Geräte, die denselben RS485-Bus verwenden, voneinander unterschieden werden können. Meine Idee ist es, etwas Ähnliches wie die 1-Draht-Geräteerkennung zu verwenden. Dazu muss ich jedoch auf verschiedenen Geräten unterschiedliche GUIDs haben, und ich möchte den Aufwand vermeiden, sie mit eindeutigen IDs programmieren zu müssen.

avl_sweden
quelle
1
+1 keine Antwort, aber schöne Frage. Ein nützliches Ziel, wenn es erreichbar ist. Eine Rauschdiode kann einfacher sein, obwohl sie Hardware und einen Pin benötigt. .
Russell McMahon
1
Verwenden Sie das vorhandene "Temperaturanzeigemodul".
JonRB
1
Die Temperatur selbst spielt keine Rolle; Sie interessieren sich für das Rauschen, das während des ADC-Betriebs erzeugt wird (Sie können jede andere Quelle für den ADC verwenden, aber der Temperatursensor benötigt keine externe Hardware).
CL.
1
Warum sollten Sie anstelle von RAM in das EEPROM schreiben?
Nick Johnson
1
Mikrochip kann die Naturgesetze nicht brechen . In der Praxis muss man jedoch messen, wie groß der Unterschied ist, wenn die Temperatur größtenteils konstant bleibt. (Und brechen Sie alle Empfehlungen von Microchip zur Rauschunterdrückung, dh verwenden Sie kürzere Abtastzeiten.)
CL.

Antworten:

4

Okay, ich habe einen Weg gefunden, genau das zu tun, was ich in der Frage gestellt habe, ohne die WDT einzubeziehen.

Es ist, gelinde gesagt, ein kleiner Hack und opfert zwei Pins (BEARBEITEN: nur ein Pin wird geopfert) (erfordert jedoch keine externen Komponenten. Wenn Sie also zwei nicht verwendete Pins haben, ist dies "kostenlos").

Die Idee ist, die PSMC (Programmable Switch Mode Control) des PIC16F1783 zu verwenden.

Dies kann vom INTOSC aus getaktet werden, indem der HFINTOSC mit der 4x PLL verbunden wird, wodurch eine Frequenz von 64 MHz zum Takten des PWM-Ausgangs erhalten wird.

Der PWM-Ausgang kann dann an einen anderen Pin auf der Platine geleitet werden.

Wenn nun der externe Kristall zum Takten der CPU verwendet wird, kann das PWM-Signal in einer engen Schleife gelesen werden. Da die beiden Takte nicht synchronisiert sind, sollte zwischen den beiden Takten Jitter auftreten, und der PWM-Eingang sollte einen unvorhersehbaren Jitter enthalten.

Um diesen Jitter zum Erstellen zufälliger Werte zu verwenden, könnte ein 16-Byte-Prüfsummenarray verwendet werden. Der TMR1 könnte dann so konfiguriert werden, dass er so schnell wie möglich läuft, und jedes Mal, wenn sich das PWM-Signal ändert, könnte der TMR1-Wert an den Anfang des Arrays geschrieben werden. Dann könnte die MD5-Summe des Arrays genommen und in dasselbe Array zurückgeschrieben werden.

Durch einige tausendmaliges Wiederholen dieser Prozedur könnte ein 16-Byte-MD5-Hash erstellt werden, der völlig zufällig sein sollte.

Ein MD5-Prüfsummenalgorithmus passt jedoch kaum auf den PIC16F1783, sodass dies bei etwas leistungsstärkeren Chips eher von Nutzen ist. Die gleiche Idee könnte jedoch verwendet werden, indem einfach ein Byte um den TMR1-Wert erhöht und einige tausend Mal umbrochen wird, bevor es als "zufällig genug" betrachtet wird.

Dies kann nur fehlschlagen, wenn die interne 500-kHz-Quelle irgendwie mit dem Quarzoszillator synchronisiert wird. Ich habe keine Ahnung, ob das möglich ist.

Aktualisieren:

Der folgende Code scheint in meinem Labor in der Praxis zu funktionieren:

#define RAND_SIZE 255
unsigned char random_data[RAND_SIZE];
void make_random_data()
{
//Used output pin: RC3. Make sure it is unconnected!
PSMC1PRH=0x0; //choose a very short period period
PSMC1PRL=0x3;

PSMC1DCH=0x00; //set 50% duty
PSMC1DCL=0x2;

PSMC1PHH=0;
PSMC1PHL=0;

PSMC1CONbits.PSMC1EN=1;

PSMC1CLK=1; //64mhz    
PSMC1STR0bits.P1STRD=1;
PSMC1OENbits.P1OED=1;
PSMC1PRSbits.P1PRST=1;
PSMC1PHSbits.P1PHST=1;
PSMC1DCSbits.P1DCST=1;

// Zero the id, to make sure any previous value does not influence result.
for(int i=0;i<RAND_SIZE;++i)
    random_data[i]=0;

// Generate the new random id:
for(int pass=0;pass<1000;++pass)
{
    for(int j=0;j<RAND_SIZE;++j)
    {
        unsigned char bitmask=1;
        for(signed char bitnum=7;bitnum>=0;--bitnum)
        {
            if (PORTCbits.RC3)
                random_data[j] ^= bitmask;
            bitmask<<=1;
        }
    }
}
}

Update 2:

Es wird nur ein Pin geopfert, da der PWM-Pin des Ausgangs gelesen werden kann. Sie müssen ihn nicht an einen Eingang weiterleiten und diesen lesen.

avl_sweden
quelle
1
Bestimmte Arten von Uhren neigen dazu, sich mit anderen Uhren zu synchronisieren, daher kann dieses Problem berechtigt sein. Das machen nicht alle Typen, also wäre ein bisschen Forschung angebracht.
AaronD
Hmm. Vielleicht ist die Idee des Temperatursensors in der Praxis dann besser.
avl_sweden
1
Ich wäre daran interessiert, einen Test der Zufälligkeit auf die Ausgabe anzuwenden (aber nicht interessiert genug, um es selbst zu tun!). Könnten Sie das bequem machen?
Scott Seidman
Ich habe sowohl den PSMC-Taktjitter als auch den Temperatursensor-Ansatz getestet. Beide funktionieren und beide können auf einem PIC16F1783 in wenigen Sekunden eine 16-Byte-Seriennummer generieren.
avl_sweden
Hier ist eine zufällige Zeichenfolge nur den Takt-Jitter Ansatz erzeugt werden: 1a7b2fecfbb0447fcce418089ea1f56082367cd921a041155181455ac437a8557d2ff122429790b170846df01434ae3c31f9ccd499882b8e38ab30f0adf550abf9ac223cc7e4820bb1956b6960c51ceeb7a59edad202b09cdb1fbd228a0ee63a586368869acc527489fed9f67073aab1f7d2ccd8259bf5980d74802add17caacdcd6f82374bfaedd092b66bc702d4cf84de320b678f2a712685c334c79741cce2c7632a5771d887d32fb52667bc190cc5517a1b0104d28a4b4644662e4dd6ad5dcf7470883de22ea9a399bc0b94a7fc4a5a2233b26900b27fdb16bc15e14bbfdaace1d6ee0568bee186985ab914058128d8208e095e3adac7284f7cce36e69
avl_sweden