Revision 1226c007
Added motor and servo code. Both timers are set to phase-correct-PWM mode, which is yet to be tested. Also, I used 32 prescaler.
paintboard/code/motor.c | ||
---|---|---|
1 |
#include <avr/io.h> |
|
2 |
#include "motor.h" |
|
3 |
#include <stdlib.h> |
|
4 |
|
|
5 |
/* |
|
6 |
|
|
7 |
motor controller. Timer2 is set to phase-correct PWM mode, with 32 prescaler. |
|
8 |
|
|
9 |
AIN1: PC0 |
|
10 |
AIN2: PC1 |
|
11 |
PWMA: PB3 (Timer2) (OCRA) |
|
12 |
|
|
13 |
BIN1: PC2 |
|
14 |
BIN2: PC3 |
|
15 |
PWMB: PD3 (Timer2) (OCRB) |
|
16 |
|
|
17 |
*/ |
|
18 |
|
|
19 |
int8_t motor1_speed; |
|
20 |
int8_t motor2_speed; |
|
21 |
|
|
22 |
void motor_init(void) |
|
23 |
{ |
|
24 |
|
|
25 |
// WGM2 0b001 (phase-correct PWM, 8-bit) |
|
26 |
// COM2A 0b10 (clear OCR2A on compare match, set on BOTTOM) |
|
27 |
// COM2B 0b10 (clear OCR2B on compare match, set on BOTTOM) |
|
28 |
// CS2 0b011 (32 prescaler) |
|
29 |
TCCR2A = _BV(WGM20) | _BV(COM2A1) |_BV(COM2B1); |
|
30 |
TCCR2B = _BV(CS21) | _BV(CS20); |
|
31 |
OCR2A = 0; |
|
32 |
OCR2B = 0; |
|
33 |
|
|
34 |
// set output pins |
|
35 |
DDRC |= _BV(PC0) | _BV(PC1) | _BV(PC2) | _BV(PC3); |
|
36 |
DDRB |= _BV(PB3); |
|
37 |
DDRD |= _BV(PD3); |
|
38 |
|
|
39 |
set_motor1(0); |
|
40 |
set_motor2(0); |
|
41 |
} |
|
42 |
|
|
43 |
void set_motor1(int8_t speed) |
|
44 |
/* Speed must be between -127 and 127 */ |
|
45 |
{ |
|
46 |
motor1_speed = speed; |
|
47 |
OCR2A = (uint8_t)abs(speed)*2; |
|
48 |
if(speed>0) //go forwards |
|
49 |
{ |
|
50 |
PORTC |= (1<<PC0); |
|
51 |
PORTC = PORTC & ~(1<<PC1); |
|
52 |
} |
|
53 |
if(speed<0) //go backwards |
|
54 |
{ |
|
55 |
PORTC |= (1<<PC1); |
|
56 |
PORTC = PORTC & ~(1<<PC0); |
|
57 |
} |
|
58 |
if(speed==0) // turn motor off |
|
59 |
{ |
|
60 |
PORTC = PORTC & ~(1<<PC1); |
|
61 |
PORTC = PORTC & ~(1<<PC0); |
|
62 |
} |
|
63 |
} |
|
64 |
|
|
65 |
void set_motor2(int8_t speed) |
|
66 |
/* Speed must be between -127 and 127 */ |
|
67 |
{ |
|
68 |
motor2_speed = speed; |
|
69 |
OCR2B = (uint8_t)abs(speed)*2; |
|
70 |
if(speed>0) //go forwards |
|
71 |
{ |
|
72 |
PORTC |= (1<<PC2); |
|
73 |
PORTC = PORTC & ~(1<<PC3); |
|
74 |
} |
|
75 |
if(speed<0) //go backwards |
|
76 |
{ |
|
77 |
PORTC |= (1<<PC3); |
|
78 |
PORTC = PORTC & ~(1<<PC2); |
|
79 |
} |
|
80 |
if(speed==0) // turn motor off |
|
81 |
{ |
|
82 |
PORTC = PORTC & ~(1<<PC3); |
|
83 |
PORTC = PORTC & ~(1<<PC2); |
|
84 |
} |
|
85 |
} |
|
86 |
|
|
87 |
int8_t get_motor1() |
|
88 |
{ |
|
89 |
return motor1_speed; |
|
90 |
} |
|
91 |
|
|
92 |
int8_t get_motor2() |
|
93 |
{ |
|
94 |
return motor2_speed; |
|
95 |
} |
paintboard/code/motor.h | ||
---|---|---|
1 |
#ifndef _MOTOR_H_ |
|
2 |
#define _MOTOR_H_ |
|
3 |
|
|
4 |
void motor_init(void); |
|
5 |
void set_motor1(int8_t speed); |
|
6 |
void set_motor2(int8_t speed); |
|
7 |
int8_t get_motor1(); |
|
8 |
int8_t get_motor2(); |
|
9 |
|
|
10 |
#endif |
paintboard/code/servo.c | ||
---|---|---|
1 |
#include <avr/io.h> |
|
2 |
#include "servo.h" |
|
3 |
#include <stdlib.h> |
|
4 |
|
|
5 |
/* |
|
6 |
|
|
7 |
servo controller. Timer0 is set to phase-correct PWM mode, with 32 prescaler. |
|
8 |
|
|
9 |
SERVO_PWM1: PD6 (Timer0) |
|
10 |
|
|
11 |
SERVO_PWM2: PD5 (Timer0) |
|
12 |
|
|
13 |
*/ |
|
14 |
|
|
15 |
int8_t servo1_angle; |
|
16 |
int8_t servo2_angle; |
|
17 |
|
|
18 |
void servo_init() |
|
19 |
{ |
|
20 |
|
|
21 |
// WGM0 0b001 (phase-correct PWM, 8-bit) |
|
22 |
// COM0A 0b10 (clear OCR0A on compare match, set on BOTTOM) |
|
23 |
// COM0B 0b10 (clear OCR0B on compare match, set on BOTTOM) |
|
24 |
// CS0 0b011 (32 prescaler) |
|
25 |
TCCR0A = _BV(WGM00) | _BV(COM0A1) |_BV(COM0B1); |
|
26 |
TCCR0B = _BV(CS01) | _BV(CS00); |
|
27 |
OCR0A = 0; |
|
28 |
OCR0B = 0; |
|
29 |
|
|
30 |
// set output pins |
|
31 |
DDRD |= _BV(PD5) | _BV(PD6); |
|
32 |
|
|
33 |
set_servo1(0); |
|
34 |
set_servo2(0); |
|
35 |
} |
|
36 |
|
|
37 |
void set_servo1(int8_t angle) |
|
38 |
/* angle must be between -128 and 127 */ |
|
39 |
{ |
|
40 |
servo1_angle = angle; |
|
41 |
OCR0A = (uint8_t)(angle + 128); |
|
42 |
} |
|
43 |
|
|
44 |
void set_servo2(int8_t angle) |
|
45 |
/* angle must be between -128 and 127 */ |
|
46 |
{ |
|
47 |
servo2_angle = angle; |
|
48 |
OCR0B = (uint8_t)(angle + 128); |
|
49 |
} |
|
50 |
|
|
51 |
int8_t get_servo1() |
|
52 |
{ |
|
53 |
return servo1_angle; |
|
54 |
} |
|
55 |
|
|
56 |
int8_t get_servo2() |
|
57 |
{ |
|
58 |
return servo2_angle; |
|
59 |
} |
|
60 |
|
paintboard/code/servo.h | ||
---|---|---|
1 |
#ifndef _SERVO_H_ |
|
2 |
#define _SERVO_H_ |
|
3 |
|
|
4 |
void servo_init(); |
|
5 |
void set_servo1(int8_t angle); |
|
6 |
void set_servo2(int8_t angle); |
|
7 |
int8_t get_servo1(); |
|
8 |
int8_t get_servo2(); |
|
9 |
|
|
10 |
#endif |
Also available in: Unified diff