Forum: Mikrocontroller und Digitale Elektronik AVR eigene Pins verbinden?


von Daniel (Gast)


Lesenswert?

Hallo,

Prozessor: Atmega8
Ich möchte testweise um zu lernen folgendes tun:
Einen Pin mit einer bestimmten Frequenz toggeln und diesen mit PB0 
(Input Capture) verbinden.

Dann möchte ich einen Code schreiben und die erfasste Zeit bzw. Frequenz 
am ICP (zwischen zwei gleichen Ereignissen) auf einem LCD ausgeben.

Funktioniert das? Kann ich einen eigenen Pin, welcher getoggelt wird am 
gleichen Prozessor am ICP einlesen?

Danke.

Daniel.

von Dirk M. (dmd)


Lesenswert?

Jawoll..., geht das.

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


Lesenswert?

Daniel schrieb:
> Kann ich einen eigenen Pin, welcher getoggelt wird am gleichen Prozessor
> am ICP einlesen?

Du musst nur an eins denken: die Erfassung der Flanke am Eingang
erfolgt beim AVR vor dem Umschalten des Ausgangs.  Folgendes
funktioniert daher nicht:
1
   PORTB |= (1 << 3); // aktivieren Sensor an PB3
2
   bool sensorData = (PINB & (1 << 2)) != 0; // Einlesen an PB2

Dazwischen muss mindestens ein NOP sein.

von Floh (Gast)


Lesenswert?

Daniel schrieb:
> Ich möchte testweise um zu lernen folgendes tun:
> Einen Pin mit einer bestimmten Frequenz toggeln und diesen mit PB0
> (Input Capture) verbinden.

Baue aber am besten einen Serienwiderstand ein (so 1kOhm), falls im 
Programm doch mal beide Pins auf Ausgang gestellt werden.

von Daniel (Gast)


Lesenswert?

Jörg Wunsch schrieb:
> Daniel schrieb:
>> Kann ich einen eigenen Pin, welcher getoggelt wird am gleichen Prozessor
>> am ICP einlesen?
>
> Du musst nur an eins denken: die Erfassung der Flanke am Eingang
> erfolgt beim AVR vor dem Umschalten des Ausgangs.  Folgendes
> funktioniert daher nicht:
>    PORTB |= (1 << 3); // aktivieren Sensor an PB3
>    bool sensorData = (PINB & (1 << 2)) != 0; // Einlesen an PB2
>
> Dazwischen muss mindestens ein NOP sein.

Ok, Serienwiderstand werde ich einfügen.

Aber das habe ich noch nicht ganz verstanden. Wäre jemand so nett und 
würde mir das nochmals erläutern?

von Dirk M. (dmd)


Lesenswert?

@Jörg
Aber er will doch den ICP-Eingang benutzen, ich denke mal in Verbindung 
mit dem Timer. Dann tritt doch dein genanntes Problem nicht auf. Oder 
hab' ich einen Denkfehler?

-Dirk-

von Daniel (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

ich habe nun einen einfachen Schaltungsaufbau:
2 LEDs
1 Pin als Taktgeber

Die eine LED (an PB4) leuchtet im Takt des Taktgebers
Die andere LED (an PC0) soll leuchten, wenn das ICP aufgerufen wird.

Das Ganze funktioniert leider nicht.
Das ICP spricht nicht an, d.h. die LED leuchtet nicht.
Wenn ich mit einem Draht eine Verbindung von GND zum ICP (PB0) 
herstelle, leuchtet die LED aber auf. Demnach scheint der Taktgeber den 
Pin nicht zu triggern.
Der Taktgeber Pin "wackelt" aber. Habe testweise dort auch einmal eine 
LED dran gehängt. Diese blinkt bzw. für unsere Auge leuchtet sie.
Messe ich die Spannung am Taktgeber Pin (unverbunden zum ICP) so liegt 
sie bei 2,40V. Messe ich die Spannung mit Verbindung zum ICP Pin, so 
liegt diese bei 4,79V.

Anbei ein Foto vom Steckbrettaufbau.

Und hier der Code:
1
// ----------------------------------------------------------------------------
2
// INCLUDES
3
// ----------------------------------------------------------------------------
4
5
#include <stdint.h>        // Standard Int-Datentypen
6
#include <avr/io.h>        // avr Header File für IO Ports
7
#include <avr/interrupt.h>    // Interrupt Vektoren
8
#include <inttypes.h>      // Makros für int Datentypen
9
10
11
// ----------------------------------------------------------------------------
12
// DEFINES
13
// ----------------------------------------------------------------------------
14
#ifndef F_CPU
15
#define F_CPU           8000000UL   // processor clock frequency 8Mhz
16
#endif
17
18
// Pin Defines  
19
#define LED1        PB4    // rote LED1
20
#define TAKTGEBER      PB7    // Taktgeber    
21
22
#define LED2        PC0    // rote LED2
23
24
// Port Defines
25
#define PORTLED1      PORTB
26
#define PORTLED2      PORTC
27
28
// Initialisierungsfunktionen
29
void init_ports(void);     
30
void init_timer1(void); 
31
32
33
34
//Timer1 16-bit Input Capture Service Routine
35
ISR (TIMER1_CAPT_vect){
36
  if ( !(TCCR1B & (1<<ICES1) )){    // Interrupt bei fallender Flanke
37
    // LED anschalten
38
    PORTLED2 &= ~(1 << LED2);
39
  }
40
  else{
41
    // LED ausschalten                
42
    PORTLED2 |= (1 << LED2);
43
  }
44
  TCCR1B ^= ( 1 << ICES1 );          
45
  TIFR = ( 1 << ICF1 );
46
}
47
48
49
//Timer1 16-bit Compare Match B Interrupt Service Routine
50
ISR (TIMER1_COMPB_vect){  
51
  // Aufruf 280x pro Sekunde --> 140Hz
52
  PORTB ^= (1 << TAKTGEBER);
53
  PORTLED1 ^= ( 1 << LED1 );  // Referenz-LED für Taktanzeige
54
  
55
  OCR1B = OCR1B+((F_CPU/8000000UL)*28571);
56
  
57
}
58
59
int main(void)
60
{
61
62
  init_ports();                              
63
  init_timer1();
64
  
65
66
  while (1){
67
  
68
  } // Ende main loop
69
} // Ende Hauptprogramm
70
71
72
73
void init_ports(void) {
74
75
  
76
  DDRB = 0x00;              
77
  DDRB |= (1 << DDB4) | (1 < DDB7) ;   // LED und Taktgeber als Ausgänge
78
  PORTB |= (1 << PB0) | (1 << PB1) | (1 << PB2) | (1 << PB3) | (1 << PB4) | (1 << PB6) | (1 << PB7);  // Pullup am ICP (PB0 ein)
79
80
81
  DDRC = 0x00;
82
  DDRC |= (1 << PC0);  // LED2 als Ausgang
83
  PORTC |= (1 << PC1) | (1 << PC2) | (1 << PC3) | (1 << PC4) | (1 << PC5);
84
85
  
86
  DDRD = 0x00;
87
  PORTD |= (1 << PD1) | (1 << PD2) | (1 << PD3) | (1 << PD4) | (1 << PD5) | (1 << PD6) | (1 << PD7) ;
88
  
89
  sei();  // setzt globales Interrupt enable
90
  
91
  return;
92
}   
93
94
void init_timer1(void) {
95
  OCR1B = ((F_CPU/8000000UL)*28571);      
96
  TIMSK |= (1 << TICIE1) | (1 << OCIE1B);  // Input Capture Interrupt enable, Compare Match B enable
97
  TCNT1 = 0;                  // Timer1 16-bit bei 0 starten
98
  TCCR1B |= (1 << CS10);   // kein Prescaler, Timer1 läuft maximal durch für höchste Auflösung
99
  return;
100
}

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.