Перейти к содержанию
    

basileus_

Новичок
  • Постов

    1
  • Зарегистрирован

  • Посещение

Репутация

0 Обычный

Старые поля

  • Facebook
    Array
  • Vkontakte
    Array
  • Twitter
    Array

Контакты

  • Сайт
    Array
  • ICQ
    Array

Информация

  • Город
    Array

Посетители профиля

195 просмотров профиля
  1. предложу следующее решение: #include <math.h> #include <stdlib.h> #include <stdio.h> const unsigned int FQz=24000000;//входная частота таймера. const float erratum=.00001;//допустимая ошибка. const unsigned int MAXLOAD=65535; //unsigned int Fs; //требуемая для установки частота. void calc(unsigned int Fs, unsigned int *ld1, unsigned int *ld2){ int delta1; int delta2; unsigned int ldt1; unsigned int ldt2; unsigned int mult=(unsigned int)floor(FQz/(Fs) + 0.5);// получим общее произведение делителя частоты unsigned int ldx=mult/65535; if(ldx==0){++ldx;}; //возьмём нижнюю оценку для делителя 1. *ld2=0; delta2=FQz;// загрузим заведомо превыщающее оценку значение int cnt=0; while((ldx<sqrt(mult))) { ldt2=(unsigned int)floor( mult/ldx); ldt1=(unsigned int)floor(mult/ldt2); if ((ldt2<MAXLOAD)){ delta1=abs(FQz-Fs*ldt1*ldt2); if(delta1>abs(FQz-Fs*ldt1*(ldt2+1))){ ++ldt2; delta1=abs(FQz-Fs*ldt1*ldt2); } if ((delta1<delta2)){//обновим пару делителей, при вновь найденной минимальной ошибке. *ld1=ldt1; *ld2=ldt2; delta2=delta1; }; if(delta1==0)break;//если найден идеальный результат- остановимся. //if((float)delta1<erratum*FQz)break;//если найден подходящий результат- остановимся. if((delta1<erratum*FQz)&&(cnt==0)){cnt=ldx;}//если найден подходящий результат- запомним. }; ++ldx; }; printf("\nfs=%d; ld1=%u; ld2=%u; delta=%d; ldx=%i; cnt=%i", Fs, *ld1, *ld2, delta2, ldx, cnt );//чисто отладочный вывод } int main() { unsigned int ld1; unsigned int ld2; for (int i=1; i<999;i++){ calc(i, &ld1, &ld2); }; printf("This is SPARTA!\r\n"); } можно убрать убрать строки, где считается число итераций (cnt), и сразу по достижении приемлемого результата брякаться.
×
×
  • Создать...