Forum: Mikrocontroller und Digitale Elektronik ATtiny2313 - Biterkennung via ICP


von daniel (Gast)


Lesenswert?

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

von daniel (Gast)


Lesenswert?

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

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.