bicycle_odometer

view odometer.c @ 0:0c1707508070

initial commit
author John Tsiombikas <nuclear@member.fsf.org>
date Tue, 23 Aug 2011 19:01:11 +0300
parents
children f74f4561e71c
line source
1 /* PORT USAGE
2 *
3 * D0-D3: data bus, connected to the D0-D3 pins of all the 4511 chips
4 * C0-C5,D4,D5: directly driving the 8 speed graph LEDs
5 * B0-B2: connected to the decoder controlling the 4511 latches as such:
6 * 000 - speed most significant
7 * 001 - speed least significant
8 * 010 - dist most significant
9 * 011 - dist middle
10 * 100 - dist least significant
11 * 101 - all latches are off (high)
12 * B3-B5: ISP. B4 also acts as generic pushbutton input
13 * B6,B7: XTAL
14 * D6,D7: comparator, hall effect sensor input and threshold trimpot.
15 */
17 /* 16mhz resonator */
18 #define F_CPU 2000000
20 #include <avr/io.h>
21 #include <avr/interrupt.h>
22 #include <util/delay.h>
24 void latch(int n);
25 void update_display(void);
27 int state;
28 int debug_mode = 1;
30 unsigned long nrot;
32 /* wheel perimeter in centimeters */
33 #define WHEEL_PERIMETER 100
35 int main(void)
36 {
37 int i;
39 DDRB = 0xf; /* only first four bits are outputs */
40 DDRC = 0xff; /* speed leds 6 bits */
41 DDRD = 0xff; /* 4bits data bus, 2 bits speed leds, 2 bits comparator (don't care) */
43 /* zero-out the displays and disable all pullups except for the reset pin */
44 PORTB = 0;
45 PORTC = 0x40; /* 6th bit set, C6 is reset */
46 PORTD = 0;
48 for(i=0; i<5; i++) {
49 latch(i);
50 }
52 /* read initial comparator state */
53 state = (ACSR >> ACO) & 1;
55 if(debug_mode) {
56 int i, j, leds, leds_val;
58 for(i=0; ; i++) {
59 for(j=0; j<5; j++) {
60 /* set bits */
61 PORTD = (PORTD & 0xf0) | (((i + j) % 10) & 0xf);
62 /* latch */
63 latch(j);
64 }
66 leds_val = 0;
67 leds = i % 8;
68 for(j=0; j<8; j++) {
69 if(j <= leds) {
70 leds_val |= (1 << j);
71 }
72 }
73 PORTC = leds_val;
74 PORTD = (PORTD & 0xf) | ((leds_val >> 2) & (3 << 4));
76 _delay_ms(1000);
77 }
78 }
80 /* disable digital input buffer for the AINn pins */
81 /*DIDR1 = 0;*/
83 ACSR = (1 << ACIE);
84 /* in debug mode we want an interrupt both on rising and falling edge
85 * to be able to blink leds when the wheel goes past. otherwise we only need
86 * a rising edge interrupt to increment the rotation counter.
87 */
88 if(!debug_mode) {
89 /* rising edge interrupt */
90 ACSR |= (3 << ACIS0);
91 }
93 sei();
95 for(;;);
96 return 0;
97 }
99 void latch(int n)
100 {
101 unsigned char upper = PORTB & 0xf0;
102 /* pull latch low */
103 PORTB = upper | n;
104 asm volatile("nop");
105 /* pull all latches high again */
106 PORTB = upper | 5;
107 }
109 ISR(ANALOG_COMP_vect)
110 {
111 if(debug_mode) {
112 int state = (ACSR >> ACO) & 1;
114 if(state) {
115 PORTB |= 1;
116 nrot++;
117 } else {
118 PORTB &= ~1;
119 }
120 } else {
121 nrot++;
122 }
124 update_display();
125 }
127 void update_display(void)
128 {
129 unsigned long dist_cm = (nrot * WHEEL_PERIMETER);
131 /* TODO */
132 }