95 / 15 / 3
Регистрация: 09.07.2009
Сообщений: 886

Работа с Keil начинающего освоение программирования STM32

08.06.2025, 21:24. Показов 11157. Ответов 164
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте!
Пытаюсь освоить программирование STM32 по книге "Освоение STM32 самостоятельно". У меня установлена версия uVision 5.38.0.0. В книге на рис. 52 и 53 показано окно с заголовком "Contex M Target Driver Setup". Подскажите, пожалуйста, через какие пункты меню Keil можно вызвать это окно. Прикрепил скриншот проекта и интерфейса Keil
Миниатюры
Работа с Keil начинающего освоение программирования STM32  
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
08.06.2025, 21:24
Ответы с готовыми решениями:

Книги "Освоение STM32 самостоятельно. Практическое руководство" без #, c #1 и #2 в названии
Здравствуйте! На Озоне появились книги с одинаковым названием, но разные по переплету и количеству...

Сравнить программные продукты Keil uVision 5.11.2.0 и Keil ARM 5.29.0.0
прив! программные среды разработки Keil uVision 5.11.2.0 и Keil ARM 5.29.0.0 это просто разные ...

STM32 + KEIL. Найти смещение функции в прошивке
Привет, коллеги! Столкнулся с проблемой - надо найти адрес и размер функции, а также все что к...

164
Эксперт .NET
 Аватар для Rius
13837 / 7879 / 1706
Регистрация: 25.05.2015
Сообщений: 23,921
Записей в блоге: 14
18.06.2025, 12:31
Студворк — интернет-сервис помощи студентам
Если учитесь по книге на основе того же ПО, что используется её автором, то возникает меньше проблем из-за расхождения версий.
1
51 / 49 / 2
Регистрация: 23.01.2019
Сообщений: 380
18.06.2025, 12:34
Не вот чтобы учусь. Скорее пока "только посмотреть"
0
Эксперт JavaЭксперт по электроникеЭксперт .NET
 Аватар для wizard41
3463 / 2784 / 575
Регистрация: 04.09.2018
Сообщений: 8,757
Записей в блоге: 3
18.06.2025, 22:46
Провода, ст-линки, софт, книги.... фить, ерунда какая. То ли еще будет..

Есть проблемы поинтереснее:
4 устройства: A, B, C, D, где A,B - это приложения на ПК, а C,D - реальные устройства (железки), причем устройство D - это STM32F4x.
Задача: обмен данными между всеми ими по некоторому протоколу.
Что происходит: программа А успешно обменивается с приложением В. Так же, А успешно обменивается с реальным устройством С. Приложение В, в свою очередь, так же общается с С и D. Но(!) приложение А не может общаться с D (прием неверных данных на D).
Каламбур: объекты A-B-C спокойно разговаривают между собой. B-C прекрасно беседуют с D. A и D не дружат!
Вот те раз..
0
Эксперт .NET
 Аватар для Rius
13837 / 7879 / 1706
Регистрация: 25.05.2015
Сообщений: 23,921
Записей в блоге: 14
18.06.2025, 22:58
Навскидку... несоблюдение таймингов, (не)побайтовая работа с последовательным портом.
1
Эксперт JavaЭксперт по электроникеЭксперт .NET
 Аватар для wizard41
3463 / 2784 / 575
Регистрация: 04.09.2018
Сообщений: 8,757
Записей в блоге: 3
18.06.2025, 23:04
Цитата Сообщение от Rius Посмотреть сообщение
Навскидку... несоблюдение таймингов, (не)побайтовая работа с последовательным портом.
Не, это слишком просто бы выяснилось. Тем более А и В -> С эти тайминги выдерживают, а вот А с D уже нет(?)..
0
Windows must die
613 / 885 / 105
Регистрация: 23.11.2021
Сообщений: 5,196
Записей в блоге: 19
18.06.2025, 23:08
Цитата Сообщение от wizard41 Посмотреть сообщение
Вот те раз..
У меня на каждое устройство свой демон работает. А сверху есть "супердемон" (и не всегда один, бывает еще и "супер-супер-демон"). Все общаются обычно через UNIX-сокеты между собой, чтобы побыстрей было и попроще (т.к. там без всяких "тюнингов" ядра есть нужные опции). И везде обычный текстовый протокол, чтобы всегда можно было в терминале открыть нужный сокет и читать/писать…

// а вот вантузоиды мучаются, да…
0
Эксперт .NET
 Аватар для Rius
13837 / 7879 / 1706
Регистрация: 25.05.2015
Сообщений: 23,921
Записей в блоге: 14
18.06.2025, 23:11
Казалось бы, какое это имеет отношение к вопросу? А, просто вы... пендриться.

Добавлено через 1 минуту
wizard41, снифффером смотрите, в логах. Если одно не работает, а другое работает, то разница должна быть видна на том или ином уровне.
0
Эксперт JavaЭксперт по электроникеЭксперт .NET
 Аватар для wizard41
3463 / 2784 / 575
Регистрация: 04.09.2018
Сообщений: 8,757
Записей в блоге: 3
18.06.2025, 23:16
Rius, поздно выяснилось. Действительно, завтра сяду анализатором на D, посмотреть посылки.. На всякий случай.

Добавлено через 2 минуты
Цитата Сообщение от Rius Посмотреть сообщение
снифффером смотрите, в логах.
Ессесно. Это я так, задачку молодым на смекалку подкинул.. Что делать и кого обвинять завтра выясню
0
Модератор
Эксперт по электронике
8982 / 6749 / 921
Регистрация: 14.02.2011
Сообщений: 23,876
18.06.2025, 23:26
Цитата Сообщение от wizard41 Посмотреть сообщение
Есть проблемы поинтереснее:
4 устройства: A, B, C, D,
какое отношение это имеет к вопросу
Цитата Сообщение от tumanovalex Посмотреть сообщение
Пытаюсь освоить программирование STM32 по книге "Освоение STM32 самостоятельно".
???

создавайте под свой вопрос свою тему
0
95 / 15 / 3
Регистрация: 09.07.2009
Сообщений: 886
19.06.2025, 18:02  [ТС]
Программа из книги скомпилировалась, прошилась, заработала:
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include "stm32f10x.h"
 
void SetSysClockTo72(void);
 
void PORTC_13_INIT (void);
 
void SetSysClockTo72(void)
{
    RCC->CR |= RCC_CR_HSEON; // bit 16 HSEON - ON external tackting
    while (READ_BIT (RCC-> CR, RCC_CR_HSERDY == RESET)) {} // waiting for clock stabilization from HSE
    FLASH-> ACR &= (uint32_t) ~FLASH_ACR_PRFTBE;  // turn off the prefetch buffer
    FLASH-> ACR |= FLASH_ACR_PRFTBE; // run the prefetch buffer programmatically - bit number 4,
    FLASH-> ACR &= (uint32_t) ~FLASH_ACR_LATENCY; // resetting a preset setting
    FLASH-> ACR |= FLASH_ACR_LATENCY_2; // delay 2 cycle
    RCC-> CFGR &= ~RCC_CFGR_HPRE; // resetting a preset setting
    RCC-> CFGR |= RCC_CFGR_HPRE_DIV1; // frequency SysClk without division
    RCC-> CFGR &= ~RCC_CFGR_PPRE2; // resetting a preset setting
    RCC-> CFGR |= RCC_CFGR_PPRE2_DIV1; // frequency HCLK without division
    RCC-> CFGR &= ~RCC_CFGR_PPRE1; // resetting a preset setting
    RCC-> CFGR |= RCC_CFGR_PPRE1_DIV2; // frequency HCLK division 2
    RCC-> CFGR &= (uint32_t) ((uint32_t) - (RCC_CFGR_PLLSRC |   RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL));
    RCC-> CFGR |= (uint32_t) (RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9);
    RCC-> CR |= RCC_CR_PLLON; 
    while (READ_BIT (RCC-> CR, RCC_CR_PLLRDY)!= (RCC_CR_PLLRDY)) {}
    RCC-> CFGR &= -RCC_CFGR_SW;
    RCC-> CFGR |= RCC_CFGR_SW_PLL;
    while (READ_BIT (RCC-> CFGR, RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL) {}
}
 
void PORTC_13_INIT (void)
{
    RCC-> APB2ENR |=RCC_APB2ENR_IOPCEN;
    GPIOC-> CRH &= ~GPIO_CRH_MODE13; 
    GPIOC-> CRH |= GPIO_CRH_MODE13_1; 
    GPIOC-> CRH &= ~GPIO_CRH_CNF13; 
}
 
int main (void)
{
    PORTC_13_INIT ();
    while (1)
    {
        GPIOC-> BSRR |= GPIO_BSRR_BS13;
        for (int i = 0; i <1000000; i++) {}
        GPIOC-> BSRR |= GPIO_BSRR_BR13;
        for (int i = 0; i <1000000; i++) {}
    }
}
Возникли следующие вопросы:
1. Заголовочный файл в кавычках вроде бы должен быть в директории с исходным кодом. Но у меня этого файла в директории проекта нет. Как Keil узнает, где он находится, и почему этот файл в кавычках?
2. В большинстве ресурсов по программированию АЦП используется STMCubeMX. Я хотел бы просто использовать HAL для STM32F103. Попробовал вставить в проект основной заголовочный файл
C
1
#include "stm32f1xx_hal.h"
получил слева от строки красный крестик. Как мне настроить проект, чтобы заголовочные файлы для HAL подключались без ошибок?
0
Эксперт .NET
 Аватар для Rius
13837 / 7879 / 1706
Регистрация: 25.05.2015
Сообщений: 23,921
Записей в блоге: 14
19.06.2025, 18:07
Цитата Сообщение от tumanovalex Посмотреть сообщение
Заголовочный файл в кавычках вроде бы должен быть в директории с исходным кодом.
Файл в <> в каталогах компилятора, в "" не у компилятора, а у вас. Условно.

Цитата Сообщение от tumanovalex Посмотреть сообщение
Как Keil узнает, где он находится, и почему этот файл в кавычках?
Где-то в настройках IDE должен быть перечень каталогов, в которых идёт поиск заголовочных файлов. Т.н. INCLUDE DIRECTORIES, может называться как-то иначе, но похоже.

Во, include paths:
0
Эксперт JavaЭксперт по электроникеЭксперт .NET
 Аватар для wizard41
3463 / 2784 / 575
Регистрация: 04.09.2018
Сообщений: 8,757
Записей в блоге: 3
19.06.2025, 18:16
tumanovalex, "stm32f1xx_hal.h" находится в папке Driver/CMSIS, которые лежат в папке проекта. Поэтому имя файла взято в кавычки.
Но для этого в настройках данного проекта должны быть включены пути поиска:

Цитата Сообщение от tumanovalex Посмотреть сообщение
Но у меня этого файла в директории проекта нет.
Не установлен (не импортирован) драйвер HAL + CMSIS.
0
Эксперт JavaЭксперт по электроникеЭксперт .NET
 Аватар для wizard41
3463 / 2784 / 575
Регистрация: 04.09.2018
Сообщений: 8,757
Записей в блоге: 3
19.06.2025, 18:18
0
Windows must die
613 / 885 / 105
Регистрация: 23.11.2021
Сообщений: 5,196
Записей в блоге: 19
20.06.2025, 09:21
Цитата Сообщение от tumanovalex Посмотреть сообщение
RCC-> CFGR &= ~RCC_CFGR_HPRE; // resetting a preset setting
RCC-> CFGR |= RCC_CFGR_HPRE_DIV1; // frequency SysClk without division
RCC-> CFGR &= ~RCC_CFGR_PPRE2; // resetting a preset setting
RCC-> CFGR |= RCC_CFGR_PPRE2_DIV1; // frequency HCLK without division
RCC-> CFGR &= ~RCC_CFGR_PPRE1; // resetting a preset setting
RCC-> CFGR |= RCC_CFGR_PPRE1_DIV2; // frequency HCLK division 2
RCC-> CFGR &= (uint32_t) ((uint32_t) - (RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL));
RCC-> CFGR |= (uint32_t) (RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9);
Жесть-то какая! А ничего, что все системные регистры объявлены как volatile? Каждая из этих строчек фактически будет выполняться: компилятор не сможет эту жесть оптимизировать на один вызов!
Ну и непонятно, зачем "обнулять" то, что и так равно нулю.
Можно ведь сразу было написать:
Code
1
 RCC->CFGR = ...;
Добавлено через 51 секунду
Цитата Сообщение от tumanovalex Посмотреть сообщение
В большинстве ресурсов по программированию АЦП используется STMCubeMX
Там для "программирования АЦП" буквально несколько строк кода нужно. Зачем калокуб?
0
 Аватар для COKPOWEHEU
4148 / 2726 / 433
Регистрация: 09.09.2017
Сообщений: 12,083
20.06.2025, 09:52
Цитата Сообщение от tumanovalex Посмотреть сообщение
PORTC_13_INIT
В Си принято капсом называть только макросы. И то не все.
Да и вообще, какой смысл писать целую функцию для инициализации одного-единственного PC13? Проще сразу в RCC->APBxENR разрешить тактирование всех портов, AFIO и, возможно, еще чего-то нужного. Все равно ж рано или поздно задействуете. Собственно, для макетных целей туда, насколько я слышал, можно вообще 0xFFFF записать - разрешить вообще все. Это ж макетка, а не батарейное устройство, миллиамперы можно не экономить.
Цитата Сообщение от tumanovalex Посмотреть сообщение
GPIOC-> CRH |= GPIO_CRH_MODE13_1;
А это какой режим-то? Из кода абсолютно непонятно. Для теста сойдет, но потом я бы советовал все-таки поименовать режимы портов и записывать их через сдвиги и битовые операции. Что-то вроде такого:
C
1
2
3
4
5
#define GPIO_PP50 0b0011 // push-pull, 50 MHz
uint32_t temp = GPIOC->CRH;
temp &=~ (0b1111 << ((port-8)*4));
temp |= (GPIO_PP50 << ((port-8)*4));
GPIOC->CRH = temp;
Это самый примитивный вариант, но даже он лучше, чем GPIO_CRH_MODE13_1.
Цитата Сообщение от tumanovalex Посмотреть сообщение
1. Заголовочный файл в кавычках вроде бы должен быть в директории с исходным кодом. Но у меня этого файла в директории проекта нет. Как Keil узнает, где он находится, и почему этот файл в кавычках?
В обычном gcc это задается флагами -I. В IDE эти флаги наверняка берутся из каких-нибудь настроек. Собственно флаг -I говорит "А еще .h файлы могут лежать вот там"
Цитата Сообщение от Eddy_Em Посмотреть сообщение
А ничего, что все системные регистры объявлены как volatile?
Да, это неэффективно, лучше было выделить буферную переменную. Но это инициализация, она выполняется единственный раз, много на ней не выиграешь.
Другое дело, что в коде ТС я вижу реализацию функции SetSysClockTo72(), но не вижу ее вызова.
Цитата Сообщение от Eddy_Em Посмотреть сообщение
Ну и непонятно, зачем "обнулять" то, что и так равно нулю.
RCC_CFGR не обязательно равен нулю. И в нем настраивается не только тактирование ядра. Мало ли, вдруг в процессе работы частоту будут менять.
Цитата Сообщение от Eddy_Em Посмотреть сообщение
Там для "программирования АЦП" буквально несколько строк кода нужно.
Для программирования АЦП нужно как-то распихать номера каналов по регистрам. То есть либо считать биты вручную, либо использовать какие-то обертки. Я предпочитаю макросы, Куберы свое средство генерирования говнокода.
0
Эксперт .NET
 Аватар для Rius
13837 / 7879 / 1706
Регистрация: 25.05.2015
Сообщений: 23,921
Записей в блоге: 14
20.06.2025, 10:29
Cube - средство быстрого прототипирования, но тупым красноглазикам этого не дано понять.
Прамая запись чисел в регистр тем плоха, что конкрентный результат без даташита не ясен.
Макросы лучше тем, что видны названия значений, но всё равно плохи тем, что позволяют писать чушь, типа битов АЦП в регистр UART, компилятор это никак не контролирует.
Каждый кулик хвалит своё болото.


0
Windows must die
613 / 885 / 105
Регистрация: 23.11.2021
Сообщений: 5,196
Записей в блоге: 19
20.06.2025, 11:00
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
То есть либо считать биты вручную, либо использовать какие-то обертки. Я предпочитаю макросы
Я вручную пишу, несложно это. И DMA использую, чтобы АЦП постоянно молотило, а я мог в любой момент из последних девяти значений на каждый используемый канал получить медиану.
0
 Аватар для COKPOWEHEU
4148 / 2726 / 433
Регистрация: 09.09.2017
Сообщений: 12,083
20.06.2025, 11:24
Цитата Сообщение от Rius Посмотреть сообщение
Прамая запись чисел в регистр тем плоха, что конкрентный результат без даташита не ясен.
Это общее соображение по "магическим числам". Запись int some_var = 123; в этом смысле ничуть не лучше записи GPIOC-> CRH |= GPIO_CRH_MODE13_1;. Они обе - запись какого-то непонятного числа. Почему выбрано именно такое число, без внешней документации непонятно.
Цитата Сообщение от Rius Посмотреть сообщение
но всё равно плохи тем, что позволяют писать чушь, типа битов АЦП в регистр UART
Скажите, что у вас в голове творится, что запись битов АЦП в регистр UART вот настолько часто происходит, что вы считаете это серьезной проблемой?!
Цитата Сообщение от Eddy_Em Посмотреть сообщение
Я вручную пишу, несложно это.
Мазохист что ли? Перебирать к какому ADCSQR какой канал относится, да еще менять если канал оказался не нужен.
C
1
2
3
4
5
ADC_SAMPLING_TIME( ADC_1, marg5(OP2_OUT0), ADC_SAMPL_TIME_240 );
ADC_SAMPLING_TIME( ADC_1, VREF, ADC_SAMPL_TIME_240 );
ADC_SEQ_SET( ADC_1, 1, marg5(OP2_OUT0) );
ADC_SEQ_SET( ADC_1, 2, VREF );
ADC_SEQ_CNT( ADC_1, 2 );
И DMA можно вполне удобно завернуть. Я даже, после того, как пару раз указал в source не адрес регистра, а его значение, даже добавил проверку:
C
1
2
3
4
5
6
7
#define dma_cfg_io(dma, dst, src, cnt) do{ \
    _DMA_CH(dma)->PADDR = (uint32_t)(src); \
    _DMA_CH(dma)->MADDR = (uint32_t)(dst); \
    _DMA_CH(dma)->CNTR  = (uint16_t)(cnt); \
    if(0)(( void(*)(volatile void*, volatile void*) )\
      "dma_cfg_io(void*, void*)")(dst, src); \
  }while(0)
Да, Rius, при желании и в макросы можно добавить проверки. И если вы настолько часто пишете в периферию биты, относящиеся к другой периферии, это тоже можно контролировать. Причем, в отличие от HAL, без тонн говнокода, обрабатываемого в рантайме.
0
Windows must die
613 / 885 / 105
Регистрация: 23.11.2021
Сообщений: 5,196
Записей в блоге: 19
20.06.2025, 12:12
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Перебирать к какому ADCSQR какой канал относится
А что там сложного? Вот:
Code
1
ADC1->CHSELR =  ADC_CHSELR_CHSEL3 | ADC_CHSELR_CHSEL5 | ADC_CHSELR_CHSEL16 | ADC_CHSELR_CHSEL17;
0
95 / 15 / 3
Регистрация: 09.07.2009
Сообщений: 886
20.06.2025, 12:17  [ТС]
Приведенный код я брал из книги "Освоение STM32 самостоятельно", просто нужно было с чего-то начать. На нем я потренировался компилировать и загружать прошивку в устройство, поскольку делал это первый раз в жизни. А попросили меня друзья сделать АЦП на STM32, которое должно получать аналоговый сигнал, сравнивать с минимальным и максимальным значением и устанавливать 0 или 1 на определенных контактах в зависимости от результатов сравнения. Как я понимаю, мне нужно запрограммировать АЦП в режиме Analog Watchdog. Но для того, чтобы сделать программу, мне еще нужно очень много понять и многому научиться. Надеюсь на вашу помощь.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
20.06.2025, 12:17

STM32, Keil, передача массива в функцию
Использую uVision 4.60.00. Есть функция, которая выполняет расчёт контрольной суммы (CRC). Для её...

C++ в Keil + STM32
Доброго времени суток. Пытаюсь написать небольшой проектик на С++ под STM32 в Keil, но что то не...

CMSIS STM32 проект в Keil - это просто
Пишу небольшую обзорную статейку про CMSIS, это её часть ... Скачайте у ST последний HAL и...

Stm32 и Keil
Здравствуйте, помогите пожалуйста. Пытаюсь оценить ограничения Keilа. 32 кб этого хватит для таких...

STM32 и Keil v5 (5.14)
Всем доброго времени суток, я навичек в МК, прошу прощения, если выкладываю мысли слегка путано для...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
120
Ответ Создать тему
Опции темы

Новые блоги и статьи
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
Оттачиваю умение писать js программы.
russiannick 30.08.2026
Проектом выходного дня стало написание Книги шифров Виженера. Итогом стала версия 200, синий туман. Синий туман назван так, потому что замораживает текст под собой. Нажатие синих кнопок управляют. . .
мат медиц модель 30. презентация проекта
anaschu 27.08.2026
хоп хоп хоп хидахоп, а я кладую))
Как у меня протекала болезнь
zorxor 27.08.2026
Здравствуйте, друзья! Эта запись блога предназначена именно для вас - для моих дорогих друзей, которые знали меня лично. Чтобы ответить на вопрос - а что же со мной произошло на самом деле? Я учился. . .
Нашел вот забавное видео о измерениях. Лучшее что я видел на эту тему
kumehtar 26.08.2026
ILETXiw9bMQ Основная суть и тезисы по измерениям: 0D (Нулевое измерение): точка, не имеющая длины, ширины, высоты или объема. Объект не может перемещаться в 0D. 1D (Первое измерение):. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru