1

Тема: STM32, CubeMX, Keil, навчання.

До вашої уваги невеличкий проект - визначення частоти.
Апаратна частина - синя пігулка. Використовую TIM1 в режимі PWM захоплення.
Налаштування системної частоти - Частота SYSCLK - 72 MHz
Налаштування TIM1:
Prescaler PSC - 71.
ARR - 65535.
Секція Trigger Output:
Trigger Output selection - Update Event - буду запускати TIM2 для підрахунку переповнень TIM1.
Input CH1 буде нога PA8 TIM1_CH1 вона ж і для CH2.
Input Trigger - TI1FP1 - Reset Mode.
Далі все по замовчуванню.
Вмикаю переривання від TIM1.
Налаштування TIM2:
Slave Mode - External Clock Mode1.
Trigger Source - ITR0.
Prescaler PSC - 0.
ARR - 65535.
Далі все по замовчуванню.
Визначати частоту буду на нозі PA5_Taho_OUTP тому з'єдную її з ногою PA8 TIM1_CH1.
Керувати ногою PA5_Taho_OUTP буду в процесі відлагодження.
В Main
Запускаю CH1 TIM1 в режимі захвату з перериванням.
Запускаю CH2 TIM1 в режимі захвату з перериванням.
Запускаю таймер TIM2 в звичайному режимі.
Далі все це працює так:
У нескінченному циклі дригаю ногою PA5_Taho_OUTP, при відлагодженні можу міняти розмір імпульсу та паузи.
Далі все дійство проходить у колбеці:
По фронту Rising спрацьовує переривання від СH1 TIM1, автоматом скидається лічильник TIM1 бо Input Trigger - TI1FP1 - Reset Mode,
Зчитую захоплене значення в каналі CH1 TIM1 - це буде розмір періоду.
Зчитую значення лічильника CNT TIM2 - чи було переповнення TIM1.
Скидаю значення лічильника CNT TIM2 в нуль.
Далі розраховую дійсний розмір періоду.
По фронту FOLLING спрацьовує переривання від СH2 TIM1
Зчитую захоплене значення в каналі CH2 TIM1 - це буде розмір імпульсу.
Зчитую значення лічильника CNT TIM2 - чи було переповнення TIM1 за час імпульсу
Далі розраховую дійсний розмір періоду.
Ну і розраховую частоту - Hz.
-----------------
Пробую режим без запуску TIM2
Використовую імпульс та паузу з періодом, що не перевищує 65,535 мілісекунд. Все працює бездоганно.
Спроба з запуском TIM2 приводить до похибки. При імпульсі та паузі з періодом, що не перевищує 65,535 мілісекунд, тобто при якому не виникає переповнення TIM1 у CNT TIM2 звідкись береться одиниця і частота рахується неправильно.
Спроба скинути прапорі апдейт UIF
TIM1->SR &= ~TIM_SR_UIF; //Скинути прапор апдейт UIF
TIM2->SR &= ~TIM_SR_UIF; //Скинути прапор апдейт UIF
позитивного результату не дала.
Що я не врахував. Куди копати.
У проекті виправте шлях до репозиторію згідно своїх налаштувань, бо щоб архів був менший я вказував на бібліотеки посилання. Дякую всім за допомогу.

2

Re: STM32, CubeMX, Keil, навчання.

Не вийшло прикрутити проект. Підкажіть як це тут робиться.

3

Re: STM32, CubeMX, Keil, навчання.

Треба натискати "Add File" після того, як вкажете файл.
Дехто з учасників працює з вимкненим JavaScript.

4 Востаннє редагувалося Droid 77 (29.08.2020 01:39:31)

Re: STM32, CubeMX, Keil, навчання.

mykola_sa написав:

звідкись береться одиниця і частота рахується неправильно

Бо при розрахунках тактової частоти одиниця додається апаратно, треба це враховувати при налаштуваннях куба.

P. S.
І дивіться обережніше з кубом по відношенню до синьої пігулки. У CubeMX є неприємний баг відносно F1-ї серії. Куб за умовчуванням додає в код параметр відключення інтерфейсів програмування JTAG та SWD. Що в свою чергу після заливки такого коду в МК унеможливлює повторне підключення ST-Link до контроллера.

Посилання на російськомовний ресурс

5

Re: STM32, CubeMX, Keil, навчання.

Droid 77 написав:

P. S.
І дивіться обережніше з кубом по відношенню до синьої пігулки. У CubeMX є неприємний баг відносно F1-ї серії. Куб за умовчуванням додає в код параметр відключення інтерфейсів програмування JTAG та SWD. Що в свою чергу після заливки такого коду в МК унеможливлює повторне підключення ST-Link до контроллера.

Якщо повторне підключення потрібне не для дебагу, а лише для перепрограмування (як у мене, коли одна з ніжок SWD теж використовується), то проблеми нема. Ну, якщо ST-LINK повний, а не «маленький» клон.
З маленьким клоном та ж сама біда, навіть якщо ніжки JTAG/SWD не відключати, а просто контролер загнати в стоп заради малого споживання. Там прошивка нормальна, просто на штирі не виведено RESET для STM32. Той, що є, він для SWIM-протоколу STM8.

«Маленький» клон ST-Link можна пропатчити для повнішої роботи з STM32 ціною відмови від STM8.

6

Re: STM32, CubeMX, Keil, навчання.

mykola_sa написав:

У проекті виправте шлях до репозиторію згідно своїх налаштувань, бо щоб архів був менший я вказував на бібліотеки посилання.

Ех, ніяк не можу себе змусити хоч щось зробити через Cube для його освоєння.
Все роблю сам врукопашну по документації.

7

Re: STM32, CubeMX, Keil, навчання.

Droid 77 написав:

Бо при розрахунках тактової частоти одиниця додається апаратно, треба це враховувати при налаштуваннях куба.


Ви не вірно зрозуміли суть мого посту - це зовсім не та одиничка про яку треба пам'ятати у лічильниках, бо вони рахують з нуля.

Спробую пояснити так: Планувалась і очікувалась робота контролера в такому режимі - поки період не перевищує 65,535 мілісекунд, не виникає переповнення у TIM1, прапор апдейт UIF не піднімається і CNT у TIM2 не збільшується. CNT у TIM2 збільшується тільки у разі переповнення TIM1.
В реалі ж TIM1 не переповнюється, а TIM2 щось ловить і збільшує CNT на одиницю.
-----
Стосовно "відключення інтерфейсів програмування JTAG та SWD."
Це зовсім не баг відносно F1-ї серії, просто при налаштуванні в CubeMX потрібно вказати що ви плануєте щось дебажити. І Cube все включить як треба. Про це вже написано у всіх варіантах уроків. І навіть якщо ви все таки забули включити відладку, в інеті є море дописів як достукатись до контролера.

8

Re: STM32, CubeMX, Keil, навчання.

ReAl написав:

Все роблю сам врукопашну по документації.

Як і люба інша обгортка для цукерки ця теж має свої плюси та мінуси.
Але для швиденького опробування якоїсь ідеї, CubeMX не цураються навіть профі.
Прийде ваш час і спробуєте.

9

Re: STM32, CubeMX, Keil, навчання.

Не працює в мене upload файлів, тому проект поклав на гуглдиск https://drive.google.com/file/d/1wGfMXD … sp=sharing
Підкажіть - як тут робити правки своїх дописів?

10

Re: STM32, CubeMX, Keil, навчання.

Вивчаю режим енкодера в таймерах STM32
Підкажіть чи можна зробити так щоб:
- переривання спрацьовувало при кожному клацанні енкодера
- при досягненні значення в CNT рівному Counter Period (ARR), при подальшому прокручуванню енкодера значення в CNT не скидалось в нуль, а залишалось на рівні значення в ARR. Наприклад в ARR є 255. Так от дійшли до 255 і далі не збільшується і в "0" не скидається

11 Востаннє редагувалося Droid 77 (24.09.2020 13:34:21)

Re: STM32, CubeMX, Keil, навчання.

По досягненню максимального значення лічильника віднімати одиницю, та додавати одиницю по досягненню мінімального.
Щось на зразок (ENC_MAX_VALUE-1) та (ENC_MIN_VALUE+1).
З такими визначеннями: #define MAX_VALUE 255 та #define MIN_VALUE 0.

12

Re: STM32, CubeMX, Keil, навчання.

Вітання всім. Шановні, маю бібліотеку для TM1637,
Є в ній дві функції - вмикання / вимикання крапок та виведення годин та хвилин
//--------------------------------------
//вмикання / вимикання крапок (POINT_ON / POINT_OFF)
// bool _PointData приймає значення POINT_ON / POINT_OFF
void  point(bool _PointData) {
  _PointData ? PointData = 0x80 : PointData = 0;    //=
  update();
}
//--------------------------------------
//виведення годин та хвилин
void  displayClock(uint8_t _Hours, uint8_t _Minutes) {
    if (_Hours > 99 || _Minutes > 99)
        return;
    uint8_t Time[4];
    !(_Hours / 10) ? Time[0] = 10 : Time[0] = (_Hours / 10);    //=
    Time[1] = _Hours % 10;
    Time[2] = _Minutes / 10;
    Time[3] = _Minutes % 10;
     display(Time);
}
//--------------------------------------

але Keil там бачить дві помилки і лається ось так

..\Src\RV_TM1637.c(193): error:  #137: expression must be a modifiable lvalue
    _PointData ? PointData = 0x80 : PointData = 0;    //=
..\Src\RV_TM1637.c(202): error:  #137: expression must be a modifiable lvalue
      !(_Hours / 10) ? Time[0] = 10 : Time[0] = (_Hours / 10);    //=

Як це можна виправити?

13

Re: STM32, CubeMX, Keil, навчання.

хуіз PointData?

14

Re: STM32, CubeMX, Keil, навчання.

Винесіть те, чому намагаєтеся присвоїти значення, з тернарного оператора. Якщо не зовсім розумієте, як він працює - скористайтеся звичайним if.

15

Re: STM32, CubeMX, Keil, навчання.

_PointData ? PointData = 0x80 : PointData = 0;

PointData = _PointData ? 0x80 : 0;

Ви функцією змінюєте глобальні змінну? -Негігієнічно.

!(_Hours / 10) ? Time[0] = 10 : Time[0] = (_Hours / 10);

Time[0] = (_Hours / 10) ? (_Hours / 10) : 10;
це щоб скомпілювалося, хоча я б так не писав -  у вас буде 1 або 10, навряд чи ви цього хочете )
тут здається треба просто
Time[0] = _Hours / 10;
як і нижче.

не використовуйте тернарний оператор там де треба оператор розгалуження if

16

Re: STM32, CubeMX, Keil, навчання.

Бібліотека не моя. Оригінал тут. https://github.com/RV-robotics
Навчаюсь на чужих роботах. І помилках. От дивуюсь, якщо це помилки, то навіщо на гітхаб викладати не працюючі програми. Ті задачі, що вирішують 193 та 202 можна вирішити і по іншому, але хочеться ж розібратись з цим Тернарним умовним оператором. Дякую всім за увагу.

17

Re: STM32, CubeMX, Keil, навчання.

Що ж, часто так буває що за чужий код отримуєш по шапці) Але з іншого боку якби ті помилки не привернули увагу - не мали би досвіду. А читаючи відкритий код можна навчитися відрізняти вдалі конструкції від невдалих та будувати власний смак/стиль. Удачі.

18

Re: STM32, CubeMX, Keil, навчання.

mykola_sa написав:

але Keil там бачить дві помилки і лається ось так

..\Src\RV_TM1637.c(193): error:  #137: expression must be a modifiable lvalue
    _PointData ? PointData = 0x80 : PointData = 0;    //=
..\Src\RV_TM1637.c(202): error:  #137: expression must be a modifiable lvalue
      !(_Hours / 10) ? Time[0] = 10 : Time[0] = (_Hours / 10);    //=

Як це можна виправити?

Тернарний оператор має вищий пріоритет, ніж оператор присвоювання. Тому

_PointData ? PointData = 0x80 : PointData = 0;

розглядається як

(_PointData ? PointData = 0x80 : PointData) = 0;

і в одній з гілок виглядає зрештою як

(PointData = 0x80) = 0;

Якщо хочеться зберегти його, то тоді так

_PointData ? (PointData = 0x80) : (PointData = 0) ;

Чому таке опинилося на гітхабі — не знаю, може воно збиралося якимось компілятором С-подібної мови програмування на зразок CodeVision AVR, у якого в певних місцях було своє бачення художника.

Подякували: mykola_sa1

19 Востаннє редагувалося ReAl (15.02.2021 20:45:00)

Re: STM32, CubeMX, Keil, навчання.

MindSpeed написав:

!(_Hours / 10) ? Time[0] = 10 : Time[0] = (_Hours / 10);

Time[0] = (_Hours / 10) ? (_Hours / 10) : 10;
це щоб скомпілювалося, хоча я б так не писав -  у вас буде 1 або 10, навряд чи ви цього хочете )
тут здається треба просто
Time[0] = _Hours / 10;

Або 10, або 1, або 2.
Не поспішайте лаяти те, що не розумієте.
Судячи з усього, йде робота з якоюсь мікросхемою драйвера динамічної індикації багаторозрядного індикатора семисегментної індикації, яка приймає нібли 0-9 для індикації цифр '0'-'9', а код 10 сприймає як пробіл (деякі мікросхеми просто декодерів 4 біт у 7 сегментів гасили всі сегменти на кодах 10..15, деякі видавали кашу). Або далі бібліотечка має масив для перекодування числа у сегменти, в якій для зручності числа 0-9 йдуть з 0.

20 Востаннє редагувалося ReAl (15.02.2021 20:46:18)

Re: STM32, CubeMX, Keil, навчання.

MindSpeed написав:

не використовуйте тернарний оператор там де треба оператор розгалуження if

І так, і ні.
З ним треба досхочу награтися самостійно, щоб почати розуміти і використовувати де це доцільно.

«де if» — якщо по algol68, то if може стояти в

a := IF cond THEN b ELSE c FI;

і навіть в

IF cond1 THEN a ELSE b FI := (IF cond2 THEN func1 ELSE func0 FI)(c);

і в таких місцях навіть CASE .. ESAC могло бути.

p.s.

IF cond1 THEN a ELSE b FI := (IF cond2 THEN func1 ELSE func0 FI)(c);

в C вдасться повторити лише так

 *(cond1 ? &a : &b) = (cond2 ? func1 : func0)(c);

а варіант з CASE ніяк.

Подякували: leofun011