www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik PWM Spannung erhöhen per Taster


Autor: Marco M. (marco1987)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Leute,


ich möchte eine Spannung 0 -5 V an einem Port ausgeben, starten soll es 
bei 0 V und stoppen bei 5 V mit einem Taster wollte ich nun die Spannung 
erhöhen.

Ich wollte das so machen:
 int a=50;
int main()
{

DDRD=0xFF;
DDRC=0x00;

void timer(){
TCCR1A = (1<<COM1A1) | (1<<WGM11);
 TCCR1B = (1<<WGM13) | (1<<WGM12) | (1<<CS10);
ICR1 = a
OCR1A = 0x0031;

TIMSK = TIMSK | (1 << OCIE1A);

 }
  for(;;){
  timer();

if (PINC & (1<<PINC0)){
  a++;}

}


aber irgendwie akzeptiert der keine variable für icr1.

Könnt ihr mir helfen?

Autor: Patrick (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was für einen Controller verwendest Du?

Dir ist schon klar, dass Du immer wieder den Timer neu initialisierst? 
Warum machst Du es nicht so:
 int a=50;
int main()
{

DDRD=0xFF;
DDRC=0x00;

TCCR1A = (1<<COM1A1) | (1<<WGM11);
 TCCR1B = (1<<WGM13) | (1<<WGM12) | (1<<CS10);
OCR1A = 0x0031;

TIMSK = TIMSK | (1 << OCIE1A);


  for(;;){
  timer();

if (PINC & (1<<PINC0)){
  ICR1 = a++;}

}}

Und Du hast das Semikolon hinter ICR1 = a vergessen.

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Eine Funktionsdefinition hat innerhalb von main() nichts zu suchen!

Außerdem solltest Du Dir endlich mal angewöhnen, Deinen Code, den Du 
hier postest, vernünftig zu formatieren. Dafür hat das Forum schließlich 
die entsprechende Funktion...

Autor: Marco M. (marco1987)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für die schnelle antwort benutze den atmega16.

hmm irgendwie verändert sich die spannung nicht wenn ich ICR1 erhöhe

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
...von Groß- und Kleinschreibung und Zeichensetzung mal ganz 
abgesehen...

Autor: Patrick (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ach so. Warum willst Du denn den Wert ins ICR1 schreiben? Die Spannung 
änderst Du durch ändern des Wertes in OCR1A. Also sollte es so heissen:
int a=50;
int main()
{

DDRD=0xFF;
DDRC=0x00;

TCCR1A = (1<<COM1A1) | (1<<WGM11);
TCCR1B = (1<<WGM13) | (1<<WGM12) | (1<<CS10);

TIMSK = TIMSK | (1 << OCIE1A);


  for(;;){
  timer();

if (PINC & (1<<PINC0)){
  OCR1A = a++;}

}}

Autor: Marco M. (marco1987)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Johannes M. wrote:
> ...von Groß- und Kleinschreibung und Zeichensetzung mal ganz
> abgesehen...

Was willst du mir damit sagen?

Autor: Patrick (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und wie sieht es mit der Initialisierung der Ports aus? Wie ist denn 
Dein taster angeschlossen? High- oder Low-activ?

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Marco Müeller wrote:
> Was willst du mir damit sagen?
Lies Dir z.B. Dein Posting von 14:58 noch mal durch... Das OP ist aber 
auch nicht zu verachten.

Autor: Marco M. (marco1987)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
low aktiv soweit ich weiss aber mit dem taster hat das nichts zu tun, 
denn wenn ich den wert so erhöhen lasse also mit zb a++ geht das auch 
nciht

Autor: Patrick (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wozu machst Du
TIMSK = TIMSK | (1 << OCIE1A);
 wenn Du den Interrupt gar nicht verwendest?

Versuche mal das:
int a=50;
int main()
{

DDRD=0xFF;
DDRC=0x00;

TCCR1A = (1<<COM1A1) | (1<<WGM11) | (1<<WGM10);
TCCR1B = (1<<WGM13) | (1<<WGM12) | (1<<CS10);


  for(;;){
 
if (PINC & ~(1<<PINC0)){
  OCR1A = a++;
}

}
return 0;
}

Autor: Patrick (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hats funktioniert?
Hast Du die Möglichkeit, den Taster auch wo anders anzuschliessen? Dann 
würde ich mit dem Taster einen externen Interrupt auslösen und damit den 
Wert erhöhen. Ansonsten wird solange Du die Taste drückst der Wert 
ziemlich schnell den Grenzwert überschreiten. Ein Beispiel:

#include <avr/interrupt.h>
#include <avr/io.h>

void init(void);

ISR (INT0_vect)
{
 OCR1A = a++;
}

void init(void)
{
 DDRD &= ~(1<<PIND2);
 PORTD &= ~(1<<PIND2);
 MCUCR = (1<<ISC01);       //fallende Flanke an INT0 löst Interrupt aus
 GICR |= (1<<INT0);        //Enable external Interrupt 0
 TCCR1A = (1<<COM1A1) | (1<<WGM11) | (1<<WGM10);
 TCCR1B = (1<<WGM13) | (1<<WGM12) | (1<<CS10);
 sei();                    //enable Interrupts
}

int main(void)
{
 init();
 while(1);
 return 0;
}

Das setzt voraus, dass Dein Taster beim drücken am Pin des Controllers 
ein Low erzeugt und über ein Pull-up Widerstand auf High angeschlossen 
ist.

Autor: Patrick (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe es bei mir getestet und es funktioniert. Ich hab an Pin 2 von 
Port D (INT0) einen low aktiven Taster und an Pin 5 (OC1A)eine LED 
angeschlossen. Durch betätigen des Tasters lässt sich die LED dimmen. 
Jedoch sind von 50 bis 255 über 200 Tastendrücke notwendig. Du könntest 
aber auch a um mehr als 1 erhöhen, um die Schrittweite zu erhöhen. Hier 
noch der Code:
#include <avr/interrupt.h>
#include <avr/io.h>

void init(void);
int a = 50;

ISR (INT0_vect)
{
 OCR1A = a++;
 if (a>=255) a = 50;
 
}

void init(void)
{
 DDRD &= ~(1<<PD2);
 DDRD |= (1<<PD5);
 PORTD &= ~(1<<PD2);
 MCUCR = (1<<ISC01);       //fallende Flanke an INT0 löst Interrupt aus
 GICR |= (1<<INT0);        //Enable external Interrupt 0
 OCR1A = 0;
 TCCR1A = (1<<COM1A1) |(1<<WGM10);
 TCCR1B = (1<<WGM12) | (1<<CS10);
 sei();                    //enable Interrupts
}

int main(void)
{
 init();
 while(1);
 return 0;
}

Autor: Patrick (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn Du jedoch willst, dass sich die Spannung sich kontinuierlich 
ändert, solange Du den Taster drückst, kannst Du es so machen:
#include <avr/interrupt.h>
#include <avr/io.h>

void init(void);
void delay (int t);
int a;

void delay (int t)
{
 int i;

 while (t--)
 {
  for (i = 0;i < 100;i++) asm volatile ("nop");
 }
}

void init(void)
{
 DDRD &= ~(1<<PD2);
 DDRD |= (1<<PD5);
 PORTD &= ~(1<<PD2);
 OCR1A = 0;
 TCCR1A = (1<<COM1A1) |(1<<WGM10);
 TCCR1B = (1<<WGM12) | (1<<CS10);
}

int main(void)
{
 init();
 while(1)
 {
  if (bit_is_clear (PIND, PD2)){
  OCR1A = a++;
 }
  delay(200);
  
  }
 return 0;
}

Mit delay kannst Du einstellen, wie lange ein Durchlauf dauern soll. Ich 
hoffe, ich konnte Dir helfen.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.