Download as pptx, pdf, or txt
Download as pptx, pdf, or txt
You are on page 1of 22

Digital Input and Output

1
Module Syllabus
 Digital Input and Output

 Voltages and Logic Values

 GPIO Controller

 Using Pointer to Access GPIO

 Define Data Structure for Peripherals

 Digital IO Examples

 Using LED

 Using 7-Segment Display

 Using Infrared Emitter/ Detector

2
Basic Programming – Digital IO

3
Voltages and Logic Values
 In digital devices, logic values (‘1’ or ‘0’) are represented as electrical voltages

 Different devices may use different voltages to represent a logic value

 For example, the external pins of Nucleo F401RE platform use 3.3 volts for logic ‘1’, and 0 volts for logic ‘0’

 Digital logic can however have different meanings in different contexts depending on the interpretation
we give to different voltage levels

Logic Voltage Boolean Circuit Switch


‘1’ 3.3V True Closed On
‘0’ 0V False Open Off

4
GPIO Design
 Normally, the external pins are not directly accessible, but accessed via a peripheral
called General-purpose input/output (GPIO)
 Used for general purpose, no special usage defined
 Widely used for most applications
 The direction of input/ output is controlled by the direction register
 A mask register is often used to mask out certain bits

Memory Mapped I/O


Alternate Function 1
Alternate Function 2 Pin

Alternate Function n

Function Select
5
GPIO Design
 GPIO pins split into groups, called ports
 Each port has 32 pins [31:0]
 Each of the ports are connected to the microcontroller via the peripheral bridge

 To reduce power consumption clocks are turned off for particular areas
 Default setting – clock is disabled
 To use a peripheral or a resource clock has to be enabled for each item individually

 Each pin is connected to a multiplexer


 Allows each pin to perform several functions
 Optimizes functionality small packages
 Signal multiplexer and other pin options can be configured in the Pin Control Register (PCR)

6
GPIO Registers
 For example, in the Nucleo F401RE MCU, there are eight GPIO peripherals named from PORTA-PORTH, and each
of them has 10 registers, which include:
 Port Mode Register (MODER) - configure the I/O direction mode (input/output/alternate/analog)

 Output Type Register (TYPER) – configure the output type of the I/O port (push-pull/open-drain)

 Output Speed Register (OSPEEDR) – configure the I/O output speed (2/25/50/100 MHz)

 Pull-Up/Pull-Down Register (PUPDR) – configure the I/O pull-up or pull-down (no pull-up, pull-down/pull-up/pull-down)

 Input Data Register (IDR) – contain the input value of the corresponding I/O port

 Output Data Register (ODR) – can be read and written by software (ODR bits can be individually set and reset by writing to the BSRR)

 Bit Set/Reset Register (BSRR) – can be used for atomic bit set/reset

 Configuration Lock Register (LCKR) – used to lock the configuration of the port bits when a correct write sequence is applied to bit 16

 Alternate Function Low Register (AFRL) – configure alternate function I/Os

 Alternate Function High Register (AFRH) – configure alternate function I/Os

7
Using Pointer to Access GPIO
 Normally, you can use a pointer to directly access a GPIO peripheral in either C or assembly. For example in C, to light an LED
on PB_10:

#define RCC_AHB1ENR (*((volatile unsigned long *) 0x40023830))


#define GPIOB_MODER (*((volatile unsigned long *) 0x40020400))
#define GPIOB_PUPDR (*((volatile unsigned long *) 0x40020408))
#define GPIOB_OSPEEDR (*((volatile unsigned long *) 0x4002040C))
#define GPIOB_ODR (*((volatile unsigned long *) 0x40020414))

RCC_AHB1ENR |= 0x02;
GPIOB_MODER |= 0x00100000;
GPIOB_PUPDR |= 0x00200000;
GPIOB_OSPEEDR |= 0x00200000;
GPIOB_ODR |= 0x0400;

 This solution is fine for simple applications. However, if multiple instantiations of the same type of peripheral are available at
the same time, we will need to define registers for each peripheral, which makes code maintenance difficult

 On the other hand, since each register is defined as a separate pointer, each register access requires a 32-bit address constant. As
a result, the program image will consume a larger memory space.

8
Define Data Structure for Peripherals
 To further simplify the code and reduce its length, we can:
 Define the peripheral register set as a data structure,

 Define the peripheral as a memory pointer to this data structure:

 For example:

typedef struct {
volatile unsigned int MODER;
volatile unsigned int OTYPER;
volatile unsigned int OSPEEDR;
volatile unsigned int PUPDR;
volatile unsigned int IDR;
volatile unsigned int ODR;
volatile unsigned int BSRRL;
volatile unsigned int BSRRH;
volatile unsigned int LCKR;
volatile unsigned int AFR[2];
} GPIO_TypeDef;

9
Why use typedef rather than conventional struct keyword?
 typedef allows us to create a synonym GPIO_TypeDef for keyword struct and actual
keyword struct need not be used. We can instantiate above 4 ports as structure as
follows:
GPIO_TypeDef GPIOA, GPIOB, GPIOC, GPIOD; // and so on up to GPIOH
However, we can not assign physical address of a particular register to its name. So we try
alternative method of description or defining.

#define GPIOB_BASE 0x40020400 // give physical address 0x40020400 a


name GPIOB_BASE for easy recognition

#define GPIOB ((GPIO_TypeDef *) GPIOB_BASE ) // Instantiate a


structure of type GPIO_TypeDef whose first element begins at address GPIOB_BASE
which is the true address of Port B MODER. Now names and addresses are well tied up.

10
Define Data Structure for Peripherals
 Then, to turn on an LED on PB_10:
#define GPIOB_BASE 0x40020400

#define GPIOB ((GPIO_TypeDef *) GPIOB_BASE )

RCC -> AHB1ENR |= 0x02;

GPIOB -> MODER |= 0x00100000;


GPIOB -> PUPDR |= 0x00200000;
GPIOB -> OSPEED |= 0x00200000;
GPIOB -> ODR |= 0x0400;

 GPIOB -> MODER means GPIOB is a pointer to a data type GPIO_TypeDef (which
is nothing but a structure) and MODER is its member. The operator “->” is called
indirect membership operator which connect s pointer name and member name.
(actually there are 3 ways to address MODER and we use one of them here)

11
Define Data Structure for Peripherals
 With such arrangement:
 The same register data structure for the peripheral can be shared between multiple instantiations
 Hence code maintenance is easier
 The requirement for immediate data storage is reduced
 Compiled code is smaller, giving better code density
 With further modification, the functions developed for one peripheral can be shared between multiple
instantiations by passing the base pointer to the function, for example:

#define GPIOA ((GPIO_TypeDef *) GPIOA_BASE )


#define GPIOB ((GPIO_TypeDef *) GPIOB_BASE )
#define GPIOC ((GPIO_TypeDef *) GPIOC_BASE )

void GPIO_init (GPIO_TypeDef *GPIO_pointer) {


GPIOB -> MODER |= 0x00100000;
GPIOA -> MODER |= 0x00010000;
}

12
//Now we will use these concepts to read from a simple switch(PC13) and write to a LED
(PA05) program
// First define Clock Initialization sequence and then init LED port pin as output and
switch port pin as input.
SystemCoreClockSetHSI();
SystemCoreClockUpdate(); // Get Core Clock Frequency
if (SysTick_Config(SystemCoreClock / 1000))
{ // SysTick 1 msec interrupts
while (1); // Capture error
}
LED_Init(); // set LEDs in output mode
BTN_Init(); // set switch in input mode
13
// declare mask
const unsigned long led_mask = (1UL << 5); // Pin 5 defined as a label for LED (Port A)
const unsigned long switch_mask = (1UL << 13); // Pin 13 defined as a label for SWITCH (Port C)

void LED_Init (void)


{
// Enable clock for GPIOA to GPIOE and GPIOH ports.
RCC->AHBENR |= 0x0000009F;// output clock enabled for all 6 ports A,B,C,D,E,H

// Configure LED (PA.05) pin as push-pull outputs


GPIOA->MODER &= ~(3UL << 2 * 5) );// set 2 bits 10,11 in MODER to 00.
GPIOA->MODER |= (1UL << 2 * 5);// set bit-10 to 1 and bit-11 stays 0. This is output mode.
GPIOA->OTYPER &= ~(1UL << 5); // set bit 5 to 0 in Output Type register to disable PU and PD.

}14
// Function that initializes Button pin as input PortC13

void BTN_Init(void) {

// Enable GPIOC clock because through Port C we will be reading switch on pin 13.

GPIOC->MODER &= ~((3UL << 2*13) );// set bit 26 and 27 to 00. PC.13 is input
GPIOC->OSPEEDR &= ~((3UL << 2*13) ); // set bit 26 and 27 to 00. PC.13 is Low Speed

GPIOC->PUPDR &= ~((3UL << 2*13) ); // // set bit 26 and 27 to 00. PC.13 is no Pull up

15
// LED_On: Turns on requested LED
// Parameters: led_mask - LED number // Return: (none)
void LED_On (uint32_t led_mask)
{
GPIOC->BSRR |= (led_mask); // set bit 5 depicted by led_mask for PA5.

}
// LED_Off: Turns off requested LED
// Parameters: led_mask - LED number // Return: (none)
void LED_Off (uint32_t led_mask)
{
GPIOC->BSRR |= (led_mask << 16); // set bit (5+16) to reset port pin PA05.
}
16
//Function that read Button pins
uint32_t BTN_Get(void)
{
return ( GPIOC->IDR & (1UL << 13) );
// Except bit 13 mask all other 31 bits to 0.
// if bit 13 is 1 then we return (1UL << 13)
// if bit 13 is 0 then we return 0.
// the calling routine should test for return value as 0 and non-zero.
// It should not look for return value as 0x00 and 0x01.
// To get return value as 0x01 we will need to shift bit 13 to bit 0 position
}

17
How to test this code?
1. Create an empty project from template or any other project in which the registers are
named or declared.
2. Add necessary startup files related to system clock and interrupts. You may use
available startup file or startup HAL functions.
3. Use initialization provided in the template. To that add initialization functions like
LED_Init() and BTN_init().
4. Inside the infinite loop, you can write the simple code practiced earlier to read the
switch . If return value is 0, switch off LED else switch on LED. Note this time do not
dump the switch value on LED variable because it will definitely not 0x01. It will be
1<<13.

18
Digital IO Example: LEDs
 Light-Emitting Diode (LED)
 Emits light when switched on
 Simplest way to indicate the status of logic
 Also widely used in applications such as automotive lighting, general lighting, traffic signals etc.

Digital Output Vcc 3.3V


ID ID
R R

LED LED
Digital Output

GND

Digital output sources current to LED Digital output sinks current from LED
19
Digital IO Example: 7-Segment Display
 Use 7 segments and a dot to display numerals or letters
 Widely used in digital electronic devices, such as digital clocks, electronic meters
 Simple control, easy to debug
 Different values can be represented by different combinations of 8-bit segments (including dot), for example:

Display 0 1 2 3 4
8-bit value 00111111 00000110 01011011 01001111 01100110
Display 5 6 7 8 9
8-bit value 01101101 01111101 00000111 01111111 01101111

20
Digital IO Example: Infrared Emitter/Detector
 Infrared emitter (LED)
 A light-emitting diode that emits invisible infrared (IR) when conducting e.g. when connected to digital output:

 ‘1’ – IR emitted (or brightness above a threshold)

 ‘0’ – no IR emitted (or brightness below a threshold)

 Infrared detector (photodiode)


 Converts light into either current or voltage e.g. when connected to digital input:

 ‘1’ – IR received (or brightness above a threshold)

 ‘0’ – no IR received (or brightness below a threshold)

Vcc 3.3V
Digital Output

R
R

Infrared emitter Infrared detector


Digital Input
GND

21
Useful Resources
 Cortex-M4 Technical Reference Manual:
http://infocenter.arm.com/help/topic/com.arm.doc.ddi0439d/DDI0439D_cortex_m4_processor_r0p1_trm.pdf

 Cortex-M4 Devices Generic User Guide:


http://infocenter.arm.com/help/topic/com.arm.doc.dui0553a/DUI0553A_cortex_m4_dgug.pdf

 STM32 Nucleo Reference Manual:


http://www.st.com/web/en/resource/technical/document/reference_manual/DM00096844.pdf

22

You might also like