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

STM8s TIM2 [ARR] [PSCR] реальное не совпадает с расчётным


Рекомендуемые сообщения

Здравствуйте обитатели форума, вернулся к кодингу и на форум после лет 12 паузы.

взялся за STM8 перед тем как штурмовть стм32 там уже получил по лбу когда-то и откотился.

суть вопроса сконфигурировал второй таймер. второй канал на кристале STM8S103F3  как ШИМ1 всё класно работает гордость за не напрасно потраченное время на дробления  RM0016.

наступил момент написания библиотеки для удобности обращения с шимом и тут началась эпопея:

Сначала как посчитать что загрузить чтобы получить желаемую частоту, потом проверка всё на осциллограммах и тут на меня приходит озарение что наверное что то не так, временные интервалы до частоты 122Hz рросчитываются и совпадают.

А после просто треш : тактовая частота HSI 16 000 000 без делителей прямо на вход таймера.

PSCR =0;  ARR=65535;   Fout=244Hz

PSCR =1;  ARR=65535;   Fout=121Hz

PSCR =2;  ARR=65535;   Fout=60Hz

PSCR =3;  ARR=65535;   Fout=30Hz

PSCR =4;  ARR=65535;   Fout=15Hz

PSCR =5;  ARR=65535;   Fout=7,59Hz

PSCR =6;  ARR=65535;   Fout=3,8Hz

PSCR =7;  ARR=65535;   Fout=1,91Hz

PSCR =8;  ARR=65535;   Fout=0,98Hz

Вроде всё гармонично но по факту както у меня не сошлось с расчётами. Там где должно быть 80 там 60. Я понимаю что встроенный генератор не блещет стабтильностью но всё равно что-то с расчётами не так либо я вообще не знаю что делаю не так.

Fout= Fтактирования/([PSCR]+1)/([ARR]+1) тз сих выходит:

PSCR =8;  ARR=65535;   Fout=???Hz

16 000 0000/9/65536/=27Hz

Что не так? где лыжи не едут?

чувствую нужно срочно заказать частотомер для измерения до чёрто знаков дабы  невроз не лечить.

 

 

 

Изменено пользователем 9Klima
Ссылка на комментарий
Поделиться на другие сайты

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

13 часов назад, snn_krs сказал:

А что у вас получается реально Fout=0,98Hz ? Должно быть 27 Hz.

Отписываюсь за успехом частичным начитал на форумах неправильный алгоритм расчёта, правильно нужно считать так:

частота тактирования таймера вычисляется по формуле Fclk_tim=Fmaster/(2^(PSCK))
тогда: 16 000 000 / 2^6 = 16 000 000 / 64 =250 000.
и дальше: 250 000 / 65536 = 3.81Hz

тут еще один вопрос по расчёту двух неизвестных для регистров ARR и PSCR пока крутил вертел основательно запутался хочу процедуре скормить частоту  тактирования и желаемую выходную а она мне что загрузить в регистры оптимальные значения. думаю что я это смогу решить но пока ступор сижу перебираю алгоритмы в голове. чувствую рекурсия пойдёт в дело но это не для контроллеров можно случайно сьесть память.

Издесь дошел консенсуса. Как жаль что я на математику в своё время забил. но главное результат поиск алгоритма затянулся но он сделан, поиск значений последовательными приближениями а точность расчёта частоты даже после запятой получается если использовать типы переменных с запятой для вычисления.

значит изначально за основу уравнение:

(Fmaster/2^N)/A=Fout   Где Fmaster частота тактирования таймера; N - значение регистра [PSCR];  a A - значение регистра [ARRx]; Fout - известная заданная выходная частота ШИМ;

Известно что значение регистра может принимать максимальное значение 0хFFFF из этого в десятичной системе это 65535.

значится упрощаем задачу например хотим частоту на выходе 122.2886 Гц;   от сих делим

16 000 0000/ 122.2886 = 130823.034;

если 130823.034 <= 65535 тогда это значение сразу попадает в регистр [ARRx] а [PSCR]=0;

иначе делаем итерации с делениями остатка и приращиваем в отдельной переменной значение степени в которую возводим двойку. (допустим Int k=1)

итерация 1)   130823.034/(2^k)=130823.034/2=65419;

проверяем результат вычисления не выходит ли он за размер регистра ARRх  65419<=65536; условие положительное и этот остаток будет непосредственно загружен в регистр ARRх а значение k в регистр PSCR.

Изменено пользователем 9Klima
Чтото с навигацией уже второй раз отправил сообщение не дописав не привык еще
Ссылка на комментарий
Поделиться на другие сайты

Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов

 Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

uint8_t    GetPrescCntVal(double freq, uint16_t *PSCRmax, uint16_t *ARRmax)                
//    freq - частота требуемая на ыходе,
//  *PSCRmax - указатель на переменную с максимумами принимаемых значений
//  *ARRmax - указатель на переменную с максимумами принимаемых значений
{
    if(*ARRmax< 1)return 1;  //ты забыл загрузить максимум
    if(*PSCRmax<1)return 2;  //ты забыл загрузить максимум    
    
     double temp1 =0;
     double temp2 =0;         
     double temp4 =0;    
     double temp3 =(double)CLK_GetClockFreq();    
    
     if(temp3<freq)return 3;  //много хочешь я так не могу
    
     double temp4 =0;    
     temp1 =(temp3/freq);
     if( ( (( modf(temp1,&temp2)*100)>=50) ? ((uint16_t)temp1+1) : ((uint16_t)temp1)  ) <=*ARRmax )
     //замысловатая конструкция для явно проверки остатка от деления на выход за максимум регистра [ARRх]
     {
         *PSCRmax =0;
         *ARRmax  =(uint16_t)temp1;        
         return 0;
     }
     else
     {
         temp3=1; //прирастим показатель степени двойки ([PSCR])
                            //так как раннее было выяснено что он явно больше 0
         while((uint16_t)temp3<=*PSCRmax)  //начинаем магию расчёта [PSCR]
         {
             temp4 = temp1/pow(2,temp3);
             if( ( (( modf(temp4,&temp2)*100)>=50) ? ((uint16_t)temp4+1) : ((uint16_t)temp4)  ) <=*ARRmax )            
             //замысловатая конструкция для явно проверки остатка от деления на выход за максимум регистра [ARRх]
             {
                 *PSCRmax =(uint16_t)temp3;
                 *ARRmax  =(uint16_t)temp4;        
                 return 0;
             }
             else temp3=temp3+1; //прирастим показатель степени двойки ([PSCR])
         }
     }
     return 255;  //чтото пошло не так
}

Навоял такую процедуру ложу для обсуждения и исправления дополнения (еще не проверял побежал по работе :))

Ссылка на комментарий
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы публикуете как гость. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...