STM8S+SDCC+SPL: использование модуля UART1 на примере функции printf()

разделы: STM8, дата: 20 июля 2016г.

UART обладает двумя важными преимуществами перед остальными интерфейсами: во-первых, через TTL-конвертер его напрямую можно подключить к компьютеру, а во-вторых, линии связи между двумя узлами могут достигать 50 метров, что позволяет без проблем построить, к примеру, локальную сеть типа SmartHome. В STM8 скорость передачи через UART может достигать 1Mbit/s при частоте системной шины в 16MHz.

Микроконтроллеры STM8S могут обладать несколькими UART модулями,правда характеристики этих модулей немного разнятся:

Использование UART с помощью стандартной периферийной библиотеки(далее SPL), не сложнее, чем в AVR или даже Arduino. Библиотека, в папке Examples содержит готовые примеры использования UART, которые подробно прокомментированы. НО что бы не скатиться до потребительского отношения, бездумно используя чужой код, я предлагаю пошуршать немного мануалами, чтобы понять, чем же все-таки являются USART модули в STM8, и как ими пользоваться максимально эффективно.

Основные возможности UART1 в stm8s103f3:

Читать дальше

STM8+SDCC+SPL: функции delay_ms() и delay_us() на таймере TIM4

разделы: STM8, дата: 16 июля 2016г.

8-битный базовый таймер TIM4 самый простой из набора STM8, но даже на таком простом таймере, можно познакомиться с некоторыми принципами всех таймеров STM8:

  • Введено такое понятие, как событие(event). Как правило, прерывание таймера может вызвать некоторый набор событий(events).
  • У некоторых регистров таймера имеются теневые/буферные регистры. Записать в них можно в любой момент, но вступят в действие новые значения только при "событии обновления/update".
  • Таймеры могут работать как в непрерывном режиме, так и одиночном, до первого прерывания.

TIM4 по возможностям примерно походит на 8-битный TIMER2 в AVR, за тем исключением, что он не может генерировать ШИМ сигнал, т.е. это тот таймер, который не жалко отдать на счетчики, поэтому попробуем на его основе сделать функции delay_ms() и delay_us(), которые широко используются при программной реализации различных протоколов.

Регистров относящихся к TIM4 сравнительно немного, в SPL их описывает следующая структура:

typedef struct TIM4_struct
{
  __IO uint8_t CR1;  /*!< control register 1 */
#if defined(STM8S103) || defined(STM8S003)
        uint8_t RESERVED1; /*!< Reserved register */
        uint8_t RESERVED2; /*!< Reserved register */
#endif
  __IO uint8_t IER;  /*!< interrupt enable register */
  __IO uint8_t SR1;  /*!< status register 1 */
  __IO uint8_t EGR;  /*!< event generation register */
  __IO uint8_t CNTR; /*!< counter register */
  __IO uint8_t PSCR; /*!< prescaler register */
  __IO uint8_t ARR;  /*!< auto-reload register */
}
TIM4_TypeDef;

CR1 - это главный управляющий регистр, IER - разрешает/запрещает прерывание, SR1- флаговый/статусный регистр прерывания, EGR - программная генерация события, нужно для обновления регистра предделителя, CNTR - счетчик, PSCR - содержит предделитель, ARR - содержит значение до которого считает таймер, после чего тот обнуляется и идет по новому кругу.

RSCR и ARR имеют теневые регистры, причем теневой регистр ARR отключаемый через TIM4_CR1.

Читать дальше

STM8+SDCC+SPL: Option bytes и прерывание высшего уровня(TLI)

разделы: STM8, дата: 14 июля 2016г.

Ковыряясь в исходниках стандартной периферийной библиотеки(далее SPL), я с досадой обнаружил, что совершенно проморгал такую интересную штуку как немаскируемое прерыване высшего уровня(Top Level Interrupt aka TLI), которое относится к группе внешних прерываний.

Однако, к еще большей досаде, вскоре обнаружилось, что в stm8s103f3p6 доступ к этому прерыванию закрыт такой штукой, как "option bytes". Эта что-то вроде фьюзов AVR, благдоря которым, было залочено немалое количество AVR чипов(мною лично в том числе).

Воспользовавшись функциями из модуля FLASH, я вставил четыре команды перед главным циклом основной программы, cкомпилировал, прошил, и... благополучно залочил чип.

Проблема решилась достаточно быстро, как оказалось, в STM8 все делается иначе чем в AVR. Вообщем, этот пост о том, "как перестать бояться, и начать использовать option bytes в STM8".

Однако, для начала предлагаю вернуться к внешним перыванияи. Они в SPL реализованы в модуле EXTI, и представлены незамысловатым набором функций:

void EXTI_DeInit(void);
void EXTI_SetExtIntSensitivity(EXTI_Port_TypeDef Port, EXTI_Sensitivity_TypeDef SensitivityValue);
void EXTI_SetTLISensitivity(EXTI_TLISensitivity_TypeDef SensitivityValue);
EXTI_Sensitivity_TypeDef EXTI_GetExtIntSensitivity(EXTI_Port_TypeDef Port);
EXTI_TLISensitivity_TypeDef EXTI_GetTLISensitivity(void);

Читать дальше

STM8+SPL+CLK: Тактирование и подключение внешнего кварца

разделы: STM8, дата: 12 июля 2016г.

В STM8 система тактирования не такая сложная как в MSP430, но гораздо сложнее чем в AVR. Здесь две основные тактовые шины. Одна идет на ЦПУ, другая на периферию. Генераторы могут быть внутренними(HSI/LSI) или внешними(HSE/LSE). В S-серии делитель может ставится и на генератор и на главную шину. В L-серии - только не шину. Зато в L-серии имеется низкочастотный RTC, со всеми вытекающими хлопотами. Чипы STM8 тактируются максимально на 16 MHz, за исключением чипов STM8S 207/208/007, на которые можно ставить внешний кварц до 24 MHz.

Мне удалось практически без изменений портировать модуль тактирования CLK, стандартной периферийной библиотеки(далее SPL), под компилятор SDCC.

Регистры тактирования S-серии, в SPL описываются структурой:

 
typedef struct CLK_struct
{
  __IO uint8_t ICKR;     // Internal Clocks Control Register
  __IO uint8_t ECKR;     // External Clocks Control Register
  uint8_t RESERVED;      // Reserved byte
  __IO uint8_t CMSR;     // Clock Master Status Register
  __IO uint8_t SWR;      // Clock Master Switch Register
  __IO uint8_t SWCR;     // Switch Control Register
  __IO uint8_t CKDIVR;   // Clock Divider Register
  __IO uint8_t PCKENR1;  // Peripheral Clock Gating Register 1
  __IO uint8_t CSSR;     // Clock Security System Register
  __IO uint8_t CCOR;     // Configurable Clock Output Register
  __IO uint8_t PCKENR2;  // Peripheral Clock Gating Register 2
  uint8_t RESERVED1;     // Reserved byte
  __IO uint8_t HSITRIMR; // HSI Calibration Trimmer Register
  __IO uint8_t SWIMCCR;  // SWIM clock control register
}
CLK_TypeDef;

Описание этих регистров для S-серии подробно на русском языке рассмотрено здесь: Микроконтроллеры STM8. Система тактирования.

Описание регистров для L-серии рассмотрено здесь: 8L-Курс, Часть 4 - Тактирование

При инициализации CLK модуля, в эти регистры записываются следующие значения:

Читать дальше

STM8 + SDCC + SPL: стандартная периферийная библиотека

разделы: STM8, дата: 9 июля 2016г.

После знакомства с внешними прерываниями, я почувствовал, что иду по неверному пути, в изучении STM8. Я понял, что есть достаточное количество весьма не очевидных вещей, как например очистка EXTI_SRx записью единицы. И даже при наличии полной оригинальной документации, я не чувствую уверенности в том, что начну с ходу писать достаточно хороший код для работы с тем или иным перифирийным модулем.

Это нерадостные мысли посетили меня после ознакомления с системой таймеров в STM8. Она довольно мощная, на мой взгляд. И тут я вспомнил про стандартную периферийную библиотеку (SPL), о которой упоминал еще в первом посте про STM8, почти год назад. Там весь код для работы с периферией уже написан, проверен и отлажен.

Короче говоря, я решил переписать/адаптировать ее под SDCC в процессе своего изучения STM8. Начать решил с модуля GPIO, и дальше добавлять модуль за модулем.

Напомню, что SPL для STM8S и для STM8L это разные библиотеки, синтаксис у них различается, хотя написаны они в одном стиле.

Итак, GPIO.

Библиотеки состоят из главного заголовочного файла stm8s.h и stm8l15x.h, где приписаны адреса регистров, основные структуры и константы.

На этом, начальном, этапе stm8s.h у меня получился довольно скромным:

Читать дальше

Внешние прерывания в микроконтроллерах серии "L", на примере: stm8l151 и IAR WORKWENCH

разделы: STM8, дата: 9 июля 2016г.

В микроконтроллере stm8l151, внешние прерывания организованы несколько иначе чем, в S-серии. Если посмотреть на таблицу прерываний слева, то наряду с прерываниями для портов E/F, B/G и D/I, имеются также прерывания для пинов 0-7. Эти прерывания являются общими для всех портов, вследствии чего, для их использования можно назначить любой порт. Они не привяны жестко к какому-то конкретному пину, как в AVR. При этом, такие прерывания могут обрабатывать сигналы с нескольких портов, если на них установить соотвествующий флаг в Px_CR2.

Наряду с конфигурирующими регистрами EXTI_CRx из S-серии, здесь имеются еще регистры EXTI_SRx и EXTI_CONF:

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

Кроме того, в EXTI_CONF, порты разделены пополам, т.е. младшую или старшую половину порта можно отдать на прерывание по порту, а остальное на прерывания о пину.

Читать дальше

STM8S103F3P6 + SDCC: внешние прерывания и режимы энергосбережения

разделы: STM8, дата: 9 июля 2016г.

В STM8S внешние прерывания походят на PCINT в AVR, в том плане, что одно прерывание, является общем для всего порта. Спасает ситуацию тот факт, что от некоторых портов в некоторых чипах, фактически может остаться лишь пара пинов.

Для примера, попробуем собрать схему аналогичную схеме поста про MSP430.

В качестве чипа я использовал известную плату с алиэксперсс. В качестве компилятора я использовал SDCC, в качестве флешера stm8flash.

Итак, на PB5 обозначенной платы висит светодиод "Test", будем его использовать для индикации рабочего цикла. Для индикации нажатой кнопки, на пин С3, посадим светодиод+резистор. Саму кнопку, посадим на пин D2. Схема подключения кнопки здесь.

Вначале составим программу индикации нажатой кнопки на основе опроса(Polling) порта:

Читать дальше