Forum: Mikrocontroller und Digitale Elektronik AVR Tiny 416 Input Capture


von Jürgen (Gast)


Lesenswert?

Hallo,

ich möchte mit einem einem Tiny416 eine Capture Messung (Timer B) 
vornehmen. Leider bekomme ich das Event System nicht richtig 
konfiguriert (das Problem sitzt wahrscheinlich vor dem Rechner). Ich 
habe in ATMEL START PA4 (Mein Frequenz Eingang) als Asynchron Event 0 
konfiguriert und in ASYNCUSER0 (Asynchronus User CH 0 - TCB0) diesen 
Asynchron Event 0 eingestellt.

Wenn ich an PA4 ein TTL Signal anlege erhalte ich jedoch im Debugger 
keinen Interrupt. Die entsprechende Interrupt Routine sind in 
driver_isr.c von ATMEL START angelegt.

Was mache ich falsch?

Ciao Jürgen

von Veit D. (devil-elec)


Lesenswert?

Hallo,

du hast das mit Atmel Start konfiguriert? Wenn ja, dass geht zwar, nur 
werden dabei soviele inklude Files erzeugt, dass man schwer durchblickt 
was wo wie definiert wurde.

Beitrag "Re: AVR128DB48 - TCB 32Bit Counter"
Hier wurden zwar zwei kaskadiert, dass sollte aber ansonsten gleich 
sein. Der Timer selbst liest sich gleich wie zum Atmega. Nimm davon 
immer nur die Konfig vom ersten TCB, dann sollte das laufen. Ansonsten 
müßtest du deinen Code zeigen. Atmel Start erzeugter Code nützt jedoch 
nichts, zu viele Dateien wie gesagt. Bau es selbst manuell auf. Die 
Register/Bitnamen etc. kannste aus dem Controller Headerfile entnehmen.

von Jürgen (Gast)


Lesenswert?

Hallo,

ich habe mir das mal angeschaut. Stimmt eigentlich mit dem überein was 
mir ATMEL START erzeugt hat. Hier mal den Code:
1
int8_t TIMER_1_init()
2
{
3
4
  // TCB0.CCMP = 0x0; /* Compare or Capture: 0x0 */
5
6
  // TCB0.CNT = 0x0; /* Count: 0x0 */
7
8
  TCB0.CTRLB = 1 << TCB_ASYNC_bp       /* Asynchronous Enable: enabled */
9
               | 0 << TCB_CCMPEN_bp    /* Pin Output Enable: disabled */
10
               | 0 << TCB_CCMPINIT_bp  /* Pin Initial State: disabled */
11
               | TCB_CNTMODE_FRQPW_gc; /* Input Capture Frequency and Pulse-Width measurement */
12
13
  TCB0.DBGCTRL = 1 << TCB_DBGRUN_bp; /* Debug Run: enabled */
14
15
  TCB0.EVCTRL = 1 << TCB_CAPTEI_bp    /* Event Input Enable: enabled */
16
                | 1 << TCB_EDGE_bp    /* Event Edge: enabled */
17
                | 0 << TCB_FILTER_bp; /* Input Capture Noise Cancellation Filter: disabled */
18
19
  TCB0.INTCTRL = 1 << TCB_CAPT_bp /* Capture or Timeout: enabled */;
20
21
  TCB0.CTRLA = TCB_CLKSEL_CLKDIV2_gc  /* CLK_PER/2 (From Prescaler) */
22
               | 1 << TCB_ENABLE_bp   /* Enable: enabled */
23
               | 0 << TCB_RUNSTDBY_bp /* Run Standby: disabled */
24
               | 0 << TCB_SYNCUPD_bp; /* Synchronize Update: disabled */
25
26
  return 0;
27
}
28
29
int8_t EVENT_SYSTEM_0_init()
30
{
31
32
  EVSYS.ASYNCCH0 = EVSYS_ASYNCCH0_PORTA_PIN5_gc; /* Asynchronous Event from Pin PA5 */
33
34
  // EVSYS.ASYNCCH1 = EVSYS_ASYNCCH1_OFF_gc; /* Off */
35
36
  // EVSYS.ASYNCCH2 = EVSYS_ASYNCCH2_OFF_gc; /* Off */
37
38
  // EVSYS.ASYNCCH3 = EVSYS_ASYNCCH3_OFF_gc; /* Off */
39
40
  EVSYS.ASYNCUSER0 = EVSYS_ASYNCUSER0_ASYNCCH0_gc; /* Asynchronous Event Channel 0 */
41
42
  // EVSYS.ASYNCUSER1 = EVSYS_ASYNCUSER1_OFF_gc; /* Off */
43
44
  // EVSYS.ASYNCUSER2 = EVSYS_ASYNCUSER2_OFF_gc; /* Off */
45
46
  // EVSYS.ASYNCUSER3 = EVSYS_ASYNCUSER3_OFF_gc; /* Off */
47
48
  // EVSYS.ASYNCUSER4 = EVSYS_ASYNCUSER4_OFF_gc; /* Off */
49
50
  // EVSYS.ASYNCUSER5 = EVSYS_ASYNCUSER5_OFF_gc; /* Off */
51
52
  // EVSYS.ASYNCUSER6 = EVSYS_ASYNCUSER6_OFF_gc; /* Off */
53
54
  // EVSYS.ASYNCUSER7 = EVSYS_ASYNCUSER7_OFF_gc; /* Off */
55
56
  // EVSYS.ASYNCUSER8 = EVSYS_ASYNCUSER8_OFF_gc; /* Off */
57
58
  // EVSYS.ASYNCUSER9 = EVSYS_ASYNCUSER9_OFF_gc; /* Off */
59
60
  // EVSYS.ASYNCUSER10 = EVSYS_ASYNCUSER10_OFF_gc; /* Off */
61
62
  // EVSYS.SYNCCH0 = EVSYS_SYNCCH0_OFF_gc; /* Off */
63
64
  // EVSYS.SYNCCH1 = EVSYS_SYNCCH1_OFF_gc; /* Off */
65
66
  // EVSYS.SYNCUSER0 = EVSYS_SYNCUSER0_OFF_gc; /* Off */
67
68
  // EVSYS.SYNCUSER1 = EVSYS_SYNCUSER1_OFF_gc; /* Off */
69
70
  return 0;
71
}
72
73
/*
74
* Interrupt der nie angesprungen wird
75
*/
76
77
ISR(TCB0_INT_vect)
78
{
79
    TimerFlags = TCB0.INTFLAGS;
80
  TimerCNT   = TCB0.CNT;
81
  TimerCCMP  = TCB0.CCMP;
82
  
83
  TCB0.INTFLAGS = TCB_CAPT_bm;
84
}

Mit dem Scope habe geprüft ob ein Signal an PA5 anliegt. Alles ok. Mit 
dem Debugger habe ich einen Break auf die Interrupt Routine gesetzt, 
kommt nie an.

Bin mit meinem Latein am Ende.

Jürgen

von Veit D. (devil-elec)


Lesenswert?

Hallo,

hast du die Interrupts mit sei() generell aktivert?
Funktioniert es ohne asyncron / mit ayncronen Event?
Machst du das alles mit Atmel Start?
Kann erst wieder heute spät Abend drüberschauen ...

von Jürgen (Gast)


Lesenswert?

Hallo Veit,

Interrupts sind freigegeben. Der RTC Periodic Interrupt (PI) kommt.

Hab keinen Plan an was es "hängen" könnte.

Ja, ich mache alles mit ATMEL Studio bzw. ATMEL START.

Ciao und Danke schon mal für deine Hilfe.

von Volker B. (Firma: L-E-A) (vobs)


Lesenswert?

Jürgen schrieb:

> Hab keinen Plan an was es "hängen" könnte.

M.W. kann ein Portpin nur dann einen Event erzeugen, wenn das zugehörige 
PINCTRL-Register entsprechend initialisiert ist, und zwar:
Bits 2:0 – ISC[2:0]

0x2 RISING Sense rising edge
0x3 FALLING Sense falling edge

Der Reset-Wert 0x0 bedeutet INTDISABLE Interrupt disabled but input 
buffer enabled.

Grüßle
Volker

von Robert (Gast)


Lesenswert?

Jürgen schrieb:
> | TCB_CNTMODE_FRQPW_gc; /* Input Capture Frequency and
> Pulse-Width measurement */
[...]
>
>   TCB0.CTRLA = TCB_CLKSEL_CLKDIV2_gc  /* CLK_PER/2 (From Prescaler) */


Schau mal die Errata des Datenblatts:
40.2.1.4 TCB1 [...]
TCB input capture frequency and pulse-width measurement mode notworking 
with prescaled clockThe TCB input capture frequency and pulse-width 
measurement mode maylock to freeze state if CLKSEL in TCB.CTRLA is set 
to other value than 0x0.Fix/Workaround:Only use CLKSEL equal to 0x0 when 
using Input capture frequency andpulse-width measurement mode.

Hat mich auch schon mal einen Arbeitstag gekostet....

von Robert (Gast)


Lesenswert?

> M.W. kann ein Portpin nur dann einen Event erzeugen, wenn das zugehörige
> PINCTRL-Register entsprechend initialisiert ist, und zwar:
> Bits 2:0 – ISC[2:0]
>
> 0x2 RISING Sense rising edge
> 0x3 FALLING Sense falling edge
>


Stimmt so nicht. Events sind völlig unabhängig von Interrupts.

von Veit D. (devil-elec)


Lesenswert?

Hallo,

also. Was ich bis jetzt herausgelesen habe ist, dass der TCB im 
asyncronen Modus funktioniert nur im Single Shot Mode erlaubt ist. Laut 
Beschreibug im Manual. Ich denke auch das benötigt der TO nicht. Wenn 
das wird der Eingang der gesamten Übung, also Pin PA4, im Event System 
asyncron konfiguriert. Meine Meinung. Ich würde erstmal versuchen alles 
normal syncron zum laufen zubekommen, dann hat man eine Basis um danach 
asyncron auszuprobieren.

TCB sollte so erstmal richtig sein.
1
void initTCB0 (void)
2
{
3
  TCB0.CTRLA = TCB_CLKSEL_CLKDIV2_gc;       // CLK_PER divider
4
  TCB0.CTRLB = TCB_CNTMODE_FRQPW_gc;        // Capture Mode
5
  TCB0.EVCTRL = TCB_CAPTEI_bm;              // Enable Event Input and Event Edge
6
  TCB0.INTCTRL = TCB_CAPT_bm;               // Enable Capture interrupt
7
  TCB0.CTRLA |= TCB_ENABLE_bm;              // Enable TCB0
8
}
9
10
ISR(TCB0_INT_vect)  // Bsp.
11
{
12
  counter.periode = TCB0.CNT;             // read out CNT first, then CCMP
13
  counter.pulsweite = TCB0.CCMP;
14
  TCB0.INTFLAGS = TCB_CAPT_bm;            // Clear the interrupt flag
15
}

Das Eventsystem ist umfangreicher im Vergleich zu meinem ATmega.
Da müßte ich mich erst noch mehr einlesen.
Was stimmen müßte als Anfang wäre
1
EVSYS.SYNCCH0 = EVSYS_SYNCCH0_PORTA_PIN4_gc;      // Synchronous Event from Pin PA4
Jetzt fehlt noch diesen Sync-Channel-0 dem TCB Capture Eventeingang zu 
zuweisen.

Bei meinem ATmega reicht das hier:
1
EVSYS.CHANNEL0 = EVSYS_CHANNEL0_PORTA_PIN4_gc;    // set Pin PA4 as input event
2
EVSYS.USERTCB0CAPT = EVSYS_USER_CHANNEL0_gc;      // Connect user to event channel 0

Beim ATtiny416 ist das anders, sollte jedoch in gewisser Weise ähnlich 
sein. Vielleicht 1-2 Zeilen mehr? Was bei deinem Code fehlt ist genau 
diese Zuordnung. Du hast mittels TCB0.INTCTRL Register den Timer für das 
Eventsystem konfiguriert. Aber das Eventsystem gibt an den 
Timer-Eventeingang noch kein Signal weiter. Hier fehlt noch wie gesagt 
die Zuordnung das der Sync-Channel-0 (woran der Pin PA4 zugewiesen 
wurde) an den TCB0 weitergereicht werden soll. Die Optionsvielfalt 
erschlägt mich jetzt auch ...

von Veit D. (devil-elec)


Lesenswert?

Hallo,

scheinbar sind alle Bezeichnungen im Headerfile anders wie ich vom 
ATmega gewohnt bin. Laut meiner Logik sollte das funktionieren. Mangels 
ATtiny kann ich selbst nicht testen. Tut mir leid.
1
void initEventSystem (void)
2
{    
3
  EVSYS.SYNCCH0 = EVSYS_SYNCCH0_PORTA_PIN4_gc;      // Synchronous Event from Pin PA4
4
  EVSYS.ASYNCUSER0 = EVSYS_ASYNCUSER0_SYNCCH0_gc;   // Connect user to event channel 0
5
}

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.