Rose-Hulman Robotics Team

root/trunk/electronics/mcc/motorcontroller.c

Revision 220, 4.2 KB (checked in by spenceal, 2 years ago)

a few files, auchter/klein, you should add teh rest

Line 
1#include <avr/io.h>
2#include <util/delay.h>
3#include <stdint.h>
4#include <avr/iom168.h>
5#include <avr/eeprom.h>
6#include <avr/interrupt.h>
7
8// macros for setting bits
9#define sbi(var, mask)   ((var) |= (uint8_t)(1 << mask))
10#define cbi(var, mask)   ((var) &= (uint8_t)~(1 << mask))
11#define ABS(x)           ((x>0)?(x):(-x))
12#define CAP(speed,max)   ((speed<max)?(speed):(max))
13
14
15// constant pin locations
16const uint8_t L_DIS = 4;
17const uint8_t R_DIS = 5;
18
19// setup EEPROM
20uint8_t EEMEM EEmax_speed=0xAF;
21uint8_t EEMEM EEmax_change=0x01;
22
23// global variables for ramping speed
24// default to stop, no speed
25volatile uint8_t count;
26volatile uint8_t ldest_speed    = 0x00;
27volatile uint8_t ldest_dir              = 0x01;
28volatile uint8_t rdest_speed    = 0x00;
29volatile uint8_t rdest_dir              = 0x01;
30volatile uint8_t max_speed;
31volatile uint8_t max_change;
32
33void serial_init(long baud)
34{
35        UBRR0H = ((F_CPU / 16 + baud / 2) / baud - 1) >> 8;
36        UBRR0L = ((F_CPU / 16 + baud / 2) / baud - 1);
37
38        UCSR0B = (1<<RXEN0) | (1<<TXEN0);
39        UCSR0C = (1<<USBS0) | (3 << UCSZ00);
40}
41
42uint8_t usart_get( void )
43{
44    while ( (UCSR0A & _BV(RXC0)) == 0 )
45        ;
46    return UDR0;
47}
48
49
50void usart_put( uint8_t b )
51{
52    while ( (UCSR0A & _BV(UDRE0)) == 0 )
53        ;
54    UDR0 = b;
55}
56
57// interrupt every 16ms
58void timer_init()
59{
60        TCCR0A = 0b00000000;
61        TCCR0B = 0b00000101;
62        OCR0A = 250;
63        TIMSK0 = 0b00000010;
64}
65
66
67void pwm_init()
68{
69        DDRB |= _BV(PB1);
70        DDRB |= _BV(PB2);
71
72        /*
73         * TCCR1A:, datasheet pg. 131
74         * [COM1A1][COM1A0][COM1B1][COM1B0][-][-][WGM11][WGM10]
75         * Channel A:  Phase & Freq. correct
76         *      OC1A set on match counting up
77         *      OC1A cleared on match counting down
78         *      OC1B cleared on match counting up
79         *      OC1B set on match counting down
80         *
81         */
82//      TCCR1A = 0b10110000;
83        TCCR1A = 0b11110000;
84        /*
85         * TCCR1B:, datasheet pg. 133
86         * [ICNC1][ICES1][-][WGM13][WGM12][CS12][CS11][CS10]
87         * Set TOP to ICR1
88         * CS1 = 0b001, ICR1 = 0x03FF: 7820Hz (10-bit resolution)
89         * CS1 = 0b001, ICR1 = 0x0200: 15655Hz (9-bit resolution)
90         */
91        TCCR1B = 0b00010001;
92
93        /* ICR1 defines TOP */
94        ICR1 = 0x0200;
95
96        OCR1A = ICR1>>1;
97        OCR1B = ICR1>>1;
98}
99
100void io_init()
101{
102        DDRB = 0b11111111;
103        DDRC = 0b11111111;
104        DDRD = 0b11111110;
105}
106
107void eeprom_init()
108{
109        max_speed = eeprom_read_byte(&EEmax_speed);
110        max_change = eeprom_read_byte(&EEmax_change);
111}
112
113void set_motors(uint8_t speed, uint8_t dir, uint8_t motor)
114{
115        enum {forward=0,stop,backward};
116        enum {lmotor=0xF0,rmotor=0x0F};
117        switch(motor)   {
118        case lmotor:
119                ldest_speed = CAP(speed,max_speed);
120                ldest_dir = dir;
121                if(dir == stop) {
122                        ldest_speed = ICR1>>1;
123                        OCR1A = ICR1>>1;
124                        sbi(PORTB,L_DIS);
125                }
126                else
127                        cbi(PORTB,L_DIS);
128                break;
129
130        case rmotor:
131                rdest_speed = CAP(speed,max_speed);
132                rdest_dir = dir;
133                if(dir == stop) {
134                        rdest_speed = ICR1>>1;
135                        OCR1B = ICR1>>1;
136                        sbi(PORTB,R_DIS);
137                }
138                else
139                        cbi(PORTB,R_DIS);
140                break;
141        default:
142                break;
143
144        }
145
146
147}
148
149
150int main(void)
151{
152        enum {motor_state=0,direction_state,speed_state,checksum_state};
153        enum {forward=0,stop,backward};
154        enum {lmotor=0xF0,rmotor=0x0F};
155
156        uint8_t state = motor_state;
157        uint8_t in;
158        uint8_t temp;
159        uint8_t motor=0;
160        uint8_t speed=0;
161        uint8_t dir=0;
162
163        eeprom_init();
164        serial_init(9600);
165        io_init();
166        pwm_init();
167        timer_init();           // interrupt every 16 ms
168        sei();                          // enable interrupts
169
170        while (1) {
171                in = usart_get();
172                switch (state) {
173                case motor_state :
174                        motor = in;
175                        state = speed_state;
176                        break;
177
178                case speed_state :
179                        speed = in;
180                        state = direction_state;
181                        break;
182
183                case direction_state :
184                        dir = in;
185                        state = checksum_state;
186                        break;
187
188                case checksum_state :
189                        temp = (motor ^ (3*speed) ^ (5*dir)) ^ in; // auchter's crazy checksum
190                        usart_put(temp);
191                        if (!temp)
192                                set_motors(speed,dir,motor);
193                        state = motor_state;
194                        break;
195
196                default:
197                        state = motor_state;
198                        break;
199                }
200        }
201}
202
203// periodic interrupt, currently every 16ms
204// ramps speed to desired speed
205ISR(TIMER0_COMPA_vect)
206{
207        uint8_t templ;
208        uint8_t tempr;
209        templ = (ICR1>>1) + ldest_speed * (ldest_dir - 1);
210        tempr = (ICR1>>1) + rdest_speed * (rdest_dir - 1);
211        OCR1A += (templ > OCR1A ? max_change : -max_change);
212        OCR1B += (tempr > OCR1B ? max_change : -max_change);
213        OCR1A = ABS(OCR1A - templ) < max_change ? templ : OCR1A;
214        OCR1B = ABS(OCR1B - tempr) < max_change ? tempr : OCR1B;
215}
Note: See TracBrowser for help on using the browser.