|
Мелкие вопросы |
|
|
|
Nov 27 2015, 11:48
|
Участник

Группа: Участник
Сообщений: 28
Регистрация: 16-10-15
Пользователь №: 88 891

|
Идет процесс бурного изучения, возникает много вопросов, все вопросы мелкие, плодить темы не хочется 1. Вопрос по отладчику Keil. Есть массив указателей, который указывает на другие массивы: Код unt8_t const* const strings[] { string1, string2... } и где то объявлены сами массивы, в некоторый момент передается номер массива, который нужно прочитать. Возможно ли в этот момент посмотреть содержимое этого массива в отладчике? 2. Имеется 1 АЦП и несколько ног, с одной нужно снимать 12битные значения, со другой 8битные. Пересчитывать пропорцией? 3. Делаю библиотеку. Где по правильному хранить платформозависимые дефайны в h или в c файле 4. Дефайны пишем заглавными буквами, а на макросы это распространяется или нет? По сути это тоже дефайны? 5. Перед некоторыми функциями ставят знак нижнего подчеркивания, что это значит? 6. Почему в библиотеках не используют структуры? Например вместо Код lcd_drawLine(x0, y0, x1, y1) не написать Код typedef struct { uint8_t x; uint8_t y; }point_t; lcd_drawLine(pont_t start_point, pont_t end_point) это же нагляднее?
|
|
|
|
|
Nov 27 2015, 14:11
|
Участник

Группа: Участник
Сообщений: 50
Регистрация: 31-03-14
Из: Харьков
Пользователь №: 81 165

|
1. да, можете посмотреть содержимое памяти по адресу вашего массива. Одно из отладочных окошек должно называться "Memory", или как-то так. я не спец в кейле  2. считайте так, чтобы было понятно тем, кто будет в будущем ваш код читать 3. в большинстве случаев платформозависимые дефайны хранятся в *.h 4. на макросы распространяется тоже 5. нижнее подчеркивание обычно обозначает, что ф-ция зарезервирована какой-то стандартной либой. старайтесь в своих ф-циях не использовать нижнее подчеркивание в начале названия 6. возможно потому, что поля структуры придется заполнять перед вызовом ф-ции. итого n лишних строк кода
|
|
|
|
|
Nov 29 2015, 08:00
|

Знающий
   
Группа: Участник
Сообщений: 794
Регистрация: 4-09-06
Из: Москва(ЗелАО), РФ
Пользователь №: 20 055

|
Добавлю еще один мелкий ( но при этом большой ) вопрос.
Изучал функцию GPIO_Init из стандартной библиотеки STM32F0xx_StdPeriph_Driver.
Правильно ли я понимаю, что при помощи этой функции можно сделать только такие настройки:
1) По умолчанию все ноги - входы General-purpose 2) Ноги, перечисленные в строке структуры GPIO_InitStructure.GPIO_Pin становятся выходами с одинаковыми параметрами, которые указаны в следующих строках структуры.
Если так, то вопрос, как сконфигурировать ноги порта, если там и входы разного типа ( General-purpose, аналоговые, с подтяжкой или без) и еще и выходы тоже разного типа?
Видел в англоязычных форумах более ручной способ конфигурирования, типа:
GPIOC-> MODER |= (GPIO_MODER_MODER8_0 | GPIO_MODER_MODER9_0) ;
Есть ли более подробные примеры? Среда - IAR 6.40
Сообщение отредактировал =L.A.= - Nov 29 2015, 08:01
--------------------
-Кто-то работает на совесть, а кто-то на других заказчиков.-
|
|
|
|
|
Nov 29 2015, 08:12
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(=L.A.= @ Nov 29 2015, 11:00)  Если так, то вопрос, как сконфигурировать ноги порта, если там и входы разного типа ( General-purpose, аналоговые, с подтяжкой или без) и еще и выходы тоже разного типа? Написать свой конфигуратор, например: CODE typedef enum { GPM_INPUT = 0, GPM_OUTPUT = 1, GPM_AF = 2, GPM_ANALOG = 3, } GPIO_MODE; typedef enum { GPF_AF0 = 0, GPF_AF1 = 1, GPF_AF2 = 2, GPF_AF3 = 3, GPF_AF4 = 4, GPF_AF5 = 5, GPF_AF6 = 6, GPF_AF7 = 7, GPF_AF8 = 8, GPF_AF9 = 9, GPF_AF10 = 10, GPF_AF11 = 11, GPF_AF12 = 12, GPF_AF13 = 13, GPF_AF14 = 14, GPF_AF15 = 15, } GPIO_AF; typedef enum { GPT_PP = 0, GPT_OD = 1, } GPIO_TYPE; typedef enum { SPD_2M = 0, SPD_25M = 1, SPD_50M = 2, SPD_100M = 3, } GPIO_SPD; struct pin_mode { void *port; char pin; GPIO_MODE mode; GPIO_AF af; GPIO_TYPE type; GPIO_SPD speed; }; void gpio_setup(const struct pin_mode *setup) { while(setup->port) { GPIO_TypeDef *port = (GPIO_TypeDef *)setup->port; port->MODER = (port->MODER & ~(3UL << setup->pin * 2)) | (setup->mode << setup->pin * 2); if(setup->mode == 2) // Alternate function { int p = (setup->pin > 7) ? 1 : 0, n = setup->pin & 7; port->AFR[p] = (port->AFR[p] & ~(15UL << n * 4)) | (setup->af << n * 4); } if(setup->type) port->OTYPER |= 1UL << setup->pin; else port->OTYPER &= ~(1UL << setup->pin); port->OSPEEDR = (port->OSPEEDR & ~(3UL << setup->pin * 2)) | (setup->speed << setup->pin * 2); setup++; } }
Вызов: Код const struct pin_mode ui_pins[] = { {LED1, GPM_OUTPUT, GPF_AF0, GPT_PP}, {LED2, GPM_OUTPUT, GPF_AF0, GPT_PP}, {KEY, GPM_INPUT}, NULL }; gpio_setup(ui_pins); Подтяжки добавить по аналогии с остальным.
|
|
|
|
|
Nov 29 2015, 08:18
|

Знающий
   
Группа: Участник
Сообщений: 794
Регистрация: 4-09-06
Из: Москва(ЗелАО), РФ
Пользователь №: 20 055

|
Цитата(=L.A.= @ Nov 29 2015, 12:00)  Есть ли более подробные примеры? Среда - IAR 6.40 Сам нашел пример: Удобная настройка GPIO портовhttp://we.easyelectronics.ru/STM32/udobnay...pio-portov.htmlНе указан только тип микроконтроллера. Цитата(aaarrr @ Nov 29 2015, 12:12)  Написать свой конфигуратор, например: CODE typedef enum { GPM_INPUT = 0, GPM_OUTPUT = 1, GPM_AF = 2, GPM_ANALOG = 3, } GPIO_MODE; typedef enum { GPF_AF0 = 0, GPF_AF1 = 1, GPF_AF2 = 2, GPF_AF3 = 3, GPF_AF4 = 4, GPF_AF5 = 5, GPF_AF6 = 6, GPF_AF7 = 7, GPF_AF8 = 8, GPF_AF9 = 9, GPF_AF10 = 10, GPF_AF11 = 11, GPF_AF12 = 12, GPF_AF13 = 13, GPF_AF14 = 14, GPF_AF15 = 15, } GPIO_AF; typedef enum { GPT_PP = 0, GPT_OD = 1, } GPIO_TYPE; typedef enum { SPD_2M = 0, SPD_25M = 1, SPD_50M = 2, SPD_100M = 3, } GPIO_SPD; struct pin_mode { void *port; char pin; GPIO_MODE mode; GPIO_AF af; GPIO_TYPE type; GPIO_SPD speed; }; void gpio_setup(const struct pin_mode *setup) { while(setup->port) { GPIO_TypeDef *port = (GPIO_TypeDef *)setup->port; port->MODER = (port->MODER & ~(3UL << setup->pin * 2)) | (setup->mode << setup->pin * 2); if(setup->mode == 2) // Alternate function { int p = (setup->pin > 7) ? 1 : 0, n = setup->pin & 7; port->AFR[p] = (port->AFR[p] & ~(15UL << n * 4)) | (setup->af << n * 4); } if(setup->type) port->OTYPER |= 1UL << setup->pin; else port->OTYPER &= ~(1UL << setup->pin); port->OSPEEDR = (port->OSPEEDR & ~(3UL << setup->pin * 2)) | (setup->speed << setup->pin * 2); setup++; } }
Вызов: Код const struct pin_mode ui_pins[] = { {LED1, GPM_OUTPUT, GPF_AF0, GPT_PP}, {LED2, GPM_OUTPUT, GPF_AF0, GPT_PP}, {KEY, GPM_INPUT}, NULL }; gpio_setup(ui_pins); Подтяжки добавить по аналогии с остальным. Я так понимаю, это всё для отдельного вход/выхода? Выходит громоздко. К тому же в хидерах стандартной библиотеки многое уже объявлено и определено, зачем придумывать целиком свой код?
--------------------
-Кто-то работает на совесть, а кто-то на других заказчиков.-
|
|
|
|
|
Nov 29 2015, 15:35
|
Участник

Группа: Участник
Сообщений: 50
Регистрация: 31-03-14
Из: Харьков
Пользователь №: 81 165

|
Я за стандартные либы. Да, местами криво. Да, жрут. Но представьте, что вам достался чужой глючный проект с десятками тысяч строк кода, и все либы - велосипед...
|
|
|
|
|
Nov 29 2015, 20:56
|
Участник

Группа: Участник
Сообщений: 50
Регистрация: 31-03-14
Из: Харьков
Пользователь №: 81 165

|
Если написать свои библиотеки на всю переферию какого-то жирного стм32, то кода там будет ого-го. Велосипед может быть весьма хорош. А может и не быть. Допускаю переписывание части библиотек, только если не будет хватать производительности.
|
|
|
|
|
Nov 30 2015, 04:49
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(slavokhire5 @ Nov 29 2015, 21:35)  Я за стандартные либы. Да, местами криво. Да, жрут. Но представьте, что вам достался чужой глючный проект с десятками тысяч строк кода, и все либы - велосипед... Какие либы на десятки тысяч строк? Для периферии??? Чушь несёте. Что там можно писать десятками тысяч строк? Вы мануал на периферию хоть раз открывали или только "либами" пользуетесь? Работа практически с любой широкораспространённой периферией типа UART-ов, SPI, I2C, таймеров ... - десятки строк аппаратно-зависимого кода. USB, Ethernet и некоторая другая - чуть побольше (к примеру в моём текущем проекте на LPC43xx в драйвере USB-device уровень работы с железом чуть больше 500строк). PS: Ну если только "кодом" называть все дефайны определяющие регистры периферии и битовые поля в них, только тогда можно раздуть на десятки тысяч строк. Только это не код.
|
|
|
|
|
Nov 30 2015, 09:17
|
Участник

Группа: Участник
Сообщений: 28
Регистрация: 16-10-15
Пользователь №: 88 891

|
Цитата(Herz @ Nov 29 2015, 10:48)  Однако потрудитесь назвать тему более информативно, иначе она будет удалена. Но если вопросов слишком много, то не лучше ли обратиться к литературе? offtop mode = true На вашем форуме не хватает такой темы, где можно сгрузить мелкие вопросы по STM32, работе с отладчиком, вопросам по оформлению кода. Этого нет в книгах. Я задал несколько не связанных вопросов, получил на них ответы, не понимаю что здесь необычного. Поверьте нигде больше я бы не нашел на них ответ. А вот нытье по поводу выбора инструментария и прочий флуд не нужен, дайте мне полномочия только на эту тему, я буду следить и чистить только ее, все будут довольны. Если я не прав, можно удалять тему, буду на каждый вопрос создавать отдельную тему. offtop mode = false
|
|
|
|
|
Dec 14 2015, 07:51
|

Знающий
   
Группа: Участник
Сообщений: 794
Регистрация: 4-09-06
Из: Москва(ЗелАО), РФ
Пользователь №: 20 055

|
Цитата(Сергей Борщ @ Dec 14 2015, 09:58)  SysTick timer и использует. Из ядра. И его описание, соответственно, в описании ядра. Кстати, и вектор SysTick_Handler находится среди векторов ядра (всяких xxxAbort_Handler и т.п.). . Спасибо. Главное для меня, что это отдельный от всех остальных таймер и если включено SysTick, то другие таймеры можно использовать. В доках на ядро F0 о таймере SysTick написано крайне мало. Даже Гугль ничего не находит  А вектор ( приоритет SysTick ) попробую переставить пониже в файле startup_stm32f051.s Вдруг подействует?
--------------------
-Кто-то работает на совесть, а кто-то на других заказчиков.-
|
|
|
|
|
Dec 14 2015, 08:38
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(=L.A.= @ Dec 14 2015, 10:51)  В доках на ядро F0 о таймере SysTick написано крайне мало. Даже Гугль ничего не находит  PM0215, "STM32F0xxx Cortex-M0 programming manual", раздел 4.4, 4 страницы с картинками. Гугль. Результатов: примерно 18 600. Попробуйте сменить интернет. Цитата(=L.A.= @ Dec 14 2015, 10:51)  А вектор ( приоритет SysTick ) попробую переставить пониже в файле startup_stm32f051.s Вдруг подействует? В файле вы можете перставлять что угодно, а в кристалле вектора прибиты к своим адресам гвоздями. Про приоритеты написано в том же описании в разделе 2.2, этот раздел аж из 6 страниц.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Dec 14 2015, 12:53
|

Знающий
   
Группа: Участник
Сообщений: 794
Регистрация: 4-09-06
Из: Москва(ЗелАО), РФ
Пользователь №: 20 055

|
Цитата(Сергей Борщ @ Dec 14 2015, 11:38)  PM0215, "STM32F0xxx Cortex-M0 programming manual", раздел 4.4, 4 страницы с картинками. Эту доку читал, но интересовался не описанием регистров, а связью SysTick c другими таймерами, о чем в в Programming manual не написали. Можно сравнить адреса регистров, но надо обратить специальное внимание, что я уже сделал. Теперь добавил в программу инициализацию TIM6 и установку прерывания по этому таймеру. ИАР выдает ошибку Error while running Linker : Error[Li005]: no definition for "NVIC_Init" [referenced from C:\ARM\2_PROJ\1Prb32F0\EWARMv5\Release\Obj\01PrbDsc.o] Что ему не нравится? Код * //######################### // /* TIM6 is used to */ // NVIC_InitTypeDef NVIC_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; // /* TIMER clock enable */ // RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6 , ENABLE);
/* Enable the TIMER global Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM6_DAC_IRQn; NVIC_InitStructure.NVIC_IRQChannelPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // NVIC_Init(&NVIC_InitStructure); // TIM_TimeBaseStructure.TIM_Period = 5000; TIM_TimeBaseStructure.TIM_Prescaler = 32; TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; // TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure); // /* TIM IT enable */ TIM_ITConfig(TIM6, TIM_IT_Update , ENABLE); // /* TIM enable counter */ // TIM_Cmd(TIM6, ENABLE); //-------
Сообщение отредактировал =L.A.= - Dec 14 2015, 13:18
--------------------
-Кто-то работает на совесть, а кто-то на других заказчиков.-
|
|
|
|
|
Dec 14 2015, 15:01
|

Знающий
   
Группа: Участник
Сообщений: 794
Регистрация: 4-09-06
Из: Москва(ЗелАО), РФ
Пользователь №: 20 055

|
Цитата(=L.A.= @ Dec 14 2015, 15:53)  Error while running Linker :
Error[Li005]: no definition for "NVIC_Init" [referenced from C:\ARM\2_PROJ\1Prb32F0\EWARMv5\Release\Obj\01PrbDsc.o] Нашел. Оказалось, что функция void NVIC_Init(....) спрятана в файле stm32f0xx_misc.c Цитата(Сергей Борщ @ Dec 14 2015, 11:38)  В файле вы можете перставлять что угодно, а в кристалле вектора прибиты к своим адресам гвоздями. Про приоритеты написано в том же описании в разделе 2.2, этот раздел аж из 6 страниц. . Насчет "прибитых гвоздями" векторов. Прочитал доку. Вижу таблицу с непонятными словами "settable". Что бы это значило?  Гугля спросить или интернет поменять?
--------------------
-Кто-то работает на совесть, а кто-то на других заказчиков.-
|
|
|
|
|
Jan 11 2016, 18:16
|

Знающий
   
Группа: Участник
Сообщений: 794
Регистрация: 4-09-06
Из: Москва(ЗелАО), РФ
Пользователь №: 20 055

|
STM32F0xxx Приоритет SysTick устанавливается программно. Тактовая частота - как в примерах: HSE (HSI) на 8 МГц, умножитель на 6, то есть имеем 48 МГц тактирование ядра. Код //**************************************************************************// // Установка периода SysTick 5 мс //==========================================================================// SysTick_Config(SystemCoreClock/200); // NVIC_SetPriority(SysTick_IRQn, 2); // IRQ Priority = 2
// // ..................... // //**************************************************************************// // IRQ SysTickTimer с периодом 5 мс //==========================================================================// void SysTick_Handler(void) { // ....trtrtrtrtrtrtrtrtrtrtr.... // }
Сообщение отредактировал =L.A.= - Jan 12 2016, 06:34
--------------------
-Кто-то работает на совесть, а кто-то на других заказчиков.-
|
|
|
|
|
Jan 12 2016, 14:09
|

Профессионал
    
Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877

|
Цитата(Ruslan1 @ Dec 15 2015, 16:35)  Вопрос по определению USB подключения на STM32F0: Обязательно ли нужно в STM32F0 (STM32F070) для работы с USB задействовать какой-то вывод МК кроме DP,DM для определения факта подключения (наличия VBUS) и начала инициализации USB соединения? Отдельный вывод под контроль VBUS очень не хочется, ножек не хватает. Про F0 ничего не скажу, не работал. А вот в USB OTG более "толстых" камней есть чудная грабля - VBUS им обязателен. При низком уровне на этой ноге соединение само собой гасится, при появлении высокого - восстанавливается. Я столкнулся с этим на F105, на ногу VBUS удобно лёг передатчик UART'а. Пока по UART'у ничего не передавалось, всё работало. Зато сразу после написания драйвера на этот UART начались произвольные пропадания данных в USB. Ремап ножек там очень убогий, пришлось много резать, к сожалению. Собственно, предложений два: - проверить (демо-плата есть?), что низкий уровень на отключенной ремапом ножке не приводит к фатальным последствиям - инициализировать один раз, и потом просто сидеть и ждать прерывания от хоста. Правда, это не очень красиво, если устройство супер-малопотребляющее.
--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|