Тёмный

STM32. CMSIS #3. SysTick - делаем точную задержку через системный таймер 

NR.electronics
Подписаться 18 тыс.
Просмотров 8 тыс.
50% 1

Скачать PVS-Studio для проверки своего можно бесплатно на:
pvs-studio.com/nr_download
Официальная страничка в RU-vid:
/ pvsstudiotool
Официальная страничка ВКонтакте:
pvsstudio_rus
Знакомимся с системный таймером SysTick по документации и начинаем его программировать для получения необходимого точного значения задержки между двумя любыми процессами. Проверяем запрограммированное значение по осциллографу. Готовый проект можно скачать по ссылке:
github.com/nr-electronics/CMS...
00:08 Введение в видео и проект
03:25 Рассмотрение SysTick
04:40 Регистр STK_CTRL
07:10 Регистр STK_LOAD
08:55 Регистр STK_VAL
09:54 Регистр STK_CALIB
13:13 Создаем проект на CMSIS - SysTick в ARM KEIL
24:24 Проверка программирования по осциллографу
26:23 Проверка правильности написания кода в PVS-Studio
__________________________________________________
Вы можете помочь каналу через Яндекс-деньги:
money.yandex.ru/to/4100115727...
или через банковскую карту:
4377 7237 6190 5714
__________________________________________________

Опубликовано:

 

15 апр 2021

Поделиться:

Ссылка:

Скачать:

Готовим ссылку...

Добавить в:

Мой плейлист
Посмотреть позже
Комментарии : 77   
@OpenFrimeTVcom
@OpenFrimeTVcom 3 года назад
спасибо, я как раз закончил с прошлым роликом, и перенес все в код. теперь буду с этим возится)
@NRelectronics
@NRelectronics 3 года назад
На благо. Отлично, я во время значит!)
@AndySm1973
@AndySm1973 3 года назад
Огромное спасибо! Очень интересный цикл видео!
@NRelectronics
@NRelectronics 3 года назад
Спасибо! Всем подписываться на канал и смотреть вместе!)
@kospov2002
@kospov2002 3 года назад
Как всегда великолепно! Стабильность признак мастерства! Спасибищееее!
@NRelectronics
@NRelectronics 3 года назад
Благодарю, приятно конечно. Но все мы люди и можем очепятаться например)
@kospov2002
@kospov2002 3 года назад
@@NRelectronics Не ошибается тот кто ничего не делает. Я про то, что уровень контента стабильно высокий и это радует))) Или я где то очепятался? 😁 В любом случае очень подробно, без воды и позновательно ))) Очень надеюсь ваш запал не угаснет! )))
@NRelectronics
@NRelectronics 3 года назад
Вы правы, кто ничего не делает) Вы не очепятались ;) Стараюсь держать планку. О да, запал тоже необходим)
@IgorPolkhanov
@IgorPolkhanov 3 года назад
Спасибо за видео. Хотелось бы видеть серии по DMA, ADC и USB)
@NRelectronics
@NRelectronics 3 года назад
Пожалуйста. По этой периферии также будут видео!
@michaelgovorov5083
@michaelgovorov5083 2 года назад
сильные лекции для основ стм. подход работы с регистрами cmsis самый правильный при прогр контроллера
@NRelectronics
@NRelectronics 2 года назад
Спасибо. С регистрами согласен.
@user-qi5li3wv6i
@user-qi5li3wv6i 3 месяца назад
Для тех кто пишет с нуля, функция обработки прерывания должна называться точно как в видео
@NRelectronics
@NRelectronics 3 месяца назад
👍
@amn5021
@amn5021 3 года назад
Переснять бы выдосик, по хорошему. Делитель нужно считать так: SysTick->VAL = SYSLOCK / 1000 - 1, т.е. скобки, меняющие порядок действий, там ошибочны. И, да, нет никакого смысла перед этой строкой что-то там писать в SysTick->VAL.
@NRelectronics
@NRelectronics 3 года назад
VAL все же вписать крайне желательно. Скобки через комит отредактирую.
@amn5021
@amn5021 3 года назад
@@NRelectronics В SysTick_Init() запись в VAL имеет смысл, в delay_mS() никакого.
@Shinsei75
@Shinsei75 3 года назад
О! Теперь понятно, а то хотел спросить зачем в скобках писать 1000-1, если можно было 999 написать, а так как без скобок тогда уже понятно
@NRelectronics
@NRelectronics 3 года назад
Досадная очепятка. Скобки лишние. Правильно SYSCLOCK/1000 - 1. На гитхабе откоммичу. Ну с минус единицей как бы наверное яснее.
@NRelectronics
@NRelectronics 3 года назад
Вам про одно и тоже про delay_ms не надоело писать?? Все это понимают давно.
@user-qc7ib5fj9n
@user-qc7ib5fj9n 3 года назад
здравствуйте , подскажите где в кейле можно посмотреть размер получившегося кода ?
@NRelectronics
@NRelectronics 3 года назад
Здравствуйте. В окне Build Output.
@user-yg4mu7rm7k
@user-yg4mu7rm7k 3 года назад
такой вопрос, а если я хочу изменить частоту тактирования, что мне нужно закоментировать?
@NRelectronics
@NRelectronics 3 года назад
В зависимости от того что нужно меняется тут: #ifdef SYSCLK_FREQ_HSE uint32_t SystemCoreClock = SYSCLK_FREQ_HSE; /*!< System Clock Frequency (Core Clock) */ #elif defined SYSCLK_FREQ_24MHz uint32_t SystemCoreClock = SYSCLK_FREQ_24MHz; /*!< System Clock Frequency (Core Clock) */ #elif defined SYSCLK_FREQ_36MHz uint32_t SystemCoreClock = SYSCLK_FREQ_36MHz; /*!< System Clock Frequency (Core Clock) */ #elif defined SYSCLK_FREQ_48MHz uint32_t SystemCoreClock = SYSCLK_FREQ_48MHz; /*!< System Clock Frequency (Core Clock) */ #elif defined SYSCLK_FREQ_56MHz uint32_t SystemCoreClock = SYSCLK_FREQ_56MHz; /*!< System Clock Frequency (Core Clock) */ #elif defined SYSCLK_FREQ_72MHz uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz; /*!< System Clock Frequency (Core Clock) */ #else /*!< HSI Selected as System Clock source */ uint32_t SystemCoreClock = HSI_VALUE; /*!< System Clock Frequency (Core Clock) */ #endif В файле system_stm32f10x.c
@user-lm3vp6hx5c
@user-lm3vp6hx5c 3 года назад
Здравствуйте, подскажите пожалуйста, что произошло на рынке STМ. Решил заказать stmмки и обалдел от цен, если раньше stm32f103 стоило в районе 130 руб, сейчас ~400. С чем связан такой резкий скачок цен?
@NRelectronics
@NRelectronics 3 года назад
Здравствуйте. Кризис полупроводниковых микросхем. Ждем к чему это приведет ещё...
@namename2031
@namename2031 2 года назад
8:40 SYST_CVR Любая запись сбрасывает регистр в 0, а также сбрасывает бит COUNTFLAG в регистре SYST_CSR. Когда вы записываете что либо в этот регистр, то значение этого регистра сбрасывается в 0. В описании этого регистра это и написано.
@NRelectronics
@NRelectronics 2 года назад
Может быть не любая запись сбрасывает в ноль, нужно смотреть состояние в Reset каждого регистра.
@namename2031
@namename2031 2 года назад
@@NRelectronics A write of any value clears the field to 0, and also clears the COUNTFLAG bit in the STK_CTRL register to 0. При старте счётчика, число из регистра LOAD загружается в регистр VAL. Для чего перед загрузкой из регистра LOAD регистр VAL обнуляют я не знаю.
@NRelectronics
@NRelectronics 2 года назад
Т.к. могут быть старые значения отличные от нулевых, т.е. мусор. Так всегда делают, это правильно.
@glebuchitel1577
@glebuchitel1577 2 года назад
Подскажите не могу понять, когда мы записываем в BS5, пин 5 выдает 1, и в следующей итерации цикла опять устанавливаем его. То же самое и с BR5. Они сами сбрасываются что ли?
@NRelectronics
@NRelectronics 2 года назад
BS5 - Bit Set 5 pin, BR5 - Bit Reset5 pin. Везде активное состояние это единичка.
@glebuchitel1577
@glebuchitel1577 2 года назад
@@NRelectronics нет я имею в виду что по всему видимому когда мы устанавливаем BS5, то BR5 сбрасывается и наоборот. Иначе они бы установились в BS5=1 и BR5=1 в первой итерации цикла и не менялись. Они сбрасываются программно либо аппаратно
@NRelectronics
@NRelectronics 2 года назад
Так и есть, с названия это и следует, я ведь расшифровал, Set - установка единицы, Reset - сброс состояния.
@glebuchitel1577
@glebuchitel1577 2 года назад
@@NRelectronics да не состояния, а значения этих регистров…
@user-kc8ec6vl9d
@user-kc8ec6vl9d Год назад
Все сделал как на видео. Но в SysTick_Handler() не попадаю. Висит в while(SysTick_CNT). Что может быть? В отладчике CVR - CURRENT крутятся значения, а в CSR - все флаги подняты(галочки стоят)
@NRelectronics
@NRelectronics Год назад
Проверьте код весь, ничего не пропустили. Код мой ведь рабочий.
@IlxlI
@IlxlI Год назад
Автор, поясните, почему Handler. Я не вижу нигде исполнения функции, это какой-то каллбэк?
@NRelectronics
@NRelectronics Год назад
Где именно? Я ролик не помню в деталях...
@IlxlI
@IlxlI Год назад
@@NRelectronics просто без функции SysTick_Handler ничего не работает, но ее ничто в коде и не вызывает. Выходит, handler придает какое-то значение?
@NRelectronics
@NRelectronics Год назад
Обработчик вызывается по прерыванию. Его не вызывают в коде программа.
@namename2031
@namename2031 2 года назад
17:51 Функция SysTick_Handler определена ведь уже где то выше. У меня в файле stm32f4xx_it.c И здесь 17:51 получаеттся повторное переопределение данной функции. Как такое возможно? У меня выдаёт ошибку.
@NRelectronics
@NRelectronics 2 года назад
Если повторное выдавал бы ошибку, у меня не выдаёт, норм.
@user-kc8ec6vl9d
@user-kc8ec6vl9d Год назад
Как это происходит? Частота падает до 71999(Hz) и делится на 1000(Ms). Или как?
@NRelectronics
@NRelectronics Год назад
Падает до 72000 и делится на 1000.
@sergeyvp
@sergeyvp 3 года назад
Очень хорошим делом вы занимаетесь, но зачем использовать функции типа delay() ? Конкретно в данном случае достаточно в основном цикле прописать условие проверки значения счётчика и выполнять нужный код в теле этого условия без прерывания. Либо выставить значение счётчика в нужный интервал и в прерывании выполнять необходимый код. Функции delay() делают код неэффективным.
@NRelectronics
@NRelectronics 3 года назад
Посыл этого видео системный таймер и работа с ним. А вот следующее видео как раз использование в подобных случаев таймера, об этом я в видео кстати говорил ;)
@sergeyvp
@sergeyvp 3 года назад
@@NRelectronics Я понял о чём видео. Но использование функций задержки это очень плохая практика программирования. Не стоит приучать к этому новичков.
@NRelectronics
@NRelectronics 3 года назад
А я и не приучаю. Знать тоже нужно как и что настраивается и работает...
@NRelectronics
@NRelectronics 3 года назад
К тому же systick полезен во FreeRTOS.
@sergeyvp
@sergeyvp 3 года назад
@@NRelectronics Новички которые смотрят ваши видео как раз приучаются. Вы же не сказали что так делать не нужно, что это просто демонстрация возможностей. Я использую контроллеры серии F0 и написал свою библиотеку для работы с регистрами, вот пример кода без функций задержек. Можно легко реализовать то же самое на CMSIS. #include "BS.h" int main(void) { _RCC->AHBENR.IOPAEN = ON; // тактирование соответствующего порта _GPIOA->MODER.Pin5 = OutputMOD; // режим вывода на соответствующем пине _SYSTICK->RVR.RELOAD = 800000; // значение счетчика _SYSTICK->CSR.ENABLE = ON; // включаем счетчик _SYSTICK->CVR.CURRENT = 0; // обнуляем текущее значение for(;;) // бесконечный цикл { if( _SYSTICK->CSR.COUNTFLAG) // проверяем переход счётчика через ноль { if( _GPIOA->OUTPUTR.Pin5) // если на выводе высокий уровень _GPIOA->RESETR.Pin5 = DROP; // включаем низкий уровень на выводе else // иначе _GPIOA->SETR.Pin5 = HIGH; // включаем высокий уровень _SYSTICK->CVR.CURRENT = 0; // обнуляем текущее значение счетчика и COUNTFLAG } } } А вот код с прерыанием. #include "BS.h" void SysTick_Handler( void) // Функция обрабатывает прерывание при переполнении системного таймера { if( _GPIOA->OUTPUTR.Pin5) // если на выводе высокий уровень _GPIOA->RESETR.Pin5 = DROP; // сбрасываем бит, включаем низкий уровень на выводе else // иначе _GPIOA->SETR.Pin5 = HIGH; // включаем высокий уровень } int main(void) { _RCC->AHBENR.IOPAEN = ON; // тактирование соответствующего порта _GPIOA->MODER.Pin5 = OutputMOD; // режим вывода на соответствующем пине _SYSTICK->RVR.RELOAD = 800000; // значение счетчика, интервал между прерываниями _SYSTICK->CSR.ENABLE = ON; // включаем счетчик _SYSTICK->CSR.TICKINT = ON; // включаем прерывание при переполнении _SYSTICK->CVR.CURRENT = 0; // обнуляем текущее значение for(;;); // бесконечный цикл }
@stm32Lab
@stm32Lab Год назад
Пишу функцию на SysTick для микросекунд. Загружаю значение в SysTick->LOAD = 3199, с расчётом что, если частота, 32 МГц, то за 100 микросекунд он дойдёт до нуля, далее проверяю, когда досчитает до 0 через: while (!(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk)). Но, судя по осциллограммам, таймер считает в 2 раза быстрее. Не понимаю, почему..
@NRelectronics
@NRelectronics Год назад
А тактирование мк при этом на 72МГц?
@stm32Lab
@stm32Lab Год назад
@@NRelectronics в том то и дело, что тактирование 32 МГц, ставлю кварц и умножитель на 4. Буду искать, понятно, что я что-то неправильно сделал.
@stm32Lab
@stm32Lab Год назад
@@NRelectronics нашёл баг, поделюсь. у меня написаны свои функции setSystemClock и т.д, на что я и надеялся. Но в system_stm32 я не отключил дефайны, и там повторно вызывалась готовая функция установки частоты на 72 по дефайну. С другой стороны, моя функция установки частоты шла после, уже в main. Но видимо из-за того, что я там у себя не сбрасывал регистры в reset state, так и оставалось 72 МГц..
@NRelectronics
@NRelectronics Год назад
Молодцы что разобрались. Я вас подтолкнул в нужную сторону ;)
@zeraphialchemy523
@zeraphialchemy523 Год назад
Не понял, а как это работает вообще? Принцип понятен, но обработчика прерываний, который будет запускать ваш хэндлер по завершению отсчета вы же не писали! Значит где-то в инклюдах должен быть обработчик, но у меня его похоже нет - контроллер другой. Добавлено: перепроверил еще раз, вектор нашел, ошибка в другом была.
@NRelectronics
@NRelectronics Год назад
Отлично, быстрей меня разобрались 😉👌
@Mozobretenie
@Mozobretenie 2 года назад
не работает, висит в вайле while(SysCnt) бесконечно
@NRelectronics
@NRelectronics 2 года назад
Сделайте строго по видео, код рабочий.
@namename2031
@namename2031 2 года назад
16:10 100/(10-1)==11.1111 Так правильно: (100/10)-1==9
@NRelectronics
@NRelectronics 2 года назад
Откуда это и к чему? Там 1000-1.
@namename2031
@namename2031 2 года назад
@@NRelectronics Это как пример, на других цифрах. SYSLOCK у вас == 72000000 72000000/(1000-1) 72000000/(999)==72 072,072072 А должно быть так: 72000000/1000-1==71 999
@NRelectronics
@NRelectronics 2 года назад
Теперь понятно что имели ввиду. Нет, тут не так как вы пишите. Если записать, как вы говорите, просто 1000, считаться будет как раз 1001, так как счёт начинается начинается с 0, поэтому его вычитают - (1000-1). Математически это получается не верно, а по логике счета именно так.
@namename2031
@namename2031 2 года назад
@@NRelectronics Допустим надо остчитать 10. Для этого в регистр надо положить число 9, потому что считается от 9 до нуля. 0,1,2,3,4,5,6,7,8,9 Давайте пока что без деления. Если надо посчитать 72 000 000, то в регистр надо положить 72 000 000-1== 71 999 999 Теперь с делением: Надо посчитать от числа, которое в 1000 раз меньше чем 72 000 000 до нуля: 72 000 000/1000==72 000 72 000-1==71 999 Это неправильно:72 000 000/(1000-1)==72 072,072
@NRelectronics
@NRelectronics 2 года назад
Так вы сами пишите 0,1,2,3,4,5,6,7,8,9 - сколько счета? А 10 же! Но записываем как (10-1) 😉
@namename2031
@namename2031 2 года назад
Функция delay_mS работает только потому что SysTick_CNT уменьшается раз в (я не знаю какая частота SYSCLK у Вас) за счёт прерываний. В функции delay_mS регистр VAL обнуляется, думаю что даже в цикл while не заходит, потому что регистр VAL сбросился и из за этого происходит прерывание. После чего уменьшается SysTick_CNT
@NRelectronics
@NRelectronics 2 года назад
Это утверждение или вопрос?) Что работает опять неправильно? 😁
@namename2031
@namename2031 2 года назад
@@NRelectronics Я разбираюсь пока что)) Мутное дело. Слежу за регистрами.
@NRelectronics
@NRelectronics 2 года назад
А, 🆗
@namename2031
@namename2031 2 года назад
@@NRelectronics Мне кажется это просто неудачное описание регистра VAL. При записи чего либо в данный регистр, обнуляется остчёт и в регистр VAL опять загружается число из регистра LOAD. То есть если например VAL досчитал от 100 до 50 и в него загрузить что нибудь, то в регистр VAL опять запишется число 100 и по новому начнёт считать до нуля. А бит COUNTFLAG регистра CTRL действительно сбрасывается в 0 если что либо записать в регистр VAL. Бит COUNTFLAG регистра CTRL обнуляется в двух случаях, первый описал, а второй случай это если прочитать бит COUNTFLAG. Здесь Вы 2 раза обнулили отсчёт в регистре VAL. SysTick->VAL &= ~SysTick_VAL_CURRENT_Msk; SysTick->VAL = SYSLOCK/1000-1; Это утверждение)
@NRelectronics
@NRelectronics 2 года назад
Я как освобожусь, доберусь до сорцов и всё посмотрю. Спасибо.
Далее
🎤Пою РЕТРО Песни ✧˖°
3:04:48
Просмотров 1,7 млн
🎤Пою РЕТРО Песни ✧˖°
3:04:48
Просмотров 1,7 млн