Jump to content
9Klima

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

Recommended Posts

Posted (edited)

Здравствуйте обитатели форума, вернулся к кодингу и на форум после лет 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

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

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

 

 

 

Edited by 9Klima

Share this post


Link to post
Share on other sites
6 hours ago, 9Klima said:

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

16 000 0000/9/65536/=27Hz

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

Share this post


Link to post
Share on other sites

Изготовление 2-х слойных плат от 2$, а 4-х слойных от 5$!

Быстрое изготовление прототипа платы всего за 24 часа! Прямая доставка с нашей фабрики!

Смотрите видео о фабрике JLCPCB: https://youtu.be/_XCznQFV-Mw

Посетите первую электронную выставку JLCPCB https://jlcpcb.com/E-exhibition чтобы получить купоны и выиграть iPhone 12, 3D-принтер и так далее...

Posted (edited)
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.

Edited by 9Klima
Чтото с навигацией уже второй раз отправил сообщение не дописав не привык еще

Share this post


Link to post
Share on other sites

Высокая надежность SiC! Как они этого добились?

За несколько лет кропотливых исследований и совершенствования технологии компания Infineon смогла довести показатели надежности и стабильности параметров высоковольтных и быстродействующих карбид-кремниевых транзисторов линейки CoolSiC практически до уровня их кремниевых собратьев.

Подробнее

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;  //чтото пошло не так
}

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

Share this post


Link to post
Share on other sites

Вебинар «Практическое использование TrustZone в STM32L5»(10.12.2020)

Приглашаем на вебинар, посвященный экосистеме безопасности и возможностях, которые появились у разработчиков благодаря новой технологии TrustZone в микроконтроллерах STM32L5. Программа рассчитана на технических специалистов и тех, кто уже знаком с основами защиты ПО в STM32.

Подробнее

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Сообщения

    • Послушай Ёмкость - это количество заряда к напряжению.    Вверху есть формула - там для дураков написано.  Дельты сокращаем.  И получается чистый заряд на напряжение.   Это строгая формула.   А без сокращения более простая.
    • Это глупость, ты смешиваешь в кучу ЗАРЯД  конденсатора и его ЁМКОСТЬ, а это разные вещи. Если налить в ведро 5 литров воды, то ёмкость ведра так и останется 10 литров, а "заряд" в нём будет 5.
    • Выставишь пороговое - то есть макс.(я правильно понял)? Правильнее сказать что разные величины порогового напряжения при одном алгоритме измерения будут по разному влиять на результат.    Мы это уже и математически доказали и по всякому.    Ну что ты споришь?
    • нет не будет, ёмкость будет получатся одна и та же   выставив пороговое напряжение для компаратора, если буду задаваться напряжением, или длительностью (время) импульса заряда, если буду задаваться временем.
    • Транзистор открывается когда через переход база - эмиттер протекает ток. А коллектор - эмиттер при этом как бы замыкаются между собой. Когда на входе "4,5 вольта" есть напряжение, первый транзистор открыт, весь ток от R2 через КЭ транзистора уходит на минус и второму транзистору ничего не достаётся, он закрыт, лампа не горит. Когда напряжение пропадает, первый транзистор закрывается, в базу второго транзистора поступает ток через R2, он открывается и лампа горит. То есть, первый транзистор как раз инвертирует входной сигнал.
    • А я говорю что величина приложенного к конденсатору напряжения будет влиять на результат измерения. Вот.    Ты сам сказал.    Как будешь задаваться?    Только зная максимальное напряжение(без него не задашься). При зарядке более мощного конденсатора потребуется и большее напряжение.
    • конечно не вычислю, я об этом ещё несколько страниц назад писал, что её нужно измерять... при определении емкости, нужно или задаваться напряжением на конденсаторе и измерять время или задаваться временем и измерять напряжение... можно и время получать, задаваясь напряжением и ёмкостью - например, как в схемах генераторов или одновибраторов на 555.

  • Универсальный LVDS скалер MT6820-B-1

  • Similar Content

    • By n_angelo
      По приходящему на ножку A1 импульсу настроено прерывание. Прерывание должно отработать один раз и должно делать следующее: пауза 7 секунд, потом на 1,5 секунды открыть реле. Во время прерывания светодиод на плате гаснет и загорается в такт секундам. Код отрабатывает верно за исключением того, что прерывание отрабатывает 2 раза. Т.е. подали импульс, заморгал светодиод в течении 7ми секунд, потом щёлкнуло реле (открылось), затем опять щёлкнуло (закрылось), потом всё повторяется еще раз (7+1,5). В режиме дебага работает нормально. Пробовал отключать реагирование на прерывания во время его отработки:
      disableInterruupts(); ... enableInterruupts(); но не помогает.
      STM8S103F3P6
      Код прерывания
      Код в main.c
       
    • By megavolt3101
      Здравствуйте уважаемые форумчане. Пытаюсь связать два микроконтроллера по шине LIN. В качестве мастера выбрал контроллер STM8S103F3P6 (Его Usart умеет только LIN MASTER). В качестве ведомого выбрал STM8S208RBT6 (У него 2 Усарта, один из которых умеет быть ведомым LIN) Собрал на двух макетных платах. LIN трансивер TJA1020 Прием и передача работают нормально. Но как дошло дело до защиты от потери линии связи, тут возникли проблемы. После обрыва линии связи и ее восстановления связь возобновляется. Но вот после короткого замыкания шины LIN ведомое (SLAVE) устройство намертво виснет. Точнее виснет в обработчике прерывания от USART3. Я пытался принудительно очистить флаг приема по узарту (UART3_FLAG_RXNE) и флаг приема хедер байта (UART3_FLAG_LHDF). А также скидывал флаг брэйк байта (UART3_FLAG_LBDF). Ничего не помогает программа не возвращается из прерывания по приему от USART_3. Но зато если в этот момент с ведущего устройства снова подать команду, то работоспособность ведомого устройства восстанавливается. Тоже самое помогает, если в обработчике прерывания по USART_3 принудительно подать рандомную команду на передачу. То есть, так как линия одна, она сама свою же команду и принимает, получается. Вроде все нормально, но как то коробит такой колхозный способ защиты от короткого замыкания шины. Подскажите, может я забываю еще какой нибудь скинуть флаг при случае коротыша на линии LIN или есть еще каrой нибудь правильный способ обойти защиту от потери связи после кратковременного замыкания на шине. Надеюсь тут есть люди, которые что-то делали с шиной LIN ?

      Прилагаю инициализацию для мастер устройства 
      UART1_Init( 9600, UART1_WORDLENGTH_8D, UART1_STOPBITS_1, UART1_PARITY_NO, UART1_SYNCMODE_CLOCK_DISABLE, UART1_MODE_TXRX_ENABLE);
      UART1_LINBreakDetectionConfig( UART1_LINBREAKDETECTIONLENGTH_11BITS);
      UART1_ITConfig( UART1_IT_RXNE_OR, ENABLE);
      UART1_LINCmd( ENABLE);
      enableInterrupts();

      И для Ведомого устройства
      UART3_Init( 9600, UART3_WORDLENGTH_8D, UART3_STOPBITS_1, UART3_PARITY_NO, UART3_MODE_TXRX_ENABLE);
      UART3_LINConfig( UART3_LIN_MODE_SLAVE, UART3_LIN_AUTOSYNC_ENABLE,UART3_LIN_DIVUP_LBRR1);
      UART3_LINBreakDetectionConfig( UART3_LINBREAKDETECTIONLENGTH_11BITS);
      UART3_ITConfig( UART3_IT_RXNE_OR, ENABLE);
      UART3_ITConfig( UART3_IT_LBDF, ENABLE);
      UART3_ITConfig( UART3_IT_LHDF, ENABLE);
      UART3_LINCmd( ENABLE);
      enableInterrupts();

      А также обработчик прерывания для ведомого устройства
      //Обработчик прерывания для UART3.
      INTERRUPT_HANDLER( UART3_RX_IRQHandler, 21)
      {
      if( UART3_GetFlagStatus( UART3_FLAG_LHDF)){recUART3_Header=UART3_ReceiveData8(); UART3_ClearFlag(UART3_FLAG_LHDF);}
      if( UART3_GetFlagStatus( UART3_FLAG_RXNE)){recUART3_Data=UART3_ReceiveData8(); UART3_ClearFlag(UART3_FLAG_RXNE);}
      if( UART3_GetFlagStatus( UART3_FLAG_LBDF)){ UART3_ClearFlag( UART3_FLAG_LBDF);}
      if( UART3_GetFlagStatus(UART3_FLAG_OR_LHE)){UART3_SendData8(0x00);UART3_ClearFlag(UART3_FLAG_OR_LHE);}// Отправляю пустую команду через USART_3
      }
    • By gafbich
      Объясните пожалуйста следующие, на руках имеется STM8S103F3P6, сначала была проблема запустить SPI, проблема была даже не в запуске а корректной работе - сделал! А вот с таймером я засел вообще. Хочу сделать программный delay по средствам таймера TIM1 без прерываний. Ниже скидываю инициализацию таймера TIM1 и обработчник(функция delay)
       
      Тактовая частота 2MHz.
       
      Где загвоздка?
       
      #include "iostm8s103f3.h" void TIM1_init(void); void delay_us(unsigned int d); void TIM1_init(void) { ////Величина автоперезагрузки//// unsigned int auto_preload = 65535; TIM1_ARRH=((auto_preload&0xFF00)>>8); TIM1_ARRL=auto_preload&0x00FF; //////////////////////////////// ////////Установка делителя////// unsigned int div_load = 2000; TIM1_PSCRH=((div_load&0xFF00)>>8); TIM1_PSCRL=div_load&0x00FF; //////////////////////////////// TIM1_CR1|=(1<<7)|(1<<1)|(1<<0); } void delay_us(unsigned int d) { TIM1_CNTRH=0;TIM1_CNTRL=0; TIM1_ARRH=((d&0xFF00)>>8); TIM1_ARRL=d&0x00FF; while(((unsigned int)((TIM1_CNTRH<<8)+TIM1_CNTRL))<d){}; } int main() { ///////////////////////////////////// //Отключаем Всю периферию // CLK_PCKENR1=0x00; CLK_PCKENR2=0x00; ///////////////////////////////////// CLK_PCKENR1|=(1<<7);//Включаем тактирование для TIM1 TIM1_init(); //Настройка ногодрыга для проверки таймера// PB_DDR|=(1<<5); PB_CR1|=(1<<5); PB_CR2|=(1<<5); //////////////////////////////////////////// while(1) { PB_ODR&=~(1<<5); delay_us(1000);//1сек PB_ODR|=(1<<5); delay_us(1000);//1сек } return 0; }  
    • By shemmer
      Продам микросхемы. Все новое. 95 % в упаковке.
      1. Микроконтроллеры
        STM32F030F4P6   - 3 шт. TSSOP20. 30 руб.   STM8S003F3U6TR - 5 шт. UFQFPN20. 20 руб.   STM8S003F3P6 - 3 шт. TSSOP20. 30 руб.   AT91SAM7S512 - 3 шт. TQPF64. 120 руб.   AT91SAM7S256 - 3 шт. TQPF64. 90 руб.   AT91SAM7S64 - 50 шт. TQPF64. Сняты с не работавших плат. 40 руб/шт.   PIC12LF1840 - 3 шт. 30 руб. 2. Память
      AT24C128C-SSHM  6 шт. SO8. 10 руб. AT25DF081A - 3 шт. SO8. 20 руб. AT45DB161 - 25 шт. 50 руб. 3. Питание
      NCP1013AP100G - 3 pcs NCP1012AP065G - 3 pcs NCP1028P100G - 2 pcs NCP1011AP100G - 3 pcs NCP1053P100G - 3 pcs NCP1011APL065R2G - 2 pcs VIPER12ASTR-E - 3 pcs VIPER12A - 5 pcs ST1S10PHR MC33063 КР142ЕН5А - 150 шт. В герметичных упаковках. 4. Прочее
      74HC595 - 50 шт. ADM485 ( SO8 )  
      Отправка почтой из Томска.
       
       
    • By Рена
      Прошу помощи в создании ШИМ регулятора вентилятора охлаждения двигателя на STM8S.
      В программировании навыков нет, учусь потихоньку, пока заказал STM8S-Discovery.
      Задача - плавное вкл/выкл. (программируемое значение) и регулирование оборотов вентилятора (ШИМ от 20-95%) в зависимости от температуры с датчика.
      Если есть возможность помогите.
×
×
  • Create New...