Forum: Gesperrte Threads Logarithmische Einstellung eines Digitalen Potis in C (Atmega328P) [Fehler gesucht]


von Yuukaa96 (Gast)


Lesenswert?

Hallo liebe Community,

Folgendes Szenario: Ein unendlicher Drehschalter ( 25 Stufen/ganzer 
Umdrehung) soll an einem Verstärker die Lautstärke einstellen. Der 
Drehschalter gibt 2 versetzte Impulse aus. Einen von beiden verwende ich 
als Referenz. Dh dieser lässt das Programm in den Interrupt springen wo 
der 2 Impuls abgefragt wird. Je nach dem ob der Impuls früher oder 
später von dem Interrupt Impuls kommt wird ein Zähler hoch/runter 
gezählt welcher dann den Ausgabe Wert im Array bestimmt, welcher 
anschließend vom uC Atmega328p über den I²C Bus an das elektronische 
Poti weitergeleitet wird.

Soviel zum Aufbau. Programmiert und Debuggt wird alles im AtmelStudio 
7.0 (wird ohne Plugins betrieben). Der Compiler liefert auch keinen 
Fehler beim erstellen der Hex-Datei. Also Syntax Fehler sind keine 
vorhanden.

Nun zum Fehler: Alles startet ganz normal nur wenn ich Step-by-Step 
runter gehe im Code überspringt er mir immer den ersten Teil meiner 
while(1) Schleife und geht direkt zum I²C Teil.

Erst danach springt er wieder hoch wo er eigentlich starten sollte. 
Zudem macht er die IF-Bedingung nicht und bleibt an dieser Stelle immer 
Stecken ( Im Code die Stelle wo er fragt ob rfz == zaehler - Damit nicht 
dauerhaft I²C beansprucht wird)
1
/* File: Projekt_Wingender.c
2
    * Descripton: Erfassen der Drehpotentiometer Drehrichtung und übergabe an Digitalpotenziometer
3
    * From:  EGS 3 MK, NM, TS
4
    * Used Ports:  PD2( Interrupt Eingang),PD3(Referenzeingang),PC4 (Serieller Ausgang SDA), PC5 (SCL)
5
  * Version V0.3.2 Stand 04.05.2016*/
6
7
8
    #include <avr/io.h>
9
    #include <avr/interrupt.h>
10
  #include <util/twi.h>               /* Einbinden des Two Wire Interface Headers*/
11
/*------------------------------------------------------------------------------------------------------------------
12
Variablendefinition
13
-----------------------------------------------------------------------------------------------------------------*/
14
15
unsigned char rfz = 0;            /* Definiert die Referenz Variable*/
16
unsigned char zaehler = 0;          /* Definiert die Zähler Variable*/
17
unsigned char DATA = 0;            /* Definiert die Output Variable*/
18
unsigned char SLA_W = 0b01010000;      /* Bit 1,2,3 bestimmen Adresse |  Adresse = 01010000*/
19
unsigned char COMMAND = 0b10101001;      /* Poti 0 wird beschrieben (Command Code in Binär) */
20
float ausgang[26] = {0,1,2,3,4,5,6,8,10,12,15,18,22,27,33,40,48,58,70,84,101,122,147,177,213,255}; /* Definiert das Array*/
21
22
   
23
 /**********************************************************************
24
 *Hauptprogramm
25
 **********************************************************************/
26
    int main (void) {
27
    
28
   /*------------------------------------------------------------------------------------------------------
29
   Ausgangszuweisung
30
   --------------------------------------------------------------------------------------------------------*/
31
32
    DDRD = 0x0C;              /* Legt ersten ( Interrupt Bit 2) und zweiten Eingang fest*/
33
    DDRB = 0x00;              /* Legt den Ausgang fest (Seriell)*/
34
35
    /*-------------------------------------------------------------------------------------------------------------
36
    Interrupt festlegen
37
    -------------------------------------------------------------------------------------------------------------*/
38
    
39
    EIMSK |= (1<<INT0);              /* Aktiviert Interrupt Eingang PortD,2)*/
40
    EICRA |= (1<<ISC01);             /* Setzt das 1 Bit für EICRA Config*/
41
    EICRA |= (1<<ISC00);             /* Setzt das 0 Bit für EICRA Config ( Interrupt bei + Steigung)*/
42
  sei();                                      /* setzt Global Interrupt Enable */
43
44
while(1){
45
    /*--------------------------------------------------------------------------------------------------
46
    Abfrage des Momentan wertes COUNT und setzen der Ausgangsvariable
47
    -----------------------------------------------------------------------------------------------------*/
48
    set:
49
    if ((rfz & 0xFF) == zaehler) {             /* Abfrage ob Refrenz gleich Zaehler ist (UND-Verknüpfung damit nur 1 Variable)*/
50
    goto set;
51
            }
52
    else {
53
      DATA = ausgang[zaehler];    /* Lädt Inhalt des Arrays ausgang je nach Zaehler Stelle*/
54
     }
55
/* -----------------------------------------------------------------------------------------------
56
I²C Ausgabeloop
57
--------------------------------------------------------------------------------------------------*/     
58
  TWCR =(1<<TWEN) | (1<<TWSTA) | (1<<TWINT);     /*Start Bit setzen und senden (*/  
59
  while  (!(TWCR & (1<<TWINT)));          /* Prüfung ob Bit TWINT in TWCR 0 ist(bei 0 ist Twint aktiv)*/
60
  if ((TWSR & 0xF8) != TW_START)          /* Gleichheitsabfrage ob TWSR richtigen Status beinhaltet*/
61
    /*ERROR();  */                /* Error Routine wenn Status falsch ist*/     
62
    
63
  TWDR = SLA_W;                  /* SLA_W wird in TWDR geschoben ( Slaveadresse + Write Bit)*/
64
  TWCR = (1<<TWINT) | (1<<TWEN);          /* Senden der Adresse auf den Bus (durch Twint auf 1, wird wieder 0 danach)*/      
65
    while (!(TWCR & (1<<TWINT)));
66
  if ((TWSR & 0xF8) != TW_MT_SLA_ACK)        /* Abfrage ob richtiger Status und Ack Bit gesetzt */
67
    /* ERROR();  */                  /* Falls nicht Error Routine*/
68
    
69
  TWDR = COMMAND;                  /* Schreiben des Kommados ins Data Register */
70
  TWCR = (1<<TWINT) | (1<<TWEN);          /* Senden des Kommandos auf den Bus */
71
    while (!(TWCR & (1<<TWINT)));          /* Prüfen ob Daten angekommen sind */
72
  if ((TWSR & 0xF8) != TW_MT_DATA_ACK)      /* Abfrage ob richtiger Status und Ack Bit gesetzt */
73
  /*  ERROR();  */                /* Falls nicht Error Routine*/
74
  
75
  TWDR = DATA;                  /* Schreiben der ersten Daten ins Data Register */
76
  TWCR = (1<<TWINT) | (1<<TWEN);          /* Senden der Daten auf den Bus */
77
    while (!(TWCR & (1<<TWINT)));        /* Prüfen ob Daten angekommen sind */
78
  if ((TWSR & 0xF8) != TW_MT_DATA_ACK)      /* Abfrage ob richtiger Status und Ack Bit gesetzt */
79
  /*  ERROR();  */                /* Falls nicht Error Routine*/  
80
    
81
  TWCR =(1<<TWEN)| (1<<TWSTO) | (1<<TWINT);      /* Stop Bit setzen und senden ( TWINT wird nicht Automatisch wieder 0 (gestzt)*/
82
     
83
     
84
  }
85
86
      return (0);
87
}
88
  
89
  
90
 /*---------------------------------------------------------------------------------------------------------------
91
*Interrupt Routine für INT0 Eingang
92
 -----------------------------------------------------------------------------------------------------------------*/
93
  ISR (INT0_vect)                        /*Verknüpft den Interrupt Vektor*/
94
   {
95
    cli ();                          /* Rücksetzt den Global Interrupt Enable */
96
   zaehler = rfz;                                          /* Setzt die Referenz auf den Counter Wert*/
97
    if  (PD3 == 1) {
98
    zaehler = zaehler + 1;
99
          }                    /* Referenz Abfrage ob Vorwärts oder Rückwärts + Counter*/
100
    else {
101
    zaehler = zaehler - 1;
102
    }
103
                                                     
104
    }
ps: Das "& 0xFF" war ein Test ob es vllt mit dem Ergebniss der Und 
Verknüpfung geht das nicht 2 Variablen verglichen werden

Vielen Dank schonmal für die Hilfe!

: Verschoben durch Moderator
von Yuukaa96 (Gast)


Lesenswert?

Beitrag kann gelöscht werden! Ausversehen Doppelpost wegen Schlechter 
Internetverbindung.

Dieser Beitrag ist gesperrt und kann nicht beantwortet werden.