Salve a tutti!
Dal mio robottino, come molti di voi sanno, voglio risposte rapide, quindi devo agire direttamente sui registri e porte. Premetto che, prima di introdurre questo argomento nel mio progetto, il robot funzionava anche se lento nelle risposte, utilizzando le funzioni classiche.
Nel codice riportato sto provando a testare ciò che ho scritto, ma come risultato, non si muove nulla, motori fermi...
//mega2560 port manipulation test
//1x dual motor carrier vnh3sp30 (max 10KHz frequenza PWM) https://www.pololu.com/product/707
//2x motori pololu 350 rpm https://www.pololu.com/product/2823
//batteria 3celle 11.1v 3000mah
/* These are used to read and write to the port registers - see http://www.arduino.cc/en/Reference/PortManipulation
I do this to save processing power - see this page for more information: http://www.billporter.info/ready-set-oscillate-the-fastest-way-to-change-arduino-pins/ */
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
/* Left motor */
#define leftPort PORTA
#define leftPortDirection DDRA
#define leftPwmPortDirection DDRL
#define leftA PINA2 // PA2 - pin 24 (2INA on the Pololu motor driver)
#define leftB PINA3 // PA3 - pin 25 (2INB on the Pololu motor driver)
#define leftPWM PINL4 // PL4 - pin 45 (2PWM on the Pololu motor driver)
/* Right motor */
#define rightPort PORTA
#define rightPortDirection DDRA
#define rightPwmPortDirection DDRL
#define rightA PINA0 // PA0 - pin 22 (1INA on the Pololu motor driver)
#define rightB PINA1 // PA1 - pin 23 (1INB on the Pololu motor driver)
#define rightPWM PINL5 // PL5 - pin 44 (1PWM on the Pololu motor driver)
void setup() {
/* Setup motor pins to output */
sbi(leftPwmPortDirection,leftPWM);
sbi(leftPortDirection,leftA);
sbi(leftPortDirection,leftB);
sbi(rightPwmPortDirection,rightPWM);
sbi(rightPortDirection,rightA);
sbi(rightPortDirection,rightB);
//Timer5 on mega is a 16-bit timer
TCCR5A = B00101001; // Phase and frequency correct PWM change at OCR5A
TCCR5B = B10001; // System clock
OCR5A = 800; // 16MHz/10kHz/2=800 prescaler a 1
OCR5B = 0; // motori fermi
OCR5C = 0;
}
void loop() {
setPWM(leftPWM,600);
setPWM(rightPWM,600);
}
void setPWM(uint8_t pin, int dutyCycle) { // dutyCycle is a value between 0-ICR
if(pin == leftPWM) {
OCR5BH = (dutyCycle >> 8);
OCR5BL = (dutyCycle & 0xFF);
// datasheet a pag. 135: 'To do a 16-bit write, the high byte must be //written before the low byte. For a 16-bit read, the low byte must
//be read before the high byte.'
} else if (pin == rightPWM) {
OCR5CH = (dutyCycle >> 8);//OCR5C=dutyCycle;
OCR5CL = (dutyCycle & 0xFF);
}
}