|
Cikkek » WILL-I - Robot, AVR mikrovezérlővel
WILL-I - Robot, AVR mikrovezérlővel
Motorvezérlő kód (motor.h)
A motorvezérlést érdemes egy külön fájlban létrehozni (motor.h) és bemásolni a WinAVR/avr/include/util könyvtárba. Így később nem kell mindig megírnunk elég csak hivatkozni rá ( egy include utasítással).
A mellékelt kódot nem magyarázom el sorról-sorra, mindenki bogarássza végig, hogy az egyes utasításokkal melyik regiszterek melyik bitjeit minek állítjuk be, melyik lábra milyen feszültséget adunk ki és mit vezérelünk vele. Ennek megértése jó kis gyakorlás lesz, de minden szükséges információ korábban már szerepelt.
Egy kis segítség: A feladatunk megkönnyítése érdekében írunk speciális motorvezerlő utasításokat:
- be_b(x), be_c(x), be_d(x) : Például a be_d(x) utasítás a PORTD x.-ik lábának értékét olvassa be. Először a lábat bemenetnek adjuk meg, majd megvizsgáljuk hogy értéke 0 vagy 1-e. Például a be_b(3) utasítás a PORTB 3. lábát vizsgálja (a PB3-ra kötött jobb oldali mikrokapcsoló be van-e nyomva)
- ki_b(x,y), ki_c(x,y), ki_d(x,y) : Például a ki_b(x,y) utasítás a PORTB x.-ik lábára 0V-ot vagy 5V-ot ad, attól függően hogy y értéke 0 vagy 1. Először a lábat kimenetnek adjuk meg, majd ha y = 1, akkor a lábra 5V-ot adunk. Ha y = 0, akkor pedig a lábra 5V-ot adunk. Például a ki_d(5,1) utasítás a PORTD 5. lábára 5V-ot ad, a ki_b(0,0) utasítás pedig a PORTB 0. lábára 0V-ot.
- pwm(a,b) : a utasítás Timer1-hez tartozó PB1 és PB2 lábakra ad PWM jelet. “a“ értéke 1 vagy 2 lehet attól függően hogy melyik csatornára (motorra) vonatkozik. “b“ értéke a PWM jel kitöltési tényezőjét adja meg (0 – 100%). Először egy 8 bites, fázishelyes, nem-invertált PWM-et állítunk be (az előosztás mértéke: FCPU/1). PORTB PB1 és PB2 lábait kimenetnek adjuk meg. Például a pwm(1,100) utasítás a PB1 lábra ad 100%-os kitöltési tényezőjű PWM jelet. A pwm(2,50) utasítás a PB2 lábra ad 50%-os kitöltési tényezőjű PWM jelet.
- motor(a,b) : az utasítás a pwm(a,b) utasítást használja fel és a motorokat vezérli. “a“ értéke a motorokat választja ki (1-es vagy 2-es), “b“ értéke pedig a motor sebességét adja meg (-100% (hátramenet) – 100% (előre)) Például a motor(1,100) utasítás az 1-es motort hajtja előre 100%-os sebességgel, a motor(2,-50) utasítás pedig a 2-es motort hajtja hátra 50%-os sebességgel.
- motor_stop(a) : az utasítás leállítja az adott motort. a“ értéke 1, 2 vagy mind (3) lehet. Például a motor _stop(1) utasítás az 1-es motort állítja le, a motor _stop(mind) és a motor _stop(3) utasítás pedig leállítja mindkét motort.
- motor_ki() : az utasítás leállítja az összes motort. Kikapcsolja a PWM jelet és az L293D IC-t vezérlő lábakra 0V-ot ad.
- elore(x) : az utasítás mindket motort előremenetbe kalcsolja. “x“értéke 0-100% lehet. Például az elore(75) utasítás mindkét motort előre hajtja 75%-os sebességgel.
- hatra(x) : az utasítás mindket motort hátramenetbe kalcsolja. “x“értéke 0-100% lehet. Például a hatra(60) utasítás mindkét motort hátramenetbe kapcsolja 60%-os sebességgel.
- fordul_bal(x) : az utasítás a robotot balra fordítja. Az 1-es motort előremenetbe, a 2-es motort pedig hátramenetbe kapcsolja. “x“ értéke 0-100% lehet. Például a fordul_bal(50) utasítás az 1-es motort előre, a 2-es motort pedig hátrafelé hajtja 50%-os sebességgel.
- fordul_jobb(x) : az utasítás a robotot jobbra fordítja. Az 1-es motort hátramenetbe, a 2-es motort előremenetbe pedig kapcsolja. “x“értéke 0-100% lehet. Például a fordul_jobb(50) utasítás a 2-es motort előre, az 1-es motort pedig hátrafelé hajtja 50%-os sebességgel.
/* ATmega8 mikrovezerlo labkiosztas
+--------------+
RESET -|1 PC5 28|-
-|2 PD0 PC4 27|-
-|3 PD1 PC3 26|-
Nyomogomb -|4 PD2 PC2 25|-
Mikrokapcs. jobb -|5 PD3 PC1 24|-
Mikrokapcs. bal -|6 PD4 PC0 23|-
VCC -|7 22 |- GND
GND -|8 21 |- AREF
(xtal) -|9 PB6 20|- AVCC
(xtal) -|10 PB7 PB5 19|- ISP(SCK)
Motor2 A -|11 PD5 PB4 18|- ISP(MISO)
Motor2 B -|12 PD6 PB3 17|- ISP(MOSI), servo PWM
Motor1 A -|13 PD7 PB2 16|- Motor2 PWM
Motor1 B -|14 PB0 PB1 15|- Motor1 PWM
+--------------+
L293D motorvezerlo IC labkiosztas
+---------------+
Motor1 PWM -| 1 1-2EN 5V 16|- VCC
Motor1 A -| 2 BE1 BE4 15|- Motor2 B
Motor1(+) -| 3 KI1 KI4 14|- Motor2(-)
GND -| 4 GND GND 13|- GND
GND -| 5 GND GND 12|- GND
Motor1(-) -| 6 KI2 KI3 11|- Motor2(+)
Motor1 B -| 7 BE2 BE3 10|- Motor2 A
Motor Fesz.(6V) -| 8 VMo 3-4EN 9|- Motor2 PWM
+---------------+
*/
//---------------------------------------------------------------------
#include <avr/io.h>
#define mind 3 // mindket motor
#define Motor1A PD7 // Motor1A = PD7
#define Motor1B PB0 // Motor1B = PB0
#define Motor2A PD5 // Motor2A = PD5
#define Motor2B PD6 // Motor2B = PD6
unsigned char _duty1=0,_duty2=0; /* motor 1 es 2 sebesseget (PWM kitolsesi tenyezot) allito valtozo */
char pwm_ini=0;
char be_b(char _bit) // be_b(x) fuggveny definialasa PORTB-re
{
DDRB &= ~(1<<_bit); // PORTB x. lab bemenet
return ((PINB & _BV(_bit))>>_bit); /* PORTB x. lab ertekenek beolvasasa (0 vagy 1)*/
}
char be_c(char _bit) // ugyan az mint az elozo fuggveny, de PORTC-re
{
DDRC &= ~(1<<_bit);
return ((PINC & _BV(_bit))>>_bit);
}
char be_d(char _bit) // be_d(x) fuggveny definialasa PORTD-re
{
DDRD &= ~(1<<_bit); // PORTB x. lab bemenet
return ((PIND & _BV(_bit))>>_bit);
}
void ki_b(char _bit,char _dat) /* ki_b(x,y) fuggveny definialasa PORTB-re. PORTB x. labara 0V-ot vagy 5V-ot adunk, attol fuggoen hogy y erteke 0 vagy 1 */
{
DDRB |= _BV(_bit); // PORTB x. lab kimenet
if(_dat)
PORTB |= _BV(_bit); // ha y=1, az x. labra 5V-ot ad
else
PORTB &= ~_BV(_bit); // ha y=0, az x. labra 5V-ot ad
}
void ki_c(char _bit,char _dat) /* ki_c(x,y) fuggveny definialasa PORTC-re */
{
DDRC |= _BV(_bit);
if(_dat)
PORTC |= _BV(_bit);
else
PORTC &= ~_BV(_bit);
}
void ki_d(char _bit,char _dat) /* ki_d(x,y) fuggveny definialasa PORTD-re */
{
DDRD |= _BV(_bit);
if(_dat)
PORTD |= _BV(_bit);
else
PORTD &= ~_BV(_bit);
}
void pwm_init() //Timer1 PWM beallitasa
{
TCCR1A |= (1<<WGM10); //8 bites fazishelyes PWM
TCCR1B |= (1<<CS10); //elooszto = FCPU/1
}
void pwm(char _channel,unsigned int _duty) /* pwm(a,b) fuggveny definialasa. a = 1 vagy 2 attol fuggoen hogy melyik motor, b = 0 – 100% (PWM kitoltesi tenyezo) */
{
_duty = (_duty*255)/100; /*motor sebesseg konvertalasa 0-100%-rol 0-255-re */
if(pwm_ini==0)
{
pwm_init();
pwm_ini=1;
}
if(_channel==1)
{
TCCR1A |= _BV(COM1A1); //nem-invertalt PWM, A csatorna
DDRB |= _BV(PB1); // PORTB PB1 lab kimenet
OCR1A = _duty; // motor1 pwm kitoltesi tenyezo
_duty1 = _duty;
}
else if(_channel==2)
{
TCCR1A |= _BV(COM1B1); //nem-invertalt PWM, B csatorna
DDRB |= _BV(PB2); // PORTB PB2 lab kimenet
OCR1B = _duty; // motor2 pwm kitoltesi tenyezo
_duty2 = _duty;
}
else if(_channel==3)
{
TCCR1A |= _BV(COM1A1); //nem-invertalt PWM, A csatorna
DDRB |= _BV(PB1);
OCR1A = _duty;
_duty1 = _duty;
TCCR1A |= _BV(COM1B1); //nem-invertalt PWM, B csatorna
DDRB |= _BV(PB2);
OCR1B = _duty;
_duty2 = _duty;
}
}
void motor(char _channel,int _power) /* motor(a,b) fuggveny definialasa. a = 1 vagy 2 attol fuggoen hogy melyik motor, b = -100% – 100% (motor sebesseg) */
{
if(_power>0) // ha b (motor sebesseg) > 0, motor elore
{
pwm(_channel,_power); // motor PWM bekapcsol
if(_channel==1) // ha a=1 (motor1 elore)
{
ki_d(Motor1A,1);
ki_b(Motor1B,0);
}
else if(_channel==2) // ha a=2 (motor2 elore)
{
ki_d(Motor2A,0);
ki_d(Motor2B,1);
}
}
else // ha b (motor sebesseg) < 0, motor hatra
{
pwm(_channel,abs(_power)); // motor PWM bekapcsol
if(_channel==1) // ha a=1 (motor1 hatra)
{
ki_d(Motor1A,0);
ki_b(Motor1B,1);
}
else if(_channel==2) // ha a=2 (motor2 hatra)
{
ki_d(Motor2A,1);
ki_d(Motor2B,0);
}
}
}
void motor_stop(char _channel) /* motor_stop(a) fuggveny definialasa. a = 1, 2 vagy mind (3) attol fuggoen hogy melyik motort akarjuk megallitani */
{
pwm(_channel,0); // motor PWM kikapcsol
if(_channel==1 ||_channel==3) //motor1 stop
{
ki_d(Motor1A,0);
ki_b(Motor1B,0);
}
if(_channel==2 ||_channel==3) //motor2 stop
{
ki_d(Motor2A,0);
ki_d(Motor2B,0);
}
}
void motor_ki()
{
pwm(3,0); // motor PWM kikapcsol, motor1 es 2 stop
ki_d(Motor1A,0);
ki_b(Motor1B,0);
ki_d(Motor2A,0);
ki_d(Motor2B,0);
}
void elore(int speed) /* elore(z) fuggveny definialasa, mindket motor elore, z = 0-100% */
{
motor(1,speed);
motor(2,speed);
}
void hatra(int speed) /* hatra(y) fuggveny definialasa, mindket motor hatra, y = 0-100% */
{
motor(1,speed*-1);
motor(2,speed*-1);
}
void fordul_bal(int speed) /* fordul_bal(n) fuggveny definialasa, balra fordulas: motor1 elore, motor2 hatra, n = 0-100% */
{
motor(1,speed);
motor(2,speed*-1);
}
void fordul_jobb(int speed) /* fordul_jobb(m) fuggveny definialasa, jobbra fordulas: motor1 hatra, motor2 elore, m = 0-100% */
{
motor(1,speed*-1);
motor(2,speed);
}
A cikk még nem ért véget, lapozz!
Értékeléshez bejelentkezés szükséges!
|
|