STM32CubeIDE (вопросы и ответы)

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

1 лайк

Вот пример как в кубе инициализировать енкодер. Можно и без библиотек обойтись.

2 лайка

Ну то есть на счетный вход эту, «тактовую».

Это как подсчёт организуешь. Можно количество импульсов на такт, можно количество тактов на импульс. Есть возможность иметь input capture при установленном внешнем тактировании.

1 лайк

а что такое “внешнее тактирование”? Кто кого куда “тактирует”? ахаха.
У таймера есть счетный вход, старт-стоп-сброс и тп прочие внешние примочки (капчуюре-компаре- рег перезагрузки…), и все их можно ээээ “тактировать”!

Берёшь из мануала диграмму на

и смотришь где на рисунке есть такт и как он соотносится с

Спасибо, понадобится ещё - посмотрю. Что мне надо было из таймеров СТМ32 я получил, а именно:

  1. точный генератор с периодом с дискретностью в 15-16 бит, несмотря на величину периода, за счет прескайлеров
  2. Часы с малой погрешностью за счет термоподстройки по термо внутри СТМ32. Погрешность порядка 3сек/мес - 1сек/год. Последнее конечно больше прикол и случайность, но всё равно прикольно. Причем замер было за ГОД.
  3. Частотомер/измеритель периода я делаю просто на завтрак.

Генератор с дискретностью периода в 32 бита было бы классно поиметь на СТМ32. Глядя на красивые картинки кажется что мы уже тут! а как до реальности то хрен. Если кто это решит я буду должен. Не то что я без этого жить не могу, но я долго бился рогами в эту дверь. Выглядело что вот-воот. А нифига ахахаа.

Дык есть же PWM c 32 битными регистрами.
Или я не то понял? - можно картинку/описание с требуемой задачей?

PWM не нужен, нужен просто период, который можно подстраивать с дискретностью в 1/32бита

Период = NN+ 1/( 2\32±1ед)

То есть юзать счетчик/компаре в 32 бита, и его подстраивать по мл. биту.
(сорри за косноязычие)

хмм, и что, там есть PWM с дискретностью в 1 на 32 бита?.. чет я такого там не видел, любопытно.

Че то у меня или с терминологией или с пониманием :thinking:

Итак: берем для примера STM32F411
TIM2 TIM5 есть 32х разрядные.
.
TIMx auto-reload register (TIMx_ARR)
Address offset: 0x2C
Reset value: 0xFFFF FFFF (for 32-bits timer)

CCR1[31:16]: High Capture/Compare 1 value (on TIM2 and TIM5)

т е мы можем сделать период счетчика (по факту длину полупериода/полуволны) с точностью до 32х бит.
Аналогично для PWM мы можем сделать сделать скважность с точностью 32 бит.

Так?

ааа. Это- ДРУГОЕ™. Я про дешевые варианты СТМ32, которые блюпил типа. Те я не смотрел пока.

Ну а блакпил? Он же почти как блюпил по цене и с stm32f401 и у него есть 2 32 битных таймера. 195 руб https://aliexpress.ru/item/1005007187824302.html

1 лайк

CUBE IDE 1.17
CUBE MX 6.13
CUBE PROGRAMMER 2.18
CUBE MONITOR 1.9
MCU FINDER 6.1
STLINK UTILITY 4.6

1 лайк

А зачем MX отдельно нужен, он же в IDE встроен?

Я ИДЕ не пользую. Вот для таких случаев.

Логично. Сам дурак, мог бы и догадаться. (

Скажите, пожалуйста, кто какую библиотеку использует для эмуляции EEPROM во флэш?
И какую для физической I2C-EEPROM (у меня AT24C08 закуплены) можете порекомендовать?

Написать самостоятельно не предлагать?

Спойлер
/*
 * f103flash.h
 *
 *  Created on: 28 февр. 2023 г.
 *      Author: Andrey
 */

#ifndef F103FLASH_H_
#define F103FLASH_H_

#define NVIC_VectTab_FLASH		((unsigned long)0x08000000) // начало флэша
#define FLASH_PAGE_SIZE			((unsigned long)128) // CHF32F103C8T6 -> 128 // размер одной страницы // размер страницы памяти для большинства МК серии STM32F103 составляет 1Kb, за исключением микроконтроллеров линейки HD и CL (Connectivity Line), в которых она равна двум килобайтам
#define NUM_PAGE_EEPROM_BEGIN	((unsigned long)256) // с какой страницы памяти будем писать свои данные // 256*128=0x8000->0x8008000
#define FIRMWARE_PAGE_OFFSET 	((unsigned long)NUM_PAGE_EEPROM_BEGIN*FLASH_PAGE_SIZE) // смещение в байтах, с которого будем писать свои данные

void FLASH_fill_page(unsigned long Value);
void FLASH_write_param(unsigned short numParam, unsigned long paramValue);
unsigned long FLASH_read_param(unsigned short numParam);

#endif /* F103FLASH_H_ */
Спойлер
/*
 * f103flash.c
 *
 *  Created on: 28 февр. 2023 г.
 *      Author: Andrey
 */

#include "stm32f10x.h"
#include "f103flash.h"

/*https://smartmode.info/stm32/13-stm32-flash*/
/*https://easystm32.ru/for-beginners/38-flash-stm32/*/
/*http://we.easyelectronics.ru/STM32/programmirovanie-flash.html?ysclid=leo3iva1x048263658*/

unsigned long FLASH_read(unsigned long address) {
	return (*(__IO unsigned long*) address);
}

#define FLASH_KEY1 ((unsigned long)0x45670123)
#define FLASH_KEY2 ((unsigned long)0xCDEF89AB)

void FLASH_Unlock(void) {
	  FLASH->KEYR = FLASH_KEY1;
	  FLASH->KEYR = FLASH_KEY2;
}

void FLASH_Lock() {
	FLASH->CR |= FLASH_CR_LOCK;
}

void FLASH_ErasePage(unsigned long inAdr) {
	  FLASH->CR |= FLASH_CR_PER; //Устанавливаем бит стирания одной страницы
	  FLASH->AR = inAdr; // Задаем её адрес
	  FLASH->CR |= FLASH_CR_STRT; // Запускаем стирание
	  while ((FLASH->SR & FLASH_SR_BSY) != 0 ); // Wait end of eraze
	  FLASH->CR &= ~FLASH_CR_PER; //Сбрасываем бит обратно
}

void FLASH_fill_page(unsigned long Value) {
	unsigned long pageAdr = NVIC_VectTab_FLASH + FIRMWARE_PAGE_OFFSET;                    // Адрес страницы памяти
	FLASH_Unlock();                                                         // Разблокируем память для записи
	FLASH_ErasePage(pageAdr);                                               // Очистим страницу памяти
	FLASH->CR |= FLASH_CR_PG; //Разрешаем программирование флеша
	for(unsigned short i = 0; i < (FLASH_PAGE_SIZE/4); ++i) {
		unsigned long inValue = Value;
		  while ((FLASH->SR & FLASH_SR_BSY) != 0 );
		  *(__IO uint16_t*)pageAdr = (uint16_t)inValue; //Пишем младшие 2 бата
		  while ((FLASH->SR & FLASH_SR_BSY) != 0 );
		  pageAdr += 2;
		  inValue>>=16;
		  *(__IO uint16_t*)pageAdr = (uint16_t)inValue; //Пишем старшие 2 байта
		  while ((FLASH->SR & FLASH_SR_BSY) != 0 );
		  pageAdr += 2;
	}
	FLASH->CR &= ~FLASH_CR_PG; //Запрещаем программирование флеша
	FLASH_Lock();
}

void FLASH_write_param(unsigned short numParam, unsigned long paramValue) {
	unsigned long pageAdr = NVIC_VectTab_FLASH + FIRMWARE_PAGE_OFFSET; // Адрес страницы памяти
	numParam %= FLASH_PAGE_SIZE/4; // номер параметра не может превысить число 4х байтовых слов в странице
	unsigned long dataPage[FLASH_PAGE_SIZE/4]; // место куда сохраним текущую страницу
	for(unsigned short i = 0; i < (FLASH_PAGE_SIZE/4); ++i) dataPage[i] = FLASH_read(pageAdr + i * 4);
	dataPage[numParam] = paramValue;
	FLASH_Unlock();                                                         // Разблокируем память для записи
	FLASH_ErasePage(pageAdr);                                               // Очистим страницу памяти
	FLASH->CR |= FLASH_CR_PG; //Разрешаем программирование флеша
	for(unsigned short i = 0; i < (FLASH_PAGE_SIZE/4); ++i) {
		unsigned long inValue = dataPage[i];
		  while ((FLASH->SR & FLASH_SR_BSY) != 0 );
		  *(__IO uint16_t*)pageAdr = (uint16_t)inValue; //Пишем младшие 2 бата
		  while ((FLASH->SR & FLASH_SR_BSY) != 0 );
		  pageAdr += 2;
		  inValue>>=16;
		  *(__IO uint16_t*)pageAdr = (uint16_t)inValue; //Пишем старшие 2 байта
		  while ((FLASH->SR & FLASH_SR_BSY) != 0 );
		  pageAdr += 2;
	}
	FLASH->CR &= ~FLASH_CR_PG; //Запрещаем программирование флеша
	FLASH_Lock();
}

unsigned long FLASH_read_param(unsigned short numParam) {
	unsigned long pageAdr = NVIC_VectTab_FLASH + FIRMWARE_PAGE_OFFSET; // Адрес страницы памяти
	numParam %= FLASH_PAGE_SIZE/4; // номер параметра не может превысить число 4х байтовых слов в странице
	return FLASH_read(pageAdr + numParam * 4);
}