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

Откроется стандартный мастер проекта и предложит указать имя будущего файла. Рекомендую также создать и папку под проект, т.к. файлов там будет дофига. Я назвал папку 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

  • core_cm3.c
  • core_cm3.h

Описание конкретного контроллера (семейства точнее), лежит в 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)

Как видим, тут уже фигурируют имена периферийных блоков с привязкой указателя к базовому адресу блока (а они все, в свою очередь, идут как смещение от базового адреса 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)

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

1
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;
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 )

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

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 не придется считать. И никаких магических чисел в коде!

Делаем так:

1
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
/*
//-------- <<< Use Configuration Wizard in Context Menu >>> ------------------
*/
 
/*--------------------- Clock Configuration ----------------------------------
//
// <e> Clock Configuration
//   <e1> System Clock Setup
//     <e2> System Oscillator Enable
//       <o3.1> Select System Oscillator Frequency Range
//                     <0=> 1 - 20 MHz
//                     <1=> 15 - 25 MHz
//     </e2>
//     <e4> Watchdog Oscillator Enable
//       <o5.0..4> Select Divider for Fclkana
//                     <0=>   2 <1=>   4 <2=>   6 <3=>   8
//                     <4=>  10 <5=>  12 <6=>  14 <7=>  16
//                     <8=>  18 <9=>  20 <10=> 22 <11=> 24
//                     <12=> 26 <13=> 28 <14=> 30 <15=> 32
//                     <16=> 34 <17=> 36 <18=> 38 <19=> 40
//                     <20=> 42 <21=> 44 <22=> 46 <23=> 48
//                     <24=> 50 <25=> 52 <26=> 54 <27=> 56
//                     <28=> 58 <29=> 60 <30=> 62 <31=> 64
//       <o5.5..8> Select Watchdog Oscillator Analog Frequency (Fclkana)
//                     <0=> Disabled
//                     <1=> 0.5 MHz
//                     <2=> 0.8 MHz
//                     <3=> 1.1 MHz
//                     <4=> 1.4 MHz
//                     <5=> 1.6 MHz
//                     <6=> 1.8 MHz
//                     <7=> 2.0 MHz
//                     <8=> 2.2 MHz
//                     <9=> 2.4 MHz
//                     <10=> 2.6 MHz
//                     <11=> 2.7 MHz
//                     <12=> 2.9 MHz
//                     <13=> 3.1 MHz
//                     <14=> 3.2 MHz
//                     <15=> 3.4 MHz
//     </e4>
...

Я вначале долго тупил, думал это что-то вроде 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\»). Если мы перетаскиваем готовый проект откуда то, то пути к его заголовочным файлам тоже надо прописать тут же. Иначе компилятор их не найдет. Вот мои пути:

  • Debug — тут выбираем отладчик. Пока можно оставить Simulator. Если у вас есть JTAG или SWD адаптер, то можно выбрать его. После я опишу пример работы с ColinkEX отладчиком. Убедитесь только, что установлена галочка Run to main(), чтобы отладка запустилась с функции Main.

Среда готова. Можно попробовать что-нибудь создать и запустить. Пустой 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	|= 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 = 1<<3;      	// Pull Dn
   LPC_GPIO0->DATA = 0;         	// DATA=0
   LPC_GPIO0->DIR = 1<<7;         	// DIR 0.7= Out
   return;
}
 
int main(void)
{
InitAll();
 
while(1)
	{
   	LPC_GPIO0->DATA &=~(1<<7);	// Clear bit
   	LPC_GPIO0->DATA  |= 1<<7;	// Set bit
	}
}

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

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

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

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

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

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

Peripherials->General Purpose IO -> GPIOA

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

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

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

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

Запись опубликована в рубрике ARM. Учебный курс с метками , , , . Добавьте в закладки постоянную ссылку.

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

  1. Vitek885 говорит:

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

  2. dansar говорит:

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

    • DI HALT говорит:

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

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

  3. A-10 говорит:

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

  4. angrykid говорит:

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

  5. Nikita Nazarenko говорит:

    у линуксоидов есть GCC-toolcahin который умеет собирать код и для cortex-M3 камней.

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

    В общем, было бы желание :)

  6. prakash говорит:

    Отдельное спасибо за выложенную книгу про STM32! Только сегодня искал, но нашёл только в html…

  7. Ultrin говорит:

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

    Спасибо за информацию

  8. shurup говорит:

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

  9. Ageofenigma говорит:

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

    • shurup говорит:

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

  10. yellowjohn говорит:

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

    • yellowjohn говорит:

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

      • shurup говорит:

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

    • DI HALT говорит:

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

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

      if(...)
      {
      	case1;
      } else {
      	case2;
      }
      

      =)

      • yellowjohn говорит:

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

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

          if(cond1)
          {
          	case1;
          } else if(cond2) {
          	case2;
          } else if(cond3) {
          	case3;
          } else {
          	case4;
          }
          
  11. Goron Dekar говорит:

    Мдааа. Если AVR-studio использовала gcc, то кайло юзает свой тулчейн. И переносимость примеров падает. Жаль.

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

  12. 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 и есть)

  13. shurup говорит:

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

  14. neosystem говорит:

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

  15. Aneg говорит:

    Где в Украине можно приобрести эту сладкую парочку?
    LPC1343FBD48 -1 шт.
    STM32F103C8T6 -1 шт.

  16. 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)0×00000100) /*!< Bit 0 */
    #define RCC_CFGR2_PLL2MUL_1 ((uint32_t)0×00000200) /*!< Bit 1 */
    #define RCC_CFGR2_PLL2MUL_2 ((uint32_t)0×00000400) /*!< Bit 2 */
    #define RCC_CFGR2_PLL2MUL_3 ((uint32_t)0×00000800) /*!< Bit 3 */

    #define RCC_CFGR2_PLL2MUL8 ((uint32_t)0×00000600) /*!< PLL2 input clock * 8 */
    #define RCC_CFGR2_PLL2MUL9 ((uint32_t)0×00000700) /*!< PLL2 input clock * 9 */
    #define RCC_CFGR2_PLL2MUL10 ((uint32_t)0×00000800) /*!< PLL2 input clock * 10 */
    #define RCC_CFGR2_PLL2MUL11 ((uint32_t)0×00000900) /*!< 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. Щас подправлю.

  17. smbd говорит:

    Вроде бы все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 ‘{‘, found ‘)…’.
    1Proj.sct: Error: L6372E: Image needs at least one load region.
    Target not created

    Заодно- разъясните , что такое axf и sct?

  18. Ultrin говорит:

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

  19. iforgotmylogin говорит:

    Дяденьки, а разве культурно так делать? В названии сайта пишете «электроника для всех». И тут же в статье у вас линуксоиды — «обламываются». И макинтошники наверное тоже? Не говоря уже о всяких там бсдунах. Получается что не очень то электроника поданая под вашим соусом и для всех, а?

    А потом еще и учите юзать платный продукт. Который стоит столько что это получается ну совсем не для всех. Особенно в России. Потому что в любительско-малотиражной практике покупать кайло совершенно неоправданно. А 32 Кб всем не хватит. Ну, как и 640Кб — почему-то не хватило.

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

    • Aneg говорит:

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

    • DI HALT говорит:

      Возможности, уважаемый, возможности.

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

      То что стоит дофига — не беда. Контора если надо купит и лицензию. А для любительского применения 32кила хватит более чем за глаза.

      Надо больше чем 32кила? Значит это уже не обучение, а серьезный проект. Тут либо раскошеливаемся, либо осваиваем опенсорц.
      Ну или не прикидываемся белыми и пушистыми и ищем кряк. Другого не дано. Кстати, цена в 2800 баксов это реально фигня. Такое, если сильно надо, можно и для домашних разработок прикупить. Окупается за 5-6 заказов на раз.

      Ну и, к примеру, какая опенсорцная среда позволит запустить процесс в эмуляции аки Кейл? Вывести диаграмму работы порта (что невозможно сделать без эмуляции кроме как на лог анализаторе или цифровом осциллографе — цена вопроса около 30тыр.
      Будете плакаться, что и цифровой осциллограф не по карману? И опять «Не для всех»?).

      А еще работа из коробки. Поставил и не паришься.

      Все же эти опенсорцыне поделия может и функцоинальные, но представляют собой набор разрозненных утилиток которые еще надо увязать в адекватную рабочую среду (шо поделать, это unix way =) ).

      2/3 материала в таком случае будет составлять инструкция как просто заставить ЭТО работать. А 90% комментариев будет на тему «у меня не работает ,что делать»

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

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

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

      • RuZzz говорит:

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

        • DI HALT говорит:

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

          • RuZzz говорит:

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

  20. 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 весь гемор из-за него. Блин столько времени убил трахаясь с Кейлом.

  21. Aneg говорит:

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

  22. 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=0×01
        устанавливается бит IACCVIOL

        Usage Faults
        USG_FAULT_STAT=0×01
        устанавливается бит UNDEFINSTR

        Hard faults
        HARD_FAULT_STAT=0×40000000
        устанавливается бит FORCED

        Наверное все это потому, что я туплю и не включил конвейер… Но почему тогда на 60 МГц работало полчаса и не скисло…?

        • Ultrin говорит:

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

          • DI HALT говорит:

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

            • Ultrin говорит:

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

              • DI HALT говорит:

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

                • Ultrin говорит:

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

  23. 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
    Подскажите пожалуйста, что мне где надо прописать, чтоб оно слинковалось? Или обязательно второй модуль как библиотеку в отдельном пректе делать?

  24. OlegG говорит:

    Вливаю код в 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 и для мигания светодиодом его надо подтягивать к питанию.

      У меня во всяком случае контроллер инициализируется в соответствии с мануалом…

      • OlegG говорит:

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

  25. 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

    Где может быть косяк???
    Пробовал создать новый проект, ошибок не пишет, но и не мигает(((

  26. 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 различаются они как раз позицией бита.

  27. goga770 говорит:

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

  28. SATS говорит:

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

  29. 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″, думаю это не сильно влияет…

    уже два раза пробовал повторить, не выходит каменная чаша :(

  30. sppol говорит:

    Подскажите, откуда у нас берется адрес какого либо регистра, например который принадлежит порту GPIOA, если у нас есть только значение начального смещения? И почему работает такая конструкция:
    GPIOA->BSSR = 0×0001; Ведь согласно записи
    #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

      • sppol говорит:

        А как тип GPIO_TypeDef дает нам понять куда двигаться? там же нет никаких значений и адресов.

        • sppol говорит:

          и еще вопрос: что значат __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;

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

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

          • sppol говорит:

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

  31. deadsoulf говорит:

    Приветствую, друзья!

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

    имя_переменной = 0b00010011;

    ????

    • DI HALT говорит:

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

  32. Delau говорит:

    Добрый вечер!

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

  33. irbis говорит:

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

    • irbis говорит:

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

      • DI HALT говорит:

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

        • irbis говорит:

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

  34. 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

    Что это значит? В чем проблема?

  35. newboy говорит:

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

  36. triggery говорит:

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

  37. triggery говорит:

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

  38. triggery говорит:

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

  39. Tiom говорит:

    Огромное спасибо за информацию.
    Наконец появились дешевые, мощные процы, которые можно ставить везде один раз обкатав среду, программатор.
    Сегодня купил 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, то прошивка не прошивается.

  40. Shumm говорит:

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

    вот тут совсем ничего не понял( что при установке Кейла он их не прописыает? их нужно дополнительно откуда то качать?

  41. Shumm говорит:

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

    вот тут совсем ничего не понял( что при установке Кейла он их не прописыает? их нужно дополнительно откуда то качать?

    и никак не получается сделать структуру в Кейле…выводит ошибку на эту строчку TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    что то я упусил и не добавил?

  42. pavelboshko говорит:

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

  43. newboy говорит:

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

  44. vasily_sib говорит:

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

  45. vasily_sib говорит:

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

    • DI HALT говорит:

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

      • vasily_sib говорит:

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

  46. vasily_sib говорит:

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

  47. newboy говорит:

    а что за фича такая автодополнение кода?

    • vasily_sib говорит:

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

  48. Ujin говорит:

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

  49. almazra говорит:

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

  50. phantom lord говорит:

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

    И всё, отладка не начинается даже. Кстати, если подозрения, что проблема не в отладке, а в компилировании, т.к. по идее вообще не должно быть никаких обращений по адресу ниже 0х08000000.

  51. PoReX говорит:

    А к 200-тому семейству STM32_Init.c где можно найти?

  52. Astronom говорит:

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

  53. BondarevD говорит:

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

  54. rts говорит:

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

  55. rts говорит:

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

    • DI HALT говорит:

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

  56. rts говорит:

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

  57. rts говорит:

    Будем разбираться.

  58. welcom говорит:

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

    • welcom говорит:

      [url=http://tempfile.ru/view/11159/1535b231b8/f7e886817cefa34167a512c2.jpg][img]http://img7.tempfile.ru/11159/1535b231b8/f7e886817cefa34167a512c2.jpgt.jpg[/img][/url]

        • 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

  59. 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 НЕ симулируется.

  60. welcom говорит:

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

  61. predator_r говорит:

    Здравствуйте. Огромное спасибо за статью.
    Подскажите пожалуйста еще:
    как CMSIS к STM32F407 подключить и где взять?

    • DI HALT говорит:

      Не знаю. Наверное аналогично.

      Взять там же где и для F103 на сайте STM

    • predator_r говорит:

      да это я решил АРМ освоить и приобрел STM32F4-DISCOVERY, с STM32F407 на борту и отладчиком из 103. к кейлу в режиме отлади цепляется, пошагово выполняется, но вот загвоздка: подключить готовый экзампл мне удалось, а вот создать свой проект без вашей статьи не очень. и вот system тоже есть, а от core_m4 — только хедерник.
      вот и возник вопрос: может я не той стороной лошадь запрягаю…..

      • DI HALT говорит:

        М4 это весьма специфический проц. Это DSP вообще. Причем новый. Неудивительно, что про него ничего нет толком.

      • newboy говорит:

        я спокойно подключил готовый example из примеров, Кейл используете?
        единственно что в нем не удалось сделать, это включить поддержку FPU

      • predator_r говорит:

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

  62. IceW1nD говорит:

    Здравствуйте!
    Подскажите пожалуйста в файле из папки CMSIS — stm32f10x.h при выборе типа семейства:

    #if !defined (STM32F10X_LD) && !defined (STM32F10X_LD_VL) && !defined (STM32F10X_MD) && !defined (STM32F10X_MD_VL) && !defined (STM32F10X_HD) && !defined (STM32F10X_XL) && !defined (STM32F10X_CL)
    /* #define STM32F10X_LD */ /*!< STM32F10X_LD: STM32 Low density devices */
    /* #define STM32F10X_LD_VL */ /*!< STM32F10X_LD_VL: STM32 Low density Value Line devices */
    /* #define STM32F10X_MD */ /*!< STM32F10X_MD: STM32 Medium density devices */
    /* #define STM32F10X_MD_VL */ /*!< STM32F10X_MD_VL: STM32 Medium density Value Line devices */
    /* #define STM32F10X_HD */ /*!< STM32F10X_HD: STM32 High density devices */
    #define STM32F10X_XL /*!< STM32F10X_XL: STM32 XL-density devices */
    /* #define STM32F10X_CL */ /*!< STM32F10X_CL: STM32 Connectivity line devices */
    #endif

    выбран #define STM32F10X_XL, но STM32F103С8 вроде относиться к /* #define STM32F10X_MD и нужно ли здесь использовать другой дефайн?

  63. Staroy говорит:

    Кто подскажет, что у меня не так? Хочу на Симуляторе запустить просмотр простенького примера из борда Кейла. Но если там нет варианта для симулятора, а есть для флэша, то он не идет в симуляторе, с нулевого адреса память остается пустая. А как сделать вариант для симулятора — нигде не написано(прочитал всю «Keil Gettin Started»).

    • DI HALT говорит:

      Ничего не понял.

      • Staroy говорит:

        Спасибо, что посмотрели мой вопрос. Вероятно я сформулировал не очень, Тогда напишу прямо, вот берем Keil \ ARM \ Boards \ ST\ EK-STM32F \ Blinky\ \ Abstract — там написано: доступно в таджетах: Simulator, Flash, RAM. И когда из них выбираешь — каждая отладка сразу работает. Вот и хотелось бы знать, как получаются такие три варианта? А то делаю как в руководстве проект, и он сразу для флэша, а мне бы сначала в RAMe. Пробую менять память на RAM, но отладчик туда не пишет.

        • DI HALT говорит:

          Как понимаю, проект скомпилирован отдельно для Симулятора и для исполнения. Причем для исполнения при запуске из FLASH (прога лежит в FLASH памяти) и из RAM (прога скомпилена так, что кладется в адресное пространство ОЗУ), но из RAM далеко не всегда можно запустить. Банально может не хватить этой самой памяти. Серьезно я там так глубоко не ковырялся. Запуск в RAM обычно нужен либо для очень быстрой работы (флеш медленней), либо если код подгружается откуда то извне, а потом ему передается управление. Например через ОС.

          • newboy говорит:

            Это пример мигания светодиода, так что вряд ли там не уместится в RAM ))

          • juray говорит:

            » Запуск в RAM обычно нужен либо для очень быстрой работы (флеш медленней)»
            - а вот нифига же ж!.
            Исполняется код из рамы медленнее, чем из флеша.

            К флешу обращение идет через отдельную шину I-code bus (или просто I-bus), а к раме — через системную матрицу шин (D-code).

            Как пишут в «Insider’s guide» (пункт 2.3.5.):

            Although code can be loaded and executed from the SRAM, the instructions would be fetched using the system bus, which incurs an extra wait state. It is likely that code would run slower from SRAM than from on-chip FLASH memory located in the code region.

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

            This speeds the download process and saves continual burning of the FLASH memory.
            (там же, п.4.1)

            В русском переводе эту фразу просто коряво транслировали:

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

  64. juray говорит:

    «Переименуем Target 1 и Source Group 1 во что-нибудь более осмысленное.»

    Стоило бы поподробнее описать, как именно это делается. А то, например, я как-то больше получаса тыкался, пытаясь найти, где эта возможность зарыта. После аврстудии с ее логичным «Rename» прямо в контекстном меню по правой кнопке — как-то сложно догадаться, что надо зайти в «Manage components» и уже там два раза щелкнуть на изменяемых именах.

  65. XanderEVG говорит:

    А в этой среде можно как нибудь отправить данные в проц по уарту?(и в дма тоже, вроде дма читает уарт…)
    либо есть ли в stm32f103c в уарте режим петли(т е что отправляешь то тебе тут же и приходит)? я бегло просмотрел доки но не нашел, но все же надежда умирает последней…
    для учебы очень нужно. спасиба!

  66. RigorMortis говорит:

    Начинаем холивар: чем Keil круче IAR?

    Я ни с тем ни с другим еще не работал, только собираюсь выбрать.
    Все остальные модные «тулчейны» сдается мне придется собирать по частям, а интересует среда с библиотеками, железными дефайнами и встроенными симуляторами/эмуляторами — чтобы сел и поехал. И чтобы развивалась.

  67. RigorMortis говорит:

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

    • newboy говорит:

      И чем же убога?

      • RigorMortis говорит:

        Ощущение, что среда делалась в прошлом веке и с тех пор мало изменилась.
        Вот просто слов нет насколько все сделано не так как надо. Ну допустим прикрутили они подсказку, которая выводит список параметров функции (memcpy), но выводит она только типы параметров, а названия параметров не выводит, хотя они есть (но только в теле функции). Когда создаешь новый проект стартапный и системный файлы для контроллеров не копируются в проект и не определяется дефайном семейство контроллеров и тем более тактирование — все вручную надо. Ну хоть бы визард какой сделали что ли, как в Keil (хотя он у меня почему то и не появляется там). Дополнения кода (code complete) сделаны тоже кое как. Русские буквы в окне компиляции не отображаются и шрифт русский не поставить. Выводится список ошибок компиляции и позиционируется в конец — до первой ошибки нужно мотать каждый раз. И такое там все. Может он как компилятор и хорош, но после Delphi, где среда довольно удобно сделана, очень неуютно в такой среде. И еще засек — стартует 21 секунду среда.

        • newboy говорит:

          с выводом ошибок они ступили. Дополнение кода терпимо, во всяком случае лучше когда его нет совсем, в кейле насколько знаю нет((
          Визарда не хватает, а так в целом не плохо
          И мне он нравится что он не тормозит, 21 секунда значит что-то не то у вас.Была конечно такая фигня что он подвисал каждую минуту, но это что-то в системе не то было

          • RigorMortis говорит:

            Да кнопки даже не назначить привычные. На тулбар тоже не придумал как что вывести. Короче надо приспосабливаться.

            А можно ли в Keil GCC компилятор прикрутить и как он в сравнении с IAR? Я вроде там галочку такую видел, но не использовал. И еще в Keil похоже CMSIS не принято использовать, хотя и можно.

  68. Dan_ex говорит:

    Как в библиотеке STM32_Init.c настроить частоту кварца с 8МГц до 12МГц?

    Проблема, значит, такого плана: мне нужно отправить байт по USART2, в визарде я выставляю все нужные галки: BaudRate: 9600 ; Data bits: 8bit; 1 stop bit; no parity; и т.п.

    u8 ch = ‘A’;
    main()
    {
    stm32_Init();
    USART2->DR=ch;
    for(;;);
    }

    А в комп данные приходят уже на скорости 14400. Это получается что я кварц неправильно задаю, т.е. выставляю меньшую скорость. Вообщем где можно это поправить?
    Если править в Clock Configuration > HSE: External High Speed Clock [Hz] вместо 8 MHz вписать 12 MHz кайл матерится варнингами integer operation result is out of range.

    • RigorMortis говорит:

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

  69. aske12345 говорит:

    Здравствуйте! помогите разобраться новичку (исходник приложил). Пытался написать свою библиотеку под ЖКИ WEH002004ALPP5N для STM32F407 для работы в 4-битном режиме код не хочет компилироваться выдаёт кучу ошибок :
    compiling leds.c…
    leds.c(76): error: #18: expected a «)»
    leds.c(78): error: #18: expected a «)»
    leds.c(80): error: #18: expected a «)»
    leds.c(82): error: #18: expected a «)»
    leds.c(84): error: #18: expected a «)»
    leds.c(86): error: #18: expected a «)»
    leds.c(88): error: #18: expected a «)»
    leds.c(90): error: #18: expected a «)»
    leds.c(92): error: #18: expected a «)»
    leds.c(94): error: #18: expected a «)»
    leds.c(107): error: #65: expected a «;»
    Target not created
    /******************/

    #include «stm32f4xx.h»
    #include «stm32f4xx_rcc.h»
    #include «stm32f4xx_gpio.h»
    #include «misc.h»
    /******************/
    uint16_t delay_count=0, data=0;

    void SysTick_Handler(void)
    {
    if(delay_count > 0)
    {
    delay_count—;

    }
    }

    void delay_ms(uint16_t delay_temp)
    {
    delay_count = delay_temp;
    while(delay_count){}

    }

    //LCD-порт :
    /*
    1-Vss
    2-Vdd
    4-RS-PD0
    5-R/!W-PD1
    6-E-PD2
    11-DB4-PD4
    12-DB5-PD5
    13-DB6-PD6
    14-DB7-PD7
    */
    #define LCD_RCC_GPIO RCC_AHB1Periph_GPIOD
    #define RS GPIO_Pin_0
    #define R_W GPIO_Pin_1
    #define E GPIO_Pin_2
    #define DB4 GPIO_Pin_4
    #define DB5 GPIO_Pin_5
    #define DB6 GPIO_Pin_6
    #define DB7 GPIO_Pin_7
    #define LCD_PORT GPIOD
    /******************/

    //функции для работы с LCD WEH002004ALPP5N начало
    void lcd_init_gpio()//инициализация LCD-порта
    {
    GPIO_InitTypeDef GPIO_InitPort;
    RCC_AHB1PeriphClockCmd(LCD_RCC_GPIO, ENABLE);

    GPIO_InitPort.GPIO_Pin = RS|R_W|DB4|DB5|DB6|DB7;
    GPIO_InitPort.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitPort.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitPort.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init(LCD_PORT, &GPIO_InitPort);
    }

    void lcd_write_data(uint16_t data)
    {
    GPIO_SetBits(LCD_PORT, data | E);
    delay_ms(2);
    GPIO_ResetBits(LCD_PORT, data | E);
    }

    void lcd_init()//инициализация LCD-дисплея
    {
    GPIO_ResetBits(LCD_PORT, R_W);
    delay_ms(2);
    lcd_init_gpio();
    delay_ms(1000);
    GPIO_ResetBits(LCD_PORT, RS);// уронили RS
    delay_ms(2);
    lcd_write_data(0b00100000);//4-bit режим
    delay_ms(2);
    lcd_write_data(0b00100000);//4-bit режим
    delay_ms(2);
    lcd_write_data(0b10000000);//2 строки, символ 5х8
    delay_ms(2);
    lcd_write_data(0b00000000);//
    delay_ms(2);
    lcd_write_data(0b11110000);// LCD-on
    delay_ms(2);
    lcd_write_data(0b00000000);// LCD-clear 1
    delay_ms(2);
    lcd_write_data(0b00010000);// LCD-clear 2
    delay_ms(2);
    lcd_write_data(0b00000000);// Entry Mode Set 1
    delay_ms(2);
    lcd_write_data(0b01100000);// Entry Mode Set 2
    delay_ms(2);
    lcd_write_data(0b01100000);// Return to home
    delay_ms(2);
    GPIO_SetBits(LCD_PORT, RS);// вернули RS в 1
    }

    void lcd_write_cmd(uint16_t cmd) {
    GPIO_ResetBits(LCD_PORT,RS);
    lcd_write_data(cmd);
    cmd<<=4;
    lcd_write_data(cmd);
    GPIO_SetBits(LCD_PORT,RS);
    }
    void lcd_set_cursor(int line,int pos) {
    pos|= 0b10000000;
    if (line == 1) {
    pos += 0×40;
    }
    lcd_write_cmd(pos);
    }

    void lcd_out_data(uint16_t data1) { //Вывод данных в 4-битном режиме
    GPIO_SetBits(LCD_PORT, data1 | E);
    GPIO_ResetBits(LCD_PORT, E);
    delay_ms(2);
    data1<<=4;
    GPIO_SetBits(LCD_PORT, data1 | E);
    GPIO_ResetBits(LCD_PORT, E);
    delay_ms(2);
    GPIO_ResetBits(LCD_PORT, data1 | E);
    }

    //функции для работы с LCD WEH002004ALPP5N конец

    int main(void)
    {

    // Enable PORTB Periph clock

    SysTick_Config(SystemCoreClock/1000);//1ms

    lcd_init();

    while(1)
    {
    lcd_set_cursor(0,0);
    lcd_out_data('H');
    lcd_out_data('E');
    lcd_out_data('L');
    lcd_out_data('L');
    lcd_out_data('O');
    lcd_out_data('U');
    }
    }

  70. aske12345 говорит:

    Да, забыл компилятор keil, почему не компилировалось догнал похоже нельзя писать константы в формате 0b00100000, заменил на шестнадцатиричные эквиваленты скомпилировалось, только в железе всё равно не пашет почему то

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