Jump to content
supercelt

STM32. Таймер отстаёт от реального времени

Recommended Posts

Posted (edited)

Добрый вечер!

У меня есть 2 вопроса, которые я хочу задать в одной теме. Потому что один вытекает из другого.

1. У меня есть самодельная отладка с stm32f405. Кварцы установлены на 32,768 кгц для часов и 8 мгц для тактирования МК. Лежала на полке где-то пол года. Тут решил достать, подключил. И как видно из видео, отсчёт секунд на дисплее отстает от красного светодиода. Светодиод горит ровно 1 сек и гаснет на 1 сек. Он подвязан в прерывании RTC. А отсчёт времени на дисплее сделан на TIM12. Пол года назад что самое интересное, работало все синхронно. Что поменялось: я переустановил винду и поставил новый Keil. Уточню: длительность между отсчётами на дисплее больше одной сек, хотя таймер настроен на 1 сек. Может в настройках что не так?

Вопрос 2. Таймер отсчитывает 1000 тиков, то есть каждую сек уходит в прерывание. Помогите настроить таймер12, что бы он считал до 20 сек и выдал прерывание И попутно еще каждую секунду давал тоже прерывание. То есть первое - по достижении числа в ARR. А ежесекундное - наверное как то по регистру сравнения.

589bde86e6f9.jpg

Мой код:

uint8_t load_sec_flag = 0;
void gsm_ini(void){
RCC->APB1ENR |= RCC_APB1ENR_TIM12EN;	//Включаем тактирование TIM12
	TIM12->CR1 &= ~TIM_CR1_CEN;		    //На всякий случай принудительно останавливаем таймер, если он был включён
	TIM12->CNT = 0;						//Обнуляем счётный регистр тамера
	TIM12->PSC |= (24000000/1000) - 1; //F = 1 kHz);//Задаём частоту таймера = 1000 Hz.
	TIM12->EGR |= TIM_EGR_UG;			//Повторно инициализирует счетчик и генерирует обновление регистров
	TIM12->ARR = 1000;				//Прерывания будут срабатывать каждую секунду
	TIM12->DIER |= TIM_DIER_UIE;
	NVIC_EnableIRQ(TIM8_BRK_TIM12_IRQn);
	__NOP();
	__NOP();
	TIM12->SR &= ~(TIM_SR_UIF);	
}
void gsm_handler(void){	
  	char buffer_timer[3] = "";
	static uint8_t load_timer = 0;
    if(load_sec_flag){
		load_sec_flag = 0;
		sprintf(buffer_timer,"%02d",load_timer); 
		lcd_send_string_xy(0, 1, buffer_timer);
		if(load_timer < 20){
			load_timer++;
		}else{
			
		}
	}
}
void TIM8_BRK_TIM12_IRQHandler(void){
	if(TIM12->SR & TIM_SR_UIF){
		TIM12->SR &= ~TIM_SR_UIF;
		load_sec_flag = 1;
	}
}

 

Edited by supercelt

Share this post


Link to post
Share on other sites
10 минут назад, supercelt сказал:

длительность между отсчётами на дисплее больше одной сек, хотя таймер настроен на 1 сек.

А камень на какой частоте запущен?

 

11 минут назад, supercelt сказал:

Может в настройках что не так?

Код у вас перед глазами.

 

11 минут назад, supercelt сказал:

считал до 20 сек и выдал прерывание И попутно еще каждую секунду давал тоже прерывание.

Такого не бывает. Либо каждую секунду, либо каждые 20 секунд. Либо делать в таймере счетчик, что логично, либо использовать два таймера.

Share this post


Link to post
Share on other sites
Posted (edited)
Цитата

А камень на какой частоте запущен?

В файле stm32f4xx.h прописано:

  #define HSE_VALUE    ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */

 в файле system_stm32f4xx.c


#include "stm32f4xx.h"

#if !defined  (HSE_VALUE) 
  #define HSE_VALUE    ((uint32_t)25000000) /*!< Default value of the External oscillator in Hz */
#endif /* HSE_VALUE */

#if !defined  (HSI_VALUE)
  #define HSI_VALUE    ((uint32_t)16000000) /*!< Value of the Internal oscillator in Hz*/
#endif /* HSI_VALUE */

uint32_t SystemCoreClock = 16000000;

 

Edited by supercelt

Share this post


Link to post
Share on other sites

Вебинар «Решения Microchip и сервисы Microsoft для интернета вещей. Подключение устройств IoT к облачным сервисам Azure» (15.07.2021)

Приглашаем всех желающих 15 июля 2021 г. принять участие в бесплатном вебинаре, посвященном решениям Microchip и сервисам Microsoft для интернета вещей. На вебинаре будут рассмотрены наиболее перспективные решения Microchip, являющиеся своеобразными «кирпичиками» – готовыми узлами, из которых можно быстро собрать конечное устройство интернета вещей на базе микроконтроллеров и микропроцессоров производства Microchip. Особое внимание на вебинаре будет уделено облачным сервисам Microsoft для IoT.
Подробнее

Всё смешалось - люди, кони...
Вас спрашивают - на какой частоте работает камень реально, а не то что у вас там понаписано. В одном месте 8МГц, в другом 25, в третьем 16.
При этом, при запуске таймера вы делите 24Мгц на 1000.

Share this post


Link to post
Share on other sites

Вебинар «Работа с графическими возможностями новой линейки STM32H7» (07.07.2021)

Приглашаем 07/07/2021 всех желающих принять участие в вебинаре, посвященном работе с графической библиотекой TouchGFX и новой линейке высокопроизводительных микроконтроллеров STM32H7A/B производства STMicroelectronics. На вебинаре будут разобраны ключевые преимущества линейки STM32H7A/B, а также показан пример создания проекта с помощью среды TouchGFX Designer и методы взаимодействия этой программы с экосистемой STM32Cube.

Подробнее

14 часов назад, supercelt сказал:

В файле stm32f4xx.h прописано:


  #define HSE_VALUE    ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */

 в файле system_stm32f4xx.c

И какое отношение это имеет к частоте камня? Где настойка PLL?

Share this post


Link to post
Share on other sites

LDH-25/65 – новые серии повышающих DC/DC LED-драйверов от Mean Well

Компания Mean Well расширила семейство популярных повышающих DC/DC LED-драйверов LDH двумя новыми сериями меньшей и большей мощности – LDH-25 и LDH-65, соответственно. Новые серии, обладая высоким КПД, применимы для изготовления экономичных светодиодных светильников с питанием от автономных источников тока, в том числе – на транспорте. Конструктивно драйверы выпускаются в двух различных вариантах.
Подробнее

Точносчть от тактирования.У вас настроен скорей всего на HSI(внутренне тактирование.А оно не стабильно.Спецы могут мне ещё один минус поставить.И  мне кажется я не берусь говорить что я прав но TIM2->PSC =0 ; //  TIM2->ARR=24000-1 ; при частоте тактирования 24 000 000 Гц . раняется 1 кГц

Share this post


Link to post
Share on other sites

Спасибо всем, что настроили на правильные мысли

#define PLL_M 4
#define PLL_N 168
#define PLL_P 2
#define PLL_Q 7
  
  void System_init(void){
  #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
    SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));  /* set CP10 and CP11 Full Access */
  #endif
	RCC->CR|= RCC_CR_HSEON;
	while (!(RCC->CR &RCC_CR_HSERDY)){};
	RCC->CFGR |=	RCC_CFGR_HPRE_DIV1 | RCC_CFGR_PPRE2_DIV2 |RCC_CFGR_PPRE1_DIV4;
	RCC->PLLCFGR = PLL_M|(PLL_N<<6)|(((PLL_P>>1)-1)<<16)|RCC_PLLCFGR_PLLSRC_HSE|(PLL_Q<<24);
	RCC->CR |= RCC_CR_PLLON;
	while (!(RCC->CR &RCC_CR_PLLRDY)){};
  FLASH->ACR|=FLASH_ACR_ICEN | FLASH_ACR_DCEN | FLASH_ACR_LATENCY_5WS | FLASH_ACR_PRFTEN;
	RCC->CFGR &= ~RCC_CFGR_SW;
  RCC->CFGR |= RCC_CFGR_SW_PLL;
  while (!(RCC->CFGR & RCC_CFGR_SWS ) ){};
}

RCC->APB1ENR |= RCC_APB1ENR_TIM12EN;																																		//Включаем тактирование TIM12
	TIM12->CR1 &= ~TIM_CR1_CEN;																																											//На всякий случай принудительно останавливаем таймер, если он был включён
	TIM12->CNT = 0;																																																							//Обнуляем счётный регистр тамера
	TIM12->PSC |= 42000 - 1; //F = 2 kHz);														//Задаём частоту таймера = 1000 Hz. (24000000/1000) - 1; (за 1 сек таймер тикает 2000 раз, т.е. с частотой 2 KHz)
	TIM12->EGR |= TIM_EGR_UG;																																													//Повторно инициализирует счетчик и генерирует обновление регистров
	TIM12->ARR = 2000;																																																//Прерывания будут срабатывать каждую секунду
	TIM12->DIER |= TIM_DIER_UIE;
	NVIC_EnableIRQ(TIM8_BRK_TIM12_IRQn);
	__NOP();
	__NOP();
	TIM12->SR &= ~(TIM_SR_UIF);

 

Share this post


Link to post
Share on other sites
1 час назад, Ivan Rusev сказал:

но TIM2->PSC =0 ; //  TIM2->ARR=24000-1

Разницы никакой. Что тактовую поделить и считать до 1000, что считать на большой тактовой и не до 1000.

Share this post


Link to post
Share on other sites
51 минуту назад, supercelt сказал:

__NOP(); __NOP();

А зачем это?

58 минут назад, supercelt сказал:

TIM12->CR1 &= ~TIM_CR1_CEN

Бит отключён.Таймер  нужно включить.Сначало настроить потом включить.

TIM12->SR &= ~(TIM_SR_UIF);Этот бит мне кажется в прерываниях устанавливается и сбрасываеться.

 

Share this post


Link to post
Share on other sites
1 час назад, Ivan Rusev сказал:

А зачем это?

Где-тона сайте прочитал что не помешает. Типа от залипания

1 час назад, Ivan Rusev сказал:

Бит отключён.Таймер  нужно включить.Сначало настроить потом включить.

Так я его настроил и мне не надо пока его запускать, а только в определённый момент

Share this post


Link to post
Share on other sites
6 часов назад, supercelt сказал:

Где-тона сайте прочитал что не помешает. Типа от залипания

Так я его настроил и мне не надо пока его запускать, а только в определённый момент

Залипания чего контакта?

Share this post


Link to post
Share on other sites
9 часов назад, supercelt сказал:

Где-тона сайте прочитал что не помешает

А надо было в даташите.

 

9 часов назад, supercelt сказал:

Типа от залипания

Залипает тут только мозг того, кто это написал. И смысл сбрасывать TIM_SR_UIF, когда он выставляется только при наличии события?

RCC->APB1ENR        |=  RCC_APB1ENR_TIM2EN;    //подаем тактирование TIM7

TIM2->PSC = 60000;         //настроить делитель для формирования миллисекунд
TIM2->ARR = 1000; // 500 mS
TIM2->DIER |= TIM_DIER_UIE;   //разрешить событие от таймера
TIM2->CR1 |= TIM_CR1_CEN;     //разрешить перезагрузку и включить таймер

NVIC_EnableIRQ(TIM2_IRQn);

Вот вся настройка.

Share this post


Link to post
Share on other sites

BARS_ - ну вот зачем спешил? Твой готовый кусок кода - очередная причина отложить изучение доков. А между прочим эти два гаврика двигались в нужном направлении, и даже каким-то мистическим образом понимали друг друга.

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

Share this post


Link to post
Share on other sites
3 часа назад, AVI-crak Home сказал:

BARS_ - ну вот зачем спешил? Твой готовый кусок кода - очередная причина отложить изучение доков. А между прочим эти два гаврика двигались в нужном направлении, и даже каким-то мистическим образом понимали друг друга.

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

CC->APB1ENR |= RCC_APB1ENR_TIM2EN; //подаем тактирование TIM7 TIM2->PSC = 60000; //настроить делитель для формирования миллисекунд TIM2->ARR = 1000; // 500 mS TIM2->DIER |= TIM_DIER_UIE; //разрешить событие от таймера TIM2->CR1 |= TIM_CR1_CEN; //разрешить перезагрузку и включить таймер NVIC_EnableIRQ(TIM2_IRQn);

Это вы мне?Эсли вы посмотрите мой код от этого ничем не отличается.Тактирование настроенно не по примерам.А методом тыка.Примеры толлько на F1 серии есть.

Куда нам до вас .Вы доценты.А мы абитуриенты.Всё что написано мной.Немного отличается от вашего.Простинько и понятно.Может 1 или 2 бита лишних.Но то что я смотрел и у вас и в нете страх и ужас.Человек может не понял.Что програмированние(самообучение)методом проб  и ошибок.Вам вобщето спасибо.Я тежело но двигаюсь к своей цели.Проект самодельный частотник.

Share this post


Link to post
Share on other sites
12 часов назад, BARS_ сказал:

А надо было в даташите.

Даташит на английском)))

Share this post


Link to post
Share on other sites
2 часа назад, Ivan Rusev сказал:

Это вы мне?Эсли вы посмотрите мой код от этого ничем не отличается.Тактирование настроенно не по примерам.А методом тыка.

Не могу смотреть, обезболивающее закончилось. Обычно метод тыка требует многократно большее время, чем чтение документации. Но вот конкретно с тактированием это время можно значительно сократить - достаточно скачать куб от st, и таки выбрать именно свой мк, чтобы все буквы и цифры совпадали. Вот там можно использовать метод тыка, куб именно для этого и предназначен. Когда у вас будет набор всех магических чисел - пора изучать доку. Для stm32f4 - это буквально несколько регистров. Изучать - потому как магические числа из кубика не всегда совпадают с тем что нужно ввести в поля регистров. А вот то что там нужно и можно вводить - очень подробно описано.

Ну и главное, основной макрос _VAL2FLD(имя поля, значение поля) - вам уже известен, осталось научиться его применять.

Share this post


Link to post
Share on other sites
6 часов назад, AVI-crak Home сказал:

Ну и главное, основной макрос _VAL2FLD(имя поля, значение поля) - вам уже известен, осталось научиться его применять.

Этот макрос ни везде работает.Даже в тактировании.Я много чего не знаю.Вот по этому спрашиваю.RM читаю с переводом.Сей час иногда фразы понимаю без перевода.

Share this post


Link to post
Share on other sites
14 часов назад, Ivan Rusev сказал:

Тактирование настроенно не по примерам.А методом тыка.Примеры толлько на F1 серии есть.

Примеры на все серии есть. И есть даташит. Например http://w.qwes.org/art/?src=stm32f2xx_taktirovaniye У 2/3/4 серии настройки одинаковые. Надо только латентность флеша в даташите смотреть. Множители/делители куб покажет.

 

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

на английском)))

О ужас. Там ведь художественный текст и перевести его невероятно трудно.

Share this post


Link to post
Share on other sites
6 часов назад, Ivan Rusev сказал:

Сей час иногда фразы понимаю без перевода.

А я вот не понимаю, и не собираюсь понимать - вместо этого использую переводчик встроенный в хром. У меня нет яндекса, спутника, ускорителя интернета, 100500 баров на экране, и прочей фигни. Есть хром, со панелью закладок. А в самом хроме - 2-4 открытых страницы. 

Share this post


Link to post
Share on other sites
7 минут назад, AVI-crak Home сказал:

вместо этого использую переводчик встроенный в хром

Глупый подход, очень глупый. Во-первых, это медленно, во-вторых, перед безумно кривой. Это я уже не говорю о том, что читать pdf из браузера не сильно удобно в принципе. Да и хром гамно редкостное. Если уж такое отвращение к английскому, то есть тот же QTranslate, который переводит любой выделенный текст в любом документе.

Share this post


Link to post
Share on other sites
33 минуты назад, BARS_ сказал:

перед безумно кривой

Перевод всегда будет безумно кривым, потому как нет бесплатных трансляторов технического английского. Платные есть, почти на все языки, но платные. Правильный корректный перевод мало поможет пользователю, если он не умеет читать и вчитываться. Потому как отличие технического от литературного - в дословности и последовательности. В техническом нельзя игнорировать часть текста, там просто нет воды!!!

Вот, а теперь открываем яндекс - обилие совершенно бесполезной информации на весь экран. Начинаем поиск - обилие бесполезных ссылок. При работе с яндексом нужен совершенно иной скил - игнорирование бесполезной части информации. Два разных скила, с полностью противоположным действием - не дадут положительного эффекта. Нужно прокачивать что-то одно.

Share this post


Link to post
Share on other sites
1 час назад, AVI-crak Home сказал:

Перевод всегда будет безумно кривым, потому как нет бесплатных трансляторов технического английского.

Поэтому и надо учиться переводить самому.

 

1 час назад, AVI-crak Home сказал:

а теперь открываем яндекс

А при чем тут яндекс? Это про их браузер? Это ж тот же хром, только с мусором от яндекса. Виндовый EDGE и то лучше работает. А что мешает использовать ту же оперу? Да и в принципе не читать pdf через браузер? Скачал, открыл в pdf ридере хоть десяток документов и спокойно работаешь. И желательно чтобы это был не адоб, а хотя бы та же sumatra. Работает на порядок шустрее. Но что-то мы ушли от темы автора....

Share this post


Link to post
Share on other sites

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...

×
×
  • Create New...