Hallo,
ich habe einen AT90PWM3B, der mit 3.3V auf 8MHz läuft. Ich möchte den
ICP1B-Eingang zum dekodieren von IR-Signalen nutzen. Leider wird der
ICP1-Interruptvektor nie aufgerufen, und auch das Interruptflag in TIFR1
nie gesetzt.
Erst initialisiere ich alles, konfiguriere den Timer (Der läuft auch,
wie ich am Overflow-Interrupt sehe), die Flanken kommen auch am
ICP1B-Eingang an, da dieser mit INT2 verbunden ist, und der INT2-Vektor
wird angesprungen.
Mein Testcode soweit:
1 | #if defined(__AVR_AT90PWM3__)
|
2 | # undef __AVR_AT90PWM3__
|
3 | #endif
|
4 |
|
5 | #define __AVR_AT90PWM3B__ 1
|
6 |
|
7 | #include <avr/io.h>
|
8 | #include <avr/interrupt.h>
|
9 | #include <avr/eeprom.h>
|
10 |
|
11 | #define USART_SIZE 256
|
12 | uint8_t usart_buf[USART_SIZE];
|
13 | volatile uint8_t usart_write = 0;
|
14 | volatile uint8_t usart_tx = 0;
|
15 | uint8_t usart_ovf = 0;
|
16 |
|
17 | static uint8_t
|
18 | usart_buffer_empty()
|
19 | {
|
20 | return (usart_write == usart_tx);
|
21 | }
|
22 |
|
23 | static uint8_t
|
24 | usart_buffer_full()
|
25 | {
|
26 | return (((usart_write + 1) & (USART_SIZE - 1)) == usart_tx);
|
27 | }
|
28 |
|
29 | static void
|
30 | usart_buffer_add(uint8_t data)
|
31 | {
|
32 | //while(usart_buffer_full());
|
33 | if(usart_buffer_full())
|
34 | {
|
35 | usart_buf[usart_write] = 'x';
|
36 | usart_ovf = 1;
|
37 | }
|
38 |
|
39 | usart_buf[usart_write] = data;
|
40 | usart_write = (usart_write + 1) & (USART_SIZE - 1);
|
41 | }
|
42 |
|
43 |
|
44 | void
|
45 | usart_transmit(uint8_t data)
|
46 | {
|
47 | usart_buffer_add(data);
|
48 | /* enable usart */
|
49 | if(!(UCSRB & (1 << TXEN)))
|
50 | {
|
51 | UCSRB = (1 << TXEN) | (1 << UDRIE);
|
52 | }
|
53 | }
|
54 |
|
55 | static void
|
56 | __puts(char* s)
|
57 | {
|
58 | while(*s)
|
59 | usart_transmit(*s++);
|
60 | }
|
61 |
|
62 | ISR(USART_UDRE_vect)
|
63 | {
|
64 | if(usart_buffer_empty())
|
65 | {
|
66 | /* disable usart */
|
67 | UCSRB &= ~((1 << TXEN) | (1 << UDRIE));
|
68 | }
|
69 | else
|
70 | {
|
71 | /* send next byte */
|
72 | UDR = usart_buf[usart_tx];
|
73 | usart_tx = (usart_tx + 1) & (USART_SIZE - 1);
|
74 | }
|
75 | }
|
76 |
|
77 | ISR(TIMER1_CAPT_vect)
|
78 | {
|
79 | __puts("icp\n\r");
|
80 | }
|
81 |
|
82 | ISR(TIMER1_OVF_vect)
|
83 | {
|
84 | __puts("ovf\n\r");
|
85 | }
|
86 |
|
87 | ISR(INT2_vect)
|
88 | {
|
89 | __puts("int2\n\r");
|
90 | }
|
91 |
|
92 | static void
|
93 | usart_init()
|
94 | {
|
95 | PRR &= ~(1 << PRUSART0);
|
96 | UBRR = 1;
|
97 | UCSRC = (1 << UCSZ1) | (1 << UCSZ0);
|
98 | }
|
99 |
|
100 | static void
|
101 | init()
|
102 | {
|
103 | MCUSR &= ~(1 << WDRF);
|
104 | WDTCSR &= ~(1 << WDE);
|
105 | }
|
106 |
|
107 | int
|
108 | main(void)
|
109 | {
|
110 | uint32_t data;
|
111 |
|
112 | init();
|
113 | usart_init();
|
114 |
|
115 | /* select ICP1B */
|
116 | GTCCR = (1 << ICPSEL1);
|
117 | /* power timer 1 */
|
118 | PRR &= ~(1 << PRTIM1);
|
119 |
|
120 | /* no compare output, nomal mode */
|
121 | TCCR1A = 0;
|
122 | /* ICNC, ICES don't matter, just test irq
|
123 | * normal mode, clk div 64 */
|
124 | TCCR1B = (1 << CS11) | (1 << CS10);
|
125 | /* no FOC */
|
126 | TCCR1C = 0;
|
127 | /* enable ICP irq */
|
128 | TIMSK1 = (1 << ICIE1) | (1 << TOIE1);
|
129 |
|
130 | /* external INT2 is connected to ICP1B */
|
131 | /* every level change on int 2 triggers an interrupt*/
|
132 | EICRA = (1 << ISC20);
|
133 | EIMSK = (1 << INT2);
|
134 |
|
135 | /* enable irq */
|
136 | sei();
|
137 |
|
138 | __puts("\n\rLogic analyzer:\n\r");
|
139 |
|
140 | /* wait for icp irq */
|
141 | while(1);
|
142 | }
|
Kann mir jemand sagen, warum der ICP-Interrupt nie ausgelöst wird?
Viele Grüße