При компиляции core_cm3.c из STM32F10x SPL v3.5.0 компилятор (gcc из Sourcery CodeBench) выдает ошибки:

Error: registers may not be the same — `strexb r0,r0,[r1]’
Error: registers may not be the same — `strexh r0,r0,[r1]’

Вычисление тактовых частот в STM32F10x

Микроконтроллеры серии STM32F10x содержат богатую периферию, которая тактируется с разными частотами. Вычислить тактовые частоты можно с помощью функции RCC_GetClocksFreq(), которая содержится в модуле RCC библиотеки STM32F10x SPL.

Функция производит вычисления на основе данных в регистрах RCC.

Прототип функции:

void RCC_GetClocksFreq(RCC_ClocksTypeDef * RCC_Clocks)

Функция заполняет структуру типа RCC_ClocksTypeDef, указатель на которую передается в функцию в качестве аргумента. Структура содержит следующие поля:

uint32_t ADCCLK_Frequency Тактовая частота АЦП в Гц
uint32_t HCLK_Frequency Тактовая частота шины AHB в Гц
uint32_t PCLK1_Frequency Тактовая частота периферии APB1 в Гц
uint32_t PCLK2_Frequency Тактовая частота периферии APB2 в Гц
uint32_t SYSCLK_Frequency Системная тактовая частота в Гц

Если используется внешнее тактирование, то функция должна знать частоту этого тактирования. Частота задается константой HSE_VALUE.

Лучше всего, определить константу опцией -D компилятора:

-DHSE_VALUE=4000000

В этом примере задается частота 4 МГц.

Если не определить константу в опциях компилятора, то она определится в файле stm32f10x.h и ей присвоится значение по умолчанию: 8000000 (8 МГц). Это значение можно отредактировать, прописав свою частоту.

Еще один способ задать собственное значение частоты: прописать в файле stm32f10x_conf.h следующие строки:

#if defined HSE_VALUE
  #undef HSE_VALUE
#endif
#define HSE_VALUE ((uint32_t)4000000) // 4 МГц

Во всех способах частота задается целым числом Герц.

Пример вызова функции RCC_GetClocksFreq():

RCC_ClocksTypeDef clocks;
RCC_GetClocksFreq(&clocks);

Кроме того, чтобы узнать источник системного тактирования микроконтроллера, можно воспользоваться функцией RCC_GetSYSCLKSource().

Прототип функции:

uint8_t RCC_GetSYSCLKSource(void)

Функция возвращает одно из значений:

  • 0x00: внутренний тактовый генератор (HSI)
  • 0x04: внешний тактовый источник (HSE)
  • 0x08: умножитель (PLL)

К сожалению библиотека SPL не имеет функций для вычисления тактовых частот конкретных периферийных устройств.
Код вычисляющий тактовые частоты таймеров:

uint32_t APB1_TIMCLK_Frequency;
uint32_t APB2_TIMCLK_Frequency;
RCC_ClocksTypeDef clocks;

RCC_GetClocksFreq(&clocks);

if (clocks.HCLK_Frequency == clocks.PCLK1_Frequency)
  APB1_TIMCLK_Frequency = clocks.PCLK1_Frequency;
else
  APB1_TIMCLK_Frequency = 2 * clocks.PCLK1_Frequency;

if (clocks.HCLK_Frequency == clocks.PCLK2_Frequency)
  APB2_TIMCLK_Frequency = clocks.PCLK2_Frequency;
else
  APB2_TIMCLK_Frequency = 2 * clocks.PCLK2_Frequency;

STM32F10x Standard Peripherals Library: соглашения

Соглашение об именах

  1. PPP — обозначение периферийного устройства, например ADC (аналого-цифровой преобразователь)
  2. Файлы исходного кода библиотеки начинаются с приставки stm32f10x_.
  3. Имена констант прописаны заглавными буквами. Если константа используется в единственном файле, то она определяется в этом файле. Константа, используемая в более, чем одном файле, определяются в заголовочном файле.
  4. Имена регистров, как и констант, прописаны заглавными буквами. Регистры именуются так же, как в документации на микроконтроллеры.
  5. Имена функций начинаются с PPP, после чего идет одно нижнее подчеркивание. Далее идут слитные слова, начинающиеся с заглавной буквы. Например: USART_SendData().
  6. Для настройки периферии PPP используется функция PPP_Init(), в которую передается указатель на структуру типа PPP_InitTypeDef, содержащую настройки периферии.
  7. Функция PPP_DeInit() сбрасывает регистры периферии в их начальное состояние.
  8. Функция PPP_StructInit() заполняет поля структуры типа PPP_InitTypeDef значениями по умолчанию, которые описывают начальное состояние периферии (состояние после сброса).
  9. Функция PPP_Cmd() включает или отключает периферию.
  10. Функция PPP_ITConfig() включает или отключает прерывания.
  11. Функция PPP_DMAConfig() включает или отключает DMA-интерфейс.
  12. Функции, оканчивающиеся на Config, настраивают отдельные функции периферии. Например GPIO_PinRemapConfig().
  13. Функция PPP_GetFlagStatus() служит для получения состояния флагов.
  14. Функция PPP_ClearFlag() сбрасывает флаги.
  15. Функция PPP_GetITStatus() сообщает о том произошло ли прерывание или нет.
  16. Функция PPP_ClearITPendingBit() сбрасывает бит захвата прерывания.

STM32F10x SPL: модуль GPIO

Введение

Статья написана на основе этой документации:
STM32F10x Standard Peripherals Library версии 3.5.0

В следующих разделах статьи будет представлено описание функций модуля GPIO и описание структуры GPIO_InitTypeDef.

Содержание

Обзор функций

В этом разделе, кликнув на имя функции, можно перейти к её подробному описанию.

void GPIO_AFIODeInit(void)
Сбрасывает в начальное состояние регистры альтернативных функций

void GPIO_DeInit(GPIO_TypeDef *GPIOx)
Сбрасывает в начальное состояние регистры GPIOx

void GPIO_ETH_MediaInterfaceConfig(uint32_t GPIO_ETH_MediaInterface)
Выбирает Ethernet media interface

void GPIO_EventOutputCmd(FunctionalState NewState)
Разрешает или запрещает событийный выход (Event Output)

void GPIO_EventOutputConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource)
Выбирает вывод для событийного выхода

void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource)
Назначает вывод GPIO_PinSource порта GPIO_PortSource источником внешнего прерывания

void GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_InitStruct)
Настраивает порт GPIOx в соответствии с параметрами из структуры GPIO_InitStruct

void GPIO_StructInit(GPIO_InitTypeDef *GPIO_InitStruct)
Заполняет поля структуры GPIO_InitStruct значениями по умолчанию

void GPIO_PinLockConfig(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
Защищает настройки выводов

void GPIO_PinRemapConfig(uint32_t GPIO_Remap, FunctionalState NewState)
Разрешает или запрещает переназначение GPIO_Remap

uint16_t GPIO_ReadInputData(GPIO_TypeDef *GPIOx)
Возвращает входные данные порта GPIOx

uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
Возвращает входное состояние вывода GPIO_Pin порта GPIOx

uint16_t GPIO_ReadOutputData(GPIO_TypeDef *GPIOx)
Возвращает выходные данные порта GPIOx

uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
Возвращает выходное состояние вывода GPIO_Pin порта GPIOx

void GPIO_ResetBits(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
Присваивает лог. 0 выходному состоянию выводов GPIO_Pin порта GPIOx

void GPIO_SetBits(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
Присваивает лог. 1 выходному состоянию выводов GPIO_Pin порта GPIOx

void GPIO_Write(GPIO_TypeDef *GPIOx, uint16_t PortVal)
Присваивает значение PortVal выходным данным порта GPIOx

void GPIO_WriteBit(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, BitAction BitVal)
Присваивает значение BitVal выходному состоянию вывода GPIO_Pin порта GPIOx

Подробное описание функций



void GPIO_AFIODeInit(void)
Сбрасывает в начальное состояние регистры альтернативных функций порта



void GPIO_DeInit(GPIO_TypeDef *GPIOx)
Сбрасывает в начальное состояние регистры порта GPIOx
Аргументы:

  • GPIOx: Порт. Варианты значений:
    • GPIOx: где x = (A…G)


void GPIO_ETH_MediaInterfaceConfig(uint32_t GPIO_ETH_MediaInterface)
Выбирает Ethernet media interface
Аргументы:

  • GPIO_ETH_MediaInterface: Media Interface. Варианты значений:
    • GPIO_ETH_MediaInterface_MII: Режим MII
    • GPIO_ETH_MediaInterface_RMII: Режим RMII


void GPIO_EventOutputCmd(FunctionalState NewState)
Разрешает или запрещает событийный выход (Event Output)
Аргументы:

  • NewState: Новое состояние событийного выхода. Варианты значений:
    • ENABLE: разрешен
    • DISABLE: запрещен


void GPIO_EventOutputConfig(uint8_t GPIO_PortSource, u8 GPIO_PinSource)
Выбирает вывод для событийного выхода
Аргументы:

  • GPIO_PortSource: Порт. Варианты значений:
    • GPIO_PortSourceGPIOx: где x = (A…E)
  • GPIO_PinSource: Вывод порта. Варианты значений:
    • GPIO_PinSourceX: где X = (0…15)


void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, u8 GPIO_PinSource)
Назначает вывод GPIO_PinSource порта GPIO_PortSource источником внешнего прерывания
Аргументы:

  • GPIO_PortSource: Порт. Варианты значений:
    • GPIO_PortSourceGPIOx: где x = (A…G)
  • GPIO_PinSource: Вывод порта и одновременно номер X внешнего прерывания. Варианты значений:
    • GPIO_PinSourceX: где X = (0…15)


void GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_InitStruct)
Настраивает порт GPIOx в соответствии с параметры из структуры GPIO_InitStruct
Аргументы:

  • GPIOx: Порт. Варианты значений:
    • GPIOx: где х = (A…G)
  • GPIO_InitStruct: Структуру типа GPIO_InitTypeDef, содержащая настройки порта.


void GPIO_PinLockConfig(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
Защищает настройки выводов
Аргументы:

  • GPIOx: Порт. Варианты значений:
    • GPIOx: где х = (A…G)
  • GPIO_Pin: Выводы, одно значение или их комбинация (с помощью оператора или |):
    • GPIO_Pin_x: где x = (0…15)


void GPIO_PinRemapConfig(uint32_t GPIO_Remap, FunctionalState NewState)
Разрешает или запрещает переназначение GPIO_Remap
Аргументы:

  • NewState: Состояние переназначения. Значения аргумента:
    • ENABLE: Разрешение
    • DISABLE: Запрет
  • GPIO_Remap: Переназначение. Значения аргумента:
    • GPIO_Remap_PPP, где PPP:
      • SPI1
      • SPI3
      • I2C1
      • USART1
      • USART2
      • USART3
      • PD01
      • TIM5CH4_LSI
      • ADC1_ETRGINJ
      • ADC1_ETRGREG
      • ADC2_ETRGINJ
      • ADC2_ETRGREG
      • ETH
      • CAN2
      • SWJ_NoJTRST
      • SWJ_JTAGDisable
      • SWJ_Disable
      • TIM2ITR1_PTP_SOF
      • PTP_PPS
      • CEC
      • TIM1_DMA
      • TIM4
      • TIM9
      • TIM10
      • TIM11
      • TIM13
      • TIM14
      • TIM15
      • TIM16
      • TIM17
      • FSMC_NADV
      • TIM67_DAC_DMA
      • TIM12MISC
    • GPIO_FullRemap_PPP, где PPP:
      • USART3
      • TIM1
      • TIM2
      • TIM3
    • GPIO_PartialRemap_PPP, где PPP:
      • TIM1
      • TIM3
    • GPIO_PartialRemap1_PPP, где PPP:
      • TIM2
      • CAN1
    • GPIO_PartialRemap2_PPP, где PPP:
      • TIM2
      • CAN1


uint16_t GPIO_ReadInputData(GPIO_TypeDef *GPIOx)
Возвращает входные данные порта GPIOx
Аргументы:

  • GPIOx: Порт. Варианты значений:
    • GPIOx: где х = (A…G)


uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
Возвращает входное состояние вывода GPIO_Pin порта GPIOx
Аргументы:

  • GPIOx: Порт. Варианты значений:
    • GPIOx: где х = (A…G)
  • GPIO_Pin: Вывод порта. Значение:
    • GPIO_Pin_x: где x = (0…15)

Возвращаемое значение: входное состояние вывода, (uint8_t)Bit_SET или (uint8_t)Bit_RESET.



u16 GPIO_ReadOutputData(GPIO_TypeDef *GPIOx)
Возвращает выходные данные порта GPIOx
Аргументы:

  • GPIOx: Порт. Варианты значений:
    • GPIOx: где х = (A…G)

Возвращаемое значение: выходные данные порта GPIOx.



uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
Возвращает выходное состояние вывода GPIO_Pin порта GPIOx
Аргументы:

  • GPIOx: Порт. Варианты значений:
    • GPIOx: где х = (A…G)
  • GPIO_Pin: Вывод порта. Варианты значений:
    • GPIO_Pin_x: где x = (0…15)

Возвращаемое значение: выходное состояние вывода, (uint8_t)Bit_SET или (uint8_t)Bit_RESET.



void GPIO_ResetBits(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
Присваивает лог. 0 выходному состоянию выводов GPIO_Pin порта GPIOx
Аргументы:

  • GPIOx: Порт. Варианты значений:
    • GPIOx: где х = (A…G)
  • GPIO_Pin: Выводы, одно значение или их комбинация (с помощью оператора или |):
    • GPIO_Pin_x: где x = (0…15)


void GPIO_SetBits(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
Присваивает лог. 1 выходному состоянию выводов GPIO_Pin порта GPIOx
Аргументы:

  • GPIOx: Порт. Варианты значений:
    • GPIOx: где х = (A…G)
  • GPIO_Pin: Выводы, одно значение или их комбинация (с помощью оператора или |):
    • GPIO_Pin_x: где x = (0…15)


void GPIO_StructInit(GPIO_InitTypeDef *GPIO_InitStruct)
Заполняет поля структуры GPIO_InitStruct значениями по-умолчанию:

GPIO_InitStruct->GPIO_Pin = GPIO_Pin_All;
GPIO_InitStruct->GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStruct->GPIO_Mode = GPIO_Mode_IN_FLOATING;

При вызове функции GPIO_Init() и передачи ей указателя на структуру, заполненную по-умолчанию, все выводы порта GPIOx, настроятся в режим плавающего входа с максимальной частотой 2 МГц.
Аргументы:

  • GPIO_InitStruct: Структура типа GPIO_InitTypeDef, содержащая настройки порта


void GPIO_Write(GPIO_TypeDef *GPIOx, uint16_t PortVal)
Присваивает значение PortVal выходным данным порта GPIOx
Аргументы:

  • GPIOx: Порт. Варианты значений:
    • GPIOx: где х = (A…G)
  • PortVal: Значение, записываемое в выходной регистр порта GPIOx


void GPIO_WriteBit(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, BitAction BitVal)
Присваивает значение BitVal выходному состоянию вывода GPIO_Pin порта GPIOx
Аргументы:

  • GPIOx: Порт. Варианты значений:
    • GPIOx: где х = (A…G)
  • GPIO_Pin: Вывод. Варианты значений:
    • GPIO_Pin_x: где x = (0…15)
  • BitVal: Значение, присваиваемое биту GPIO_Pin выходного регистра порта GPIOx. Варианты значений:
    • Bit_RESET: логический 0
    • Bit_SET: логическая 1

Описание структуры GPIO_InitTypeDef

GPIO_InitTypeDef — тип структуры данных для настройки выводов портов. Для настройки выводов порта необходимо вызвать функцию GPIO_Init(), передав ей указатель на переменную типа GPIO_InitTypeDef. На практике настройка выводов выглядит так:

// Объявляем структуру для настройки вывода
GPIO_InitTypeDef GPIO_InitStruct;
// Настройки: вывод 0 и 1 как двухтактный выход с частотой 50 МГц
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; // Режим
GPIO_InitStruct.GPIO_Pin = (GPIO_Pin_0 | GPIO_Pin_1); // Выводы
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; // Макс. частота
// Настроить выводы порта А
GPIO_Init(GPIOA, &GPIO_InitStruct);

или, тоже самое:

GPIO_InitTypeDef GPIO_InitStruct = {GPIO_Pin_0 | GPIO_Pin_1, GPIO_Speed_50MHz, GPIO_Mode_Out_PP};
GPIO_Init(GPIOA, &GPIO_InitStruct);

Поля структуры:

  • GPIOMode_TypeDef GPIO_Mode: Режим работы порта. Варианты значений:
    • GPIO_Mode_AIN: Аналоговый вход
    • GPIO_Mode_IN_FLOATING: Плавающий вход
    • GPIO_Mode_IPD: Вход с подтяжкой к земле
    • GPIO_Mode_IPU: Вход с подтяжкой к питанию
    • GPIO_Mode_Out_OD: Выход с открытым стоком
    • GPIO_Mode_Out_PP: Двухтактный выход
    • GPIO_Mode_AF_OD: Альтернативный выход с открытым стоком
    • GPIO_Mode_AF_PP: Альтернативный двухтактный выход
  • uint16_t GPIO_Pin: Выводы порта. Поле может принимать одно из значений или их комбинацию (с помощью оператора или |):
    • GPIO_Pin_x: Вывод x, где x = (0…15)
    • GPIO_Pin_All: все выводы
  • GPIOSpeed_TypeDef GPIO_Speed: Максимальная частота выходного сигнала. Варианты значений:
    • GPIO_Speed_2MHz: 2 МГц
    • GPIO_Speed_10MHz: 10 МГц
    • GPIO_Speed_50MHz: 50 МГц

Конец статьи.