eddy_em: (Костерок)
eddy_em ([personal profile] eddy_em) wrote2016-12-29 04:04 pm
Entry tags:

"A /= 2" или же "A >>=1"?

Я всегда думал, что это одно и то же, однако, оказалось, что совсем не так! Обратил внимание, что код из предыдущей записи как-то неоптимально компилируется: в ассемблерном листинге в операции деления на 2 вместо сдвига было реальное деление. "Что за нафиг?" — подумал я, и заменил деление на сдвиг. Благо, коммит не делал — решил сначала проверить. И вот, вместо ожидаемого периода в 10мс (6000 об/мин) получаю какую-то чертовщину! Меняю обратно на деление: вуаля!

Что за … ?

Вот так — работает:
uint16_t current_RPM = 0;
/**
 * Calculate motor speed in RPM
 * RPM = 1/tim2_arr / 40 * 60
 */
void get_RPM(){
    uint32_t R = 3000000 / (uint32_t)TIM2_ARR;
    current_RPM = R/2;
}

// calculate TIM2_ARR by RPM
uint16_t get_ARR(uint32_t RPM){
    uint32_t R = 3000000 / RPM;
    R /= 2;
    return (uint16_t)R;
}

А вот так — не работает!
uint16_t current_RPM = 0;
/**
 * Calculate motor speed in RPM
 * RPM = 1/tim2_arr / 40 * 60
 */
void get_RPM(){
    uint32_t R = 3000000 / (uint32_t)TIM2_ARR;
    current_RPM = R;
    current_RPM >>= 1;
}

// calculate TIM2_ARR by RPM
uint16_t get_ARR(uint32_t RPM){
    uint32_t R = 3000000 / RPM;
    R >>= 1;
    return (uint16_t)R;
}

Значения current_RPM — от 180 до 6000, т.е. в uint16_t влезают с хорошим запасом! Что за фокусы gcc выдает?

Post a comment in response:

This account has disabled anonymous posting.
If you don't have an account you can create one now.
HTML doesn't work in the subject.
More info about formatting

If you are unable to use this captcha for any reason, please contact us by email at support@dreamwidth.org