Кто любит RISC в жизни, заходим, не стесняемся.
Ответить

STM32 - Не работает ногодрыг на порту B, а на A и C работает

Вт окт 11, 2022 12:18:32

Здравствуйте!

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

Я написал минимальный пример, в котором проверяется ногодрыг на ножках:


  • Порт A - нога A0
  • Порт C - нога C13 (встроенный светодиод),
  • Порт C - нога C14 - для сравнения с C13, мало ли
  • Порт B - нога B3
  • Порт B - нога B4


Проблема в том, что ногодрыг работает на ножках портов A и C, но не работает на ножках порта B.

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

Вот код:
Код:
int main(void)
{
    // Начальные инициализации оборудования STM32
    clockInit();

    // Включение тактирования портов GPIOA, GPIOB, GPIOC
    RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
    RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;
    RCC->APB2ENR |= RCC_APB2ENR_IOPCEN;

    // Обязательный сброс конфигурации портов в 0
    GPIOA->CRL &= ~(GPIO_CRL_MODE0 | GPIO_CRL_CNF0);

    GPIOC->CRH &= ~(GPIO_CRH_MODE13 | GPIO_CRH_CNF13);
    GPIOC->CRH &= ~(GPIO_CRH_MODE14 | GPIO_CRH_CNF14);

    GPIOB->CRL &= ~(GPIO_CRL_MODE3 | GPIO_CRL_CNF3);
    GPIOB->CRL &= ~(GPIO_CRL_MODE4 | GPIO_CRL_CNF4);

    // Настройка режимов портов
    uint32_t mode=0b11; // Режим выхода, с максимальной частотой 50 МГц
    uint32_t cnf=0b00;  // Режим push-pull

    GPIOA->CRL |= (mode << GPIO_CRL_MODE0_Pos)  | (cnf << GPIO_CRL_CNF0_Pos);

    GPIOC->CRH |= (mode << GPIO_CRH_MODE13_Pos) | (cnf << GPIO_CRH_CNF13_Pos);
    GPIOC->CRH |= (mode << GPIO_CRH_MODE14_Pos) | (cnf << GPIO_CRH_CNF14_Pos);

    GPIOB->CRL |= (mode << GPIO_CRL_MODE3_Pos) | (cnf << GPIO_CRL_CNF3_Pos);
    GPIOB->CRL |= (mode << GPIO_CRL_MODE4_Pos) | (cnf << GPIO_CRL_CNF4_Pos);


    while (true)
    {
        delayMs(500);
        GPIOA->BSRR = (1<<GPIO_BSRR_BR0_Pos);

        GPIOC->BSRR = (1<<GPIO_BSRR_BR13_Pos);
        GPIOC->BSRR = (1<<GPIO_BSRR_BR14_Pos);
       
        GPIOB->BSRR = (1<<GPIO_BSRR_BR3_Pos);
        GPIOB->BSRR = (1<<GPIO_BSRR_BR4_Pos);

        delayMs(500);
        GPIOA->BSRR = (1<<GPIO_BSRR_BS0_Pos);

        GPIOC->BSRR = (1<<GPIO_BSRR_BS13_Pos);
        GPIOC->BSRR = (1<<GPIO_BSRR_BS14_Pos);

        GPIOB->BSRR = (1<<GPIO_BSRR_BS3_Pos);
        GPIOB->BSRR = (1<<GPIO_BSRR_BS4_Pos);
    };
      
    return 0;
}


Полный код: https://pastebin.com/yTygZsP2

Что не так с портом B? Как исправить?

Re: STM32 - Не работает ногодрыг на порту B, а на A и C рабо

Вт окт 11, 2022 12:25:59

Читаем мануал RM0008, раздел GPIO, таблицу JTAG/SWD. Ваши PB3, PB4 заняты под JTAG, и его надо отключить в регистре AFIO->MAPR, биты SWJ_CFG = 010.
Да, и не забудьте включить тактирования AFIO в регистра RCC, прежде мем записывать регистры AFIO.

И по коду. Функция clockInit() излишняя, поскольку все настройки частот выполняются ранее, ещё до входа в main. Полистайте файлы проекта, найдёте функцию SystemInit(), в которой уже выполняется настройка частоты. Если нужна другая частота, прям в этой функции и пишите то, что надо

Re: STM32 - Не работает ногодрыг на порту B, а на A и C рабо

Вт окт 11, 2022 14:32:05

Читаем мануал RM0008, раздел GPIO, таблицу JTAG/SWD. Ваши PB3, PB4 заняты под JTAG, и его надо отключить в регистре AFIO->MAPR, биты SWJ_CFG = 010.
Да, и не забудьте включить тактирования AFIO в регистра RCC, прежде мем записывать регистры AFIO.

Благодарю, поразбираюсь.

И по коду. Функция clockInit() излишняя, поскольку все настройки частот выполняются ранее, ещё до входа в main. Полистайте файлы проекта, найдёте функцию SystemInit(), в которой уже выполняется настройка частоты. Если нужна другая частота, прям в этой функции и пишите то, что надо

Что-то я посмотрел CMSIS, нету там такой функции. Я, если что в PlatformIO работаю под Linux. Вы может думали что в Cube проект сделан, там возможно и есть такое. Но мне Cube не подошел, он напроч отказывается работать с китайскими STM32, которые раньше маркировались CS32, а потом стали маркироваться как и оригинал. Все эти пляски с правкой ChipID в разных местах Cube ни к чему не привели - видимо все рецепты для более старых версий, поэтому среды OpenSource наше все.

Re: STM32 - Не работает ногодрыг на порту B, а на A и C рабо

Вт окт 11, 2022 16:08:41

И по коду. Функция clockInit() излишняя, поскольку все настройки частот выполняются ранее, ещё до входа в main. Полистайте файлы проекта, найдёте функцию SystemInit(), в которой уже выполняется настройка частоты. Если нужна другая частота, прям в этой функции и пишите то, что надо

Что-то я посмотрел CMSIS, нету там такой функции.

Код:
$ grep -rnw ./CMSIS -e 'SystemInit'
./CMSIS/device/system_stm32f10x.h:79:extern void SystemInit(void);

Re: STM32 - Не работает ногодрыг на порту B, а на A и C рабо

Вт окт 11, 2022 16:34:10

Файл исходника называется system_stm32f10x.c. Про PlatformIO не знаю, может он не создает таких файлов и работает по иному шаблону. Ну а в CubeIDE этот файл функцией SystemInit() хоть и создается, но остается практически пустым, а настройка частот вынесена в другое место.
В принципе, единых правил нет, это всего лишь рекомендация.

Re: STM32 - Не работает ногодрыг на порту B, а на A и C рабо

Вт окт 11, 2022 17:34:57

Код:
$ grep -rnw ./CMSIS -e &#39;SystemInit&#39;
./CMSIS/device/system_stm32f10x.h:79:extern void SystemInit(void);

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

Только в моем случае файл называется ./CMSIS/Include/system_stm32f1xx.h

Добавлено after 12 minutes 54 seconds:
Код:
$ grep -rnw ./CMSIS -e 'SystemInit'
./CMSIS/device/system_stm32f10x.h:79:extern void SystemInit(void);

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

Только в моем случае файл называется ./CMSIS/Include/system_stm32f1xx.h


Но я не увидел там настройку на 72MHz и делителей для Flash. Вроде как есть инициализация кварца, но не боле того - просто выставили регистры настроек и все, ни тебе ожидания инициализации, ни ожидания переключения в режим. Странно.

Re: STM32 - Не работает ногодрыг на порту B, а на A и C рабо

Вт окт 11, 2022 18:11:07

Все эти вещи нужно самому делать: CMSIS без понятия, что у тебя за МК, нужны еще заголовочники ST'шные + свои стартап и т.п.
Я вот так сделал: вызываю функцию StartHSE(), если мне нужен HSE, а при включении можно sysreset() вызвать (но обычно это не требуется).

Re: STM32 - Не работает ногодрыг на порту B, а на A и C рабо

Вт окт 11, 2022 19:39:54

Добавлено after 9 minutes 37 seconds:
[uquote="MLX90640",url="/forum/viewtopic.php?p=4302979#p4302979"]Читаем мануал RM0008, раздел GPIO, таблицу JTAG/SWD. Ваши PB3, PB4 заняты под JTAG, и его надо отключить в регистре AFIO->MAPR, биты SWJ_CFG = 010.
Да, и не забудьте включить тактирования AFIO в регистра RCC, прежде мем записывать регистры AFIO.


В общем, я так решил настроить:

Код:
   
    // Включение тактирования портов GPIOA, GPIOB, GPIOC
    RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
    RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;
    RCC->APB2ENR |= RCC_APB2ENR_IOPCEN;

    // Конфигурирование AFIO, чтобы работали ножки PB3, PB4, PA15
    AFIO->MAPR |= AFIO_MAPR_SWJ_CFG_JTAGDISABLE; // Отключение JTAG
    RCC->APB2ENR |= RCC_APB2ENR_AFIOEN; // Разрешение тактирования AFIO для PA15


Но ножки PB3, PB4, PA15 не освобождаются, ногодрыг на них не работает.
Последний раз редактировалось xintrea Вт окт 11, 2022 19:42:16, всего редактировалось 2 раз(а).

Re: STM32 - Не работает ногодрыг на порту B, а на A и C рабо

Вт окт 11, 2022 19:40:31

В общем, всё верно, только наоборот. Строчки местами поменять. В RCC разрешается тактирование, то есть доступ к регистрам AFIO в целом, чтобы их модно было перезаписать. Я ж там и написал - тактирование включить ПЕРЕД, а не после.

Re: STM32 - Не работает ногодрыг на порту B, а на A и C рабо

Вт окт 11, 2022 19:44:21

В общем, всё верно, только наоборот. Строчки местами поменять. В RCC разрешается тактирование, то есть доступ к регистрам AFIO в целом, чтобы их модно было перезаписать. Я ж там и написал - тактирование включить ПЕРЕД, а не после.


Благодарю, вот так заработало (я не понял что такое "мем", думал какая-то память, а это было "чем"):

Код:
    // Включение тактирования портов GPIOA, GPIOB, GPIOC
    RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
    RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;
    RCC->APB2ENR |= RCC_APB2ENR_IOPCEN;

    // Конфигурирование AFIO, чтобы работали ножки PB3, PB4, PA15
    RCC->APB2ENR |= RCC_APB2ENR_AFIOEN; // Разрешение тактирования AFIO для PA15
    AFIO->MAPR |= AFIO_MAPR_SWJ_CFG_JTAGDISABLE; // Отключение JTAG

Re: STM32 - Не работает ногодрыг на порту B, а на A и C рабо

Вт окт 11, 2022 19:56:39

Со смартфона писал, кнопочки мелкие, пальцы толстые.
Ответить