Как работать с keil uvision 5
Перейти к содержимому

Как работать с keil uvision 5

  • автор:

SamPawno

Первое, что нужно сделать — это скачать с официального сайта Keil и установить себе на компьютер пакет MDK-ARM.

MDK-ARM MDK-ARM.png (52.81 КБ) 5604 просмотра

//=======================================
Но для того что бы скачать нужно указать некоторые данные.

MDK-ARM данные.png

MDK-ARM данные MDK-ARM данные.png (213.82 КБ) 5604 просмотра

//=======================================
После этого вам будет доступен для скачивания, файл программы Keil uVision

файл программы Keil uVision.png

файл программы Keil uVision файл программы Keil uVision.png (49.13 КБ) 5604 просмотра

//=======================================
Скачав и установив программу, приступаем к созданию проекта. На панели инструментов вверху нажимаем кнопку PackInstaller откроется окно PackInstaller в нем две вкладки слева и две справа

Нажимаем на вкладку Devices и выбираем из списка производителей STMicroelectronics далее выбираем нашу серию МК (МК- микро контроллер) у меня серия F1 если у вас другая серия выбирайте свою серию. И на вкладке Pack по очереди инсталлируйте все пакеты.

PackInstaller .png

PackInstaller

//=======================================
Далее создаем проект нажимаем кнопку Project и в выпадающем меню нажимаем NewProject
Сразу появится окно предлагающее выбрать где будет храниться наш проект.
Потом появится окно предлагающее выбрать для какого микро контроллера будет писаться программа.
Нужно выбрать точную модель МК. Моя STM32F103C8 если ваша другая, то выберите свою модель и жмем ок.
//=======================================
Следующее окно у нас будет ManageComponents

ManageComponents ManageComponents.png (89.63 КБ) 5604 просмотра

Ставим галочки согласно скриншота

Что они означают?

Самая первая строка “ BoardSupport ” при выборе открывается список поддерживаемых отладочных плат если там есть ваша то можете выбрать ее и поставить галочку Keil загрузит для нее драйвер, моей платы тут нет я ни чего не выбираю.

Далее “ CMSIS ”- тут ставим галочку “ CORE ” это поддержка основного ядра ARM

Тут же “ RTOS (API) ” — это операционная система реального времени (с ней позже то же будем работать )

CMSIS DRIVER – это драйвера интерфейсов

DEVICE – тут содержится практически вся основная периферия микро контроллера

Ставим галочки GPIO — это основной драйвер портов ввода/вывода,

Startup – это основной конфигурационный системный файл.

StdPeriph Diver – это стандартные драйверы периферии .

Ставим галочки и нажимаем ок . Если у вас квадратики светятся желтым не паникуем в меню

DEVICE выбираете GPIO и Startup

Далее в Stdperiph Diver+6 ставите галочки на той периферии которая вам нужна и нажимаете в самом низу окна кнопку “ Resolve ” потом ОК . Окно должно исчезнуть . Теперь вы скажете а где писать наш код, да надо создать файл.
//=======================================
Правой кнопкой мыши по Sourcegroup 1 далее Add new item.

Sourcegroup 1.png

Sourcegroup 1 Sourcegroup 1.png (41.96 КБ) 5604 просмотра

//=======================================
Далее выбираем тип файла

выбираем тип файла.png

выбираем тип файла выбираем тип файла.png (30.61 КБ) 5604 просмотра

//=======================================
И пишем его имя в поле “ Namе ” я назвал его main , и нажимаем ADD .
Сразу открывается наш созданный файл

созданный файл.png

созданный файл созданный файл.png (59.95 КБ) 5604 просмотра

Нажимаем правой кнопкой мыши в поле где должен быть код и выбираем
Insert #include file далее stm32f10x.h
Если у вас другой микро контроллер выполняете все то же самое только вместо stm32f10 выбираете свой файл.
//=======================================
Далее на панели инструментов нажимаем кнопку “ OptionsforTarget ” Пока что все оставляем без изменений кроме частоты.

OptionsforTarget OptionsforTarget.png (48.03 КБ) 5604 просмотра

//=======================================
На следующей вкладке надо поставить галочку “ CreateHEXfile ”

CreateHEXfile CreateHEXfile.png (25.84 КБ) 5604 просмотра

//=======================================
Далее надо прописать строку “ USE_STDPERIPH_DRIVER,STM32F10X ” без нее проект не соберется . И жмете ОК

USE_STDPERIPH_DRIVER,STM32F10X.png

USE_STDPERIPH_DRIVER,STM32F10X USE_STDPERIPH_DRIVER,STM32F10X.png (30.61 КБ) 5604 просмотра

//=======================================
Осталось самую малость — нужно написать функцию

На панели инструментов нажимаем кнопку “ Build ” и ждем в нижнем окне будет результат.

Build Build.png (53.76 КБ) 5604 просмотра

Установка Keil μVision

image00

Использовать мы будем отладочную плату STM32F4-DISCOVERY.

Запускаем там pack installer

image02

Слева выбираем наш контроллер

image01

А справа затем Device Specific и жмем Install.

После загрузки пакета выбираем справа еще ARM::CMSIS также жмем Install.

image04

Создаем новый проект Project->New uVision Project

Даем ему имя, выбираем контроллер

image03

Появляется Manage Run-Time Enveroment

Выбираем CMSIS->CORE и Device->Startup, ставим галки напротив и жмем «ОК»

image06

В Target1 добавляем новую папки pl, а папку Source Group 1 переименовываем в user

Такие же папки создаем в физическом каталоге проекта.

Копируем файл \STM32F4xx_DSP_StdPeriph_Lib_V1.6.1\Libraries\CMSIS\Device\ST\STM32F4xx\Include\stm32f4xx.h

в папку pl и снимаем с него атрибут «для чтения».

Также в данную папку копируем две папки (inc и src) из \STM32F4xx_DSP_StdPeriph_Lib_V1.6.1\Libraries\STM32F4xx_StdPeriph_Driver

Можно также снять с этих папок тот же атрибут, включая их содержимое.

Также из любого примера в \STM32F4xx_DSP_StdPeriph_Lib_V1.6.1\Project\

Копируем в папку pl файл stm32f4xx_conf.h

В проекте в группу pl добавляем все файлы из папки \pl\src, кроме файла stm32f4xx_fmc.c,

а также тот файл stm32f4xx_conf.h, который мы копировали выше.

В папке user создаем новый пустой файл main.c

Подключаем его в группу user в проекте

Пишем туда подключение добавленного хедер-файла вот таким образом (нажмите на картинку для увеличения размера)

Затем пропишем пути, выбрав контекстное меню на группе Target 1 и выбрав там следующий пункт

image08

На закладке C/C++ нажмем … справа от поля Include Paths и в открывшийся диалог добавим пути

image07

Добавим в main.c функцию main с бесконечным циклом

Вызовем контекстное меню на объявлении заголовочного файла

image11

И внесем следующие исправления

и /*#define USE_STDPERIPH_DRIVER */

изменить 25000000 на 8000000 здесь

Чтобы включить возможность писать комментарии на русском языке,

в панели инструментов нажимаем пункт «Configuration»

image09

И выбираем там кодовую страницу

image10

Также вот здесь можно поменять размер и тип шрифта в редакторе

image12

Добавим код в main()

RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN; // включим тактирование порта

GPIOD->MODER = 0x55000000; // включим ножки 12,13,14,15 на выход

GPIOD->OTYPER = 0; //подтянем резистор ко всем ножкам порта

GPIOD->OSPEEDR = 0; //установим скорость LOW на все лапки порта

GPIOD->ODR = 0xF000; // 12,13,14,15 лапки установим в 1, тем самым зажжем светодиод

Соберём код, прошьём контроллер и посмотрим результат

image13

STM32 STM Урок 1. Установка Keil μVision

Post Views: 22 184

40 комментариев на “ STM Урок 1. Установка Keil μVision ”

Для скачивания нужной STM32F10x_StdPeriph_Lib_V3.5.0 (например) не нужно ничего писать в строке. Идем на сайт http://www.st.com выбираем Products->Microcontrollers->STM32F1(например) и в Total Parts ищем свой МК (STM32f103c8t6 например — мой случай). Выбираем его. Идем вниз где расположены архивы MCUS EMBEDDED SOFTWARE. Уделяем внимание тем ссылкам которые начинаются с STSW-STM и среди них находим ту рядом с которой есть такое описание (с правой стороны) STM32F10x standard peripheral library. Скачиваем.

На момент съёмки урока и написания сценария было так.
Спасибо за подсказку!
Думаю, многим пригодится, хотя в актуальности на данный момент этой библиотеки, есть определённые сомнения.

Копируем файл \STM32F4xx_DSP_StdPeriph_Lib_V1.6.1\Libraries\CMSIS\Device\ST\STM32F4xx\Include\stm32f4xx.h в папку pl и снимаем с него атрибут «для чтения». Также в данную папку копируем две папки (inc и src) из \STM32F4xx_DSP_StdPeriph_Lib_V1.6.1\Libraries\STM32F4xx_StdPeriph_Driver-А где их взять то?

Таким писарям статей нужно по рукам стучать…
«Скачиваем отсюда библиотеку «… А дальше что ? Что с ней делать ?
«Слева выбираем наш контроллер» … А если его нет ? Что ? Статья — ниачом..

Посмотрите видеоурок, возможно Вам станет понятнее.
В любом случае, спасибо за критику, хотя конечно этому уроку уже более 2х лет.
Посмотрите последние уроки, заодно и оцените, исправился ли я за это время или нет.

Поддерживаю! Хорошо бы в духе уроков по AVR.

Я уже вторую неделю не могу диодом моргнуть на blue pill. И на борту программатот st-link.
Мануалы просто трубовые . У всех !
90% диких перепечаток .stm32 обзывают arduino . Ни у кого 5 лет подряд нет 3 бакса на программатор . Подключают всякие чёрт те што. Шьют где угодно , но только не в бесплатных от родной stm.
От самоката плату в openocd-0.10.0 перепрошил практически сразу.
Этот автор тоже перец . Я себе даже в дурном сне не могу представить total comander в пользовании . Зачем он в роликах щёлкает этим командером ?

Total commander — очень удобный файловый менеджер, большинство программистов, воспинанных на нортон командере им пользуются. Видно размер, расширение, время модификации файлов. Так что предъява не принимается.

ArduinoIDE полдня настраивается.
В уроках по AVR вы подробно рассказывали про регистры, хотелось бы и здесь.
Спасибо!

Имеется контроллер STM32L476 но нет к нему библиотек ни в Keil μVision3 ни в Keil μVision4, а Keil μVision5 нет

Непонятна цель манипуляций с переименовыванием папок, файлов, копированием туда — сюда. У меня проект заработал и без этих манипуляций. Тогда зачем эти получасовые танцы с бубнем при создании проекта — осталось загадкой. )))

Это такой порядок. А ещё для того, чтобы посмотреть, где всё находится. Цель моих занятий — не дать проект, который работает, а показать, почему оно работает.
Я очень рад, что у Вас всё заработало!

Пользуясь случаем, выражаю Вам свою глубокую благодарность за эти уроки!
Я не сомневаюсь что эти манипуляции для чего то нужны, и это заведенный Вами порядок. Но для чего они нужны и зачем заведен такой сложный порядок создания пооекта, ни одним словом не объясняется. Прошу прощения, но это сбивает с толку начинающего. Спасибо Вам еще раз!

И Вам также спасибо за интерес к ресурсу!
А вообще, по большому счёту, урок этот был записан очень давно, когда Keil 5 практически только появился, также невозможно было по-нормальному найти и собрать библиотеки, поэтому получилось у меня только вот так.

Понял Вас. Представьте, два раза собирал проект пошагово, как сказано в уроке, ничего не получилось, куча ошибок. Видимо где то, что то напутал. В третий раз собрал проект по умолчанию, только вставил код и все заработало. Поэтому возникли у меня вышеозвученные вопросы.

«Цель моих занятий — не дать проект, который работает, а показать, почему оно работает.» Абсолютно не показали «почему это работает». Вот как Вы пришли к решению переименовывать папки, например? Если доступно объясните, то у остальных не будет вопросов. Также необходимо пояснять зачем эти файлы в данных папках, что они дают. Вы просто запутали начинающих. А гуру уже все умеют. Здесь надо как в детском саду:)

Я думаю, что это элементарно и все поняли, почему мы это делаем, так как данный урок был сделан 2,5 года назад, видео по нему «претерпело» 85 тысяч просмотров, 623 лайка к 59 дизлайкам, что составляет более 90 процентов и такой вопрос прозвучал за это время впервые.
Посему предъява не принимается.

Это не предъява. Если кто-то спросил, значит он не понял элементарного и хочет получить ответ (и до сих пор не получил). Если трудно объяснить — не напрягайся. Ведь у тебя столько лайков. Пойдем к другим изучать элементарное.

умник, влет могу тебе дизлайков накрутить! малейшие пояснения можно дать, что для чего делается, абсолютно бесполезный урок, не поясняются действия при создании проекта, отсюда и вывод = ничерта не работает! пришлось самому переделывать все.

Пожалуйста поподробнее. И не надо, пожалуйста, угрожать дизлайками и разными там хейтерствами. Слава Богу, дизлайки сейчас ничем не грозаят, сейчас это в ранжирование ресурса не учитывается. Сейчас учитывается только общее время просмотра. Если Вы как-то хотите навредить какому-то каналу, единственное, что Вы можете сделать, это только поменьше его смотреть. Больше никак.
Что именно у Вас не получилось с установкой IDE?
Может быть то, что уроку уже 2,5 года на что-то повлияло, и сейчас уже установка как-то по-другому происходит. Я, например в ту пору ничего подобного и бесплатного по установке не нашел, поэтому и решил поделиться своими мыслями, как это делаю именно я. Мне кажется подробнее-то некуда.

Недовольства свои мамке с папкой своим высказывай, за то-что дебила вырастили. Если не можешь мозги включить, как программировать собираешься? К тому-же, тебе никто ничего не обязан. Нравится — читай, нет — иди лесом.
Автору СПАСИБО за ресурс.

Иван,
Спасибо за высокую оценку ресурса!
Только, пожалуйста, поаккуратней с высказываниями друг против друга, старайтесь как-то в личных сообщениях.

Автору большое спасибо за материал. Долго не знал как подойти к stm, какую среду выбрать и как откуда что брать. Очень помогло видео урока.

Александр Федоров :

Хочу поблагодарить автора за данные уроки. Хочу задать вопрос. Для создания паяльноц станции нлвичку какую платформу выбрать stm32 или avr. Еще мне не понятно если я выберу stm32 f3 или f4, то я смогу шить только такие же контроллеры, которые установленные на отладочной плате? Ну и если stm 32то какую модель дискавери брать (или не дискавери)!?

Здравствуйте!
Спасибо!
Шить можно и желательно все-таки STM. А шить с помощью ST-Link, а не Discovery. Discovery — это отладочная плата, в которой стоит и контроллер и программатор ST-Link.

Начало работы с STM32 в Keil MDK-ARM

STM32 — это семейство 32-разрядных микроконтроллеров фирмы STMicroelectronics.

Микроконтроллеры содержат микропроцессорное ядро ARM, точнее ARM Cortex-M. Это ядро присуще не только микроконтроллерам STM32, оно существует само по себе, и на его основе выпускается множество микроконтроллеров от разных производителей.

Keil MDK-ARM (произносится «Кеил эм-ди-кей арм») — это среда разработки для микроконтроллеров с ядром ARM Cortex-M.

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

Существует множество других сред разработки. Например, последнее время автор пользуется средой, которую описал в другой статье. Но в этой пойдет речь о Keil MDK-ARM, потому что она имеет большую популярность и достаточно проста.

Первым делом качаем последнюю версию Keil MDK-ARM с официального сайта. Она имеет ряд ограничений, которые не влияют на большинство задач. Самое существенное ограничение состоит в том, что среда не сгенерирует программу объемом больше 32 КБ, но такую программу надо постараться написать. Хотя микроконтроллеры STM32 часто имеют намного больший объем, вплоть до 2 МБ.

На момент написания статьи последняя версия Keil MDK-ARM — 5.18 (от 5 февраля 2016).

Чтобы скачать среду, надо заполнить форму на сайте Keil:

Форма для скачивания MDK-ARM

Следует ввести настоящий адрес электронной почты, иначе сайт будет ругаться. После заполнения и нажатия Submit, дается ссылка для скачивания:

Сcылка для скачивания MDK-ARM

Если вы хотите избежать заполнения формы, то воспользуйтесь страницей, которую сделал автор, чтобы облегчить скачивание.

Качаем и устанавливаем. Установленная среда занимает на диске около 1,3 ГБ. После установки автоматически запускается менеджер пакетов:

Менеджер пакетов

Он нужен, чтобы качать, устанавливать и обновлять различные дополнения (пакеты).

Менеджер пакетов появился в MDK-ARM версии 5, что уменьшило объем установочного файла почти в два раза (версия 4.71 была объемом 550 МВ, а версия 5.00 — 300 МБ).

В левой части менеджера мы выбираем устройства (микроконтроллеры), а в правой соответствующие им пакеты.

Допустим, нам надо вести разработку под микроконтроллер STM32F407VG, который установлен на отладочной плате STM32F4-Discovery.

Тогда находим этот микроконтроллер в списке слева и устанавливаем соответствующий пакет DFP:

Установка DFP

Можно заметить, что среди установленных пакетов есть CMSIS. CMSIS — это библиотека для ядра Cortex-M, общая для всех микроконтроллеров. Библиотека разрабатывается фирмой ARM и доступна для скачивания с официального сайта после регистрации. Можно было бы не устанавливать этот пакет, а пользоваться официальным выпуском библиотеки, но это дополнительные сложности.

Закрываем менеджер пакетов и запускаем Keil uVision5 (произносится мю-вижен):

Значек Keil uVision5

Keil uVision5 — это часть MDK-ARM, графический интерфейс среды, который включает редактор кода:

Keil uVision5

Я рекомендую произвести небольшую настройку редактора. Выбираем меню «Edit -> Configuration…», и производим следующие настройки:

Настройка Keil uVision5

  1. Кодировка UTF-8.
  2. Правая граница кода в 80 символов.
  3. Отступы по 4 пробела.

Эти настройки довольно спорные. У каждого разработчика свои предпочтения.

Теперь создаем проект. Для этого выбираем меню «Project -> New uVision Project…». В открывшемся окне выбираем расположение и имя проекта. Для проекта лучше создать отдельную папку и сохранить проект туда.

После сохранения появится окно выбора устройства. Выбираем нужный микроконтроллер и нажимаем «ОК». Если бы мы не установили нужный пакет, то микроконтроллера не было бы в списке:

Выбор микроконтроллера

В следующем окне предстоит выбрать компоненты, которые будут использоваться в проекте. Необходимо выбрать «CMSIS:CORE» и «Device:Startup»:

Компоненты CMSIS и Startup

После нажатия «OK» процесс создания проекта завершится.

В дальнейшем вы всегда сможете запустить окно выбора компонентов, чтобы добавить или удалить их. Для этого надо выбрать меню «Project -> Manage -> Run-Time Evironment…».

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

Изначальная структура проекта

После создания проекта описанным способом, в окне справа вы увидите следующую структуру проекта:

Здесь мы видим название проекта «example», цель проекта «Target 1», пустую группу файлов «Source Group 1», компоненты CMSIS и Device.

Целей проекта может быть сколько угодно. Цель включает в себя важнейшие настройки проекта в том числе выбор микроконтроллера. Цели нужны, чтобы можно было собрать программу разными способами для одних и тех же файлов исходного кода. Например, вам может понадобиться, чтобы проект охватывал множество микроконтроллеров.

Группы файлов нужны, чтобы красиво группировать файлы исходного кода. Группы помогают легко ориентироваться в файлах в большом проекте. Например, у вас может быть группа файлов, отвечающих за светодиоды, и отдельная группа с файлами для взаимодействия с USB.

В структуре мы видим два файла. Один с расширением «s». Он содержит исходный код на языке ассемблера. Другой с расширением «с». Он содержит исходный код на языке Си.

Собрать проект и получить файл прошивки можно нажав клавишу F7. Но в таком виде проект не будет собран и вы получите ошибку, потому что отсутствует функция «main()».

Функция «main()» — это точка входа в вашу программу, то с чего начинается программа. Ее наличие обязательно если вы пишите программу на языке Си.

Давайте создадим эту функцию. Кликнем на группе «Source Group 1» правой кнопкой и выберем «Add New Item to ‘Source Group 1’…» (перевод: добавить новый элемент в группу ‘Source Group 1’). Создадим файл «main.c»:

Создание файла main.c

В созданный файл добавим код:

int main()

В конец файла стоит добавить пустую строку, иначе при сборке вы получите предупреждение «warning: #1-D: last line of file ends without a newline».

Теперь проект можно собрать клавишей F7. В результате вы получите файл «Objects\example.axf» (по умолчанию имя файла совпадает с именем проекта). Файл располагается в папке с проектом.

Обычно разработчику требуется файл прошивки в формате Intel HEX. Чтобы получить его, надо произвести настройку цели. Чтобы увидеть настройки цели нажмите Alt-F7, перейдите на вкладку «Output» и выберите «Create HEX File».

После очередной сборки вы получите файл «Objects\example.hex».

Сейчас программа не делает ничего, и прошивать ее бессмысленно. Давайте напишем программу, которая управляет состоянием ножки микроконтроллера.

Запустим выбор компонентов с помощью меню «Project -> Manage -> Run-Time Evironment…» и выберем компонент «Device:STM32Cube Hal:GPIO».

В нижней части окна мы увидим неудовлетворенную зависимость «Device:STM32Cube Hal:Common». Выберем этот компонент и увидим еще больший список зависимостей. Необходимо выбрать все требуемые зависимости:

  • Device:STM32Cube Hal:Common
  • Device:STM32Cube Hal:RCC
  • Device:STM32Cube Hal:PWR
  • Device:STM32Cube Hal:Cortex
  • Device:STM32Cube Framework:Classic

STM32Cube — это библиотека, которую предоставляет STMicroelectronics.

При выборе компонентов мы выбираем какие возможности этой библиотеки использовать.

Микроконтроллер, кроме ядра, содержит большое количество периферийных устройств: АЦП, ЦАП, таймеры, различные интерфейсы и многое другое. Каждое периферийное устройство имеет свое название. Например, устройство для работы с портами микроконтроллера называется GPIO, об этом можно узнать из документации на микроконтроллер.

Библиотека STM32Cube многоуровневая, то есть включает в себя множество промежуточных библиотек. Одна из промежуточных библиотек называется STM32Cube HAL, или просто HAL. Она поделена на модули и каждый модуль соответствует какому-нибудь периферийному устройству. Название модуля совпадает с названием устройства, например, имеется модуль GPIO.

Существует большое количество документации по STM32Cube. Но основное описание по работе с периферийными устройствами содержится в руководстве по HAL. Это руководство разработчик использует большую часть времени. Обратимся к нему, чтобы заставить шевелиться ножки микроконтроллера.

Для начала подключим HAL в нашей программе, добавив строчку перед определением функции «main()»:

#include "stm32f4xx_hal.h"

В самом начале функции «main()» вызовем функцию «HAL_Init()», которая инициализирует библиотеку.

Таким образом мы получим следующий код в файле «main.c»:

#include «stm32f4xx_hal.h» int main()

Продолжение следует…

На этом я вынужден прервать свою статью, так как в данный момент мне не на чем отлаживать программу, то есть нет под рукой отладочной платы.

Я написал программу, которая собирается и теоретически должна работать, но я не хочу вводить в заблуждение читателя. Выше изложенный материал считаю полезным и без конечного результата.

В статье я хотел еще привести конечный код и объяснить, как он работает. Могу лишь поделиться непроверенной программой:

#include «stm32f4xx_hal.h» int main() < HAL_Init(); // Разрешить тактирование порта A. __HAL_RCC_GPIOA_CLK_ENABLE(); // Настройки порта. GPIO_InitTypeDef s; s.Pin = GPIO_PIN_0; // Вывод 0. s.Mode = GPIO_MODE_OUTPUT_PP; // Цифровой выход. s.Pull = GPIO_NOPULL; // Без подтяжки. s.Speed = GPIO_SPEED_FREQ_VERY_HIGH; // Максимальная скорость. // Настроить вывод 0 порт A. HAL_GPIO_Init(GPIOA, &s); // Бесконечно переключать состояние порта с максимальной скоростью. while(1) < HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_0); >//return 0; > void SysTick_Handler(void)

Ссылки

  1. Скачать продукты Keil без заполнения формы.
  2. Скринкаст «Eclipse и GNU Tools для разработки под ARM-микроконтроллеры«.
  3. Микроконтроллер STM32F407VG.
  4. Отладочная плата STM32F4-Discovery.
  5. Библиотека STM32CubeF4.
  6. Руководство по STM32CubeF4 HAL.
  7. Библиотека CMSIS.
  8. Отсчет времени в STM32Cube.

ARM. Учебный Курс. Keil + CMSIS. Создание проекта

Хотел вначале толкнуть речугу за ядро, но потом подумал, что этой то инфы на каждом углу, да и рано пока еще. А вот создать простейший проект будет полезней. Также я решил краешком поддерживать и описывать не только STM32F103, но и LPC1343. LPC я буду уделять меньше времени, скорей показывать различия и аналогии. Но, думаю, проблем в освоении не возникнет.

Среда разработки
Я тут однозначно остановился на Keil uVision 4. Эта IDE, пожалуй, является одной из самых мощных и самых массовых не только на ARM, но и на С51 и ряде других камней.
Собственный, весьма неплохой, Си компилятор. Весьма продвинутая и функциональная IDE, плюс в нагрузку там идет мощный симулятор, в том числе с поддержкой периферии, а также всяких виртуальных приборов.
Не как в Proteus, конечно. Схему там не нарисуешь, но вот поглядеть на виртуальный логический анализатор или UART можно запросто. Плюс удобная система создания мастеров кода на ровном месте (всякие визарды аля CVAVR тут дружно пьют йад).
А также Keil поддерживает огромное число разных отладочных систем и JTAG адаптеров. В том числе и ColInkEx, который юзаю я.

Недостатки тоже есть. Во-первых, Keil uVision идет только под винду. Так что линухоиды либо извращаются с виртуалками (но не факт что получится), либо обламываются и корячат из подручного материала что то свое. Впрочем, им не привыкать к геморою со спец софтом 🙂
Во-вторых, Keil платный. И стоит он весьма неслабых денежек.
Кряки, конечно же, валяются на каждом углу. Но! Мы же честные и на наше счастье в Keil есть демо режим, дающий нам ограничение в 32кила. Под наши заморочки с Cortex M3 хватит вполне (а в LPC1343 больше и нету, кстати 😉 ).

Итак, тащим Keil с оффсайта www.keil.com Чтобы не шариться там, сразу двигаем на анкетку, заполняем ее и получаем ссылку на скачивание.

Скачали, ставим, запускаем. Открывается главное окно Keil

Project -> New uvision project

Project -> New uvision project

Откроется стандартный мастер проекта и предложит указать имя будущего файла. Рекомендую также создать и папку под проект, т.к. файлов там будет дофига. Я назвал папку Keil_p1, а проект STM32_p1

Кейл предложит выбрать проц. Список фирм там внушает уважение. Наш выбор:

STMicroelectronics -> STM32F103C8

Там же, в окошке справа, покажут его краткий фарш.

Жмем «ОК» и Keil тут же спрашивает сделать ли стартовый файл с инициализирущим кодом. Говорим «да».

У нас открывается новый проект, в нем есть папочка Target 1 — файлы проекта. Пока там лишь одна группа исходников и один файл:

Переименуем Target 1 и Source Group 1 во что-нибудь более осмысленное. Я их обозвал как STM32 и Startup соответственно.
Добавляем еще две Source Group (это не критично, но так будет логичней и не будет бардака). Одну назовем MainCode, вторую CMSIS.
Дважды кликаем по группе MainCode и у нас открывается диалог добавления файлов. Т.к. файлов пока нет, то мы идем в папку проекта, создаем там подпапку Main и в ней делаем простой текстовый файл с именем main.c
Теперь его можно добавить в кодовую группу. Тут же появился в дереве проекта файл main.c

Теперь надо добавить в проект библиотеку CMSIS

Что такое CMSIS
Проект никуда не убежит, потому сделаю небольшое отступление и опишу что есть CMSIS.

Итак, CMSIS это стандартная для всех кортексов библиотека. Как бы единый стандарт описаний ресурсов. Благодаря ей легко таскать код с одного вида ARM Cortex контроллеров на другой. Конечно периферия у всех армов разная, даже в пределах одной линейки, но вот доступ к регистрам периферии из Си стандартизирован и описан в CMSIS. А то, что едино для всех Cortex M3 — ядро, контроллер прерываний и системный таймер, то едино и во всех CMSIS и при переносе с контроллера на контроллер правки не требует вообще.

Библиотека состоит из нескольких файлов:

Описание ядра стандартные для всех Cortex M3

Описание конкретного контроллера (семейства точнее), лежит в CMSIS библиотеке конкретного семейства и качается с официального сайта производителя контроллера.

  • stm32f10x.h — файл описание периферии, а также структуры доступа к ним. Все самое нужное и важное лежит тут
  • system_stm32f10x.c — функции CMSIS. Их немного (SystemInit, SystemCoreClockUpdate, SystemCoreClock), касаются они только стартовой инициализации контроллерной периферии и работе с установками тактовой частоты. Они стандартны для всех CMSIS для M3 семейства.
  • system_stm32f10x.h — заголовочные файлы для функций CMSIS.

В файле stm32f10x.h все регистры периферии увязаны в такую конструкцию:

Вначале описаны типы

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
typedef struct { __IO uint16_t CR1; uint16_t RESERVED0; __IO uint16_t CR2; uint16_t RESERVED1; __IO uint16_t OAR1; uint16_t RESERVED2; __IO uint16_t OAR2; uint16_t RESERVED3; __IO uint16_t DR; uint16_t RESERVED4; __IO uint16_t SR1; uint16_t RESERVED5; __IO uint16_t SR2; uint16_t RESERVED6; __IO uint16_t CCR; uint16_t RESERVED7; __IO uint16_t TRISE; uint16_t RESERVED8; } I2C_TypeDef;
1 2 3 4 5 6 7 8 9 10
typedef struct { __IO uint32_t CRL; __IO uint32_t CRH; __IO uint32_t IDR; __IO uint32_t ODR; __IO uint32_t BSRR; __IO uint32_t BRR; __IO uint32_t LCKR; } GPIO_TypeDef;

Таких и похожих записей там добрая половина файла. Рекомендую открыть этот файл каким нибудь NotePad++ и оглядеть, что там вообще есть. Пригодится когда будете работать с разной периферией, чтобы знать как зовутся те или иные группы периферии.

А ниже идет привязка этих типов к конкретным адресам. Вначале задается базовый адрес откуда идет пространство адресов IO

1 2 3 4 5 6 7
#define PERIPH_BB_BASE ((uint32_t)0x42000000) /*! < Peripheral base address in the alias region */#define SRAM_BB_BASE ((uint32_t)0x22000000) /*! < SRAM base address in the alias region */#define SRAM_BASE ((uint32_t)0x20000000) /*! < SRAM base address in the bit-band region */#define PERIPH_BASE ((uint32_t)0x40000000) /*! < Peripheral base address in the bit-band region */#define FSMC_R_BASE ((uint32_t)0xA0000000) /*!< FSMC registers base address */

и затем пошли дефайнить базовые адреса для конкретной периферии. Записи такого вида:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/*! < Peripheral memory map */#define APB1PERIPH_BASE PERIPH_BASE #define APB2PERIPH_BASE (PERIPH_BASE + 0x10000) #define AHBPERIPH_BASE (PERIPH_BASE + 0x20000) #define TIM2_BASE (APB1PERIPH_BASE + 0x0000) #define TIM3_BASE (APB1PERIPH_BASE + 0x0400) #define TIM4_BASE (APB1PERIPH_BASE + 0x0800) #define TIM5_BASE (APB1PERIPH_BASE + 0x0C00) #define TIM6_BASE (APB1PERIPH_BASE + 0x1000) #define TIM7_BASE (APB1PERIPH_BASE + 0x1400) #define TIM12_BASE (APB1PERIPH_BASE + 0x1800) #define TIM13_BASE (APB1PERIPH_BASE + 0x1C00) #define TIM14_BASE (APB1PERIPH_BASE + 0x2000) .

Их там очень много — вся периферия которая есть в STM32 семействе. А ее ОЧЕНЬ много.

После присовоения баз идет уже создание непосредственно указателей на структуры к которым мы и будем обращаться. Идет прорва записей вида:

1 2 3 4 5 6
#define TIM2 ((TIM_TypeDef *) TIM2_BASE) #define TIM3 ((TIM_TypeDef *) TIM3_BASE) #define TIM4 ((TIM_TypeDef *) TIM4_BASE) #define TIM5 ((TIM_TypeDef *) TIM5_BASE) #define TIM6 ((TIM_TypeDef *) TIM6_BASE) #define TIM7 ((TIM_TypeDef *) TIM7_BASE)

#define TIM2 ((TIM_TypeDef *) TIM2_BASE) #define TIM3 ((TIM_TypeDef *) TIM3_BASE) #define TIM4 ((TIM_TypeDef *) TIM4_BASE) #define TIM5 ((TIM_TypeDef *) TIM5_BASE) #define TIM6 ((TIM_TypeDef *) TIM6_BASE) #define TIM7 ((TIM_TypeDef *) TIM7_BASE)

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

И теперь, что мы имеем. Покажу на примере порта GPIO.

Есть общая для всех портов структура типа:

1 2 3 4 5 6 7 8 9 10
typedef struct { __IO uint32_t CRL; __IO uint32_t CRH; __IO uint32_t IDR; __IO uint32_t ODR; __IO uint32_t BSRR; __IO uint32_t BRR; __IO uint32_t LCKR; } GPIO_TypeDef;

И есть указатели на нее, с привязкой к конкретным GPIO

1 2 3 4 5 6 7
#define GPIOA ((GPIO_TypeDef *) GPIOA_BASE) #define GPIOB ((GPIO_TypeDef *) GPIOB_BASE) #define GPIOC ((GPIO_TypeDef *) GPIOC_BASE) #define GPIOD ((GPIO_TypeDef *) GPIOD_BASE) #define GPIOE ((GPIO_TypeDef *) GPIOE_BASE) #define GPIOF ((GPIO_TypeDef *) GPIOF_BASE) #define GPIOG ((GPIO_TypeDef *) GPIOG_BASE)

#define GPIOA ((GPIO_TypeDef *) GPIOA_BASE) #define GPIOB ((GPIO_TypeDef *) GPIOB_BASE) #define GPIOC ((GPIO_TypeDef *) GPIOC_BASE) #define GPIOD ((GPIO_TypeDef *) GPIOD_BASE) #define GPIOE ((GPIO_TypeDef *) GPIOE_BASE) #define GPIOF ((GPIO_TypeDef *) GPIOF_BASE) #define GPIOG ((GPIO_TypeDef *) GPIOG_BASE)

И если теперь нам надо что-то записать в регистр BSRR порта G, то обращение к нему идет в таком виде:

GPIOG->BSSR = 0x0001;

И не надо думать о том, где какой адрес и по какому смещению лежит. Все сгруппировано и собрано в связки удобные. Конечно у разных процов по разному все имена зовутся. Например, у LPC13хх в CMSIS прописано чуток иначе:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
typedef struct { union { __IO uint32_t MASKED_ACCESS[4096]; struct { uint32_t RESERVED0[4095]; __IO uint32_t DATA; }; }; uint32_t RESERVED1[4096]; __IO uint32_t DIR; __IO uint32_t IS; __IO uint32_t IBE; __IO uint32_t IEV; __IO uint32_t IE; __IO uint32_t RIS; __IO uint32_t MIS; __IO uint32_t IC; } LPC_GPIO_TypeDef;

typedef struct < union < __IO uint32_t MASKED_ACCESS[4096]; struct < uint32_t RESERVED0[4095]; __IO uint32_t DATA; >; >; uint32_t RESERVED1[4096]; __IO uint32_t DIR; __IO uint32_t IS; __IO uint32_t IBE; __IO uint32_t IEV; __IO uint32_t IE; __IO uint32_t RIS; __IO uint32_t MIS; __IO uint32_t IC; > LPC_GPIO_TypeDef;

1 2 3 4
#define LPC_GPIO0 ((LPC_GPIO_TypeDef *) LPC_GPIO0_BASE ) #define LPC_GPIO1 ((LPC_GPIO_TypeDef *) LPC_GPIO1_BASE ) #define LPC_GPIO2 ((LPC_GPIO_TypeDef *) LPC_GPIO2_BASE ) #define LPC_GPIO3 ((LPC_GPIO_TypeDef *) LPC_GPIO3_BASE )

#define LPC_GPIO0 ((LPC_GPIO_TypeDef *) LPC_GPIO0_BASE ) #define LPC_GPIO1 ((LPC_GPIO_TypeDef *) LPC_GPIO1_BASE ) #define LPC_GPIO2 ((LPC_GPIO_TypeDef *) LPC_GPIO2_BASE ) #define LPC_GPIO3 ((LPC_GPIO_TypeDef *) LPC_GPIO3_BASE )

Но система та же самая. И доступ будет такой же. Например, к регистру DIR порта 1:

LPC_GPIO1->DIR = 0x0002;

Названия иные конечно, но суть не меняется. Это существенно упрощает написание слоя HAL

В разных CMSIS от разных производителей есть свои фишки. Т.е. в базовой части они совпадают друг с другом, но вот дальше кто во что горазд. Впрочем это уже не имеет значения и делается для нашего удобства.

Например, в CMSIS от STM32 после обязательной части идет произвольная программа вида:

1 2 3 4 5 6 7 8 9 10 11 12 13 14
/******************* Bit definition for GPIO_CRL register *******************/ #define GPIO_CRL_MODE ((uint32_t)0x33333333) /*! < Port x mode bits */#define GPIO_CRL_MODE0 ((uint32_t)0x00000003) /*! < MODE0[1:0] bits (Port x mode bits, pin 0) */#define GPIO_CRL_MODE0_0 ((uint32_t)0x00000001) /*! < Bit 0 */#define GPIO_CRL_MODE0_1 ((uint32_t)0x00000002) /*! < Bit 1 */#define GPIO_CRL_MODE1 ((uint32_t)0x00000030) /*! < MODE1[1:0] bits (Port x mode bits, pin 1) */#define GPIO_CRL_MODE1_0 ((uint32_t)0x00000010) /*! < Bit 0 */#define GPIO_CRL_MODE1_1 ((uint32_t)0x00000020) /*! < Bit 1 */#define GPIO_CRL_MODE2 ((uint32_t)0x00000300) /*! < MODE2[1:0] bits (Port x mode bits, pin 2) */#define GPIO_CRL_MODE2_0 ((uint32_t)0x00000100) /*! < Bit 0 */#define GPIO_CRL_MODE2_1 ((uint32_t)0x00000200) /*!< Bit 1 */

и таких записей почти на пол мегабайта.
Что это? А Это расшифровка отдельных битов каждого из регистров по функциям! Готовые битмаски. Т.е. производитель уже заранее позаботился о том, чтобы нам не пришлось ломать голову над режимами и помнить где какие биты стоят. Например, хотим мы выставить для порта GPIOG.1 бит режима MODE[0] (RM0008 стр. 148 табл. 18 и 19) Так нам даже биты регистра CRL не придется считать. И никаких магических чисел в коде!

GPIOG->CRL |= GPIO_CRL_MODE1_0; //Битте!

GPIOG->CRL |= GPIO_CRL_MODE1_0; //Битте!

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

А в CMSIS LPC1300 есть не менее доставляющая фишка (работает правда только в Keil) — встроенный визард.

Там в комментах (!) есть хитрые тэги примерно такого вида:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
/* //-------- >> ------------------ */ /*--------------------- Clock Configuration ---------------------------------- // // Clock Configuration // System Clock Setup // System Oscillator Enable // Select System Oscillator Frequency Range // 1 - 20 MHz // 15 - 25 MHz // // Watchdog Oscillator Enable // Select Divider for Fclkana // 2 4 6 8 // 10 12 14 16 // 18 20 22 24 // 26 28 30 32 // 34 36 38 40 // 42 44 46 48 // 50 52 54 56 // 58 60 62 64 // Select Watchdog Oscillator Analog Frequency (Fclkana) // Disabled // 0.5 MHz // 0.8 MHz // 1.1 MHz // 1.4 MHz // 1.6 MHz // 1.8 MHz // 2.0 MHz // 2.2 MHz // 2.4 MHz // 2.6 MHz // 2.7 MHz // 2.9 MHz // 3.1 MHz // 3.2 MHz // 3.4 MHz // . 

/* //——— >> —————— */ /*——————— Clock Configuration ———————————- // // Clock Configuration // System Clock Setup // System Oscillator Enable // Select System Oscillator Frequency Range // 1 — 20 MHz // 15 — 25 MHz // // Watchdog Oscillator Enable // Select Divider for Fclkana // 2 4 6 8 // 10 12 14 16 // 18 20 22 24 // 26 28 30 32 // 34 36 38 40 // 42 44 46 48 // 50 52 54 56 // 58 60 62 64 // Select Watchdog Oscillator Analog Frequency (Fclkana) // Disabled // 0.5 MHz // 0.8 MHz // 1.1 MHz // 1.4 MHz // 1.6 MHz // 1.8 MHz // 2.0 MHz // 2.2 MHz // 2.4 MHz // 2.6 MHz // 2.7 MHz // 2.9 MHz // 3.1 MHz // 3.2 MHz // 3.4 MHz // .

Я вначале долго тупил, думал это что-то вроде DOXYGEN для автоматической генерации описаний (как в AVRLIBC), а это оказался скрипт визарда. Когда Keil находит такую ботву, то снизу, рядом с вкладкой сорца, появляется вкладка Configuration Wizard

Где галочками расставляешь опции, а эти галочки в реальном времени меняют биты в #define строках которыми описывается периферия. Так что потом, после конфигурирования, остается только вызвать SystemInit() и вся периферия сконфигурирована, проц запущен на нужной частоте.
Впрочем, в CMSIS от LPC1300 визардом конфигурировать можно только тактовый генератор. А вот в убойном файле STM32_Init.c для STM32 можно сконфигурировать ВООБЩЕ ВСЕ!

Он, правда, к CMSIS отношение не имеет (и фиг знает что там с корректностью, поэтому надо с оглядками его юзать). Однако, никто не мешает подцепить его до кучи и вызвать из него аналог того же SystemInit, вместо CMSIS овского.

Подключаем CMSIS
В том, что эта библиотечка есть рулез думаю никто не сомневается, потому подключаем мы ее в обязательном порядке. Копируем ее в нашу папочку проекта целиком, со всем барахлом, прям как есть.

А затем даблклик по кодовой группе CMSIS и добавляем все .С файлы из состава CMSIS

  • system_stm32f10x.c
  • core_cm3.c

у STM там еще есть какие-то примеры и левые файлы. Их добавлять не надо. У LPC же CMSIS рафинированая. Там только system_LPC13xx.c и core_cm3.c

Вот так выглядит теперь наш проект.

Осталось сконфигурировать пути и настроить среду. Жмем ALT+F7 и или из контекстного меню

И попадаем в диалог настройки проекта:

  • Target можно настроить тактовую частоту эмуляции. Оставим пока 8МГц
  • Output — тут только поставить галочку Create Hex file иначе мы кекса не дождемся. Что заливать то будем?
  • Listing — настройка текстовых листнигов.
  • User — запуск всяких батников после компиляции.
  • С/С++ — вот тут уже стоит поковряться. В первую очередь обратите внимание на переключатель оптимизатора. А еще там же прописываются Include пути.

Нам надо указать пути к хидерам CMSIS. У STM32 они раскиданы по двум папкам «CMSIS\CoreSupport\» и «CMSIS\DeviceSupport\ST\STM32F10x\» (У LPC более умно — хидеры там лежат в отдельной папочке «CMSISv1p30_LPC13xx\inc\»). Если мы перетаскиваем готовый проект откуда то, то пути к его заголовочным файлам тоже надо прописать тут же. Иначе компилятор их не найдет. Вот мои пути:

Среда готова. Можно попробовать что-нибудь создать и запустить. Пустой main.c ждет, чтобы мы туда накатали код. Сделаем простейшую мигалку, скорей даже генератор — даже без задержек временных. В симуляторе то один хрен пошагово выполнять.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
#include "stm32f10x.h" void InitAll(void) = RCC_APB2ENR_IOPAEN; // Подали такты на порт. Без этого работать не будет. // Жоские вилы STM32 =))) А в симуляторе без этого работает на ура GPIOA->CRL &= ~GPIO_CRL_CNF3; // Обнулили биты CNF3 т.к. после старта они настроены как (01) // режим Open Drain. А нам надо Push-Pull (00) GPIOA->CRL  int main(void) { InitAll(); while(1) { GPIOA->BSRR =GPIO_BSRR_BS3; // Выставили бит 3. GPIO_BSRR_BS3 это битмаска GPIOA->BSRR =GPIO_BSRR_BR3; // Сбросили бит 3. } }

#include «stm32f10x.h» void InitAll(void) < RCC->APB2ENR |= RCC_APB2ENR_IOPAEN; // Подали такты на порт. Без этого работать не будет. // Жоские вилы STM32 =))) А в симуляторе без этого работает на ура GPIOA->CRL &= ~GPIO_CRL_CNF3; // Обнулили биты CNF3 т.к. после старта они настроены как (01) // режим Open Drain. А нам надо Push-Pull (00) GPIOA->CRL |= GPIO_CRL_MODE3_0; // Настроили порт на выход (для простоты возьмем тот факт, // что GPIOA-CRL-MODE после сброса равны (00). Но в реальной программе // эти моменты надо проверять и делать полную инициализацию порта. // Согласно таблице 18 из RM return; > int main(void) < InitAll(); while(1) < GPIOA->BSRR =GPIO_BSRR_BS3; // Выставили бит 3. GPIO_BSRR_BS3 это битмаска GPIOA->BSRR =GPIO_BSRR_BR3; // Сбросили бит 3. > >

Сброс и установка бита в STM32 может делаться через регистр сброса и установки (логично, да?) при этом порты тут 16ти разрядные. А регистр 32 разрядный. Запись единички в бит старшего слова дает сброс, в бит младшего — установку бита. Или наоборот, не помню точно.

Для LPC1343 будет выглядеть так (пишу по памяти, могут быть мелкие косяки, проверяйте):

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
#include "LPC13xx.h" void InitAll(void) { LPC_IOCON->PIO0_7 = 13; // Pull Dn LPC_GPIO0->DATA = 0; // DATA=0 LPC_GPIO0->DIR = 17; // DIR 0.7= Out return; } int main(void)  InitAll(); while(1) { LPC_GPIO0->DATA &=~(17); // Clear bit LPC_GPIO0->DATA  }

Теперь поэмулируем и поглядим так ли это.

Жмем компиляцию (F7 build) и затем отладку — такая красная буковка d в лупе (Ctrl+F5).

Откроется сразу окно отладки, примерно как в AVR Studio.

Вверху окно дизассемблера (удобно, кстати). Слева регистры РОН. На тулбаре прорва кнопочек, рекомендую там полазить. Много интересного нароете.

Как и в любом отладчике мы можем ходить пошагово (F11) с пропуском (F10) функций, с выходом из функции (Ctrl+F11) и прыжок до курсора (Ctrl+F10).

Осталось проверить дрыгается ли наш вывод порта. Надо открыть вкладку периферии и достать панельку порта IO.

Peripherials->General Purpose IO -> GPIOA

Peripherials->General Purpose IO -> GPIOA

Вылезет вот такая вот штука:

Там сразу видно все режимы в котором находится порт, а также регистры конфигурации. Начинаем шагать по программе, наблюдая за содержимым порта. Видим, что сначала на порт подались такты и надпись внизу изменилась на Clock Enabled. Потом переключился режим одного из выводов на выход. А дальше, с каждой итерацией цикла while, в регистре ODR начала прыгать туда сюда галочка, указывая на то, что внешний уровень меняется.

Первая программа работает. Пока в эмуляции. В следующий раз расскажу как и чем прошивать этот контроллер.

Файлы к статье
Чтобы тебе не шариться по инету, вот я тут положил:

  • CMSIS для LPC1300
  • CMSIS для STM32F10x
  • Файл проекта в Keil для STM32
  • Адский визард STM32_Init.c способный настроить все что угодно
  • Обзорное описание вкусняшек STM32 на русском языке. Читать всем, чтобы знать кого нам подсунули

Спасибо. Вы потрясающие! Всего за месяц мы собрали нужную сумму в 500000 на хоккейную коробку для детского дома Аистенок. Из которых 125000+ было от вас, читателей EasyElectronics. Были даже переводы на 25000+ и просто поток платежей на 251 рубль. Это невероятно круто. Сейчас идет заключение договора и подготовка к строительству!

А я встрял на три года, как минимум, ежемесячной пахоты над статьями :)))))))))))) Спасибо вам за такой мощный пинок.

214 thoughts on “ARM. Учебный Курс. Keil + CMSIS. Создание проекта”

Vitek885 :

Вау круто!
тока сцыль «Адский визард STM32_Init.c способный настроить все что угодно» ведет на архив прожекта («Файл проекта в Keil для STM32»)

DI HALT :
dansar :
Я так понимаю, владельцы LPCExpresso идут лесом, нужно паять другой адаптер?
DI HALT :

Expresso слив полный. Мало того, что работает только на LPC так еще с кейлом не дружит. В топку! Впрочем, ничего не мешает делать по аналогии. Между GCC и Keil разница то, в общем, не сильно большая в коде.

Неплохо. Я не знал, что надо вызывать функцию InitAll(), видно поэтому у меня с конфигом не работало.
Вообщем, имхо, arm-вские контроллеры часто требуют домысливания за пределами основной документации. Уже не раз обращал внимание на то, что некоторые довольно важные вещи не расписаны. Не то что в 8-битниках =)

angrykid :
Спасибо Ди, как всегда в тему:)

у линуксоидов есть GCC-toolcahin который умеет собирать код и для cortex-M3 камней. засада в удобстве, есть Sourcery G++ Lite, в котором уже всё есть, но многие любят собирать свой тулчейн с шахматами и поэтессами. Вот тут и начинается поиск и прикручивание… http://www.onarm.com/download/download395.asp например есть такое. В общем, было бы желание 🙂

DI HALT :

Ну кроме компилера еще не помешают отладчики разные. Хотя что то для работы с JTAG там имеется, но вот поддерживат ли оно SWD это еще надо проверить.

Не помешают. Всё хочу добраться до OpenOCD, но пока нет ни отладчика, ни задач для использования отладчика.

prakash :
Отдельное спасибо за выложенную книгу про STM32! Только сегодня искал, но нашёл только в html…
О какой книге идет речь?
prakash :
Дык об ентой:
http://easyelectronics.ru/img/ARM_kurs/CMSIS/stm32.pdf
Jack_Pot :

Осторожнее с этими русскими шитами. Глянул ща в этот шит про режимы загрузки (стр.46), а там «Для перевода STM32 в режим загрузчика,
внешние выводы BOOT0 и BOOT1 должны быть переведены соответственно в низкое и высокое состояние.»
в RM0008 про System Memory boot mode все в точности до наоборот.

Ultrin :
Да уж… Читаю русскоязычное описание вкусностей, заляпал весь стол слюнями… Спасибо за информацию
shurup :

Какой-то обрезанный Си в Keil. Напрягает такая мелочь — надо объявлять переменные используемые в функции в самом её начале. Т.е. конструкция типа «for(int i=0;….» не канает. Да и с приведением типов тоже голяк. А что еще будет дальше …. .

Нормальный C89, олдскул во все поля 🙂
Ageofenigma :

Нормальный в кейле Си. Вообще «конструкция типа “for(int i=0;….” не канает» никогда и не канала в стандарте СИ 89го, нельзя было где угодно объявлять переменные. Это в СИ 99го можно, а также inline функции и прочее. Просто в настройках кейла во вкладке С/C++ в строчке Misc Controls напиши —c99 и будет у тебя всё хорошо.

shurup :

Спасибо за подсказку. Не знал. А так вообще моразм — на дворе 2010 год. Могли бы и по умолчанию эту опцию включить. Кому сейчас нужно писать в формате 89-го. Дико было бы наверно после установки на комп Win7 видеть интерфейс 98-й винды «примечание: что бы работать с граф интерфейсом Win7 включите пожалуйста…..»

Открою тебе небольшую тайну — несмотря на то, что на дворе 2010 год, в настоящее время полностью поддерживает стандарт C99 только один компилятор, а некоторые (весьма распространённые, кстати) компиляторы о нём даже и не подозревают =).

shurup :
Спасибо. Оч. ценная информция )). Ух ты тайна — аж муражки по всему телу пробежались.
shurup :

А в общем мой вопрос уже решился. Спасибо Ageofenigma. Действительно не знал, что и где включить, чтобы писать в привычном для меня виде. Знакомство с Кейл началось вот только-только.

newboy :
IAR получается не поддерживает 99-ого ?
yellowjohn :

Немного офф, но все-же… В этой статье было применено 3 варианта обращения с фигурными скобками. Щас постараюсь показать на примере, о чем я.
Вариант1:
void function () тут пишем функцию
>
Вариант2:
void function()
тут пишем функцию
>
И вариант 3:
void function ()
тут пишем функцию
>
лично мне с точки зрения кашерности нравится стиль написания 3, но может быть существует некий стандарт, или правила написания в зависимости от контекста?

yellowjohn :

Блин, вордпресс сожрал символ табуляции перед телом функции в примере 3. Должно было получиться что-то типа:
void function ()
..tab..тут пишем функцию
>

shurup :

в 1-м варианте тоже полезны будут табы. отступы желательно применять — повышает читабельность текста. Я применяю тоже 3-й вариант. А так можно хоть в одну строку набрать весь текст программы, компилятору пофигу.

DI HALT :

Я предпочитаю вариант 2. Третий получился случайно. Т.к. я его копипастил из другого проекта. А где применен 1й вариант? Чето не нашел, обычно я так не пишу — самого бесит.

yellowjohn :
В примерах кода, после фразы «Например, у LPC13хх в CMSIS прописано чуток иначе:»
DI HALT :
А ну это не мой код, а создателей CMSIS

Ну стандарта на это нет, есть просто куча разных стилей. Если взять IDE Code::Blocks, то там есть инструмент, позволяющий отформатировать исходники под определённый стиль и в настройках есть десяток преднастроенных стилей. Например третий вариант — это, скорее всего, стиль ANSI.
Кстати, мне этот форматтер не удалось настроить под мой стиль, потому что я люблю условия писать в виде:

if(. ) < case1; >else
yellowjohn :

типа у тебя уже рефлекс на три скобки?) А если else не нужен, все равно пишешь? Ведь если не написать, потеряется трехскобочность — характерный признак условия в коде.

Не, конечно не до такой степени =) Я вообще часто скобки опускаю, где они не обязательны (хотя иногда и ставлю даже там где не нужны — зависит от ситуации). Кроме того, частенько встречается ещё и вариант, условий где больше трех скобок:

if(cond1) < case1; >else if(cond2) < case2; >else if(cond3) < case3; >else
Goron Dekar :

Мдааа. Если AVR-studio использовала gcc, то кайло юзает свой тулчейн. И переносимость примеров падает. Жаль. Да, в открытых реализациях SWD просто нет. Но зато JTAG позволяет «Граничное сканирование» — boundary scan. А освоение этой технологии может быть интересно, ибо отладка и ремонт чужых устройств становятся проще в разы.

shurup :

Подскажите кто уже разбирался с этим. Пока не пришла заказанная демо боард с стм32 прикупил кучку LPC1114-х, сижу ковыряю их пока. Вот возник вопрос. В CMSIS есть по паре функций разрешения и запрета прерываний (__enable_irq(), __enable_fault_irq(), __disable_irq(), __disable_fault_irq()). В чем разница между например __enable_irq() и
__enable_fault_irq(). Насколько смог понять __enable_irq() — общее разрешение прерываний, а что означает fault.

DI HALT :

Не совсем. Обычные IRQ это неприоритетные прерывания, вроде таймеров всяких. А Fault IRQ это прервания вроде систика, а также разных жоп, вроде неправильного операнда или срыва стека какого (чо там в первых числах по прерываниям, вот это FIQ и есть)

shurup :

Всем привет. Россияне тоже начали мутить с выпуском CortexM3 (1986ВЕ91). На данную микруху на сайте Миландр есть Р_У_С_С_К_И_Й шит. Хороший (т.е. на нашенском) шит, мож кому сгодится. По нему пытаюсь пока вкурить в контроллер прерываний.

DI HALT :
О прикольно.
newboy :
Такое ощущение что делали они даташит в ворде а потом в пдф перевели
neosystem :

Решил тоже арм изучить, такая плата пойдет под этот учебный курс?
http://item.taobao.com/item.htm?id=7155579947
собрана на STM32F103VCT6 LQFP100

DI HALT :
ХЗ у меня этот сайт даже грузиться не захотел.
neosystem :
нажми обновить должен загрузится с пятого раза
а нормальный комп не дешевле ли будет купить? 😀
Где в Украине можно приобрести эту сладкую парочку?
LPC1343FBD48 -1 шт.
STM32F103C8T6 -1 шт.
kalvenolt :

STM32F103C8 есть на имраде.
LPC я нашел вот здесь http://amel.com.ua по 22 грн.
Всё это находится в Киеве

vertermcu :

Что это? А Это расшифровка отдельных битов каждого из регистров по функциям! Т.е. производитель уже заранее позаботился о том, чтобы нам не пришлось ломать голову над режимами и помнить где какие биты стоят. Например, хотим мы выставить порт GPIOG.1 в режим MODE[0] (он так в даташите зовется). Так нам даже биты не придется считать! И никаких магических чисел в коде! Делаем так:1 GPIOG->CRL = GPIO_CRL_MODE1_0; //Битте! GPIO_CRL_MODE1_0 — это не режим, а битовая маска, где вы смогли найти режим MODE[0] в даташите, там про это ни слова. Соответсвенно GPIOG->CRL = GPIO_CRL_MODE1_0; присвоит значение битовой маски регистру GPIOG_CRL, сбросив все остальные биты. Можно установить это бит в единичку с помощью лог. сложения (у вас дальше в примере так и сделано) GPIOG->CRL |= GPIO_CRL_MODE1_0; , но это не определит режим работы вывода порта полностью, т.к остался не инициализированным бит MODE[1] (GPIO_CRL_MODE1_1). Вот пример дефайнов режимов:
/*! < PLL2MUL configuration */
#define RCC_CFGR2_PLL2MUL ((uint32_t)0x00000F00) /*! < PLL2MUL[3:0] bits */
#define RCC_CFGR2_PLL2MUL_0 ((uint32_t)0x00000100) /*! < Bit 0 */
#define RCC_CFGR2_PLL2MUL_1 ((uint32_t)0x00000200) /*! < Bit 1 */
#define RCC_CFGR2_PLL2MUL_2 ((uint32_t)0x00000400) /*! < Bit 2 */
#define RCC_CFGR2_PLL2MUL_3 ((uint32_t)0x00000800) /*! < Bit 3 */ #define RCC_CFGR2_PLL2MUL8 ((uint32_t)0x00000600) /*!< PLL2 input clock * 8 */
#define RCC_CFGR2_PLL2MUL9 ((uint32_t)0x00000700) /*! < PLL2 input clock * 9 */
#define RCC_CFGR2_PLL2MUL10 ((uint32_t)0x00000800) /*! < PLL2 input clock * 10 */
#define RCC_CFGR2_PLL2MUL11 ((uint32_t)0x00000900) /*! < PLL2 input clock * 11 */
#define RCC_CFGR2_PLL2MUL12 ((uint32_t)0x00000A00) /*! < PLL2 input clock * 12 */
#define RCC_CFGR2_PLL2MUL13 ((uint32_t)0x00000B00) /*! < PLL2 input clock * 13 */
#define RCC_CFGR2_PLL2MUL14 ((uint32_t)0x00000C00) /*! < PLL2 input clock * 14 */
#define RCC_CFGR2_PLL2MUL16 ((uint32_t)0x00000E00) /*! < PLL2 input clock * 16 */
#define RCC_CFGR2_PLL2MUL20 ((uint32_t)0x00000F00) /*!CFGR2 = (RCC_CFGR2 & ~RCC_CFGR2_PLL2MUL) | RCC_CFGR2_PLL2MUL11

vertermcu :

Первая строка — это битовая маска на все 4 бита отвечающих за режим. Следующие 4 строки — это битмаска на каждый отдельный бит, ну а дальше идут режимы. Соответственно для того, чтобы установить PLL2 в режим умножения частоты на 11 (не изменив другие биты регистра) нужно написать нечто подобное:
RCC->CFGR2 = (RCC_CFGR2 & ~RCC_CFGR2_PLL2MUL) | RCC_CFGR2_PLL2MUL11

DI HALT :

Неправильно выразился. MODE[0] это бит 0 из группы MODE соответственно битмаска GPIO_CRL_MODE1_0 выставит для первого пина порта моде0. Щас подправлю.

Вроде бы все6 как написано сделал , но: Build target ‘STM32F100’
compiling main.c…
linking…
1Proj.axf: Error: L6630E: Invalid token start expected number or ( but found n at position 5 on line 5
1Proj.axf: Error: L6629E: Unmatched parentheses expecting ) but found n at position 5 on line 5
1Proj.sct(5): error: L6292E: Ignoring unknown attribute ‘null’ specified for region LR_.
1Proj.sct(5): error: L6228E: Expected ‘ 1Proj.sct: Error: L6372E: Image needs at least one load region.
Target not created Заодно- разъясните , что такое axf и sct?

DI HALT :

А ХЗ я сам с армами разбираюсь не больше недели 🙂 Что смущает — у меня проект собирается для 103 у тебя же 100 И еще что то он у тебя ругается на кучу всего. Словно синтаксические ошибки какие. Возьми поудаляй из кода все что может содержать косяк. Оставь только пустой майн.

Дык билиотеки то вроде для всей 100-серии. И ругается не на майн. Май
Майн вообще из твоего проекта взят.
DI HALT :
Нет, для 101 и далее. 100я серия оказывается не из этой оперы.

Обманываете вы все же, господин хороший. Серия одна. Надо было просто во вкладке Target указать диапазон ROM1( нашел в UM0986 -http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/USER_MANUAL/CD00283786.pdf)

DI HALT :

Ну в RM указана сквозная 101…103 сотки там нет. На нее отдельнй RM. Может они и сходные очень, но серии это разные.

Ultrin :

Ди, а как Кейлу в во вкладке Debug сказать что у меня CoLinkEx? Чет я его там в списке найти не могу…

Ultrin :
Туплю… Нашел плагин для Кейла…
Ultrin :

Запустил пример со статьи на пришедшем STM32F103C8. Заодно проверил самопальный CoLinkEx и самопальную макетку. Все вроде работает. Светодиод уже мигает.

iforgotmylogin :

Дяденьки, а разве культурно так делать? В названии сайта пишете «электроника для всех». И тут же в статье у вас линуксоиды — «обламываются». И макинтошники наверное тоже? Не говоря уже о всяких там бсдунах. Получается что не очень то электроника поданая под вашим соусом и для всех, а? А потом еще и учите юзать платный продукт. Который стоит столько что это получается ну совсем не для всех. Особенно в России. Потому что в любительско-малотиражной практике покупать кайло совершенно неоправданно. А 32 Кб всем не хватит. Ну, как и 640Кб — почему-то не хватило. К чему это я? К тому что нынче полно кроссплатформенных тулзей (тот же CodeSourcery gcc для армов например), которые можно законно и бесплатно использовать, да еще и под разными системами. Не логичнее ли обучать их использованию, если уж хочется чтобы электроника была действительно для *всех* и сразу *легально*? Без пираси и махинаций, за которые нынче еще и reboot. Без ценза по типу операционки, толщине кошелька достаточной для покупки кайлы и подобным несуразицам. Лично я вот пользуюсь этак тремя разными типами операционок и такая подмена понятий мне не нравится. И кстати я бы не сказал что Windows наиболее удобная для меня операционка. В ней многие вещи удобные для программирования, особенно программирования железок делаются довольно сложно. В *никсах, например, есть чудная либа libusb, позволяющая удобно работать с юсб из своих программ без попадания на написание ядерных драйверов. Под винду она конечно тоже есть, но есть и куча грабелек отсутствующих под другими платформами. В итоге с USB в виде как он есть — проще всего работать под другими операционками, особенно если впадлу писать ядерные дрова. А в современных виндах до кучи придется еще и с подписями на самописные помучаться.

В принципе присоединяюсь к замечаниям iforgotmylogin. Но меня все это особенно сейчас не волнует, у меня другая проблема. Я никак не могу достать LPC1343FBD48 в Украине. Кто знает где их здесь взять?

DI HALT :

Возможности, уважаемый, возможности. С кейлом просто — поставил и работай. Можно и эмуляции гонять и периферию щупать и без гемороя в два тыка ставится и цепляет большинство адаптеров. То что стоит дофига — не беда. Контора если надо купит и лицензию. А для любительского применения 32кила хватит более чем за глаза. Надо больше чем 32кила? Значит это уже не обучение, а серьезный проект. Тут либо раскошеливаемся, либо осваиваем опенсорц.
Ну или не прикидываемся белыми и пушистыми и ищем кряк. Другого не дано. Кстати, цена в 2800 баксов это реально фигня. Такое, если сильно надо, можно и для домашних разработок прикупить. Окупается за 5-6 заказов на раз. Ну и, к примеру, какая опенсорцная среда позволит запустить процесс в эмуляции аки Кейл? Вывести диаграмму работы порта (что невозможно сделать без эмуляции кроме как на лог анализаторе или цифровом осциллографе — цена вопроса около 30тыр.
Будете плакаться, что и цифровой осциллограф не по карману? И опять «Не для всех»?). А еще работа из коробки. Поставил и не паришься. Все же эти опенсорцыне поделия может и функцоинальные, но представляют собой набор разрозненных утилиток которые еще надо увязать в адекватную рабочую среду (шо поделать, это unix way =) ). 2/3 материала в таком случае будет составлять инструкция как просто заставить ЭТО работать. А 90% комментариев будет на тему «у меня не работает ,что делать» Почитайте комменты к статьям про программаторы. Там народ в линухе не может даже заставить работать уже изьезженную вдоль и поперек и простую как мычание avdrdue, а вы тут про армы заикнулись. Да там такой набор подпорок и решений, что книги писать можно о том как это все комбинировать и соединять. А вот готового из коробки продукта нет (и походу и не будет). Ну, разве что, ограниченная со всех сторон ардуино какая. Да и мне куда интересней ковырять непосредственно процы, а не отвлекаться на еблю с системой. Не думать о том как скрестить ежа с ужом. Так что линуксоиды/макинтошники обламываются дальше. Ну или продираются через тернии своих священных путей дальше. Выбирая из моего материала только то что относится непосредственно к исследуемому железу, а не к его средствам разработки.

ну вообще то я склоняюсь больше к мнению iforgotmylogin, поэтому и просил написать статью про Eclipse+gcc. Однако я понимаю, что таких людей немного кто умеет это делать по линухом. Сам дома сижу на gentoo linux он сильно упрощает жизнь в плане обычного программирования(и не только программирования). Но армы программировать дома не пытался потому как не было программатора, щас он появился и буду разбираться. Замечание iforgotmylogin довольно острое, но действительно когда читаешь то создаётся впечатление что open source не существует и что платный софт, чем то лучше чем бесплатный. При этом считаю новые статьи очень полезными и авторы молодцы что нашли время на то чтобы поделиться опытом.

DI HALT :

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

ну вообще то в gentoo linux для установки eclipse например нужно просто написать в консоли -хочу eclipse-sdk (emerge -av eclipse-sdk). На что ОС ответит у меня вот такие флаги стоят для сборки, собираем? говоришь да и ОС , устанавливает java, сама скачивает, определяет зависимости, собирает(благодаря системе портов, пока что не встречал нужных мне программ которых нет в системе портов). в других ОС мы долго ищем ссылку для скачивания eclipse, находим качаем, понимаем что нету явы, опять ищем где скачать яву, устанавливаем при этом отвечаем на глупые вопросы куда поставить прогу, и прочее. Вместо того чтоб спокойно играть в КС. А флаги при этом обеспечивают тонкие хирургические настройки и оптимизацию софта именно для моего железа. Поэтому у меня эта ОС вызывает ассоциации с тонким скальпелем и микроскопом.

shurup :

Ди подскажи если пользовал как правильно подключить библиотеку STM32F10x Standard Peripherals Library. Задавал этот вопрос на форуме пока реакция = 0. Инклюдю stm32f10x.h в нем подправил деф USE_STDPERIPH_DRIVER. Блин идут ошибки C:\Keil\ARM\INC\ST\STM32F10x\stm32f10x_type.h(23): error: #256: invalid redeclaration of type name «s32» (declared at line 313 of «C:\Keil\ARM\INC\ST\STM32F10x\stm32f10x.h») и до ху-вой тучи таких же

shurup :

Все. Разобрался. В скаченной версии библы 3.3.0 был файл stm32f10x_conf. Кейл брал этот файл из своих папок. Там он отличается от скаченного. В этом файлике инклюдился файл stm32f10x_types.h весь гемор из-за него. Блин столько времени убил трахаясь с Кейлом.

Что означает 151 в конце названия чипа LPC1343FBD48,151 ?
Ultrin :

Подскажите пожалуйста, что может быть.
Заливаю следующий код:
»
#include «stm32f10x.h» void InitAll(void)
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN; // Подали такты на порт. Без этого работать не будет.
// Жоские вилы STM32 =))) А в симуляторе без этого работает на ура GPIOA->CRL |=GPIO_CRL_MODE3_0; // Настроили порт на выход (для простоты возьмем тот факт,
// что GPIOA-CRL после сброса равен нулю. Но в реальной программе
//эти моменты надо проверять и делать полную инициализацию порта.
// Согласно таблице 18 из RM
GPIOA->CRL &=(~GPIO_CRL_CNF3_0); // Перевести в режим двухтактного выхода RCC->CR|=RCC_CR_HSEON; //включаем HSE (внешний кварц)
while (!(RCC->CR&RCC_CR_HSERDY))
;
>
RCC->CFGR |=RCC_CFGR_SW_HSE; // включаем HSE как системные часы
while (!(RCC->CFGR&RCC_CFGR_SWS_HSE))
;
> RCC->CFGR &=(~(RCC_CFGR_PLLMULL));// сбрасываем умножитель в 0
RCC->CFGR |=RCC_CFGR_PLLMULL6; // устанавливаем умножитель равный 6 (12*6=72)
RCC->CFGR |=RCC_CFGR_PLLSRC; // устанавливаем источник PLL от HSE
RCC->CR |=RCC_CR_PLLON; // запускаем PLL
while (!(RCC->CR&RCC_CR_PLLRDY)) // ждем установившегося режима
;
>
RCC->CFGR&=(~(RCC_CFGR_SW));//сбрасываем источник тактового сигнала на внутренний осцилятор
RCC->CFGR|=RCC_CFGR_SW_PLL; // устанавливваем источником тактового сигнала PLL // RCC->CR &=(~(RCC_CR_HSION)); //выключаем HSI return;
> void delay(volatile uint32_t delay_i)
while (delay_i!=0)
delay_i—;
>
> int main(void)
InitAll(); while(1)
GPIOA->BSRR =GPIO_BSRR_BS3; // Выставили бит 3. GPIO_BSRR_BS3 это битмаска
delay(0x00FFFFFF);
GPIOA->BSRR =GPIO_BSRR_BR3; // Сбросили бит 3.
delay(0x00FFFFFF); > >
»
Это немного расширенный пример из статьи.
Вобщем проц виснет в произвольный момент времени после выбора PLL источником системного тактирования. Вдебагере при уходе в основной цикл программы выкидывает на адрес 0 и стопится.
Если ставлю умножитель PLLMULL5 (у меня на плате кварц 12 МГц) — то на 60 МГц программа нормально работает и ничего не виснет. Как только 72 МГц — вилы. Может зажечь светодиод, а может и не зажечь.
В какую сторону мне копать?

DI HALT :
хм. может что то еще там надо для 72мгц.
Ultrin :

Дополнительная информация:
Окно Fault reports: Memory Manages faults
MM_FAULT_STAT=0x01
устанавливается бит IACCVIOL Usage Faults
USG_FAULT_STAT=0x01
устанавливается бит UNDEFINSTR Hard faults
HARD_FAULT_STAT=0x40000000
устанавливается бит FORCED Наверное все это потому, что я туплю и не включил конвейер… Но почему тогда на 60 МГц работало полчаса и не скисло…?

Ultrin :

Вобщем вставил перед инициализацией PLL строчку:
«FLASH->ACR=0x00000000|FLASH_ACR_PRFTBE|FLASH_ACR_LATENCY_2; // Запускаем буферризацию FLASH»
и все заработало…
Колдунство однако…

DI HALT :

Аааа это не колдунство. Просто память программ не может работать на 72мгцах. ПОэтому, кстати, на кортексах (а может и на других армах) практикуют для сверхбыстрых операций копировать исполняемый код в ОЗУ и прогонять там. А щас ты ограничил время доступа к памяти. ИМХО от этого скорость выполнения кода пострадает.

Ultrin :

Странно, я понял так, что задержка перед первым обращением к памяти, чтоб буфер заплнить, а потом все через этот буфер рабтает… Во всяком случае в русскоязычном мануале на это намекается, а английский я чего-то не переводил дословно… 🙁

DI HALT :
Ну я тоже не вникал. Запомнил только, что там какие то проблемы со скоростью работы из флеша.
Ultrin :

Посмотрел щас английскую версию. Так и есть, скорость доступа к флэшу снижена, но т.к. частота 72 МГц и включены оба буфера — то все получается тип-топ. Этот механизм специально придуман, чтоб на высоких частотах работать…

Ultrin :

Чего-то я опять туплю…
Переделываю библиотеку для общения с двухстрочным дисплеем с AVR на STM. Koд вроде весь поправил как надо, но не могу слинковать проект. IDE Keil.
Вставил инклудом заголовочный файл lcd.h в main.c, в коде пока воткнул одну единственную функцию lcd_init(). Компилятор все собирает нормально, а Линкер ругается:
first_prb.axf: Error: L6218E: Undefined symbol lcd_init (referred from main.o).
Target not created
Подскажите пожалуйста, что мне где надо прописать, чтоб оно слинковалось? Или обязательно второй модуль как библиотеку в отдельном пректе делать?

DI HALT :
А ты функции и переменные экстернами обьявлял?
Ultrin :

Объявлял.
Все разобрался…
Я когда с кусками кода из библиотеки в майне экспериментировал, lcd.c отключал от проекта. А обратно включить забыл. В окне-то он открыт, а в списке нет…
Щас все собрал буду проверять в железе… Еще дурацкий вопрос:
Дисплей WH1202A, работает от 5V. Чтоб гонять данные выбрал старшие разряды GPIOB с 9 по 15, которые к 5V толерантны. Назначил в режиме входа как Floating Input, а в режиме выхода как Open Drain Output. Думаю линии притянуть к 5V через 10К резюки. Вправильном направлении я мыслю или нет?

DI HALT :
А зачем подтягивать? Должно же хватить 3.3 вольт на 1ку для дисплея
Ultrin :
там в характеристиках 3.5 вольта минимум при 70 градусах цельсия. А при комнатной 4.1 V…
DI HALT :
Я не про питание дисплея. А про лог уровни его
Ultrin :
хз. Пока соберу с подтяжкой, чтоб заработало… Чтоб проверить напрямую — надо опять код лопатить…
Ultrin :

Вобщем докладаю… 🙂
С подтяжкой чего-то нифига оно не заработало. Переделал выходы на push-pull и все стало OK. 3.3 V на ногах дисплею вполне хватает.

Вливаю код в stm32f100c4. Светодиодик на землю и на ножку — не работает. Не моргает.
Оказывается, вот то утверждение в коде в комментарии, что управляющий регистр порта инициализирован нолями неверен! По умолчанию в управляющем порту MODE = 10 и CNF = 10.
Так что светодиодик нужно подключать к +. Иначе выходной каскад настроен с открытым истоком и моргать не будет. Что бы моргало нужно порт перенастроить на push-pull.
Примерно вот так. void InitAll(void)
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN; // Подали такты на порт. Без этого работать не будет.
// Жоские вилы STM32 =))) А в симуляторе без этого работает на ура GPIOA->CRL |= GPIO_CRL_MODE3_0; // Настроили порт на выход (для простоты возьмем тот факт,
// что GPIOA-CRL после сброса равен нулю. Но в реальной программе
//эти моменты надо проверять и делать полную инициализацию порта.
// Согласно таблице 18 из RM
// Утверждение, что после сброса CRL = 0 ЛОЖНО .
GPIOA->CRL &= ~GPIO_CRL_CNF3; // Сбросили все биты CNF для данного порта, нога — push-pull return;
>

DI HALT :

А у меня работает. Я же не с потолка код беру. Все проверяю в железе. Впрочем да, все значения надо инициализировать полностью.

Ultrin :

Вот строчки из мануала: CNFy[1:0]: Port x configuration bits (y= 0 .. 7)
These bits are written by software to configure the corresponding I/O port.
Refer to Table 18: Port bit configuration table on page 148.
In input mode (MODE[1:0]=00):
00: Analog mode
01: Floating input (reset state)
10: Input with pull-up / pull-down
11: Reserved
In output mode (MODE[1:0] >00):
00: General purpose output push-pull
01: General purpose output Open-drain
10: Alternate function output Push-pull
11: Alternate function output Open-drain
MODEy[1:0]: Port x mode bits (y= 0 .. 7)
These bits are written by software to configure the corresponding I/O port.
Refer to Table 18: Port bit configuration table on page 148.
00: Input mode (reset state)
01: Output mode, max speed 10 MHz.
10: Output mode, max speed 2 MHz.
11: Output mode, max speed 50 MHz. Точнее CNF: 01: Floating input (reset state)
MODE: 00: Input mode (reset state)
Если вы не меняли эти биты то у вас все правильно. В примере ДИ выход как раз и настраивается как Open drain и для мигания светодиодом его надо подтягивать к питанию. У меня во всяком случае контроллер инициализируется в соответствии с мануалом…

Я себя странно чувствую. Два человека написали типа опровержение. Не прочитав, что я написал. Причем один из них говорит, что он подключал диод между землей и ногой — и у него все работает. Уж не глюки ли у меня? И может быть действительно CRL = 0 после сброса ?

DI HALT :

Нет, я мог ошибиться. Собирал на макетке и сейчас глянул и даже точно не скажу как я тогда подключал. Мог быть и Open-Drain. А после сброса CRL = 0x4444 4444

Ultrin :

Я если и опровергал, то только вашу строчку: «По умолчанию в управляющем порту MODE = 10 и CNF = 10.» Вы скорее всего опечатались. А так я только уточнял…

goga770 :

Добрый вечер!
Помогите разобраться!
Взял Ваш готовый проект Keil_p1, все вроде настроил, компилю, а тут такая вещь выдается:
Build target ‘STM32’
linking…
STM32_p1.axf: error: L6031U: Could not open scatter description file STM32_p1.sct: No such file or directory
STM32_p1.axf: Not enough information to list image symbols.
STM32_p1.axf: Not enough information to list the image map.
STM32_p1.axf: Finished: 2 information, 0 warning, 0 error and 1 fatal error messages.
Target not created Где может быть косяк.
Пробовал создать новый проект, ошибок не пишет, но и не мигает(((

DI HALT :
Такое ощущение, что где то с путями косяк.
Ultrin :

«Пробовал создать новый проект, ошибок не пишет, но и не мигает(((»
Если код инициализации регистров GPIO из статьи не менял, то притяни ногу, которая на диод идет, через резистор на +3.3V. Тогда замигает…

goga770 :

Вполне возможно, с Кейлом сталкиваюсь впервые.
Еще вопрос по поводу: GPIOA->BSRR =GPIO_BSRR_BS3; // Выставили бит 3. GPIO_BSRR_BS3 это битмаска
GPIOA->BSRR =GPIO_BSRR_BR3; // Сбросили бит 3. В данном коде биту 3 порта А выставляется 1, затем 0.
Спасибо!

DI HALT :

Да. Это такой хитрый регистр. BSRR = Bit Set/Reset Register Порт у стм32 16ти разрядный, а архитектура 32х разрядная. У регистра BSRR получается как бы две 16ти разрядные половины старшая и младшая. Так как он Set/Reset то запись бита в старшую половину устанавливает, а в младшую сбрасывает (или наоборот, не помню, надо ДШ смотреть). Т.е. биту 0 порта соответствуют биты регистра BSRR 0 и 16 запись в бит 0 сбрасывает лог уровень, заись в бит 16 устанавливает. Есть там еще и регистры отдельно для сброса и для установки. Нафига такая избыточность я хз. Вот такой вот пердимонокль 🙂

DI HALT :

Обрати внимание еще на то, что битмаски разные. Одна **_BS3 другая **_BR3 различаются они как раз позицией бита.

goga770 :
Спасибо! Буду грызть дальше)))

Привет. Помогите советом.
Я использую отладочную плату LPC2378, программатор uLINK, иср uVision.
Элементарная программа типа выставить 1 на пинах и потушить ее, работает в режиме эмуляции прекрасно. НО, когда я подключаю плату, отладчик прыгает не понятно по какому адресу, соответственно, программа не работает.
Слышал, что народ правит стартаповские файлы. а именно адрес старта. но пока туда руки не опускал. Может быть стоит выставить или снять где-то секретную галочку?
Подскажите.

SergeyDon :

интересно кто нибудь по этому примеру создал проект ;(
….
откуда на создавали файлы? куда их натыкали… вот что выдаёт при компиляции: Build target ‘Target 1’
assembling startup_stm32f10x_md_vl.s…
compiling main.с…
main.с: Error: C3065E: type of input file ‘main.?nknown
main.с: Error: C3079E: ArmCC command with no effect
Target not created -=-
единственное не переименовал проект… оставил «Target 1», думаю это не сильно влияет… уже два раза пробовал повторить, не выходит каменная чаша 🙁

Подскажите, откуда у нас берется адрес какого либо регистра, например который принадлежит порту GPIOA, если у нас есть только значение начального смещения? И почему работает такая конструкция:
GPIOA->BSSR = 0x0001; Ведь согласно записи
#define GPIOA ((GPIO_TypeDef *) GPIOA_BASE)
получается, что GPIOA это набор указателей и мы просто присваиваем им адрес а не записываем значение по этому адресу(чтобы записать значение по адресу в указателе нужно ставить звездочку перед ним: p-указатель с каким либо адресом, *p=10 — записываем значение по адресу из указателя). Помогите найти ошибку в рассуждениях.

DI HALT :

Почему только начальное смещение? Есть же там же: #define GPIOA_BASE (APB1PERIPH_BASE + 0xNNNN), где мы привязываем к GPIO_BASE реальное смещение от начала базового смещения области периферии. Из которого уже идут наши регистры GPIOA А еще есть тип GPIO_TypeDef который дает компилятору понять, как нам надо скакать от этого адреса. А дальше мы просто по этому адресу определяем указатель на структуру типа GPIO_TypeDef. Ведь что такое структура? Структура это всего лишь начальный указатель и инфа о расположении данных. Вот мы к ней и обращаемся. А операнд -> означает, что мы оперируем указателем на структуру. Т.е. blbla->blblbla эквивалентно (*blbla).blblbla

А как тип GPIO_TypeDef дает нам понять куда двигаться? там же нет никаких значений и адресов.
и еще вопрос: что значат __IO и __I когда мы определяем типы с помощью структуры?
DI HALT :

Там есть типы данных. Это достаточно. У каждого типа свой размер, идут они в порядке их передчисления:

1 2 3 4 5 6 7 8 9 10
typedef struct { __IO uint32_t CRL; __IO uint32_t CRH; __IO uint32_t IDR; __IO uint32_t ODR; __IO uint32_t BSRR; __IO uint32_t BRR; __IO uint32_t LCKR; } GPIO_TypeDef;

typedef struct < __IO uint32_t CRL; __IO uint32_t CRH; __IO uint32_t IDR; __IO uint32_t ODR; __IO uint32_t BSRR; __IO uint32_t BRR; __IO uint32_t LCKR; >GPIO_TypeDef;

А как считать начальное смещение относительно которого действительна эта область я указал в прошлом комменте. А что такое IO и I я те так не скажу. Это какие то префиксы для компилятора. Может чтобы он корректней обрабатывал их или, например, не оптимизировал, т.к. они могут измениться самопроизвольно.

Оказалось __IO это замена для ключевого слова volatile , можно посмотреть в кейле щелкнув правой кнопкой на __IO и там перейти к определению _IO. Попадаем в файлик где дефайняться эти штуки. Действительно, это нужно для отключения оптимизации т.к. в некоторых случаях она может привести к неверному выполнению кода. Вот тут статейка по этой теме:
http://www.crossplatform.ru/node/183

deadsoulf :

Приветствую, друзья! Я только начал осваивать МК LPC17xx и программирование из под uVision и сразу же столкнулся с такой проблемой: позволяет ли кайл присваивать переменным значения в бинарной форме, как это было сделано в компиляторах AVR (CVAVR, AVRStudio, etc.), например: имя_переменной = 0b00010011; .

DI HALT :

Вообщи Си вроде как не имеет стандарта бинарного представления. Да и вообще такие вот магические числа лажа. Я их даже на авр не испльзую, предпочитая обходится макросами

Добрый вечер! DI попробовал твой пример только для 100й серии. Скачал библиотеку с сайта для верности. Откорректировал stm32f10x.h в той части где нужно разкоментировать тип процессора. Скомпилил — 0 ошибок 0 предупреждений.
Захожу в дебагер и *** error 65: access violation at 0x0000000C : no ‘read’ permission
В чём может быть дело?

DI HALT :

Сотка тока тока вышла. Боюсь дебагер ее еще не поддерживает. Разве что ты юзаешь ST-Link что шел в комплекте с STEVAL

Понял спасибо. Юзал симулятор. Вернее теперь уже пытался юзать

А такой вопрос: чудные платки любезно раздаваемые ST нахаляву, которые дисковери, можно к кейлу цапнуть? и как, если можно ^___^»

С Discovery разобрался.. на 103м камне тут реализован отладчик ST-Link, он чудно работает. Но с примером, что-то не клеится.. таргет проекта поменял на STM32F100RB, тот, что установлен на демо-плате. В интернетах пишут, что с совместимостью всё просто чудесно, можно даже прошивку 103 камня запихнуть в 100 и всё будет работать.. Ан нет, видимо что-то я упустил, но что?- Железка у меня уходит в инициализации в ХардФаулт и всё тут, вываливается из SetSysClockTo72. Почему падает примерно понятно, не способен он держать такую частоту, но откуда взялась такая канитель? Нигде в настройках ничего подобного не нашёл.. И мало того, он же и не выйдет на 72MHz никогда, он же от кварца работает, который вообще 8MHz =(
Что делать, где косяк?

DI HALT :

В настройках PLL кварц может быть хоть на 4мгц, а PLL позволяет разгоняться хоть до 140 (т.к. множителей там дофига разных).

С точки зрения проекта всё оказалось проще. Для линейки «Value Line» часть определений отличается, в том числе и дефолтная частота, для них 24MHz. Чтоб библиотека всё верно поняла надо лишь в настойках проекта добавить определение указывающее на наш контроллер(STM32F100XX= Value Line)- вкладка настроек проекта «C/C++», Define. заносим туда «STM32F10X_MD_VL», И. Чудным образом всё начинает работать %)

Marik_MADI :

Спасибо за отличную статью! Все подробно расписано! Повторил всё в точности, потом попробовал с выложенными файлами, и все равно кейл выдает такую штуку:
assembling STM32F10x.s…
STM32F10x.s: ARM/Thumb RVCT3.1 [Build 934] for uVision
STM32F10x.s: Error: A9932E: This Evaluation Version has expired. Please contact your supplier.
STM32F10x.s:
Target not created Что это значит? В чем проблема?

DI HALT :
This Evaluation Version has expired. Вот в этом и проблема.
newboy :

А как посмотреть что визард в кейле намутил за код?
После выставленяи галочек в нем. Что-то ничего не изменяется

DI HALT :
Он в этом же файле меняется. Правда не сам код, а биты в байтах.
newboy :
А что вы имели ввиду под биты в байтах? там какие-то строки коментируются?
DI HALT :

Макрос он же вписан в реальный исходник. В виде хитрых камментов. И вот после этой бодяги обычно идет дефайн что то там и большое магическое число. И вот когда в визарде что то меняшь то меняется это магическое число.

newboy :
да это не кашерно ! а на сколько вы оцениваете надежность того что он нагенерил?
DI HALT :

Там же просто инициализация. С тем же успехом и я могу накосячить когда буду биты с даташита перебивать.

triggery :

всем привет. вот пытался сделать все как сказано — получилось. но у меня проц STM32F100C8T6B. когда в свойствах проекта меняю на свой — компилируется, но не отлаживается. в чем мой затык?

DI HALT :
В том что отладка F100 вроде как еще не поддерживается. Это слишком новый проц
triggery :

совсем беда, толи со мной толи с кейлом. только добавляю инклуд #include «SPI_STM32F103.c» так он на все начинает матюкаться. помогите пожалуйста. уже выбираю в проекте проц STM32F103C8T6B

triggery :
путь к файлу указаваю — маты идут на все определения в SPI_STM32F103.c”

Огромное спасибо за информацию.
Наконец появились дешевые, мощные процы, которые можно ставить везде один раз обкатав среду, программатор.
Сегодня купил STM32VLDISCOVERY (за 320р).
На нем стоит STM32F100RB + встроенный программатор ST-Link.
Подключил к Keil uVision4.
Скачал с сайта ST STM32VLDISCOVERY firmware package (в нем есть проект для Keil).
Скомпилировалось удачно.
В режиме симулятора не отлаживается.
Пишет: *** error 65: access violation at 0x0000000C : no ‘read’ permission).
Заработало в режиме Debug через ST-Link Debugger.
Светодиоды мигают вслед за нажатием F10.
Изменил код прошивки и заметил следующую вещь:
Если нажать на Debug и сделать несколько шагов, то прошивка прошивается.
Если нажать на Download code to flash memory, то прошивка не прошивается.

DI HALT :

Проц (100е семейство) совсем новый, так что кейл не поддерживает отладку в симуляторе для этого проца.

newboy :

У меня такая же х-ня с кейлом и ИАРом. ПРошивается только через дебаг…
Еще в придачу в кейле пропала панель system windows где все переферийные регистры причем сразу на двух машинах((

Проблему обошел так:
1) кейл генерит hex файл, кот. прошиваю с помощью STM32 ST-LINK Utility
http://www.st.com/internet/com/SOFTWARE_RESOURCES/TOOL/DEVICE_PROGRAMMER/um0892.zip
2) Для отладки симулятором поменял в настройках девайс на STM32F103RB.
Обратно не меняю и полученную прошивку так и шью.
И вообще я подозреваю, что все процы STM32F10X одинаковые и отличаются
только частотой и наличием/отсутствием 1-2 периферий.
Где-то прочитал, что кто-то догадался замениль живой STM32F100RB на
STM32F103RB на плате DISCOVERY.
Я думаю, что это предел развития науки и техники.
Больше уже ничего не надо.

Да и еще после прошивки надо на ресет нажать!

На ресет можно нажать и в STM32 ST-LINK Utility.
Меню Target -> MCU Core. Любопытно. Там можно запустить МК, остановить,
сделать ресет и выполнять пошагово.

Вот в чем проблема с прошиванием:
http://www.keil.com/support/docs/3547.htm
Действительно, чтобы прошить, на Debug жать надо.

Добрый день не могли бы вы подробнее хоть немного описать как вы настраивали библиотеки компилятора Кейл4.по вашей картинке не поняно что у вас пропсано.. какая то папка main…и та кдалее..
Нам надо указать пути к хидерам CMSIS. У STM32 они раскиданы по двум папкам “CMSIS\CoreSupport\” и “CMSIS\DeviceSupport\ST\STM32F10x\” ……..Иначе компилятор их не найдет. Вот мои пути: вот тут совсем ничего не понял( что при установке Кейла он их не прописыает? их нужно дополнительно откуда то качать?

DI HALT :

CMSIS качается отдельно с сайта производителя контроллера на конкретное семейство. В Состав Кейл они не входят.

Добрый день не могли бы вы подробнее хоть немного описать как вы настраивали библиотеки компилятора Кейл4.по вашей картинке не поняно что у вас пропсано.. какая то папка main…и та кдалее..
Нам надо указать пути к хидерам CMSIS. У STM32 они раскиданы по двум папкам “CMSIS\CoreSupport\” и “CMSIS\DeviceSupport\ST\STM32F10x\” ……..Иначе компилятор их не найдет. Вот мои пути: вот тут совсем ничего не понял( что при установке Кейла он их не прописыает? их нужно дополнительно откуда то качать? и никак не получается сделать структуру в Кейле…выводит ошибку на эту строчку TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
что то я упусил и не добавил?

newboy :
Надо не только указать пути к сорцам! но добавить их хидеры в код:
#include «tim.h»
pavelboshko :

Доброго дня.
Подскажите а CMSIS из статьи для LPC13xx подойдет для LPC2104, а то CMSIS LPC21xx
что то нагуглить я не смог.

newboy :

CMSIS это только для кортексов! если нагуглите расшифровку то там будет что-то типа Cortex Microcontroller …

vasily_sib :

Что-то не хочет Кеил работать с STM32VLDISCOVERY 🙁
При установки драйвера ST-Link V2 создается пустая папка 🙁
Сам Кеил при запуске дебага пишет что не найден ULINK (при чем тут ULINK я вообще понять немогу, когда я в настройках явно указал ST-Link).
Тем ни менее, ST-Link Utility прекрасно все видит и читает:\
Херня какая-то:\ Кто наступал на эти грабли, дайте совет плз?

vasily_sib :

Разобрался!
ВНЕЗАПНО все дело было в том, что Кеил предполагает, что я могу использовать разные платы для программатора и дебагера (что весьма глупо ИМХО). Т.е. устанавливая дебагер ST-Link, и не изменив программатор с ULINK на ST-Link я получаю тонну удовольствия от сообщения «ULINK device not found»:)
uVision IDE такая Vision:\

DI HALT :

Ничего не понял. Ты не настроил дебаггер в кейл и ждешь что он тебе сделает это сам? А с какой радости то вообще? Деббагеров может быть в системе сколько угодно и надо выбирать под текущую задачу нужный.

vasily_sib :

Не, ты меня не понял. В том то и дело, что я настроил только дебагер.
Т.е. в настройках проекта дебагером выбран ST-Link, а программатором по-умолчанию выбран ULINK. Не залезть я случайно в настройки программатора, точно умом бы тронулся: выбрал ST-Link, а ищется ULINK.
При запускает отладки, программа сначала заливается в МК, а уже после отлаживается. И я всегда был уверен, что раз я использую отладчик, то и программировать МК я буду им же. Для Кеила, видимо, это не так очивидно.

vasily_sib :

Кстати, такой вопрос:
В Кеил нет автодополнения/автозавершения кода? А то я что-то не могу найти этой фичи ни в настройках, ни в описании на сайте :\ ИМХО, за такие неплохие деньги, эта фишка просто обязана присутствовать:\

DI HALT :
Насколько знаю нету.
coracio :
Вопрос. А в IAR`e автодополнение есть?
vasily_sib :

тоже нет. Ну, или по крайней мере я не нашел:\
ИМХО продукт ценой в 100500$ и без подобной фичи — это какое-то мошенечество:\

coracio :

+1.
Мне например очень нравится работать в mikroc. Сейчас и в авр студию 5 прикрутили.
Тоже кажется нелепым отсутствие автодополнения, т.к количество регистров, функций и библиотек для ARM намного больше чем скажем у PIC и AVR.

DI HALT :

Кейл рулит не своим иде, а компиляторами и дебагерами. У того же иара оболочка не далеко ушла от блокнота

vasily_sib :

Тут сложно сказать что лучше:\
Компилятор у Кеила, наскок я знаю — ARM GCC (т.е. не свой). А один дебагер столько не стоит:\
Собственно вопрос:
— Кто нибудь знает IDE для Cortex M3, где есть автодополнение и работает с ST-Link?
Да, кстати к слову о блокнотах:) В блокноте от ИАР можно хотя бы группы кода вложенными делать (группа в группе)

DI HALT :
У кейла свой компилер. Keil MDK вроде бы зовется.
newboy :
а что за фича такая автодополнение кода?
vasily_sib :

Это когда ты вводишь «prin», а среда разработки автоматически дополняет это до «printf(» и подсказывает какие переменные и какого типа ждет эта функция. Или когда вводишь «SomeObject->» и тебе выводится список членов и методов класса с соответствующими описаниями.

здравствуйте подскажите, пробовал по этой статье создать проект на процессор stm32l152rb, подключил библиотеки ядра и периферии для него….проект не компилится
main.c(1):error #13 :expected a file name….
в строке 1 мain.c запись #include stm32l1xx.h подскажите где у меня затык или плис скинте рыбу кейловского проекта пустого с подклчеными библиотеками…за ранее спасибо….

almazra :

Здравствуйте!
Пытаюсь создать проект в keil’e для stm32f203ret. Простейшая программа имеет отличия по сравнению с stm32f10x… из-за другого оформления обращения к GPIO в 2хх серии. Скомпилировать без ошибок удалось, но debugger выдаёт «error 65…»! Стартует с нулевого адреса. В настройках стоит флажок Run to main(). В чем может быть проблема? Неужели keil не поддерживает 2хх-е серии? Если проблема действительно в этом, какие Вы можете порекомендовать поддерживающие 205-ю серию отладчиком программы?

almazra :
Видимо не поддерживает. Может кому-нибудь пригодится http://www.keil.com/forum/19246/
phantom lord :

Буду благодарен за помощь с отладкой в кейле. Запускаю отладку, появляется куча окон, всё как надо. Жму F11, получаю:
*** error 65: access violation at 0x0000000C : no ‘read’ permission И всё, отладка не начинается даже. Кстати, если подозрения, что проблема не в отладке, а в компилировании, т.к. по идее вообще не должно быть никаких обращений по адресу ниже 0х08000000.

phantom lord :
Сорри, увидел комментарий выше. С F1 работает нормально, а F4 видимо не поддерживает
А к 200-тому семейству STM32_Init.c где можно найти?
Astronom :

Могли бы вы показать пример Keil + CAN на основе stm32f10x. Отправка и получение сообщений по шине.? Пытаюсь освоить СAN.

DI HALT :
Не мог, в данный момент нет такой задачи у меня.
BondarevD :

С выражением <А вот в убойном файле STM32_Init.c для STM32 можно сконфигурировать ВООБЩЕ ВСЕ!>оказалось не совсем всё просто. Сам визард в КЕЙЛЕ — весьма полезная функция, но STM32_Init.c не позволяет настроить всю переферию. Понятно стало после попытки запустить базовый таймер TIM6. В визарде создал пункт инициализации, вставил код инициализации таймера, прерывания — висяк. Вообщем в результате пришлось и поправлять даже STM32F10x.s — ибо корень зла начинается с него. Вообщем только после ентого заработала дискавера. Я так предполагаю, что родной STM32_Init.c настраивает только ту переферию, которая поддерживается симулятором.

DI HALT :
В дискавере стоит слишком новый камень. Его даже кейл то не до конца поддерживал вот еще недавно.
BondarevD :

То, что Кейл не поддерживает симулятор — это не беда, а то что STM32_Init.c с хидерами не отточен под архитектуру STM32F10x — это печально, TIM6, TIM7 прерывания — не прописаны в стартапе (это не проблема КЕЙЛА). Просто ST спит.

DI HALT :
А не пробовал искать более свежую версию этого файла?

Поясните что за ошибка —
*** error 65: access violation at 0x40021000 : no ‘read’ permission
*** error 65: access violation at 0x40021000 : no ‘write’ permission
*** error 65: access violation at 0x40021004 : no ‘read’ permission
*** error 65: access violation at 0x40021004 : no ‘write’ permission
появляется на каждое нажатие F11?
Что такое off-chip и on-chip во вкладке Target?
Правильно ли сделал что указал контроллеру границы памяти ОЗУ и ПЗУ? У меня 107VC. А то по умолчанию там что то левое стояло?

DI HALT :
Понятя не имею, не сталкивался. Но похоже что то пытается обратиться за границы памяти.

Да вот и я так же понял. Но что? Скопировал просто код из IAR рабочий и все. ошибок при компиляции не дает. В дизассеблере начинаю смотреть пошагово — вылазит ошибка. Непонятно.

DI HALT :

А с настройками проекта по умолчанию не взелетело? Там еще какие то настройки скорости доступа к флеш памяти есть. Не разбирался, становятся актуальным когда скорость до максимума разгоняешь.

Скопировал проект из статьи — ошибка наблюдалась. Потом свой — есть ошибка. Потом поменял границы памяти — все равно осталась. В Target Xtal стоит 25 Мгц, по умолчанию. Снизил до 10 — не помогло. Может там где то галочки поставить еще надо? Или границы памяти надо прописывать в off-chip, а не в on-chip?

DI HALT :
Не знаю, я с армами практически не работал.
Будем разбираться.
welcom :

Привет. Обьясните плз как пользоваться визардом STM32_Init.c ? как его прикрутить?
Собрал по теме проект, запустил в дебаге , однако не смог найти здесь Peripherials->General Purpose IO -> GPIOA, нашел что то похожее в System Viewer Windows, но немного не то что указано здесь. При выполнении кода на выходах порта никакой реакции нет. Подскажите что не так? Спасибо.

welcom :
welcom :
welcom :

Посмотрел я здесь http://www.keil.com/dd/, похоже что кейл не поддерживает симуляцию процов STM32xxx, по крайней мере я пересмотрел больше 2-х детсяков! Как быть в таком случае. ведь нужен STM

DI HALT :

Куда ты там смотрел? STMicroelectronics (ARM7/ARM9/Cortex Family)
STA2051, STM32F051C6, STM32F051C8, STM32F051K6, STM32F051K8, STM32F051R6, STM32F051R8, STM32F100C4, STM32F100C6, STM32F100C8, STM32F100CB, STM32F100R4, STM32F100R6, STM32F100R8, STM32F100RB, STM32F100RC, STM32F100RD, STM32F100RE, STM32F100V8, STM32F100VB, STM32F100VC, STM32F100VD, STM32F100VE, STM32F100ZC, STM32F100ZD, STM32F100ZE, STM32F101C4, STM32F101C6, STM32F101C8, STM32F101CB, STM32F101R4, STM32F101R6, STM32F101R8, STM32F101RB, STM32F101RC, STM32F101RD, STM32F101RE, STM32F101RF, STM32F101RG, STM32F101T4, STM32F101T6, STM32F101T8, STM32F101TB, STM32F101V8, STM32F101VB, STM32F101VC, STM32F101VD, STM32F101VE, STM32F101VF, STM32F101VG, STM32F101ZC, STM32F101ZD, STM32F101ZE, STM32F101ZF, STM32F101ZG, STM32F102C4, STM32F102C6, STM32F102C8, STM32F102CB, STM32F102R4, STM32F102R6, STM32F102R8, STM32F102RB, STM32F103C4, STM32F103C6, STM32F103C8, STM32F103CB, STM32F103R4, STM32F103R6, STM32F103R8, STM32F103RB, STM32F103RC, STM32F103RD, STM32F103RE, STM32F103RF, STM32F103RG, STM32F103T4, STM32F103T6, STM32F103T8, STM32F103TB, STM32F103V8, STM32F103VB, STM32F103VC, STM32F103VD, STM32F103VE, STM32F103VF, STM32F103VG, STM32F103ZC, STM32F103ZD, STM32F103ZE, STM32F103ZF, STM32F103ZG, STM32F105R8, STM32F105RB, STM32F105RC, STM32F105V8, STM32F105VB, STM32F105VC, STM32F107RB, STM32F107RC, STM32F107VB, STM32F107VC, STM32F205RB, STM32F205RC, STM32F205RE, STM32F205RF, STM32F205RG, STM32F205VB, STM32F205VC, STM32F205VE, STM32F205VF, STM32F205VG, STM32F205ZC, STM32F205ZE, STM32F205ZF, STM32F205ZG, STM32F207IC, STM32F207IE, STM32F207IF, STM32F207IG, STM32F207VC, STM32F207VE, STM32F207VF, STM32F207VG, STM32F207ZC, STM32F207ZE, STM32F207ZF, STM32F207ZG, STM32F215RE, STM32F215RG, STM32F215VE, STM32F215VG, STM32F215ZE, STM32F215ZG, STM32F217IE, STM32F217IG, STM32F217VE, STM32F217VG, STM32F217ZE, STM32F217ZG, STM32F405RG, STM32F405VG, STM32F405ZG, STM32F407IE, STM32F407IG, STM32F407VE, STM32F407VG, STM32F407ZE, STM32F407ZG, STM32F415RG, STM32F415VG, STM32F415ZG, STM32F417IE, STM32F417IG, STM32F417VE, STM32F417VG, STM32F417ZE, STM32F417ZG, STM32L151C6, STM32L151C8, STM32L151CB, New!STM32L151QC, New!STM32L151QD, STM32L151R6, STM32L151R8, STM32L151RB, New!STM32L151RC, New!STM32L151RD, STM32L151V8, STM32L151VB, New!STM32L151VC, New!STM32L151VD, New!STM32L151ZC, New!STM32L151ZD, STM32L152C6, STM32L152C8, STM32L152CB, New!STM32L152QC, New!STM32L152QD, STM32L152R6, STM32L152R8, STM32L152RB, New!STM32L152RC, New!STM32L152RD, STM32L152V8, STM32L152VB, New!STM32L152VC, STM32L152VD, New!STM32L152ZC, STM32L152ZD, New!STM32L162QD, New!STM32L162RD, STM32L162VD, STM32L162ZD, STR710FZ1, STR710FZ2, STR711FR0, STR711FR1, STR711FR2, STR712FR0, STR712FR1, STR712FR2, STR715FR0, STR730FZ1, STR730FZ2, STR731FV0, STR731FV1, STR731FV2, STR735FZ1, STR735FZ2, STR736FV0, STR736FV1, STR750FL2, STR750FV0, STR750FV1, STR750FV2, STR751FR0, STR751FR1, STR751FR2, STR752FR0, STR752FR1, STR752FR2, STR755FR0, STR755FR1, STR755FR2, STR755FV0, STR755FV1, STR755FV2, STR910FAM32, STR910FAW32, STR910FAZ32, STR910FM32, STR910FW32, STR911FAM42, STR911FAM44, STR911FAM46, STR911FAM47, STR911FAW42, STR911FAW44, STR911FAW46, STR911FAW47, STR911FM42, STR911FM44, STR912FAW42, STR912FAW44, STR912FAW46, STR912FAW47, STR912FAZ42, STR912FAZ44, STR912FAZ46, STR912FAZ47, STR912FW42, STR912FW44

welcom :

Смотрел я правильно, только немного не досмотрел. Так вот, кому интерестно, пересмотрел я каждый чип отдельно, там есть пункт «Simulated Features», где и указано что симулируется а что нет и выяснил, что на данный момент симулируются не все перечисленные выше чипы а только STM32F101XX, STM32F103XX, STR711XXX, STR710XXX, STR712XXX, STR730XXX, STR731XXX, STR735XXX, STR736XXX, STR750XXX, STR751XXX, STR752XXX, STR755XXX, STR910XXX, STR911XXX, STR912XXX. Например: здесь http://www.keil.com/dd/chip/4233.htm камень симулируется с периферией а уже здесь http://www.keil.com/dd/chip/4888.htm НЕ симулируется.

DI HALT :

Ну само собой. Одно дело добавить поддержку в компилятор, другое дело в симулятор. Постепенно добавляют.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *