Forum: Mikrocontroller und Digitale Elektronik MSP430 F1232 startet nicht


von SuperGrobi (Gast)


Lesenswert?

Hallo Forum,

ich hab mich dazu durchgerungen, meinen Dimmercode neu zu schreiben.
Jetzt kommt es aber vor, das der MSP in der neuen Version nicht
startet, wenn ich ihn mit Spannung versorge. Erst, wenn ich ihn über
den Compiler starte, rennt er los. In meiner alten Version lief er auch
ohne Compiler. Ich hab dann zum testen das alte Programm noch mal
eingespielt, danach gab es keine Probleme: Einschalten --> läuft aber
mit der neuen Version: Einschalten --> läuft nicht.

Ich schätze mal, das es an der Initialisierung liegt. Jedoch ist die
weitgehend identisch. Ich hab in der neuen Version einige Routinen
ausgelagert. Darunter auch die Initialisierung. Hier mal der Code:

alte Routine (läuft):
1
#include <msp430x12x2.h>
2
#include "i2c.c"
3
4
void main(void);
5
void Schieberegister(int);
6
void wait_zykl(unsigned int, unsigned int);
7
void Display(int);
8
void Control_Word(int,int);
9
void Disp_Zeit(int,int);
10
void Disp_Charmap(char*);
11
volatile int Menue, enc_delta;    // 
12
13
void main(void)
14
{
15
  WDTCTL = WDTPW + WDTHOLD; // watchdog aus
16
  P1DIR = 0x08;             // Definieren der E/As
17
  P2DIR |= 0xFF;            // Set P2 to output direction
18
  P3DIR |= 0x83;            // Set P3 to output direction 3.0, 3.1 3.7
19
= Out Rest Input
20
  P1OUT = 0x00;             // initialisieren der Ausgänge
21
  P2OUT = 0x00; 
22
  P3OUT = 0x00; 
23
  
24
  // Starten des Quarzes 
25
  BCSCTL1 |= XTS;         // ACLK = LFXT1 = HF XTAL
26
  do 
27
  {                       // pruefroutine, ob 8 Mhz-oszillator schon
28
stabil ist
29
    IFG1 &= ~OFIFG;       // OSCFault flag loeschen (zeigt
30
oszillatorfehler an)
31
    for (i=0xFF;i>0;i--); // warten, ob es wieder gesetzt wird
32
  }
33
  while (IFG1 & OFIFG);   // OSCFault immer noch gesetzt?       
34
  BCSCTL2 |= SELM_3;      // MCLK = LFXT1 (safe) 8 MHz 8,0005560
35
  BCSCTL2 |= SELS;        // SMCLK = LFXT1
36
  BCSCTL2 |= DIVS_0;      // SMCLK = LFXT1/2 = 4 MHz
37
38
  _BIS_SR(GIE);           // allgemeiner interrupt-enable (noetig fuer
39
nulldurchgangserkennung)
40
  CCTL0 = CCIE;           // CCR0 interrupt enabled
41
  CCR0 = 200;
42
  TACTL = TASSEL_2 + MC_1;// SMCLK, upmode
43
44
  P1IE=0x04;              // pin 1.1 interrupt-faehig machen (noetig
45
fuer nulldurchgangserkennung)
46
  P1IES=0x00;             // interrupt auf pin 1.1 ausloesen bei
47
low->high - uebergang
48
49
//  ADC10CTL1 = INCH_10+ADC10DIV_7;           // Temp Sensor
50
ADC10CLK/4
51
//  ADC10CTL0 = SREF_1 + ADC10SHT_3 + REFON + ADC10ON; // + ADC10IE
52
keinen Interrupt !!;
53
54
  helligkeit_global = 4;  // Helligkeit Start und Min
55
  helligkeit_max = 395;   // Helligkeit Max
56
57
// Watchdog Timer wird als Takt-Timer benutzt, weil Timer A für das
58
Dimmen eingesetzt werden soll
59
  WDTCTL = WDT_MDLY_8;                      // Watchdog Timer auf 1ms
60
setzen (kein Reset)
61
  IE1 |= WDTIE;                             // Enable WDT interrupt

Variablen hab ich jetzt mal weggelassen.
Und jetzt das neue Programm, das nicht startet:
1
#include <msp430x12x2.h>
2
#include "i2c.c"              // einbinden der I²C Funktionen
3
#include "init.c"             // einbinden der Prozessor
4
Initialisierung
5
#include "dimmer_routinen.c"  // einbinden der Dimmer Routinen
6
7
void mcu_init(void);
8
void Status(int);
9
void Uhr_abfrage(void);
10
void Flash_lesen(void);
11
void Flash_speichern(void);
12
void Status_Drehgeber(void);
13
void drehgeberAbfrage(void);
14
void displayZeit(void);
15
void Temp_abfrage(void);
16
void displayMenu(char,char);
17
18
// Varialblen deklarationen
19
struct Zeit{char stunde, minute, sekunde;};
20
21
struct Zeit Uhrzeit;
22
23
void main(void)
24
{
25
  char TasteDr, TA;
26
  unsigned int wait, Taste1Time;
27
  Status(128);
28
  P2OUT = 0xff;
29
  mcu_init();                               // Prozessor
30
initialisierung
31
//...
32
}

in der Datei init.c ist dann die Routine mcu_init:
1
void mcu_init(void)         // Init des MSP430
2
{
3
  unsigned int i;
4
5
  WDTCTL = WDTPW + WDTHOLD; // watchdog aus
6
  P1DIR = 0x08;             // Definieren der E/As
7
  P2DIR |= 0xFF;            // Set P2 to output direction
8
  P3DIR |= 0x83;            // Set P3 to output direction 3.0, 3.1 3.7
9
= Out Rest Input
10
  P1SEL = 0x08;             // P1.3 auf Timer A schalten
11
  P1OUT = 0x00;             // initialisieren der Ausgänge
12
  P2OUT = 0x00; 
13
  P3OUT = 0x00; 
14
  
15
  // Starten des Quarzes 
16
  BCSCTL1 |= 0x40;         //  HF XTAL
17
  do 
18
  {                       // pruefroutine, ob 8 Mhz-oszillator schon
19
stabil ist
20
    IFG1 &= ~OFIFG;       // OSCFault flag loeschen (zeigt
21
oszillatorfehler an)
22
    for (i=0xFF;i>0;i--); // warten, ob es wieder gesetzt wird
23
  }
24
  while (IFG1 & OFIFG);   // OSCFault immer noch gesetzt?       
25
  BCSCTL2 |= SELM_3;      // MCLK = LFXT1 (safe) 8 MHz 8,0005560
26
  BCSCTL2 |= SELS;        // SMCLK = LFXT1
27
  BCSCTL2 |= DIVS_0;      // SMCLK = LFXT1/2 = 4 MHz
28
29
  _BIS_SR(GIE);           // allgemeiner interrupt-enable (noetig fuer
30
nulldurchgangserkennung)
31
  CCTL0 = CCIE;           // CCR0 interrupt enabled
32
  CCR0 = 39000;
33
  CCR2 = 39000;
34
  TACTL = TASSEL_2 + MC_1;// SMCLK, upmode
35
  CCTL2 = OUTMOD_3;       // Ausgang Toggeln
36
  
37
  P1IE=0x04;              // pin 1.1 interrupt-faehig machen (noetig
38
fuer nulldurchgangserkennung)
39
  P1IES=0x00;             // interrupt auf pin 1.1 ausloesen bei
40
low->high - uebergang
41
  
42
  // Watchdog Timer wird als Takt-Timer benutzt, weil Timer A für das
43
Dimmen eingesetzt werden soll
44
  WDTCTL = WDT_MDLY_8;                      // Watchdog Timer auf 1ms
45
setzen (kein Reset)
46
  IE1 |= WDTIE;                             // Enable WDT interrupt
47
48
  // Initialisieren der RTC (Trickle Charger) daran hängt ein 2200uF
49
Kondensator, 
50
  // der reicht für ca. 12 Stunden Stromausfall
51
  I2C_start();                              // START senden
52
  I2C_init(0x68, 'w');                      // den RTC adressieren
53
  while (!(I2C_gotACK()));
54
  I2C_sendbyte(0x0A);                       // Control Register
55
auswählen
56
  while (!(I2C_gotACK()));
57
  I2C_sendbyte(169);                        // INT einschalten
58
  while (!(I2C_gotACK()));
59
  I2C_stop();                               // STOP senden     
60
  
61
  // Initialisieren des Temperatursensors (12 Bit Modus)
62
  I2C_init(0x49, 'w');                      // den sensor auslesen
63
  while (!(I2C_gotACK())); I2C_sendbyte(0x01);  // pointer register:
64
P1=0, P0=1 (d.h.: config. reg. ansprechen)
65
  while (!(I2C_gotACK())); I2C_sendbyte(0x60);  // TMP100 auf
66
12-bit-modus stellen
67
  while (!(I2C_gotACK())); I2C_start();
68
  I2C_init(0x49, 'w');                      // address: I2C-adresse
69
des auszulesenden TMP101; schreibender zugriff
70
  while (!(I2C_gotACK())); I2C_sendbyte(0x00);  // pointer register:
71
P1=0, P0=0 (d.h.: temperaturreg. ansprechen)
72
73
}

jedoch springt er hier gar nicht erst hin. Irgendwie hängt der sich
vorher schon auf. Debuggen ist nicht möglich, weil mit Compiler läuft
das Programm... Ohne jedoch nicht.

Kann das an dem POR liegen ? ich dachte der wäre beim 1232
standartmässig aktiviert. Weis jemand Rat ?

Gruß
Thomas

von Jörg S. (Gast)


Lesenswert?

Mach doch anstatt "P1OUT = 0x00" mal "P1OUT = 0xFF" dann siehst du
ob er wenigstens bis dahin kommt.

von SuperGrobi (Gast)


Lesenswert?

Sorry, hab ich vergessen zu erwähnen. Das hab ich schon mit
verschiedenen Möglichkeiten versucht. Bevor die mcu_init Routine
aufgerufen wird hab ich mit P2OUT = 0xff versucht die P2 Ausgänge zu
schalten, das klappt schon nicht. Das funktioniert auch nicht, wenn
"P2OUT = 0xff" vor der "Status" Routine gesetzt wird.
Also ich hab das gefühl, das die Main Routine nicht aufgerufen wird.
Diese ist aber unter den Options bei Debugger --> Setup --> Run to
(Häkchen gesetzt) "main" eingetragen.

(Die Status Routine gibt den Wert an ein Schieberegister (HC164) aus).

gruß
Thomas

von SuperGrobi (Gast)


Lesenswert?

noch was:

wenn ich am Reset Pin einen Reset auslöse, rennt er auch los, als wenn
nix wäre...

gruß
Thomas

von tenner (Gast)


Lesenswert?

setz mal das Abschalten des Watchdog wieder in die 1. Zeile der main.

evt. prototyp für main wieder einfügen?

Gruß
Tenner

von SuperGrobi (Gast)


Lesenswert?

Ich hab das gerade mal versucht. Hab die Zeile

void main(void);

wieder reingenommen und direkt am Anfang der Main Routine mit

  WDTCTL = WDTPW + WDTHOLD;

den Watchdoch abgeschaltet.
Dies bringt jedoch keine Änderung. Der MSP lässt sich nur im Debugger
oder über den Reset Pin starten. Ich gehe doch richtig in der Annahme,
das eine Externe Einschalt-Reset-Logik nicht notwendig ist, oder ?
Müsste ich sonst den Reset Pin nach dem Einschalten kurzzeitig auf Low
ziehen ? Achso, der ist natürlich über einen 5k1 Wiederstand an Plus
angeschlossen.

gruß
Thomas

von szimmi (Gast)


Lesenswert?

Hiho,
mal ne dumme Frage. Hast Du alle ISR's implementiert? Du enablest ja
einige (Flanke, Watchdog). Nicht, dass in der Vectortabelle FF's
stehen. Dann geht er natuerlich irgendwann in den Wald...

von SuperGrobi (Gast)


Angehängte Dateien:

Lesenswert?

Ich gehe davon aus, das ich das getan habe :)

Es sind 3 ISR`s vorhanden: Watchdog, TimerA und Port1
er geht ja nicht irgendwann in die Wicken, sondern fängt gar nicht erst
an, was zu machen... Und mit Debugger (IAR) läuft das ja...
kann dann hinterher den JTAG abziehen und der läuft weiter.
Ohne läuft es auch, ich muss halt einmalig nur den Reset machen...

ich schicke am besten mal den gesamten code als Anhang.

gruß
Thomas

die Routinen folgen gleich...

von SuperGrobi (Gast)


Angehängte Dateien:

Lesenswert?

hier die init Routine

von SuperGrobi (Gast)


Angehängte Dateien:

Lesenswert?

allgemeine Routinen

von szimmi (Gast)


Angehängte Dateien:

Lesenswert?

Hmmm, hast Du einen Kondensator am Reset-Pin gegen Masse?
Der Controller sollte beim Einschalten wenigestens kurz mal ein Low
sehen.
Anbei mal die Beschaltung von Standard-Olimex-Boards.

von SuperGrobi (Gast)


Lesenswert?

ich werde das mal probieren... ist aber lötarbeit :)

dies würde jedoch nicht erklären, warum das Programm_alt läuft und das
Programm_neu nicht.

gruß
Thomas

von SuperGrobi (Gast)


Lesenswert?

hab jetzt 15nF von Masse zum Reset Pin gelötet.
bringt jedoch keine Besserung.
Ist leider alles beim alten geblieben.

gruß
Thomas

von Supergrobi (Gast)


Lesenswert?

Sorry, ich muss diesen Beitrag jetzt doch noch mal nach oben holen, da
ich leider noch keine Lösung gefunden habe.

vielleicht kann mir jemand noch einen Tip geben, was ich noch probieren
kann ?

danke
Thomas

von Steffen (Gast)


Lesenswert?

mal ordentliche header-files schreiben und kein .c's includieren ->
schlechter Stil... zu deinem Problem habe ich leider keine Antwort
parat... is scho komisch, check das morgen mal durch... schönen sa
abend...

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.