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( );
}