STM32 STM32VL Discovery STM32F100RBT6 (урок 2) GPIO, порты ввода-вывода

0

Восстановленные материалы удаленного сайта www.doneathome.ru

По многочисленным просьбам пользователей попробую восстановить


Микроконтроллеры семейства STM32 содержат в своём составе до семи 16-разрядных портов ввода-вывода c именами от PORTA до PORTG. В конкретной модели микроконтроллера без исключений доступны все выводы портов, общее количество которых зависит от типа корпуса и оговорено в DataSheet на соответствующее подсемейство. Для нашего микроконтроллера (STM32F100RBT6) доступна 51 ножка.

Режимы работы ножек портов GPIO

Input floating [GPIO_Mode_IN_FLOATING]
Высоко импедансное состояние или Z-состояние — такое состояние контакта логической схемы, при котором сопротивление между этим контактом и остальной схемой очень велико. Физически реализуется закрытым транзистором, работающим в ключевом режиме.
Вывод, переведённый в Z-состояние, ведёт себя как не подключенный к схеме. Внешние устройства, подключенные к этому выводу, могут изменять напряжение на нём по своему усмотрению (в некоторых рамках), не влияя на работу схемы. И наоборот — схема не мешает внешним устройствам менять напряжение на контакте.

Input pull-up [GPIO_Mode_IPU]
Это вход с подтяжкой к питанию, т.е. между входом и питанием включен подтягивающий резистор. Подтягивающий резистор позволяет выходу находиться в высоком(подтянут к питанию) состоянии и не запрещает подключение этой ножки к земле (так как в цепи будет включено сопротивление).

Input-pull-down [GPIO_Mode_IPD]
Тот же самый режим что и был выше только с одним отличием: теперь подтяжкой к земле, а не к питанию.

Analog [GPIO_Mode_AIN]
Вывод может быть сконфигурирован как аналоговый вход или выход. Это касается отдельных периферийных блоков(АЦП, ЦАП), так что пока просто запомним, что такой режим есть.

Output open-drain [GPIO_Mode_Out_OD]
Выход с открытым коллектором (также называют выход с открытым стоком) [все зависит от типа транзистора].

Output push-pull [GPIO_Mode_Out_PP]
Двухтактный выход. Можно сказать что это некий базовый режим работы ножки. Так как в этом режиме мы подключаем ножку либо к потенциалу питания либо земли.

Alternate function push-pull [GPIO_Mode_AF_PP]
Тот же режим что и выше, только для альтернативной функции.

Alternate function open-drain [GPIO_Mode_AF_OD]
И также есть режим: выход с открытым коллектором для альтернативной функции. так же пока не трогаем.

Устройство ножки порта GPIO

Режимы работы ножки порта GPIO

Регистры портов GPIO

Описание: Это регистр настройки режима работы ножки порта (один из 8-ми). Заметим что на каждую ножку требуется 8бит. Из этого следует, что одного 32-ух разрядного регистра недостаточно для определения 16-ти ножек. Поэтому таких регистров два (для старшей и младшей части порта по регистру [GPIOx_CRL и GPIOx_CRH])
Биты:
MODEx[1:0] – Биты MODEx определяют направление вывода и ограничение скорости переключения в режиме выхода:
MODEx[1:0] = 00: Режим входа (состояние после сброса);
MODEx[1:0] = 01: Режим выхода, максимальная скорость – 10МГц;
MODEx[1:0] = 10: Режим выхода, максимальная скорость – 2МГц;
MODEx[1:0] = 11: Режим выхода, максимальная скорость – 50МГц;

CNFx[1:0] – Биты CNF задают конфигурацию соответствующих выводов:
В режиме входа (MODE[1:0]=00):
CNFx[1:0] = 00: Аналоговый вход;
CNFx[1:0] = 01: Вход в третьем состоянии (состояние после сброса);
CNFx[1:0] = 10: Вход с притягивающим резистором pull-up (если PxODR=1) или pull-down (если PxODR=0);
CNFx[1:0] = 11: Зарезервировано;
В режиме выхода (MODE[1:0] > 00):
CNFx[1:0] = 00: Двухтактный выход общего назначения;

CNFx[1:0] = 01: Выход с открытым стоком общего назначения;
CNFx[1:0] = 10: Двухтактный выход с альтернативной функцией;
CNFx[1:0] = 11: Выход с открытым стоком с альтернативной функцией;

GPIOx_CRH [0x4444 4444]

Описание: Это регистр настройки режима работы ножки порта (один из 8-ми). Заметим что на каждую ножку требуется 8бит. Из этого следует, что одного 32-ух разрядного регистра недостаточно для определения 16-ти ножек. Поэтому таких регистров два (для старшей и младшей части порта по регистру [GPIOx_CRL и GPIOx_CRH])
Биты:
MODEx[1:0] – Биты MODEx определяют направление вывода и ограничение скорости переключения в режиме выхода:
MODEx[1:0] = 00: Режим входа (состояние после сброса);
MODEx[1:0] = 01: Режим выхода, максимальная скорость – 10МГц;
MODEx[1:0] = 10: Режим выхода, максимальная скорость – 2МГц;
MODEx[1:0] = 11: Режим выхода, максимальная скорость – 50МГц;

CNFx[1:0] – Биты CNF задают конфигурацию соответствующих выводов:
В режиме входа (MODE[1:0]=00):
CNFx[1:0] = 00: Аналоговый вход;
CNFx[1:0] = 01: Вход в третьем состоянии (состояние после сброса);
CNFx[1:0] = 10: Вход с притягивающим резистором pull-up (если PxODR=1) или pull-down (если PxODR=0);
CNFx[1:0] = 11: Зарезервировано;
В режиме выхода (MODE[1:0] > 00):
CNFx[1:0] = 00: Двухтактный выход общего назначения;

CNFx[1:0] = 01: Выход с открытым стоком общего назначения;
CNFx[1:0] = 10: Двухтактный выход с альтернативной функцией;
CNFx[1:0] = 11: Выход с открытым стоком с альтернативной функцией;

GPIOx_IDR [0x0000 XXXX]

Описание:  Это регистр входа, регистр входа имеет толь 16 младших действующих бит из 32-ух. Чтение GPIOx_IDR возвращает значение состояния всех линий (напряжение на ножках) порта. Биты регистра доступны только для чтения.
Биты:
[“0” – Ноль в регистре (бите) == Лог “0” на ножке]
[“1” – Единица в регистре (бите) == Лог “1” на ножке]

GPIOx_ODR [0x0000 0000]

Описание:  Это регистр выхода, регистр входа имеет толь 16 младших действующих бит из 32-ух. Запись сюда значений поменяет состояние ножки в соответствии с его конфигурацией. (Напоминаю что при настройке ножки как вход с подтяжкой то бит в этом регистре определяет к чему будет подтянута ножка).
Чтение GPIOx_ODR возвращает значение НЕ состояния всех лог уровней на ножках, а значение ранее записанное в этот регистр. Биты регистра доступны как для чтения, так и для записи.
Значение битов этих регистров может быть изменено через регистры: GPIOx_BSRR и GPIOx_BRR

Биты:
Режим Output push-pull [GPIO_Mode_Out_PP] 
[“0” – Ноль в регистре (бите) == Лог “0” на ножке]
[“1” – Единица в регистре (бите) == Лог “1” на ножке]

Режим Output open-drain [GPIO_Mode_Out_OD]
[“0” – Ноль в регистре (бите) == Транзистор закрыт (3-сост на ножке)]
[“1″ – Единица в регистре (бите) == Транзистор открыт (Лог”0” на ножке)]

GPIOx_BSRR [0x0000 0000]

Описание:  Это очень хитрый регистр)) видим тут только два типа битов BSx и BRx. Эти биты необходимы для управления регистром GPIOx_ODR. Cуть в том, что записав в бит BS0 единицу, мы установим единицу в бите ODR0 в регистре GPIOx_ODR. Также дела обстоят при использовании битов сброса BRx, только единица в этом бите сбрасывает соответствующий бит в регистре GPIOx_ODR в ноль.
Значения этих битов управляют регистром: GPIOx_ODR

Биты:
BSx
[“0” – Ноль в регистре (бите) == не приведет ни к какому эффекту]
[“1” – Единица в регистре (бите) == Лог “1” в соответствующем бите регистра GPIOx_ODR ]

BRx
[“0” – Ноль в регистре (бите) == не приведет ни к какому эффекту]
[“1” – Единица в регистре (бите) == Лог “0” в соответствующем бите регистра GPIOx_ODR ]

GPIOx_BRR [0x0000 0000]

Описание:  Это очень хитрый регистр)) видим тут только один тип битов BRx. Эти биты необходимы для управления регистром GPIOx_ODR. Cуть в том, что записав в бит BRx единицу,будет произведен сброс соответствующего бита в регистре GPIOx_ODR в ноль. То есть это половинка регистра GPIOx_BSRR.
Значения этих битов управляют регистром: GPIOx_ODR

Биты:
BRx
[“0” – Ноль в регистре (бите) == не приведет ни к какому эффекту]
[“1” – Единица в регистре (бите) == Лог “0” в соответствующем бите регистра GPIOx_ODR ]

GPIOx_LCKR [0x0000 0000]

Описание:  Это очередной очень хитрый регистр)) Про него отдельно надо разговаривать… В паре слов этот регистр позволяет запретить изменение значений в регистре GPIOx_ODR
Значения этих битов управляют регистром (БЛОК): GPIOx_ODR

Программирование портов GPIO
Сейчас на примерах можно немного освоится с принципами программирования GPIO. Так же как и при программировании чего угодно другого необходимо добиваться стиля при котором можно легко читать код. Это достигается обилием комментариев и прозрачностью действий (не надо лепить кучу всего в одну строчку). Присвоение голых чисел должно быть минимальным (пользуйтесь текстовыми заменами, что бы каждое число имело имя).

1) Вариант № 1 (библиотека  stm32f10x.h)

#include "stm32f10x.h"
 
void Delay (unsigned int t) // функция задержки
{
	unsigned int i;
    for (i = 0;i<t; i++);
}
 
int main(void) {
    RCC->APB2ENR |= RCC_APB2ENR_IOPCEN; //Затактировали порт (регистор = RCC_APB2RSTR + бит разрешения тактирования порта IOPCRST)
 
    // НОЖКА 8
    GPIOC->CRH &= ~GPIO_CRH_CNF8_0 & ~GPIO_CRH_CNF8_1;//определили режим работы CNF[1:0] = {0,0} = General purpose output push-pull
    GPIOC->CRH |= GPIO_CRH_MODE8_0 | GPIO_CRH_MODE8_1; //определили направление + частоту в 50MHz
 
    // НОЖКА 9
    GPIOC->CRH &= ~GPIO_CRH_CNF9_0 & ~GPIO_CRH_CNF9_1;//определили режим работы CNF[1:0] = {0,0} = General purpose output push-pull
    GPIOC->CRH |= GPIO_CRH_MODE9_0 | GPIO_CRH_MODE9_1; //определили направление + частоту в 50MHz
 
    while (1) {
    	// ножку 8 - лог "0"  ножку 9 - лог "1"
    	GPIOC->ODR &= ~GPIO_ODR_ODR8;
    	GPIOC->ODR |= GPIO_ODR_ODR9;
 
        Delay(0xFFFFF); //задержечка (а на сколько?)
 
    	// ножку 8 - лог "1"  ножку 9 - лог "0"
        GPIOC->ODR |= GPIO_ODR_ODR8;
        GPIOC->ODR &= ~GPIO_ODR_ODR9;
 
        Delay(0xFFFFF); //задержечка (а на сколько?)
    }
    return 0;
}

2) Вариант № 2 (библиотека  stm32f10x.h + BSRR и BRR)

#include "stm32f10x.h"
 
void Delay (unsigned int t) // функция задержки
{
	unsigned int i;
    for (i = 0;i<t; i++);
}
 
int main(void) {
    RCC->APB2ENR |= RCC_APB2ENR_IOPCEN; //Затактировали порт (регистор = RCC_APB2RSTR + бит разрешения тактирования порта IOPCRST)
 
    // НОЖКА 8
    GPIOC->CRH &= ~GPIO_CRH_CNF8_0 & ~GPIO_CRH_CNF8_1;//определили режим работы CNF[1:0] = {0,0} = General purpose output push-pull
    GPIOC->CRH |= GPIO_CRH_MODE8_0 | GPIO_CRH_MODE8_1; //определили направление + частоту в 50MHz
 
    // НОЖКА 9
    GPIOC->CRH &= ~GPIO_CRH_CNF9_0 & ~GPIO_CRH_CNF9_1;//определили режим работы CNF[1:0] = {0,0} = General purpose output push-pull
    GPIOC->CRH |= GPIO_CRH_MODE9_0 | GPIO_CRH_MODE9_1; //определили направление + частоту в 50MHz
 
    while (1) {
    	// ножку 8 - лог "0"  ножку 9 - лог "1"
        GPIOC->BRR = GPIO_ODR_ODR8;
        GPIOC->BSRR = GPIO_ODR_ODR9;
 
        Delay(0xFFFFF); //задержечка (а на сколько?)
 
    	// ножку 8 - лог "1"  ножку 9 - лог "0"
        GPIOC->BSRR = GPIO_ODR_ODR8;
        GPIOC->BRR = GPIO_ODR_ODR9;
 
        Delay(0xFFFFF); //задержечка (а на сколько?)
    }
    return 0;
}

3) Вариант № 3 (библиотека  stm32f10x.h + stm32f10x_gpio.h и stm32f10x_rcc.h)

#include "stm32f10x.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
 
void Delay (unsigned int t) // функция задержки
{
	unsigned int i;
    for (i = 0;i<t; i++);
}
 
int main(void) {
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC , ENABLE); // это функция разрешения тактирования порта С
 
    GPIO_InitTypeDef Pinyshka; // создаём переменную (структуру) для ножки
 
    // заполняем поля структуры для определения режима ножки
    Pinyshka.GPIO_Pin = GPIO_Pin_9;  // определяем ножку порта
    Pinyshka.GPIO_Mode = GPIO_Mode_Out_PP; // определяем режим работы ножки
    Pinyshka.GPIO_Speed = GPIO_Speed_50MHz; // так как режим на выход то определяем скорость работы ножки
 
    // этой функцией мы определяем работу ножки (ссылка на заполненную структуру ножки) + (указываем порт необходимой нам ножки)
    GPIO_Init( GPIOC , &Pinyshka);
 
    // чтобы занова не заполнять структуру (меняем только поле определяющее ножку на порте)
    Pinyshka.GPIO_Pin = GPIO_Pin_8;
 
    // этой функцией мы определяем работу ножки (ссылка на заполненную структуру ножки) + (указываем порт необходимой нам ножки)
    GPIO_Init( GPIOC , &Pinyshka);
 
 
    while (1) {
    	// ножку 8 - лог "0"  ножку 9 - лог "1"
        GPIO_WriteBit(GPIOC, GPIO_Pin_8, Bit_RESET);
        GPIO_WriteBit(GPIOC, GPIO_Pin_9, Bit_SET);
 
        Delay(0xFFFFF); //задержечка (а на сколько?)
 
    	// ножку 8 - лог "1"  ножку 9 - лог "0"
        GPIO_WriteBit(GPIOC, GPIO_Pin_8, Bit_SET);
        GPIO_WriteBit(GPIOC, GPIO_Pin_9, Bit_RESET);
 
 
        Delay(0xFFFFF); //задержечка (а на сколько?)
    }
    return 0;
}

4) Пример № 4 (Используем кнопку)

#include "stm32f10x.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
 
void Delay (unsigned int t) // функция задержки
{
	unsigned int i;
    for (i = 0;i<t; i++);
}
 
int main(void) {
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE); // это функция разрешения тактирования порта A
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC , ENABLE); // это функция разрешения тактирования порта С
 
    GPIO_InitTypeDef Pinyshka; // создаём переменную (структуру) для ножки
 
    // заполняем поля структуры для определения режима ножки(ЗАМЕТИМ определение 2-ух ножек)
    Pinyshka.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_8;  // определяем ножки!!! порта
    Pinyshka.GPIO_Mode = GPIO_Mode_Out_PP; // определяем режим работы ножки
    Pinyshka.GPIO_Speed = GPIO_Speed_50MHz; // так как режим на выход то определяем скорость работы ножки
 
    // этой функцией мы определяем работу ножек (ссылка на заполненную структуру ножки) + (указываем порт необходимых нам ножек)
    GPIO_Init( GPIOC , &Pinyshka);
 
    // заполняем поля структуры для определения режима ножки
    Pinyshka.GPIO_Pin = GPIO_Pin_0;  // определяем ножку порта
    Pinyshka.GPIO_Mode = GPIO_Mode_IN_FLOATING; // определяем режим работы ножки
 
    // этой функцией мы определяем работу ножки (ссылка на заполненную структуру ножки) + (указываем порт необходимой нам ножки)
    GPIO_Init( GPIOA , &Pinyshka);
 
    while (1) {
 
    	if ( GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0) ) //условие что кнопка нажата
    	{
    		GPIO_WriteBit(GPIOC, GPIO_Pin_8, Bit_SET);
    		GPIO_WriteBit(GPIOC, GPIO_Pin_9, Bit_SET);
    	}
    	else {
    		GPIO_WriteBit(GPIOC, GPIO_Pin_8, Bit_RESET);
    		GPIO_WriteBit(GPIOC, GPIO_Pin_9, Bit_RESET);
		}
    }
    return 0;
}
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest
0 комментариев
Межтекстовые Отзывы
Посмотреть все комментарии
0
Оставьте комментарий! Напишите, что думаете по поводу статьи.x