Odečítání z enkodérů rychlosti
Moderátor: Moderátoři
-
ATMEGA
Odečítání z enkodérů rychlosti
- Přílohy
-
main.c.txt- (14.49 KiB) Staženo 128 x
-
ATMEGA
Taky jsem se dival na ten kód. Obecně bych řekl, že tam máš na můj vkus zbytečně moc proměnných. Např. místo pwm1counter, pwm2counter a pwm3counter stačí jen jeden pwmCounter. Dále speedLcounted1 a speedLcounted3 mají vždy právě opačné hodnoty, takže by stačila jen jedna z nich. A tak podobně. Kdyby se Ti povedlo všechny vstupy ze senzorů dát na jeden port, možná by se ta jedna časovací rutina dala trochu zjednodušit. Třeba takhle:
Kód: Vybrat vše
static int oldSenzorPin = 0;
...
ISR(TIMER2_OVF_vect) { // zavola se pri preteceni interniho 8bit citace
int senzorPin;
int senzorDelta;
TCNT2=254; // 14.7456MHz/256/2=28800 preruseni/sec - pocita s nastavenim interniho oscilatoru na
// 14.7456MHz. Pokud tak neni, je nutne prepocitat
// 1024 (velikost counteru) - 9 (nas delitel) = 6 (pri kazdem preteceni
// zaciname od 6 a ne od 0)
longac++;
// longac ma byt 600 pro poslani 1x/vterinu, 120 pro 5x/vterinu
if (longac>=28800) {
longac=0;
longacDOit=1;
longac3DOit=1;
longac10++;
}
if ( pwmCounter <= PWMD1 ) bitSet(PORTC, 3); else bitClear(PORTC, 3);
if ( pwmCounter <= PWMD2 ) bitSet(PORTC, 4); else bitClear(PORTC, 4);
if ( pwmCounter <= PWMD3 ) bitSet(PORTC, 5); else bitClear(PORTC, 5);
pwmCounter = (pwmCounter + 1) & 0xFF;
pulsecounterL++;
pulsecounterP++;
senzorPin = SENZOR_PIN;
senzorDelta = senzorPin ^ oldSenzorPin;
if ( senzorDelta & (1<<LEVY_SENZOR_H | 1<<LEVY_SENZOR_Z) ) pulseL++;
if ( senzorDelta & (1<<PRAVY_SENZOR_H | 1<<PRAVY_SENZOR_Z) ) pulseP++;
if ( (senzorPin & (1<<LEVY_SENZOR_H & 1<<LEVY_SENZOR_Z)) == 0 ) speedLdir = senzorDelta>>LEVY_SENZOR_H & 1;
if ( (senzorPin & (1<<PRAVY_SENZOR_H & 1<<PRAVY_SENZOR_Z)) == 0 ) speedPdir = senzorDelta>>PRAVY_SENZOR_H & 1;
oldSenzorPin = senzorPin;
if (pulseL>=12 || pulsecounterL>28800) {
finalSpeedL = (pulseL*(28800000/pulsecounterL))/1000; // nevim, jak je rychle deleni, mozna by pomohlo, kdyby se
hodnoty pulseL a pulseCounterL jen zkopirovaly do globalnich promennych a delilo by se to mimo preruseni
pulsecounterL = 0;
pulseL = 0;
}
if (pulseP>=12 || pulsecounterP>28800) {
finalSpeedP = (pulseP*(28800000/pulsecounterP))/1000;
pulsecounterP = 0;
pulseP = 0;
}
}
Edit: Chyběly mi tam jedny závorky, protože & má nižší prioritu než ==. Tak jsem je tam přidal.
Edit2: Ještě jsem odstranil jednu operaci &, protože byla vlastně zbytečná.
-
Návštěvník
Já jsem teda nekoukal, co všechno v tom přerušení od sériové linky máš, ale tak nějak bych zvažoval, tam dát jen uložení přijatého bajtu do bufferu, odeslání bajtu z jiného bufferu a zbytek dát do hlavního programu. Tak si nějak neumím představit, co tam může tak dlouho trvat.
-
Návštěvník
Kód: Vybrat vše
finalSpeedL = (pulseL*(28800000/pulsecounterL))/1000;oproti jednomu:
Kód: Vybrat vše
finalSpeedL = pulseL*28800/pulsecounterL;?