car004f/main.c

changeset 147
f66c5b3b3ed2
child 148
08cb88614d69
equal deleted inserted replaced
146:a1eb2dc83819 147:f66c5b3b3ed2
1 #include <avr/interrupt.h>
2 #include <avr/io.h>
3 #include <avr/wdt.h>
4 #include <avr/eeprom.h>
5 #include <stdlib.h>
6 #include <stdint.h>
7 #include <avr/pgmspace.h>
8
9 #include "main.h"
10 #include "util/delay.h"
11
12
13 ISR ( USART_RXC_vect ) {
14 }
15
16 #define PULSE_PORT PORTD
17 #define PULSE_BIT PD2
18
19 #define RESPONSE_PORT PORTC
20 #define RESPONSE_PIN PC1
21
22 volatile uint16_t data = 0;
23 volatile uint8_t data_len = 0;
24 volatile uint8_t bitbuf_len = 0;
25 volatile uint16_t bitbuf = 0;
26 volatile uint8_t car_speed[8];
27 volatile uint8_t car_switch[8];
28 volatile uint8_t my_id; // Die ID des Autos!
29
30 uint8_t my_switch;
31 uint8_t my_speed;
32 uint8_t light_mode;
33
34 ISR ( INT0_vect ) {
35 GICR &= ~_BV(INT0) ; // Disable INT0
36 // Startsignal erkannt, ab hier den Timer2 starten,
37 // der liest dann alle 50µs den Zustand ein und schreibt das
38 // empfangene Bit in den Puffer
39 bitbuf = 0; // init
40 bitbuf_len = 0b10000000; // init 1 pulse received
41 TCNT2 = 0;
42 TIMSK |= _BV(OCIE2); //enable timer2 interrupt
43 }
44
45 ISR ( TIMER2_COMP_vect ) {
46 uint8_t clock;
47 uint8_t state;
48 uint8_t state2;
49 if ((bitbuf_len & 0b10000000) == 0) clock = 0; else clock = 0xff;
50 if ((bitbuf_len & 0b01000000) == 0) state = 0; else state = 0xff;
51 if ((PIN(PULSE_PORT) & _BV(PULSE_BIT)) == 0) state2 = 0xff; else state2 = 0;
52
53 if (clock) {
54 bitbuf_len &= ~_BV(7); // switch clock to low
55 // second pulse of bit
56 if ((state==state2) & state2) {
57 // two cycles high: packet end received
58 data_len = (bitbuf_len & 0b00111111);
59 TIMSK &= ~_BV(OCIE2); //disable timer2 interrupt
60 GICR |= _BV(INT0) ; // Enable INT0
61
62 //data = bitbuf; // output data
63 // write data of controllers to array
64 if (data_len == 10) { // controller data packet
65 clock = (bitbuf >> 6) & 0b00000111;
66 car_speed[clock] = (bitbuf >> 1) & 0x0F;
67 car_switch[clock] = (bitbuf >> 5) & 1;
68 // current response for this car?
69 /*
70 if (response != 0) {
71 if ( ((response & 0b00001110) >> 1) == clock) {
72 // add our ID to response:
73 send_response(response | self_id << 6);
74 response = 0;
75 }
76 }
77 */
78 }
79
80
81 } else {
82 bitbuf_len++; // increment bit counter
83 bitbuf = bitbuf << 1; // shift bits
84 if (state2 == 0) bitbuf |= 1; // receive logic one
85 }
86 } else {
87 bitbuf_len |= _BV(7); // switch clock to high
88 // first pulse of bit
89 if (state2) {
90 bitbuf_len |= _BV(6); // store new state
91 } else {
92 bitbuf_len &= ~_BV(6); // store new state
93 }
94 }
95 }
96
97 ISR (TIMER1_OVF_vect) {
98 }
99
100 ISR (INT1_vect) {
101 }
102
103 #define LIGHT_PORT PORTC
104 #define LIGHT_FRONT 2
105 #define LIGHT_BRAKE 4
106
107 #define IR_PORT PORTB
108 #define IR_LED 3
109
110
111 #define LIGHT_MODES 1 // anzahl der lichtmodi (ohne den modus "aus")
112
113
114
115 int main(void)
116 {
117 uint8_t car0_state, car1_state;
118
119 // setup data bit timer2
120 TCCR2 = (1<<CS21) | (1<<WGM21); //divide by 8, set compare match
121 OCR2 = TIMER2_50US;
122
123
124 // enable both external interrupts
125 // int 0 = data RX
126 MCUCR = _BV(ISC00) | _BV(ISC01) | _BV(ISC10) | _BV(ISC11); // INT0/1 rising edge
127 GICR = _BV(INT0) | _BV(INT1) ; // Enable INT0 + INT1
128
129 // oscillator calibration
130 // atmega8@1mhz = 0xac
131 // @4mhz = ca 0xa0
132 //OSCCAL = 0xa0;
133 //OSCCAL = 0x9A;
134 //OSCCAL = 0xa0; // internal oscillator @ 4 mhz.... doesnt work accurate!
135 sei();
136
137 DDR(LIGHT_PORT) |= (_BV(LIGHT_FRONT) | _BV(LIGHT_BRAKE));
138
139 //defaults (from eeprom!)
140 my_id = 1;
141 light_mode = 0;
142
143 while (1) {
144 // main loop
145
146 // Light cycle if switch pressed without speed
147 if (my_speed == 0) {
148 if (my_switch != car_switch[my_id]) {
149 my_switch = car_switch[my_id];
150 if (my_switch != 0) {
151 // cycle light
152 if (light_mode == LIGHT_MODES) light_mode = 0; else light_mode++;
153 }
154 }
155 }
156
157 switch (light_mode) {
158 case 0:
159 LIGHT_PORT &= ~_BV(LIGHT_FRONT); // switch lights off
160 break;
161 case 1:
162 LIGHT_PORT |= _BV(LIGHT_FRONT); // switch lights on
163 break;
164 }
165
166 _delay_ms(100);
167 LIGHT_PORT |= _BV(LIGHT_BRAKE); // brake light on
168 _delay_ms(100);
169 LIGHT_PORT &= ~_BV(LIGHT_BRAKE); // brake light off
170
171
172
173
174 } // main loop end
175 };
176

mercurial