середу, 12 жовтня 2016 р.

Таймери STM32 -- remapping/CMSIS

Мультиплексор. Зображення взято тут.
STM32 надають певну гнучкість у тому, які піни прив'язані до яких функцій -- так-званий remapping (перепризначення). STM32CubeMX автоматично користується цією можливістю під час візуального редагування конфігурації. Для кращого розуміння, спробуємо зробити це ж вручну, на рівні CMSIS.

Що це за можливість і де шукати інформацію про неї, вже описувалася в попередньому пості: "Таймери STM32 -- огляд", то я просто зацитую:

Контролер підтримує перепризначення, remapping-гу, пінів -- в залежності від потреб, існує кілька фіксованих комбінацій відповідності пінів "функціям" таймерів. Тобто, можна зробити, щоб TIM2_CH1 був під'єднаний до PB3, але при цьому, TIM2_CH1_ETR перейде з PA0 до PA15. Комбінацій небагато і вони фіксовані, але навіть такий обмежений ремапінг сильно спрощує розробку схем.
Щодо документації, то знайти відповідну інформацію -- задача нетривіальна. Зокрема, описана вона не там, де мова про таймери, а:

Почнемо із прикладу "Таймери STM32 -- ШІМ/CMSIS", де за допомогою каналу CH2 таймера TIM3, генерувався ШІМ, змінюючи яскравість світлодіодна. TIM3_CH2 під'єднано до піна PA7. Припустимо, нас це не влаштовує і спробуємо знайти альтернативи. Візьмемо табличку для TIM3 (нагадаю, що приклади цієї серії -- для STM32F100):

Як видно, є два варіанти ремапінгу -- на пін PB5 чи на PC7. Зауважте, при тому буде перепризначено й інші канали -- немає можливості перепризначити лише один канал.

За ремаппінг (перепризначення) в STM32F100 відповідають два регістри, AFIO_MAPR і AFIO_MAPR2:

Регістр AFIO_MAPR STM32F100

Регістр AFIO_MAPR2 STM32F100.
За TIM3 відповідають біти TIM3_REMAP регістра AFIO_MAPR:
Код налаштування таймера не змінився -- див. відповідний пост, змінилося лише налаштування пінів порту. 

Отож, режим по замовчуванню:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
 RCC->APB2ENR  |= RCC_APB2ENR_IOPAEN; // Дозволяємо тактування порту A

 GPIOA->CRL &= ~GPIO_CRL_CNF7_0; // 10 -- AF PP (Alternative function -- push-pull)
 GPIOA->CRL |=  GPIO_CRL_CNF7_1;
 GPIOA->CRL  |=  GPIO_CRL_MODE7; //Встановити обидва біти MODE для піна 1 -- швидкість 50MHz

 // Значення по замовчуванню -- 0, NOREMAP нас влаштують.
 // Встановити його можна так:
 AFIO->MAPR   &=~AFIO_MAPR_TIM3_REMAP;
 // Формально треба так, але так як AFIO_MAPR_TIM3_REMAP_NOREMAP == 0,
 // воно нічого не змінить:
 // AFIO->MAPR   &=~AFIO_MAPR_TIM3_REMAP;
 // AFIO->MAPR   |= AFIO_MAPR_TIM3_REMAP_NORE

Рядок 9 показує, як до нього (режиму по замовчуванню) можна повернутися.

Зараз плавно загоратиметься світлодіод, під'єднаний до піна PA7.

Частковий ремапінг:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
 RCC->APB2ENR  |= RCC_APB2ENR_IOPBEN; // Дозволяємо тактування порту B
 RCC->APB2ENR  |= RCC_APB2Periph_AFIO; // Дозволяємо альтернативні ф-ції,
           // без цього remapping не працює
 AFIO->MAPR   &=~AFIO_MAPR_TIM3_REMAP;// Зануляємо. По замовчуванню і так буде нуль,
           // але для порядку і з педагогічних міркувань...
 AFIO->MAPR   |= AFIO_MAPR_TIM3_REMAP_PARTIALREMAP;

 GPIOB->CRL &= ~GPIO_CRL_CNF5_0; // 10 -- AF PP (Alternative function -- push-pull)
 GPIOB->CRL |=  GPIO_CRL_CNF5_1;
 GPIOB->CRL  |=  GPIO_CRL_MODE5; //Встановити обидва біти MODE для піна 1 -- швидкість 50MHz

Зауважте, без тактування блоку альтернативних функцій ремапінг не працює! Також доводиться налаштовувати інший порт.

Тепер працюватиме світлодіод на піні PB5, а той, що на PA7 -- не світитиметься.

Нарешті, повний ремапінг:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
 RCC->APB2ENR  |= RCC_APB2ENR_IOPCEN; // Дозволяємо тактування порту C

 RCC->APB2ENR  |= RCC_APB2Periph_AFIO; // Дозволяємо альтернативні ф-ції,
           // без цього remapping не працює
 AFIO->MAPR   &=~AFIO_MAPR_TIM3_REMAP;// Зануляємо. По замовчуванню і так буде нуль,
           // але для порядку і з педагогічних міркувань...
 AFIO->MAPR   |= AFIO_MAPR_TIM3_REMAP_FULLREMAP;

 GPIOC->CRL &= ~GPIO_CRL_CNF7_0; // 10 -- AF PP (Alternative function -- push-pull)
 GPIOC->CRL |=  GPIO_CRL_CNF7_1;
 GPIOC->CRL  |=  GPIO_CRL_MODE7; //Встановити обидва біти MODE для піна 1 -- швидкість 50MHz

В такій конфігурації працюватиме світлодіод, під'єднаний до PC7.

Нотатка щодо STM32F303

Для сімейства STM32F3 підсистема GPIO була реорганізована -- зокрема, змінилися імена регістрів. Детальніше про це, можливо, іншим разом, а зараз глянемо, як у них організований ремапінг. (Де шукати відповідну інформацію в документації -- див. цитату вище.)

За перепризначення відповідають регістри GPIOx_AFRL ("нижні" піни 0-7) та GPIOx_AFRH ("верхні" піни 8-15):
Регістра GPIOx_AFRL сімейства STM32F303
Регістра GPIOx_AFRH сімейства STM32F303

Для кожного піна поле AFRy містить номер альтернативної функції:

Номери альтернативних функцій для GPIOx_AFRL, такі ж вони для GPIOx_AFRH.
Тепер доведеться, на жаль, прочісувати таблиці "Alternate functions for port X" із документу на конкретний мікроконтролер (див. цитату на початку). Наприклад, знайдемо варіанти для TIM3_CH2:





Тобто, бути піном, керованим каналом CH2 таймера TIM3, можуть піни PA4, PA7, PB5, PC7 i PE3. Для всіх них це є альтернативна функція номер два -- AF2.
Зауваження: для більшої читабельності, зображення обрізані, але подивившись на оригінал, можна побачити, що порти A i B використовують до 16 альтернативних функцій, а решту -- до восьми. (Насправді, навіть на обрізаному це видно із масштабу стовпців :-).
Чому так зробили із керування перепризначення -- можна запідозрити. Але отак сходу -- працювати стало важче. Правда, якщо користуватися STM32Cube -- проблем немає. 


Проект можна скачати тут. Вибір ремапінгу здійснюється макросом REMAP_LEVEL:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
//! REMAP_LEVEL = 0 --- no remap, TIM3_CH2 -> PA7
//! REMAP_LEVEL = 1 --- partial remap, TIM3_CH2 - > PB5
//! REMAP_LEVEL = 2 --- full remap, TIM3_CH2 - > PC7

#define REMAP_LEVEL 0
#if REMAP_LEVEL == 0
// .................
#elif REMAP_LEVEL == 1
// .................
#elif REMAP_LEVEL == 2
// .................
#endif

Як вже згадувалося, для Cube + HAL повторювати сенсу немає -- все буде зроблено автоматично.


Немає коментарів:

Дописати коментар