Skip to content

Digital Input / Output

This section will cover the use of mikroSDK V2 functions for initializing and working with GPIO (General-purpose input/output) modules inside microcontrollers.

There are different files that you will be required to include, depending on whether you want to control pins individually or entire ports.

The following example will show both cases and will be broken down to steps.

The example assumes you had created an empty mikroSDK V2 application using NECTO Studio. If you need to, refer to the Creating a new project tutorial.

We will begin by initializing one pin as digital input and one more as digital output.
The example will cause the output pin to mimic the state of the input pin.

First, we need to include the necessary driver files, called drv_digital_in.h and drv_digital_out.h as well as define the appropriate context structures (driver objects).
We will do this at the beginning of the code, like so:

#include "drv_digital_in.h"
#include "drv_digital_out.h"

static digital_in_t input_pin;
static digital_out_t output_pin;

The two driver files we included will help us initialize our pins properly using the functions they provide. In order to use these functions we have to have context structures.

Naming convention

The naming convention for context structures is <module_name>_t (hence digital_in_t and digital_out_t).
Context structures contents are used by the module and must not be altered.

Next step is to use provided functions to initialize the pins. This is done inside of the application_init() function:

void application_init ( void )
{
    digital_in_init( &input_pin, PA0 ); /* Initialize digital input driver
    context structure and individual GPIO pin as digital input. */
    digital_out_init( &output_pin, PA1 ); /* Initialize digital output driver
    context structure and individual GPIO pin as digital output. */
}

input_pin and output_pin refer to the context structures we created earlier, while PA0 and PA1 refer to the actual pins that you want to control.
You will have to make sure that the pins you stated here are available and that they can, in fact, be used as GPIO.
These predefined constants correspond to the actual pins of the MCU, therefore, they are dependent on the port width of your MCU (8-bit, 16-bit, 24-bit, 32-bit).

Now that the pins are properly initialized we can move onto the application_task() function, which gets the state of the input pin and sets the output pin to the same state.

void application_task ( void )
{
    uint8_t value;

    value = digital_in_read( &input_pin );   // Read digital input value.
    digital_out_write( &output_pin, value ); /* Write read value to the
                                                output pin */
}

As you can see, the function we use for reading the pin state is called digital_in_read() and the function for writing to the pin is called digital_out_write().

If you have done everything correctly, your project should look like this:

#include "drv_digital_in.h"
#include "drv_digital_out.h"

static digital_in_t input_pin;
static digital_out_t output_pin;

void application_init ( void )
{
    digital_in_init( &input_pin, PA0 );
    digital_out_init( &output_pin, PA1 );
}


void application_task ( void )
{
    uint8_t value;

    value = digital_in_read( &input_pin );
    digital_out_write( &output_pin, value );
}

void main( void )
{
    application_init( );

    for ( ; ; )
    {
        application_task( );
    }
}

Now we can move onto controlling entire ports, which we will demonstrate via simple LED blink example.

For this, we will create a new project using the mikroSDK2.0 template.
We follow the same principle as in the previous example.

This time, the header file you have to include is called drv_port.h.
We will also initialise context structures as well as two global variables called mask and value, which we will use for initializing and controlling IO ports.

#include "drv_port.h"

static port_t port_a;
static port_t port_b;
static port_t port_c;
static port_t port_d;
static port_t port_e;
static port_t port_f;

uint16_t mask = 0xFFFF;
uint16_t value = 0;

In the application_init() we call the port_init() function from the drv_port.h file, which initializes ports according to input parameters. The variable mask is used here to specify which pins we want to set as digital output. mask variable holds value 0xFFFF, meaning all pins will be set as digital output.

void application_init ( void )
{
    port_init( &port_a, PORT_A, mask, GPIO_DIGITAL_OUTPUT );
    port_init( &port_b, PORT_B, mask, GPIO_DIGITAL_OUTPUT );
    port_init( &port_c, PORT_C, mask, GPIO_DIGITAL_OUTPUT );
    port_init( &port_d, PORT_D, mask, GPIO_DIGITAL_OUTPUT );
    port_init( &port_e, PORT_E, mask, GPIO_DIGITAL_OUTPUT );
    port_init( &port_f, PORT_F, mask, GPIO_DIGITAL_OUTPUT );
}

Now that the ports are set as digital output, we can use the port_write() function to write desired values to the ports. In this case, value variable will be changing each second from 0 to 0xFFFF and so on, making the LEDs blink.

void application_task ( void )
{
    value = ~value;
    port_write( &port_a, value );
    port_write( &port_b, value );
    port_write( &port_c, value );
    port_write( &port_d, value );
    port_write( &port_e, value );
    port_write( &port_f, value );
    Delay_1sec( );
}