Код инициализации портов ввода / вывода

Для того, что бы порты стали управляемы, нужно понять следующее. По умолчанию, когда включается питание или по сигналу сброса контроллера, тактирование всей системной периферии отключено. Порты ввода / вывода находятся на системной шине APB2. И для того, что бы они могли принимать команды от процессорного ядра, их нужно затактировать. Делается это просто, установите в регистре RCC_APB2ENR флажок напротив нужного вам порта.

    ; Для включения флажка используем метод BitBand
    MOV32 R0, (RCC_APB2ENR & 0x00FFFFFF) * 0x20 \
            + 0x42000000 \
            + 2 * 4
            ;^^^ здесь цифра 2 - тот самый бит, который нужно установить в 1
    MOV R1, 1
    STR R1, [R0]

И это касается не только портов, но и всей периферии, находящейся на шинах APB1/APB2. Для большей наглядности, посмотрите вкладку APB Bridges в режиме отладчика Keil.


Что бы изменить настройки только избранных ножек порта, можно использовать метод чтение-модификация-запись. Создайте 4-битную маску режима порта и скопируйте её в необходимый пин. Используйте таблицу истинности Port bit configuration table из datasheet на камень, что бы понять, какие биты и зачем нужны. На следующем примере, три младших ножки порта A будут переведены в состояние выхода.

    ; Адрес порта
    MOV32 R0, GPIOA_CRL
    ; 4-битная маска настроек для Output mode 50mHz, Push-Pull
    MOV R1, GPIO_CRL_MODE0_0 + GPIO_CRL_MODE0_1
    ; Считали порт
    LDR R3, [R0]
    ; Что бы растолкать маску по отдельным ножкам порта
    ; Используем команду копирования битового поля
    ; Скопировали биты маски в позицию PIN0
    BFI R3, R1, 0, 4
    ; Скопировали биты маски в позицию PIN1
    BFI R3, R1, 4, 4
    ; Скопировали биты маски в позицию PIN2
    BFI R3, R1, 8, 4
    ; Сохранили в порт
    STR R3, [R0]


Что бы настроить порт целиком, создайте 32-битную маску режимов и запишите её в порт. С точки зрения экономии времени, эта операция более предпочтительная. Например, установим пины 0..3 и 6 на Output mode 50mHz, Push-Pull, а пины 4, 5 и 7 на вход с подтяжкой резистором к плюсу.

    ; Адрес младшей половины порта
    MOV32 R0, GPIOA_CRL
    ; Соберём 32-биную конфигурацию для младшей половины порта
    MOV32 R1, GPIO_CRL_MODE0_0 + GPIO_CRL_MODE0_1 \
             + GPIO_CRL_MODE1_0 + GPIO_CRL_MODE1_1 \
             + GPIO_CRL_MODE2_0 + GPIO_CRL_MODE2_1 \
             + GPIO_CRL_MODE3_0 + GPIO_CRL_MODE3_1 \
             + GPIO_CRL_MODE6_0 + GPIO_CRL_MODE6_1 \
             + GPIO_CRL_CNF4_1 \
             + GPIO_CRL_CNF5_1 \
             + GPIO_CRL_CNF7_1
    ; Сохраним в порт
    STR R1, [R0]

    ; Включим pull-up резисторы для пинов 4, 5 и 7
    MOV R1, GPIO_ODR_ODR4 \
            + GPIO_ODR_ODR5 \
            + GPIO_ODR_ODR7
    ; Сохраним в порт
    MOV32 R0, GPIOA_ODR
    STR R1, [R0]


Для вывода информации в порт, можно использовать разные методы. Например, через биты принудительного включения в регистре GPIOA_BSRR, установим в 1 настроенные ранее выводы 0..3 и 6. Так сказать, дрыгнем ножками.

    ; Адрес порта выходных сигналов
    MOV32 R0, GPIOA_BSRR
    ; Эти ножки установить в 1
    MOV R1, PIN0 + PIN1 + PIN2 + PIN3 + PIN6
    ; Сохранили в порт
    STR R1, [R0]

Только не забывайте, что если в регистр выходных данных записать 0x0000, любым методом, то в ранее настроенных ножках 4, 5 и 7 отключатся подтягивающие pull-up резисторы. Вернее, они переключатся на pull-down и подтянут ножки к земле.


Что ещё можно сделать

Что бы избежать случайного изменения настроек порта, залОчим отдельные ножки специальной процедурой. После чего, вы не сможете изменить настройки этих ножек до сигнала сброса порта. Порт можно сбросить установкой соотв. бита в регистре RCC_APB2ENR. Или кнопкой RESET, если таковая имеется! Или просто, отключив питание микроконтроллеру.

    ; Процедура залочки отдельных ножек порта
    MOV32 R0, GPIOA_LCKR        
    ; Эти ножки залочить
    MOV R1, PIN4 + PIN5 + PIN7
    ; Последовательно установить в 1-0-1 флаг GPIO_LCKR_LCKK
    MOVT R1, 1
    STR R1, [R0]
    MOVT R1, 0
    STR R1, [R0]
    MOVT R1, 1
    STR R1, [R0]
    ; Всё, ножки защищены от изменения


Периодически заглядывайте в файлы stm32f10x.asm и stm32f4xx.asm. Там содержится много полезной информации относительно регистров и отдельных флагов-битов, с которыми вы будете плотно работать, настраивая периферию.