Forum: Mikrocontroller und Digitale Elektronik AVR stürzt ab nach PCINT


von Mr. Fehler (Gast)


Lesenswert?

Hallo,

hat jmd. eine Ahnung, woran es liegen könnte, das meine AVR beim Starten 
immer so 2-3x abstürzen direkt nach dem Start, nachdem ich PCINT 
aktiviert habe?!

Ich setze den Pin auf Eingang, dann PCINT aktiv (während dessen liegt 
dort bereits ein 20khz Signal an). Dann einige Sachen später mache ich 
sei().

Woran liegt das?!

von Bastian W. (jackfrost)


Lesenswert?

Ohne dein Program zu kennen kann dir keiner helfen.

Gruß JackFrost

von tremolo (Gast)


Lesenswert?

Schaltplan und Code bitte. Sonst hilft nur die Glaskugel. Die sagt 
Kurzschluss oder Abblockkondensatoren vergessen.

von Dieter F. (Gast)


Lesenswert?

Mr. Fehler schrieb:
> Woran liegt das?!

Keine ISR definiert.

von H.Joachim S. (crazyhorse)


Lesenswert?

Dieter F. schrieb:
> Keine ISR definiert.

Mr. Fehler schrieb:
> Dann einige Sachen später mache ich
> sei().

Vorher dürfte das also nichts machen.
Aber ohne Programm gehts hier nicht weiter.

von Rätsel Rater (Gast)


Lesenswert?

Mr. Fehler schrieb:
> das meine AVR beim Starten
> immer so 2-3x abstürzen

Ich würde erst mal wissen wollen woran man erkennt das
der Controller "abstürzt".

Am Bluescreen?
Ach so, hat keinen Screen ... hmmmm ....

von Karl (Gast)


Lesenswert?

Mr. Fehler schrieb:
> hat jmd. eine Ahnung, woran es liegen könnte, das meine AVR beim Starten
> immer so 2-3x abstürzen direkt nach dem Start, nachdem ich PCINT
> aktiviert habe?!

Hast Du einen Programmer angeschlossen?

von Mr. Fehler (Gast)


Lesenswert?

Hallo,

kein Programmer angeschlossen, 100n habe ich natürlich und woran man das 
merkt, ganz einfach:

Es wird vor dem ganzen Init die IOs eingestellt, und 2 Ausgangspinne auf 
5V geschaltet. Und da hängen LEDs dran über einen Mosfet. Und die 
flackern halt 2-3x bevor alles normal läuft. Man sieht es auch am Osci.


ISR habe ich natürlich.


In der ISR ist eine recht große inline Funktion, das geht nicht anders. 
Ich habe das mal schrittweise durchgetestet, die Variablen sind alle 
volatile. Ich poste später das Programm noch.

von Mr. Fehler (Gast)


Lesenswert?

By the way: Was mir aufgefallen ist: Wir der controller initialisiert 
ohne das das 20khz Signal anliegt, dann stürzt er nicht ab.

von Wolfgang (Gast)


Lesenswert?

Mr. Fehler schrieb:
> In der ISR ist eine recht große inline Funktion, das geht nicht anders.

Und die braucht maximal wie lange?

von Mr. Fehler (Gast)


Lesenswert?

Das steht in der ISR drin um das Signal zu detectieren:
1
//get and reset the timer ovf bits
2
  if (decoder.dcc.state.systemBits.timer_status)  decoder.dcc.state.systemBits.timer_status = FALSE;
3
  
4
  //dcc is now high
5
  if (DCC_IS_HIGH && !decoder.dcc.state.systemBits.cnt_starts)
6
  {
7
    TCNT0 = NULL;
8
    decoder.dcc.state.systemBits.cnt_starts = TRUE;
9
  }
10
  else if (!DCC_IS_HIGH && decoder.dcc.state.systemBits.cnt_starts)
11
  {            
12
    if (decoder.dcc.dcc_stretched_0)  decoder.dcc.dcc_cnted_time = 0xFF;
13
    else                decoder.dcc.dcc_cnted_time = TCNT0;
14
    
15
    decoder.dcc.dcc_stretched_0 = FALSE;
16
    decoder.dcc.state.systemBits.cnt_starts = FALSE;
17
    decoder.dcc.state.systemBits.timer_status = TRUE;
18
  }
19
  else if (decoder.dcc.state.systemBits.cnt_starts && TCNT0 >= 220)   //detect streched 0
20
  {
21
    decoder.dcc.dcc_stretched_0 = TRUE;
22
  }
23
24
if (decoder.dcc.sysCond.systemBits.init_time_over && !decoder.timer.timer_univ[start_switching_timer])
25
  {
26
    decoder.signalstate = signalstate_stop;
27
    decoder.signalstate_last = signalstate_stop;
28
    decoder.dcc.sysCond.systemBits.init_time_over = FALSE;
29
  }
30
31
  
32
  //noch kein ganzes packet bekommen?
33
  if (decoder.dcc.state.systemBits.timer_status && !decoder.dcc.state.systemBits.received_all_valid)
34
  {
35
    if (!decoder.dcc.state.systemBits.start_detected)  //find beginning!
36
    {
37
      //cnt all 1 bits up to get a 0 and cnter >= 10 ==> Start!
38
      if (decoder.dcc.dcc_cnted_time <= decoder.dcc.dcc_time_logic_one)  decoder.dcc.cnt_bit_pos++;
39
      else //0 is detected
40
      {
41
        //start is detected!! //more than 9 1's bits? ==> must be the start!
42
        if (decoder.dcc.cnt_bit_pos > 9)
43
        {
44
          decoder.dcc.cnt_byte_pos = NULL;
45
          decoder.dcc.state.systemBits.start_detected = TRUE;
46
          decoder.dcc.state.systemBits.get_data_byte = TRUE;
47
          
48
          for (uint8_t i = NULL; i < 15; i++)  decoder.dcc.RX[i] = NULL;
49
        }
50
        
51
        decoder.dcc.cnt_bit_pos = NULL;
52
      }
53
    }
54
    else if (decoder.dcc.state.systemBits.get_data_byte)  //byte transfer
55
    {
56
      if (decoder.dcc.dcc_cnted_time <= decoder.dcc.dcc_time_logic_one)  decoder.dcc.RX[decoder.dcc.cnt_byte_pos] |= (1<<(7 - decoder.dcc.cnt_bit_pos));
57
      
58
      decoder.dcc.cnt_bit_pos++;
59
      
60
      
61
      //complete byte detected, now check the divisionbit
62
      if (decoder.dcc.cnt_bit_pos > 7)
63
      {
64
        decoder.dcc.cnt_bit_pos = NULL;
65
        decoder.dcc.state.systemBits.get_data_byte = FALSE;
66
      }
67
    }
68
    else  //get the division bit, 0 = divide ==> next bytes comes, 1 = end (then check the data)
69
    {      
70
      if (decoder.dcc.dcc_cnted_time <= decoder.dcc.dcc_time_logic_one)   //division bit is 1 ==> end transmission
71
      {
72
        //check parity, if good ==> you can work with data
73
        decoder.dcc.RX[decoder.dcc.cnt_byte_pos + 1] = decoder.dcc.RX[decoder.dcc.cnt_byte_pos - 1];
74
        for (uint8_t i = NULL; i < (decoder.dcc.cnt_byte_pos - 1); i++)  decoder.dcc.RX[decoder.dcc.cnt_byte_pos + 1] ^= decoder.dcc.RX[i];
75
        
76
        //calculated parity is same as transmitted ==> data is correct! Now check the 2 0815 states (empty data and decoder restart)
77
        if (decoder.dcc.RX[decoder.dcc.cnt_byte_pos] == decoder.dcc.RX[decoder.dcc.cnt_byte_pos + 1])
78
        {  
79
          //set instruktion pointer!
80
          //where is the real data?! (only for locomotives)
81
          if (DCC_IS_NORMAL_ADR_SHORT)  decoder.dcc.operation_instr_pos = 1;
82
          else              decoder.dcc.operation_instr_pos = 2;
83
          
84
          decoder.dcc.state.systemBits.operation_dcc = TRUE;
85
          decoder.dcc.state.systemBits.received_mode = 2;  //deceoder reset as init
86
          
87
          for (uint8_t i = NULL; i < decoder.dcc.cnt_byte_pos; i++)  //check if every byte is 0
88
            if (decoder.dcc.RX[i])  decoder.dcc.state.systemBits.received_mode = 1;  //not every 0's ==> check if every 2nd byte is 0
89
          
90
          for (uint8_t i = NULL; i < decoder.dcc.cnt_byte_pos; i+=2)  //check if every 2nd byte is 0
91
            if (decoder.dcc.RX[i])  decoder.dcc.state.systemBits.received_mode = NULL;  //not every 2nd byte is 0 ==> normal op
92
          
93
          
94
          //check the states
95
          if (decoder.dcc.state.systemBits.received_mode == 1)    //idle mode received
96
          {
97
            decoder.dcc.dcc_reset_state = NULL;
98
            decoder.dcc.state.systemBits.start_detected = FALSE;
99
          }
100
          else if (decoder.dcc.state.systemBits.received_mode == 2)  //reset mode received
101
          {
102
            decoder.dcc.dcc_reset_state++;
103
            decoder.dcc.state.systemBits.start_detected = FALSE;
104
            
105
            if (decoder.dcc.dcc_reset_state >= 8)  dcc_reset_decoder();
106
          }
107
          else  //check normal op or programming mode
108
          {
109
            decoder.dcc.dcc_reset_state = NULL;
110
            
111
            //cv programming (service mode)
112
            if (DCC_IS_SERVICE_MODE)    
113
            {          
114
              dcc_handle_service_mode();
115
              decoder.dcc.sysCond.systemBits.init_time_over = FALSE;  
116
            }
117
            else if (DCC_IS_POM_MODE_ASSCES(DCC_16BIT_ADDRESS(decoder.system.switch1.switch_addr_hi, decoder.system.switch1.switch_addr_lo)))  
118
            {
119
              dcc_handle_service_POM_mode();  
120
              decoder.dcc.sysCond.systemBits.init_time_over = FALSE;  
121
            }
122
            else
123
              decoder.dcc.state.systemBits.received_all_valid = TRUE;
124
          }
125
        }
126
        
127
        decoder.dcc.state.systemBits.start_detected = FALSE;
128
      }
129
      else //got next byte
130
        decoder.dcc.cnt_byte_pos++;
131
      
132
      
133
      decoder.dcc.state.systemBits.get_data_byte = TRUE;
134
    }
135
  }

von Karl M. (Gast)


Lesenswert?

Hallo Mr. Fehler,

leider kann man die PCINT intitialisierung nicht sehen.

Meistens wird der 8er Block PCINTx Eingänge einem falschen PCINTy 
Interrupt Requenst zugeordnet.

Ich denke hier liegt auch dein Fehler.

von Mr. Fehler (Gast)


Lesenswert?

Ich denke nicht (und hoffe).

Angeschlossen an PB3 an einem Attiny85

Aus der init funktion:
1
  decoder.peripherie.dcc_ack_pin = pin_ack;
2
  decoder.peripherie.dcc_pin = pin_dcc;
3
  decoder.peripherie.dcc_dir = dir_dcc;
4
  decoder.peripherie.dcc_port = port_dcc;
5
  decoder.peripherie.ack_dir = dir_ack;
6
  decoder.peripherie.ack_port = port_ack;
7
  decoder.peripherie.dcc_pin_reg = pin_reg;
8
  
9
  
10
  //Timer init with 1ms/ovf (only for timing, e.g can dimming (soft)
11
  //Für den Timer (interrupt)
12
  TCCR1 |= (1<<CS11)|(1<<CS12);    //prescaler 32
13
  TIMSK |= (1<<TOIE1);  //TOIE ==> ~1 kHz
14
  
15
  //timer for dcc detection
16
  TCCR0B |= (1<<CS01);    //prescaler 8
17
18
#if (DCC_DETECTION_INTERRUPT)  //PCINT3
19
  PCMSK |= (1<<PCINT3);
20
  GIMSK |= (1<<PCIE);  
21
#endif
22
23
sei();

von Karl M. (Gast)


Lesenswert?

Hallo,

was soll das sein ?
1
decoder.peripherie.dcc_ack_pin = pin_ack;
2
  decoder.peripherie.dcc_pin = pin_dcc;
3
  decoder.peripherie.dcc_dir = dir_dcc;
4
  decoder.peripherie.dcc_port = port_dcc;
5
  decoder.peripherie.ack_dir = dir_ack;
6
  decoder.peripherie.ack_port = port_ack;
7
  decoder.peripherie.dcc_pin_reg = pin_reg;
Wo stehen die AVR Register und ist der Interrupt Vector belegt worden?

von Mr. Fehler (Gast)


Lesenswert?

Karl M. schrieb:
> Hallo,
>
> was soll das sein ?decoder.peripherie.dcc_ack_pin = pin_ack;
>   decoder.peripherie.dcc_pin = pin_dcc;
>   decoder.peripherie.dcc_dir = dir_dcc;
>   decoder.peripherie.dcc_port = port_dcc;
>   decoder.peripherie.ack_dir = dir_ack;
>   decoder.peripherie.ack_port = port_ack;
>   decoder.peripherie.dcc_pin_reg = pin_reg;Wo stehen die AVR Register
> und ist der Interrupt Vector belegt worden?

Das ist von der oberen Funktion wo die entsprechenden PORT und Pin und 
PIN übergeben werden. Ist das wichtig/interessant?! Das ist nur PORTB, 
PBx und PINB

Das ist der Vector:

ISR(PCINT0_vect)
{
   //hier steht das von oben als inline void
}

von B. P. (skorpionx)


Lesenswert?

Das habe ich mit PIC erlebt.:

Unbenutzte Pins vom Mikroprozessor als Fehlerquelle.

von Cerberus (Gast)


Lesenswert?

Ich würde erst mal die Betriebsspannung des AVR stabilisieren
BEVOR man ein Signal auf einen Eingang gibt. Sonst können durch
die interne Schutzbeschaltung die seltsamsten Dinge passieren,
z.B. das so ein Signal wie eine Fremdversorgung wirkt, aber die
ist eben nicht stabil.

von Mr. EEPROM (Gast)


Lesenswert?

Ich habe tatsächlich alle benutzt

von Mr. EEPROM (Gast)


Lesenswert?

Das kann gut sein, dass Signal liegt aber immer an das kann ich gar 
nicht ändern. Ich kann es mal testen aber im Betrieb geht das nicht 
anders. Evtl pin als Ausgang warten dann Eingang

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.