Forum: Mikrocontroller und Digitale Elektronik MSP430 Sleep Funktion


von Entwickler (Gast)


Lesenswert?

Hallo,

für eine Anwendung wird ein MSP430 Mikrocontroller eingesetzt. Bestimmt 
IO Pins müssen unterschiedlich von high auf low und so weiter gesetzt 
werden.
Dazu benötige ich quasi eine Sleep Funktion. mit delay und while 
Schleife möchte ich allerdings nicht benutzen. Gibt es bereits schon 
Implementierungen auf Interrupt Basis die sowas ermöglichen?

von PittyJ (Gast)


Lesenswert?

Benutzt du irgendein Rtos, oder eine sonstige Programmierumgebung, die 
schon etwas anbietet?

Ansonsten zyklisch einen Timer abfragen. Wie das geht, steht im 
Handbuch.

von Entwickler (Gast)


Lesenswert?

Hallo, ich benutze kein RTOS. Ja das mit einem Timer müsste sowas 
machbar sein.

von Renzo (Gast)


Lesenswert?

Die Variante die dir nicht passt, wäre ja die folgende, oder?
1
#define MCLK (8000000)
2
void delay_ms(unsigned int delay_in_milliseconds) {
3
  do {
4
    __delay_cycles(1000 / MCLK);
5
  } while(--delay_in_milliseconds > 0);
6
}

Geht es darum, dass ein so generiertes "Delay" relativ ungenau ist - 
oder geht es darum, dass der Mikrocontroller so "busy" wartet?

von dummschwaetzer (Gast)


Lesenswert?

>Gibt es bereits schon
>Implementierungen auf Interrupt Basis die sowas ermöglichen?

Du schickst den MSP in eine der möglichen LOW-Power-Modies
hast aber einen Timer und/oder Port(Interrupt), der ihn periodisch 
aufweckt.

In dieser Timer oder/und Port-ISR schaltest du dene Ports.

von Renzo (Gast)


Lesenswert?

Konkret könnte dies so ähnlich wie folgt aussehen:
1
void config_sys_tick(void) {
2
  TB0CTL |= TBSSEL_2;
3
  TB0CCTL0 &= ~CCIE;
4
  TB0CCR0 = 16000000 * 0.01; //T = 10 ms @ SMCLK = 16 MHz
5
  TB0CTL &= ~MC;
6
  TB0CTL |= TBCLR;
7
}
8
9
void start_sys_tick(void) {
10
  TB0CCTL0 |= CCIE;
11
  TB0CTL |= MC_1;
12
  __enable_interrupt();
13
}
14
15
int main(void) {
16
  config_sys_tick();
17
  start_sys_tick();
18
}
19
20
unsigned long Sys_Tick_Count = 0;
21
22
#pragma vector=TIMER0_B0_VECTOR
23
__interrupt void My_Application_Loop(void) {
24
  ++Sys_Tick_Count;
25
26
  {
27
    //Deine Anwendung... Dieser "Loop" wird nun alle 10 ms ausgeführt.
28
    //(Sys_Tick_Count muss da auf jeden Fall noch periodisch irgendwie
29
    //zurückgesetzt werden.)
30
  }
31
32
  __bis_SR_register(LPM0_bits + GIE);
33
}

Andererseits könntest du auch jeweils einen entsprechend konfigurierten 
Timer starten und in einer Schlaufe das Überlauf-Flag pollen. Falls du 
es aber eben nicht "busy" haben möchtest, könntest du statt pollen dann 
auch einfach den Interrupt benutzen, der bei Überlauf "abgefeuert" 
wird...

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.