Forum: Mikrocontroller und Digitale Elektronik Logaritmisches E-Poti in C (Atmega328P)


von Kevin (Gast)


Angehängte Dateien:

Lesenswert?

Hallo liebe Community,

Projekt Beschreibung:

Ein unendlicher Drehschalter ( Ausgang = 2 Versetze Rechtecksimpulse je 
nach Drehrichtung) wird über ein Atmega328P ausgewertet und über den I²C 
Bus an ein elektronisches Poti weitergegeben. Dies dient zur 
logaritmischen Lautstärkeneinstellung eines Verstärkers.

Aktueller Stand:

Der Code ist soweit fertig. Nur das er im Debugger ( Tool: Atmelstudio 
7.0 ohne extra Plugins) eine Stelle im Code einfach überspringt und eine 
andere garnicht ausführt.

Fehler1: Beim Durlauf wird in der while(1) Schleife der erste Teil bis 
zum I²C übersprungen.
Fehler2: Beim 1 Teil der While Schleife funktioniert die If - Bedingung 
nicht ((rfz & 0xFF) == zaehler)
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
    }

Weitere Infos wie Datenblätter etc kann ich auf Nachfrage noch posten!

Vielen Dank schonmal :)

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.