Страницы

Страницы

среда, 8 февраля 2012 г.

STM32F4 Discovery GPIO for C

// main.c

#include <stm32f4xx.h>

// Простая программная задержка
static void delay_cycles(uint32_t cycles)
{
    // Пока не вычтем до нуля, цикл не закончится
        while(cycles--);
}

// Здесь нельзя инициализировать глобальные переменные, не помеченные специально
// как не нуждающиеся в инициализации. Память инициализируется после вызова
// SystemInit и все значения будут затёрты.
//void SystemInit(void)
//{
//   // Пока тут ещё ничего нет.
//}

// Отсюда начинается выполнение пользовательского кода.
int main(void)
{
    // Светодиоды сидят на порту D и выводах 12 - 15.

    // Первым делом надо включить тактирование порту D.
    // За это отвечает 3 бит (GPIODEN) в регистре RCC_AHB1ENR (Reference manual, p.110)
    RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN;

    // Дальше надо настроить выводы как выходы типа Push-pull, с максимальной частотой,
    // например, 50 МГц (от частоты зависит энергопотребление ножки).
 
    // Первый регистр, GPIOx_MODER: режим работы выхода, (RM, p. 148)
    // 2 бита на каждую ножку
    // 0: Вход, 1: выход, 2: альтернативная функция, 3: аналоговый
    GPIOD->MODER |= (1UL << 12 * 2) | (1UL << 13 * 2) | (1UL << 14 * 2) | (1UL << 15 * 2);
 
    // Второй регистр, GPIOx_OTYPER: тип выхода. Двухтактный (0) али открытый коллектор (1)
    // Один бит на каждую ножку. По умолчанию всё так, как и надо.
 
    // Третий регистр, GPIOx_OSPEEDR: максимальная скорость порта.
    // По умолчанию 2 МГц, так что ок.
 
    // Четвёртый регистр, GPIOx_PUPDR: куда он будет по умолчанию подтягивать, если выбран двухтактный режим.
    // 0: никуда, 1: питание, 2: земля, 3: резервировано. Два бита на вывод.
    // Допустим, к питанию.
    GPIOD->PUPDR |= (1UL << 12 * 2) | (1UL << 13 * 2) | (1UL << 14 * 2) | (1UL << 15 * 2);
 
    // Регистр вывода: GPIOx_ODR. Что запишешь, то на ножках и будет.
    // Есть регистр для установки битов и для их сброса (GPIOx_BSRR).
    // Младшие 2 байта отвечают за установку, старшие - за сброс.
 
    // Жги!
    GPIOD->BSRRL = (1UL << 12) | (1UL << 13) | (1UL << 14) | (1UL << 15);
    delay_cycles(1000000UL);
 
    // Утухни
    GPIOD->BSRRH = (1UL << 12) | (1UL << 13) | (1UL << 14) | (1UL << 15);
    delay_cycles(1000000UL);
 
    while(1)
    {
        // Зажжём 12й
        GPIOD->BSRRL = (1UL << 12);
     
                delay_cycles(1000000UL);
        // Погасим 12й
        GPIOD->BSRRH = (1UL << 12);
        // Зажжём 13й
        GPIOD->BSRRL = (1UL << 13);
     
                delay_cycles(1000000UL);
     
        // Погасим 13й
        GPIOD->BSRRH = (1UL << 13);
        // Зажжём 14й
        GPIOD->BSRRL = (1UL << 14);
     
                delay_cycles(1000000UL);
     
        // Погасим 14й
        GPIOD->BSRRH = (1UL << 14);
        // Зажжём 15й
        GPIOD->BSRRL = (1UL << 15);
     
                delay_cycles(1000000UL);
     
        // Погасим 15й
        GPIOD->BSRRH = (1UL << 15);
    }
}

Комментариев нет:

Отправить комментарий