Часть 2 - Практика
После теории можно рассмотреть обе части библиотеки с практической точки зрения. При этом надо заметить, что помимо явного указания достоинств каждой части, я также укажу недостатки, с большинством из которых вы наверное даже и не столкнётесь до той поры, пока не копнёте чуть глубже чем обычные проекты с использованием МК."Hello Led"
В качестве примера возьмём простое включение 4х цветных светодиодов на плате (которые вокруг акселерометра).
CMSIS
Проект - 000-libs-cmsis. Помимо констант (удобство использования которых не вызывает сомнения) в файле work.h:
/** Led port */ #define LED_PORT GPIOD /** Led pins */ #define GREEN_LED (1 << 12) #define ORANGE_LED (1 << 13) #define RED_LED (1 << 14) #define BLUE_LED (1 << 15) #define ALL_LEDS (GREEN_LED | ORANGE_LED | RED_LED | BLUE_LED)Код в файле work.c не занимает много места и достаточно прост:
/* enable led port */ RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN; /* set led pins to output state */ LED_PORT->MODER |= GPIO_MODER_MODER12_0 | GPIO_MODER_MODER13_0 | GPIO_MODER_MODER14_0 | GPIO_MODER_MODER15_0; /* enable leds */ LED_PORT->ODR |= ALL_LEDS; /* infinity loop */ while (1);Начиная с инициализации и заканчивая собственно переводом выводов в активное состояние.
Для настройки хватило 2 регистров, т.к. значения по умолчанию соответствуют тем, которые нам нужны.
SPL
Проект - 001-libs-spl. Немного изменились константы(которые правильней называть объявлениями) в файле work.h:
/** Led port */ #define LED_PORT GPIOD ///** Led pins */ #define GREEN_LED GPIO_Pin_12 #define ORANGE_LED GPIO_Pin_13 #define RED_LED GPIO_Pin_14 #define BLUE_LED GPIO_Pin_15 #define ALL_LEDS (GREEN_LED | ORANGE_LED | RED_LED | BLUE_LED)А вот с точки зрения кода (work.c) мы поменяли полностью всю логику:
GPIO_InitTypeDef GPIO_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Pin = ALL_LEDS; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_Init(LED_PORT, &GPIO_InitStructure); GPIO_SetBits(LED_PORT, ALL_LEDS); /* infinity loop */ while (1);В SPL мы оперируем не отдельными регистрами, а блоками. Т.е. проще говоря код из указательного превратился в декларативный. В примере мы объявили структуру для порта ввода-вывода. Затем включили тактирование нужного нам порта в/в. Настройка порта осуществляется полностью через его структуру. Для установки-снятия битов существуют соответствующие функции, одной из которых мы и воспользовались. Для иллюстрации фото работы этого примера:
Теперь собственно поговорим чем же различаются эти два подхода к написанию кода. CMSIS даёт непосредственный доступ к периферии, сочетающийся с тем, что при непосредственной записи в регистры мы получаем максимально возможную скорость. Однако вместе с этим мы получаем
Комментариев нет:
Отправить комментарий