Forum: Mikrocontroller und Digitale Elektronik MSP430 Brown Out?


von Manuel Keel (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Zusammen

Ich mache mein erstes Microcontroller Projekt und habe noch sehr wenig 
Erfahrung in C Programmierung. Ich verwende einen MSP430FR5739, da 
dieser ein eingebautes FRAM besitzt. Er funktioniert ab einer Spannung 
von 2 Volt.

Ich habe für meine Aufgabe nur eine sehr begrenzte Energiemenge. (Siehe 
KO Screen) In dieser Zeit soll der MC aufstarten und das Programm 
mindestens einmal durchlaufen. Dafür benötigt er ca. 2 ms. Die Energie 
steht mir für ca. 4-6 ms zur Verfügung. Im ganzen KO Ausschnitt muss das 
Programm nur 1 mal ausgeführt werden. Es kann jedoch auch mehrmals 
ausgeführt werden. Die türkis Linie zeigt die Programmausführungen 
welche über 2.1V waren, die Pinkfarbene alle unter 2.1V.

Wenn ich mein MC extern speise, funktioniert alles wie erwartet. Sobald 
ich ihn jedoch nur mit diesen Energie Impulse (KO-Screen) versorge macht 
er nicht das, was ich erwarte…

Ich gehe davon aus, dass dies an der langsam absinkenden Spannung liegt. 
Ist dies möglich? bzw. könnte dies der Grund sein für das Fehlverhalten?


Wäre dies mit einem Brown Out Dedection zu verhindern? Falls ja, hat 
jemand ein Beispiel, wie ich dies Implementieren könnte? Nach tausend 
Versuchen weiss ich nicht mehr weiter und bin kurz vor dem verzweifeln…

Für jegliche Tipps bin ich sehr dankbar.

Viele Grüsse
Manuel
1
#include <msp430.h>
2
3
//FRAM Variabeln Definieren
4
#pragma SET_DATA_SECTION(".fram_vars")
5
long umdrehung;
6
//Positionszustände
7
char pos;
8
char pos1;
9
char pos2;
10
#pragma SET_DATA_SECTION()
11
12
volatile unsigned int i;
13
volatile unsigned int j;
14
volatile unsigned long temp = 0;
15
16
17
int main(void) {
18
  WDTCTL = WDTPW | WDTHOLD;    // Stop watchdog timer
19
20
////////////// Clockspeed auf 8Mhz
21
    CSCTL0_H = 0xA5;
22
    CSCTL1 |= DCOFSEL0 + DCOFSEL1;             // Set max. DCO setting
23
    CSCTL2 = SELA_3 + SELS_3 + SELM_3;        // set ACLK = MCLK = DCO
24
    CSCTL3 = DIVA_0 + DIVS_0 + DIVM_0;        // set all dividers
25
26
    // _delay_cycles(1); = 0.125us
27
28
///////////////// ADC Konfiguration
29
    // Configure ADC10 - Pulse sample mode; ADC10SC trigger
30
    ADC10CTL0 = ADC10SHT_2 + ADC10ON;         // 16 ADC10CLKs; ADC ON
31
    ADC10CTL1 = ADC10SHP + ADC10CONSEQ_0;     // s/w trig, single ch/conv
32
    ADC10CTL2 = ADC10RES;                     // 10-bit conversion results
33
    ADC10MCTL0 = ADC10SREF_1 + ADC10INCH_11;  // AVcc/2
34
35
    // Configure internal reference
36
    while(REFCTL0 & REFGENBUSY);              // If ref generator busy, WAIT
37
    REFCTL0 |= REFVSEL_0+REFON;               // Select internal ref = 1.5V
38
                                              // Internal Reference ON
39
    //__delay_cycles(400);                      // Delay for Ref to settle
40
41
//////////////    P3DIR |= 0x70;  // Pin 4, 5, 6 Als ausgang definieren
42
    P2DIR |= 0x07;  // Pin 2.0, 2.1, 2.2 Als ausgang definieren
43
    P1DIR |= 0x08;  // Pin 3.0 Als ausgang
44
    P1DIR &= 0x07 + ~BIT1 + ~BIT2 + ~BIT4; // P1.0 1.1 1.2  als eingang def
45
    P1DIR &= ~BIT4; // P1.0 1.1 1.2  als eingang def
46
    P4DIR &= ~BIT0; // P4.0 Als Reset eingang
47
//    P4REN |= BIT0;  //Interner Pullup aktivieren
48
49
    P1DIR |= BIT6;
50
    P1DIR |= BIT7;
51
52
//LED's
53
//    PJDIR |= 0xff;
54
//    PJOUT = 0;
55
56
// Slaveselect P2.2 auf 1 setzen
57
    P2OUT |= BIT2;
58
59
  while(1){
60
61
62
    P1OUT |= BIT3;  // IR Dioden aktivieren
63
    _delay_cycles(80); //10us wait
64
    pos = P1IN;  //Zustände in pos schreiben
65
    P1OUT &= ~BIT3;  // IR Dioden deaktivieren
66
67
    //PJOUT = P1IN;   // Zur Kontrolle
68
69
    ADC10CTL0 |= ADC10ENC + ADC10SC;        // Sampling and conversion start
70
      while (ADC10CTL1 & ADC10BUSY);          // ADC10BUSY?
71
72
      if (ADC10MEM0 > 0x2cc){                  // is ADC10MEM = A11 > 1.10V? = 2.2V     2CC = 2.1V
73
  //    Auswertung
74
75
        if(!(pos==pos1) && (!((pos&0x07)==0)))//eine veränderung hat stattgefunden und ein sensor aktiv
76
            {
77
              if(pos&BIT0 && pos1&BIT1 && pos2&BIT2)umdrehung++;
78
79
              if(pos&BIT2 && pos1&BIT1 && pos2&BIT0)umdrehung--;
80
81
              pos2=pos1;
82
              pos1=pos;
83
            }
84
85
            _delay_cycles(2);
86
            P1OUT |= BIT7;
87
            _delay_cycles(5);
88
            P1OUT &= ~BIT7;
89
            _delay_cycles(2);
90
91
      }else{
92
93
        _delay_cycles(2);
94
          P1OUT |= BIT6;
95
          _delay_cycles(5);
96
          P1OUT &= ~BIT6;
97
          _delay_cycles(2);
98
      }
99
100
///////////////////////////////////////////////// Send
101
  temp = umdrehung;
102
  P2OUT &= ~BIT2;  // Slave Aktivieren
103
  for(j=4; j>0; j--){
104
    for(i=8; i>0; i--){
105
    if(temp&0x80000000) P2OUT |= BIT1;
106
    else P2OUT &= ~BIT1;
107
    temp=temp<<1;
108
    _delay_cycles(5);
109
      P2OUT |= BIT0;  // CLK Setzen
110
      _delay_cycles(1);
111
      P2OUT &= ~BIT0; // CLK zurücksetzen
112
113
    }
114
    _delay_cycles(50); // Pause zwischen den 8Bit  Blöcken
115
  }
116
  P2OUT |= BIT2;  // Slave deaktivieren
117
  _delay_cycles(800); // 100us delay
118
  }
119
}

von Davis (Gast)


Lesenswert?

Manuel Keel schrieb:
> Im ganzen KO Ausschnitt muss das
> Programm nur 1 mal ausgeführt werden.

Halte das Programm nach der einmaligen Ausführung an. Beim nächsten POR 
gehts wieder von Vorne los.

von Manuel Keel (Gast)


Lesenswert?

Hallo Davis, Vielen Dank für deinen wertvollen Input. Du meinst einfach 
den while(1) Loop entfernen, oder?

Ich werde das gerne ausprobieren.

Ein Problem sehe ich noch, diese Impulse kommen je Situation, 1 mal pro 
Jahr oder auch bis zu 400 mal in der Sekunde.  Und im letzteren Fall 
hätte ich ja praktisch immer Energie. Aber vielleicht finde ich einen 
weg dies zu detektieren oder zu umgehen...

Vielen Dank und Viele Grüsse Manuel

von Davis (Gast)


Lesenswert?

Manuel Keel schrieb:
> Du meinst einfach
> den while(1) Loop entfernen, oder?

Nein, das ist ganz schlecht, weil undefiniert

Die while(1) als leere Schleife ans Ende oder besser ab in den low power 
mode.

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.