Forum: Compiler & IDEs Erfahrung wäre nicht schnell


von Liloba (Gast)


Lesenswert?

Hallo, ich hab ein kleines Programm geschrieben und habe noch zwei 
Problem.
Die Funktion: OUTPUT_PWM_INIT soll einfach nur einen Pin ein und 
ausschalten. mit ca. 2000 Hz (1000 bis 5000Hz sind OK). Kurz um, geht so 
noch nicht!

Das zweite Problem ist in der main, im while loop. Ich möchte einen 
sollwert aus dem PORTC einlesen. Und diesen Wert für das Zählen des 
Interrupt ereignisses nutzen. Das lesen geht so nicht. Was muss ich 
machen?

Hier der Code.
Danke Liloba
PS. ich bin Anfänger, bitte bei der Antwort berücksichtigen!

#include <avr/io.h>
#include <avr/interrupt.h>
//unsigned char
typedef enum {FALSE,TRUE} logic;
logic HolzIstNeu;
int sollwert=4;
int istwert=0;

void Init(void);
void output_H(void);
void output_L(void);
void OUTPUT_PWM_INIT(void);

SIGNAL(SIG_INTERRUPT0){   // Laser Singnal
if (HolzIstNeu == 1){
    istwert++;
    if(istwert>=sollwert){
      HolzIstNeu = FALSE;
      istwert=0;
      output_L();
    }
}
else{
  output_L();
  }
}

SIGNAL(SIG_INTERRUPT1){ // Holz Singnal
HolzIstNeu = TRUE;
output_H();
}

void Init(void){
DDRB=0xff;
            // MCU Contol Register
MCUCR |= 0b00001111;  //-steigende Flanke
            //General Interrupt Control Register
GICR |= (1 <<INT0);
GICR |= (1 <<INT1);    // 1 meint Frei, 0 meint gesperrt
sei();          // alle interrupt frei
OUTPUT_PWM_INIT();
}

void OUTPUT_PWM_INIT(void){
  TCCR1A |= (1 << COM1A0);  //Invertierende PWM
  TCCR1A |= (1 << COM1A1);  //Der Ausgangspin wird gelöscht beim 
Herunterzählen und gesetzt beim Hochzählen
  TCCR1A = (1<<COM1A1) | (1<<WGM11);
                //PWM, Phase Correct, 9-Bit

  TCCR1B = (1<<WGM13) | (1<<WGM12) | (1<<CS10);
                // | (1<<CS12); //Teiler auf 64 gesetzt
  OCR1A = 0b00001111;      //verglichswert für Timer 
(Abschaltungszeitpunkt)
}

void output_H(void){
PORTB |= (1 << PB0);
}
void output_L(void){
PORTB &= ~(1<<PB0);
}

int main(void)
{
Init();            // Init starten
do{ sollwert = 10*PORTC;  // einlesen von "sollwert"
  }while(1);
}

von Albert .. (albert-k)


Lesenswert?

Liloba schrieb:
> Das zweite Problem ist in der main, im while loop. Ich möchte einen
> sollwert aus dem PORTC einlesen. Und diesen Wert für das Zählen des
> Interrupt ereignisses nutzen. Das lesen geht so nicht. Was muss ich
> machen?

Einlesen vom Port nicht über PORTx sondern über PINx, sonst liest du 
immer nur die Einstellungen der Pullups ein.
Nicht vergessen PORTC als Input zu definieren.
Desweiteren sollwert als volatile definieren damit die optimierung in 
der ISR sollwert nicht seperat anlegt.

Mach deine Register initialisierung mal etwas übersichtlicher. Manchmal 
setzt du Bits aus einem Register irgendwann später nochmal extra 
dazu...schwierig zu verstehen was du eigentlich machst...

Dadurch das du WGM11, WGM12 und WGM13 geetzt ahst verwendest du Fast 
PWM, da ist der TOP Wert aber in ICR1 definiert und nicht in OCR1A. 
Außerdem must du COM1A0 auf 0 lsassen wenn ich dein vorhaben richtig 
verstanden habe.

von Liloba (Gast)


Lesenswert?

hallo danke für die antwort,
das mit dem PINx habe ich davor versucht gehabt aber die es geht dennoch 
nicht. kann es noch woanders dran liegen?

was heist "volatile definieren" ist das ein Typ einer Variablen?

Das mit der PWM versuch ich mal zu überarbeiten danke für den wichtigen 
Hinweis!

Mal abgesehen von der PWM_init die noch Baustelle ist, hab ich da noch 
irgendwo verwirrende Bits und Register die ich setzte?

Danke!
Liloba

von Albert .. (albert-k)


Lesenswert?

Liloba schrieb:
> das mit dem PINx habe ich davor versucht gehabt aber die es geht dennoch
> nicht. kann es noch woanders dran liegen?
Es wird wohl daran gelegen haben das du du PORTC nicht als Input 
definiert hast. Zumindest ist davon in deiner Init funktion nichts zu 
sehen. Außerdem müsstest du dann für die Inputs noch die Pull-ups 
aktivieren, wenn du nicht gerade externe verwendest.
1
DDRC = 0xff; //PORTC auf Input
2
PORTC = 0xff; //Pull-Ups an PORTC initialisieren
3
4
...
5
6
sollwert = PINC; //auslesen

Liloba schrieb:
> was heist "volatile definieren" ist das ein Typ einer Variablen?
Damit gibst du dem Compiler an das er die Variable nicht lokal in der 
ISR ablegen darf, sondern ihren Wert bei jeder Benutzung neu laden soll. 
Schließlich wird bei dir ja auch außerhalb der ISR auf diese variable 
zugegriffen. Geschrieben dann so:
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
logic HolzIstNeu;
4
volatile int sollwert=4;
5
int istwert=0;
6
7
 ... 
8
9
SIGNAL(SIG_INTERRUPT0){   // Laser Singnal
10
if (HolzIstNeu == 1){
11
    istwert++;
12
    if(istwert>=sollwert){
13
      HolzIstNeu = FALSE;
14
      istwert=0;
15
      output_L();
16
    }
17
}
18
else{
19
      output_L();
20
    }
21
}
22
 ...

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Liloba schrieb:
> PS. ich bin Anfänger, bitte bei der Antwort berücksichtigen!

Daher noch zwei Hinweise:

Dein Betreff ist völlig aussagelos.  Bitte wähle etwas vernünftiges,
wie "Probleme mit PWM und Eingabe auf Pin".

Bitte markiere deinen Quellcode mit [ c ] ... [ /c ] (Leerzeichen
weglassen).

von Liloba (Gast)


Lesenswert?

Danke für die Infos, das Program geht jetzt, nur ein fehler war glaub 
ich in den Hilfen Albert schrieb:
DDRC = 0xff; //PORTC auf Input
aber ich glaub das muss DDRC = 0x00; sein um C als Eingang zu nutzen.

Danke!
Liloba

von Klaus W. (mfgkw)


Lesenswert?

Liloba schrieb:
> aber ich glaub das muss DDRC = 0x00; sein um C als Eingang zu nutzen.

Man soll ja jedem seinen Glauben lassen, aber als Tatsache würde ich es 
nicht anpreisen.
Evtl. mal das Datenblatt zu deinem Controller lesen?

Da findet man die die ganze Wahrheit...

von Klaus W. (mfgkw)


Lesenswert?

Ich behaupte ja auch nicht das Gegenteil.
Aber wenn man "glaubt", kann man doch einfach nachlesen, wie es wirklich 
ist.

So wie man mit wenig Lesen erfährt
- wie man Quelltexte hier im Forum einfügt,
- daß es Sinn macht ganze verständliche Sätze zu schreiben und 
Interpunktion zu verwenden,
- daß man sinnvollerweise das Problem vollständig beschreibt (auch wenn 
man am #include wenigstens sieht, daß es um einen AVR geht)
- man seinen Mitmenschen mit einem sinnvollen Betreff etwas gutes tut
- den Sinn von volatile erfährt
- ...

von Klaus W. (mfgkw)


Lesenswert?

> Beitrag #2290627 wurde vom Autor gelöscht.

@Stefan Ernst:
Schade, hattest ja im Prinzip recht.

Lösche ich meinen jetzt auch?
Nö, besser nicht.

von Stefan E. (sternst)


Lesenswert?

Klaus Wachtler schrieb:
> Ich behaupte ja auch nicht das Gegenteil.
> Aber wenn man "glaubt", kann man doch einfach nachlesen, wie es wirklich
> ist.

Ja, ist mir dann auch aufgefallen, dass du wohl nur auf das "glauben" 
abgezielt hast. Deshalb hab ich den Beitrag auch schnell gleich wieder 
gelöscht, war damit aber offensichtlich nicht schnell genug. ;-)

Hier der gelöschte Beitrag, damit der Zusammenhang ersichtlich bleibt:

> Klaus Wachtler schrieb:
>> Liloba schrieb:
>>> aber ich glaub das muss DDRC = 0x00; sein um C als Eingang zu nutzen.
>>
>> Man soll ja jedem seinen Glauben lassen, aber als Tatsache würde ich es
>> nicht anpreisen.
>> Evtl. mal das Datenblatt zu deinem Controller lesen?
>>
>> Da findet man die die ganze Wahrheit...

> Auf was willst du hinaus? Er hat doch recht.

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.