ATtiny2313 - Biterkennung via ICP

Gast #2592436
Hallo,

ich möchte gern eine Zeitmessung mittels ICP auf einem ATtiny2313 
machen. Das Prinzip soll zur Biterkennung von einem Protokoll dienen. 
Das Protokoll ist (kommas nur logische Trennung)
 ___,__|-|,_|--|,__|-|_
 SPACE SYNC  0     1

 1 = 2/3T low + 1/3T high
 0 = 1/3T low + 2/3T high
 SPACE = min. 11T
 SYNC = 1

Kenndaten:
Quary 8Mhz
LFUSE 0xEF (kein Teiler, Oszilator)

Timer1 initialisierung, interrupt routine
1
#define CODINGTIMERCNT  TCNT1
2
#define CODINGTIMERCTRA TCCR1A
3
#define CODINGTIMERCTRB TCCR1B
4
#define CODINGTIMERCTRC TCCR1C
5
#define CODINGTIMERMSK  TIMSK
6
#define CODINGTIMER_OVF TIMER1_OVF_vect
7
#define CODINGTIMER_IPC TIMER1_CAPT_vect
8

9
/* prescaler timer 1 page 107 */
10
#define PRESC_T1    64
11
#define PRES_BITS   0x03
12

13
/* 2,5 ms - 12800Hz */
14
#define BASE_IMP    10000UL/24UL
15
#define BASE_TOL    10000UL/8UL   /* 0,8ms - tolerance */
16

17
/* precalculation */
18
#define IMP_MIN     (F_CPU/(PRESC_T1 * BASE_IMP)) // 300 ticks
19
#define SPACE_LOW   (32UL * IMP_MIN)  // 9600 ticks
20
#if (SPACE_LOW > 65535UL)
21
#error invalid prescaler, out of border
22
#endif
23
#define TOLERANCE   (F_CPU/(PRESC_T1 * BASE_TOL))  // 100ticks
24
#define BIT1_LOW    (2UL * IMP_MIN) // 600 ticks
25
#define BIT0_LOW    (1UL * IMP_MIN) // 300 ticks
26

27
void HardwareInit(void)
28
{
29
  CODINGTIMERCNT = 0x0000;      //Load TC1 count value
30
  sbi(CODINGTIMERMSK,ICIE1);    // Timer1 Input Capture & Interrupt Enable 
31
  sbi(CODINGTIMERMSK,TOIE1);     // Timer1 Overflow  
32
  CODINGTIMERCTRA = 0x00;        //Normal mode              
33
  sbi(CODINGTIMERCTRB,ICES1);    //Look for Falling Edge on ICP1
34
  CODINGTIMERCTRB |= (PRES_BITS<<CS10);  //prescale  =  clock  source / 64
35
}
36

37
ISR(CODINGTIMER_OVF)
38
{
39
  /* disable and set to maximum */
40
  cbi(CODINGTIMERMSK,TOIE1);
41
  CODINGTIMERCTRB &= ~(PRES_BITS<<CS10);  // off
42
  CODINGTIMERCNT = 0xFFFF; 
43
}
44

45
ISR(CODINGTIMER_IPC)
46
{
47
  CODINGTIMERCNT = 0UL;
48
  sbi(CODINGTIMERMSK,TOIE1);
49
  CODINGTIMERCTRB |= (PRES_BITS<<CS10);  // on
50
  uwTime = ICR1;
51
  tgl(CODINGTIMERCTRB,ICES1);  /* change edge detection */
52
}
53

54
void SuchDasBit(uwTime)
55
{
56
  if (ubEdge) /* rising edge detected */
57
  {
58
    sbi(PORTB,PB1); //test
59
    if (uwTime > SPACE_LOW) {
60
      ... einmal hier
61
    }
62
    else if ((uwTime > BIT1_LOW_M) 
63
     && (uwTime < BIT1_LOW_P))
64
   {
65
     ... nie hier, warum ?
66
   } else if ((uwTime > BIT0_LOW_M)
67
              && (uwTime < BIT0_LOW_P)) 
68
   {
69
     ... nie hier, warum ?
70
   } else {
71
    ... dann immer hier 
72
   }
73
  } else { /* falling edge detected */
74
    cbi(PORTB,PB1); //test
75
    if ((uwTime > BIT1_HIGH_M) 
76
     && (uwTime < BIT1_HIGH_P))
77
    {
78
      .... nie hier warum?
79
    } 
80
    else if ((uwTime > BIT0_HIGH_M)
81
       && (uwTime < BIT0_HIGH_P))
82
    {
83
      ...  nie hier, warum ?
84
    } else {
85
      ... und immmer hier
86
    }
87
  }
88
}

Auf dem Oszi sehe ich das Testsignal (Kopie des Signal auf ICP1), die 
Timings auf dem Ozsi stimmen mit meinen Ticks ueberein (umgerechnet in 
ms).

Hab ich was vergessen ist der Interrupt nur einmal aktiv? Weiter Fragen 
und Kommentare sind codiert ;) (siehe Code)?

Vielen Dank, für einen hilfreichen Hinweis.
Daniel
Gast #2592614
Hallo,

nach 2 langen Nächten, dem Entschluss im Forum Hilfe zu suchen, und 
weitern 2 h Däumchen drehen, möchte ich mich entschludigen 
unvollständigen Code gepostet zu haben.
1
#define TOLERANCE   (F_CPU/(PRESC_T1 * BASE_TOL)) //100
2
#define BIT1_LOW    (2UL * IMP_MIN) // 600
3
#define BIT1_LOW_M  (BIT1_LOW - TOLERANCE) //500
4
#define BIT1_LOW_P  (BIT1_LOW + TOLERANCE) //700
5
#define BIT0_LOW    (1UL * IMP_MIN) // 300
6
#define BIT0_LOW_M  (BIT0_LOW - TOLERANCE) //200
7
#define BIT0_LOW_P  (BIT0_LOW + TOLERANCE) //400 <- HIER war der Fehler - statt +
8
#define BIT1_HIGH_M BIT0_LOW_M
9
#define BIT1_HIGH_P BIT0_LOW_P
10
#define BIT0_HIGH_M BIT1_LOW_M
11
#define BIT0_HIGH_P BIT1_LOW_P

daniel

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 14 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.