реклама на сайте
подробности

 
 
> stm32 - генерация точной частоты таймера, задачка школьной программы
Sprite
сообщение May 17 2015, 07:49
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 173
Регистрация: 11-05-08
Пользователь №: 37 414



Здравствуйте, уважаемые форумчане!

Задача в следующем: есть таймер, например, 5-й, питается от 72 мГц шины. Требуется генерировать ШИМ частотой в пределах от 10 до 2000 Гц с минимально возможной погрешностью (разницы нет - в большую или меньшую сторону). Когда частота кратна 72 - все прекрасно, но если требуется вывести частоту, например, 13 Гц, то возникает погрешность. Настройка соответственно происходит регистрами PSC и ARR, комбинаций их может быть достаточно много. Самое первое, что приходит в голову - это тупой перебор всех возможных комбинаций с вычислением ошибки и выбором пары PSC и ARR с наименьшей их них, но это не наш метод wink.gif
Может существует формула для расчета? Или на крайний случай таблица значений регистров для каждой частоты с минимальной погрешностью?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
basileus_
сообщение May 19 2015, 09:27
Сообщение #2





Группа: Новичок
Сообщений: 1
Регистрация: 15-05-15
Из: Piter
Пользователь №: 86 702



предложу следующее решение:
CODE

#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), и сразу по достижении приемлемого результата брякаться.

Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- Sprite   stm32 - генерация точной частоты таймера   May 17 2015, 07:49
- - Эдди   Подсказываю: есть цепные дроби. Я, кстати, активно...   May 17 2015, 12:32
- - adnega   Цитата(Sprite @ May 17 2015, 10:49) есть ...   May 17 2015, 15:49
- - BaN   Цитата(Эдди @ May 17 2015, 18:32) Подсказ...   May 17 2015, 16:07
- - _Pasha   В общем-то решается не только цепными дробями. Я т...   May 17 2015, 16:34
|- - jcxz   Цитата(_Pasha @ May 17 2015, 22:34) Я тут...   May 21 2015, 17:16
|- - _Pasha   Цитата(jcxz @ May 21 2015, 20:16) PS: Кст...   May 21 2015, 17:56
|- - jcxz   Цитата(_Pasha @ May 21 2015, 23:56) Проще...   May 21 2015, 18:56
|- - _Pasha   Цитата(jcxz @ May 21 2015, 21:56) Для реш...   May 21 2015, 19:22
||- - jcxz   Цитата(_Pasha @ May 22 2015, 01:22) Интер...   May 22 2015, 07:47
||- - _Pasha   Цитата(jcxz @ May 22 2015, 10:47) Нет. Дл...   May 22 2015, 08:44
||- - adnega   Цитата(jcxz @ May 22 2015, 10:47) Любого ...   May 22 2015, 09:11
|- - adnega   Цитата(jcxz @ May 21 2015, 21:56) А этого...   May 21 2015, 21:46
|- - _Pasha   Цитата(jcxz @ May 21 2015, 21:56) Для реш...   May 22 2015, 02:57
- - adnega   Как вариант, для низких частот (когда делитель не ...   May 19 2015, 12:11
- - Sprite   Спасибо всем за советы! Сейчас буду перемалыва...   May 20 2015, 12:21
- - _Pasha   вишенка на торте Кодchar isPrime(uint_least16_...   May 22 2015, 04:50
- - _Pasha   А знаете ли вы, что ... http://cyberleninka.ru/art...   May 22 2015, 09:43


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 30th July 2025 - 01:22
Рейтинг@Mail.ru


Страница сгенерированна за 0.01444 секунд с 7
ELECTRONIX ©2004-2016