Второй частью блока сброса и генерации тактового сигнала, является собственно блок генерации тактового сигнала. Свойственное армам и семейству stm32 богатство периферии, распространяется и на этот блок. Большое количество настроек позволяет максимально удобно настроить тактовую частоту основных блоков.
3 источника тактового сигнала для системного тактирования (SYSCLK):
2 источника тактового сигнала для вторичных системных нужд:3 источника тактового сигнала для системного тактирования (SYSCLK):
- HSI - высокоскоростной встроенный осциллятор тактового сигнала
- HSE - высокоскоростной внешний осциллятор тактового сигнала
- PLL - ФАПЧ для гибкой настройки тактового сигнала
- LSI - низкоскоростной 40 кГц встроенный осциллятор для сервисных устройств: ватчдоги, часы реального времени и системы авто-старта для режимов ожидания/останова.
- LSE - низкоскоростной 32768 Гц внешний осциллятор для опционального источника тактового сигнала часов реального времени
Источники и блоки могут быть подключены и отключены, когда не использованы для оптимизации энергопотребления
Как видно из блок-схемы, источники через делители и предделители, множители в ФАПЧ поставляют тактовый сигнал до потребителей - блоков периферии. Когда нет проблем по потреблению то предпочтительнее использование внешних источников тактового сигнала т.к. они стабильнее внутренних. Однако внутренние предпочтительнее по потреблению и безопасности.Основной тактовый сигнал разделен и пропущен через блоки предделителей для того чтобы соответствовать требованиям периферии. Для основной линии используется сигнал с AHB источника, который используется для генерации тактового сигнала арм ядра, ПДП, системного таймера, AHB шины.
Далее через предделители APB1(низкоскоростная линия) и APB2(высокоскоростная линия) сигнал подается на таймеры через предделители или напрямую на различные блоки периферии. Отдельно с APB2 сигнал через собственный предделитель идет на АЦП.
Особняком стоят несколько периферийных блоков которые используют только встроенные источники тактирования - это интерфейс программирования флешь памяти, а также ватчдоги (сторожевые таймеры).
Также присутствует вывод для тактового сигнала - можно потключить внешние потребители тактового сигнала. Источником для этого вывода могут быть:
- SYSCLK
- HSI
- HSE
- PLL тактовый сигнал деленный на 2
Тактирование часов реального времени осуществляется от нескольких источников - HSE/128, LSE или LSI. Это программируется из регистра резервного домена RCC_BDCR и не может быть изменено без сброса самого домена.
Более подробно о всех подробностях тактовой системы можно прочитать в соответствующем разделе дш, а мы переходим к практическому примеру. В качестве примера возьмем следующий алгоритм - в пример с использованием в таймере ШИМ добавим в качестве основного тактового сигнала ФАПЧ ( с использованием HSE), частоту которого будем увеличивать с каждым внешним прерыванием. А заодно поставим прерывание на сбой внешнего тактового сигнала, активацию которого будет индицировать другой один светодиод, другой оставим для индикации основного тактового сигнала.
Как обычно начинаем с создания проекта:
nis@jane ~/stm32/examples $ cp -a 06-tim3-pwm/ 08-clocking
nis@jane ~/stm32/examples $ cd 08-clocking/
В код функции main добавим защиту от сбоя внешнего осциллятора тактового сигнала. После этого добавим код инициализации внешнего осциллятора, настройку ФАПЧ и переключение его на внешний осциллятор, переключение системы генерации тактового сигнала на ФАПЧ:
/* enable security HSE - CSS */
RCC->CR |= RCC_CR_CSSON;
/* setup PLL from HSE */
/** enable HSE and wait to ready */
RCC->CR |= RCC_CR_HSEON;
while ((RCC->CR & RCC_CR_HSERDY) == 0);
/** setup PLL, enable and wait to ready */
RCC->CFGR &= ~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL);
RCC->CFGR |= (RCC_CFGR_PLLSRC_PREDIV1);
RCC->CR |= RCC_CR_PLLON;
while ((RCC->CR & RCC_CR_PLLRDY) == 0);
/** select PLL for system clock and wait to select */
RCC->CFGR &= ~RCC_CFGR_SW;
RCC->CFGR |= RCC_CFGR_SW_PLL;
while ((RCC->CFGR & RCC_CFGR_SWS_PLL) == 0);
Также перестроим блоки сравнения/захвата:
/** setup value to compare registers 3..4 */
TIM3->CCR3 = 0;
TIM3->CCR4 = 500;
В файле системной инициализации, векторов и обработчиков прерываний - startup.c добавим функцию обработки на немаскируемое прерывание - именно его вызывает ядро мк по событию системы защиты тактового сигнала:
/* NMI interrupt */
void NMI_Handler(void) {
if (RCC->CIR & RCC_CIR_CSSF) {
/* fail led blink enabled */
TIM3->CCR3 = 100;
/* reset CSSC flag */
RCC->CIR |= RCC_CIR_CSSC;
}
}
А также изменим прерывание по внешенему событию чтобы оно переключало множитель ФАПЧ:
Полный исходный код проекта. main.c:
startup.c:
Cоберем проект и зальем прошивку в мк:
nis@jane ~/stm32/examples/08-clocking $ make all write
arm-softfloat-linux-gnueabi-gcc -g -O2 -mlittle-endian -mthumb -ffreestanding -nostdlib -nostdinc -mcpu=cortex-m3 -DSTM32F10X_MD_VL -I. -I../../stlink/example/libs_stm/inc/base -I../../stlink/example/libs_stm/inc/core_support -I../../stlink/example/libs_stm/inc/device_support -Wl,-T,stm32f100xb_flash.ld -c -o startup.o startup.c
arm-softfloat-linux-gnueabi-gcc -g -O2 -mlittle-endian -mthumb -ffreestanding -nostdlib -nostdinc -mcpu=cortex-m3 -DSTM32F10X_MD_VL -I. -I../../stlink/example/libs_stm/inc/base -I../../stlink/example/libs_stm/inc/core_support -I../../stlink/example/libs_stm/inc/device_support -Wl,-T,stm32f100xb_flash.ld -o firmware.elf main.o sys_init.o startup.o -L.
arm-softfloat-linux-gnueabi-objcopy -O binary firmware.elf firmware.bin
st-flash write v1 firmware.bin 0x8000000
2012-03-16T23:51:36 INFO src/stlink-sg.c: Current mode unusable, trying to get back to a useful state...
2012-03-16T23:51:36 WARN src/stlink-sg.c: received tag 0 but expected 3
2012-03-16T23:51:36 INFO src/stlink-common.c: Loading device parameters....
2012-03-16T23:51:36 INFO src/stlink-common.c: Device connected is: F1 Medium-density Value Line device
2012-03-16T23:51:36 INFO src/stlink-common.c: SRAM size: 0x2000 bytes (8 KiB), Flash: 0x20000 bytes (128 KiB) in pages of 1024 bytes
2012-03-16T23:51:36 INFO src/stlink-sg.c: Successfully opened a stlink v1 debugger
2012-03-16T23:51:36 INFO src/stlink-common.c: Successfully unlocked flash
Erasing chip entirely... Done
2012-03-16T23:51:36 INFO src/stlink-common.c: Attempting to write 884 (0x374) bytes to stm32 address: 134217728 (0x8000000)
2012-03-16T23:51:36 INFO src/stlink-common.c: Erasing flash page at addr: 0x8000000
2012-03-16T23:51:36 INFO src/stlink-common.c: Successfully unlocked flash
2012-03-16T23:51:36 INFO src/stlink-common.c: Finished erasing 1 pages of 1024 (0x400) bytes
2012-03-16T23:51:36 INFO src/stlink-common.c: Starting Flash write for VL core id
2012-03-16T23:51:36 INFO src/stlink-common.c: Successfully loaded flash loader in sram
2012-03-16T23:51:36 INFO src/stlink-common.c: Writing flash block 0 of size 64 (0x40)
...
2012-03-16T23:51:37 INFO src/stlink-common.c: Successfully unlocked flash
2012-03-16T23:51:37 INFO src/stlink-common.c: Writing flash block 13 of size 64 (0x40)
2012-03-16T23:51:37 INFO src/stlink-common.c: Successfully unlocked flash
2012-03-16T23:51:37 INFO src/stlink-common.c: Starting verification of write complete
2012-03-16T23:51:37 INFO src/stlink-common.c: Flash written and verified! jolly good!
И наконец видео:
На этом все.
void NMI_Handler(void) {
if (RCC->CIR & RCC_CIR_CSSF) {
/* fail led blink enabled */
TIM3->CCR3 = 100;
/* reset CSSC flag */
RCC->CIR |= RCC_CIR_CSSC;
}
}
А также изменим прерывание по внешенему событию чтобы оно переключало множитель ФАПЧ:
/* EXTI line0 interrupt */
void EXTI_L0_Handler(void) {
if (EXTI->PR & (1 << 0)) {
volatile static int pll_mul = 0;
/* change multiply for PLL */
if (pll_mul > (4 << 18))
pll_mul = 0;
else
pll_mul += (1 << 18);
/* if enable HSI CSS enabled, return */
if ((RCC->CFGR & RCC_CFGR_SWS) == RCC_CFGR_SWS_HSI)
return;
/* switch to HSI and wait for stable*/
RCC->CFGR &= ~RCC_CFGR_SW;
while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI);
/* disable PLL and wait for off */
RCC->CR &= ~RCC_CR_PLLON;
while ((RCC->CR & RCC_CR_PLLRDY) == 1);
/* setup PLL, enable and wait to ready */
RCC->CFGR &= ~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL);
RCC->CFGR |= (RCC_CFGR_PLLSRC_PREDIV1 | pll_mul);
RCC->CR |= RCC_CR_PLLON;
while ((RCC->CR & RCC_CR_PLLRDY) == 0);
/* select PLL for system clock and wait to select */
RCC->CFGR &= ~RCC_CFGR_SW;
RCC->CFGR |= RCC_CFGR_SW_PLL;
while ((RCC->CFGR & RCC_CFGR_SWS_PLL) == 0);
/* reset EXTI flag */
EXTI->PR |= (1 << 0);
}
}
void EXTI_L0_Handler(void) {
if (EXTI->PR & (1 << 0)) {
volatile static int pll_mul = 0;
/* change multiply for PLL */
if (pll_mul > (4 << 18))
pll_mul = 0;
else
pll_mul += (1 << 18);
/* if enable HSI CSS enabled, return */
if ((RCC->CFGR & RCC_CFGR_SWS) == RCC_CFGR_SWS_HSI)
return;
/* switch to HSI and wait for stable*/
RCC->CFGR &= ~RCC_CFGR_SW;
while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI);
/* disable PLL and wait for off */
RCC->CR &= ~RCC_CR_PLLON;
while ((RCC->CR & RCC_CR_PLLRDY) == 1);
/* setup PLL, enable and wait to ready */
RCC->CFGR &= ~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL);
RCC->CFGR |= (RCC_CFGR_PLLSRC_PREDIV1 | pll_mul);
RCC->CR |= RCC_CR_PLLON;
while ((RCC->CR & RCC_CR_PLLRDY) == 0);
/* select PLL for system clock and wait to select */
RCC->CFGR &= ~RCC_CFGR_SW;
RCC->CFGR |= RCC_CFGR_SW_PLL;
while ((RCC->CFGR & RCC_CFGR_SWS_PLL) == 0);
/* reset EXTI flag */
EXTI->PR |= (1 << 0);
}
}
Полный исходный код проекта. main.c:
startup.c:
Cоберем проект и зальем прошивку в мк:
arm-softfloat-linux-gnueabi-gcc -g -O2 -mlittle-endian -mthumb -ffreestanding -nostdlib -nostdinc -mcpu=cortex-m3 -DSTM32F10X_MD_VL -I. -I../../stlink/example/libs_stm/inc/base -I../../stlink/example/libs_stm/inc/core_support -I../../stlink/example/libs_stm/inc/device_support -Wl,-T,stm32f100xb_flash.ld -c -o startup.o startup.c
arm-softfloat-linux-gnueabi-gcc -g -O2 -mlittle-endian -mthumb -ffreestanding -nostdlib -nostdinc -mcpu=cortex-m3 -DSTM32F10X_MD_VL -I. -I../../stlink/example/libs_stm/inc/base -I../../stlink/example/libs_stm/inc/core_support -I../../stlink/example/libs_stm/inc/device_support -Wl,-T,stm32f100xb_flash.ld -o firmware.elf main.o sys_init.o startup.o -L.
arm-softfloat-linux-gnueabi-objcopy -O binary firmware.elf firmware.bin
st-flash write v1 firmware.bin 0x8000000
2012-03-16T23:51:36 INFO src/stlink-sg.c: Current mode unusable, trying to get back to a useful state...
2012-03-16T23:51:36 WARN src/stlink-sg.c: received tag 0 but expected 3
2012-03-16T23:51:36 INFO src/stlink-common.c: Loading device parameters....
2012-03-16T23:51:36 INFO src/stlink-common.c: Device connected is: F1 Medium-density Value Line device
2012-03-16T23:51:36 INFO src/stlink-common.c: SRAM size: 0x2000 bytes (8 KiB), Flash: 0x20000 bytes (128 KiB) in pages of 1024 bytes
2012-03-16T23:51:36 INFO src/stlink-sg.c: Successfully opened a stlink v1 debugger
2012-03-16T23:51:36 INFO src/stlink-common.c: Successfully unlocked flash
Erasing chip entirely... Done
2012-03-16T23:51:36 INFO src/stlink-common.c: Attempting to write 884 (0x374) bytes to stm32 address: 134217728 (0x8000000)
2012-03-16T23:51:36 INFO src/stlink-common.c: Erasing flash page at addr: 0x8000000
2012-03-16T23:51:36 INFO src/stlink-common.c: Successfully unlocked flash
2012-03-16T23:51:36 INFO src/stlink-common.c: Finished erasing 1 pages of 1024 (0x400) bytes
2012-03-16T23:51:36 INFO src/stlink-common.c: Starting Flash write for VL core id
2012-03-16T23:51:36 INFO src/stlink-common.c: Successfully loaded flash loader in sram
2012-03-16T23:51:36 INFO src/stlink-common.c: Writing flash block 0 of size 64 (0x40)
...
2012-03-16T23:51:37 INFO src/stlink-common.c: Successfully unlocked flash
2012-03-16T23:51:37 INFO src/stlink-common.c: Writing flash block 13 of size 64 (0x40)
2012-03-16T23:51:37 INFO src/stlink-common.c: Successfully unlocked flash
2012-03-16T23:51:37 INFO src/stlink-common.c: Starting verification of write complete
2012-03-16T23:51:37 INFO src/stlink-common.c: Flash written and verified! jolly good!
И наконец видео:
Комментариев нет:
Отправить комментарий