Vous êtes sur la page 1sur 23

MICROPROCESADORES II (A)

INFORME DE LABORATORIO Nº6

COMUNICACIÓN MEDIANTE INTERFAZ I2C


SEMESTRE II/2023
Estudiante:
Natalia Berrocal Gamez

La Paz 6 de diciembre del 2023


Tabla de contenido
ÍNDICE DE FIGURAS................................................................................................................ 3
ÍNDICE DE TABLAS .................................................................................................................. 3
1. INTRODUCCIÓN ................................................................................................................ 4
2. OBJETIVOS ........................................................................................................................ 4
2.1. OBJETIVO GENERAL .................................................................................................. 4
2.2. OBJETIVOS ESPECÍFICOS............................................................................................ 4
3. FUNDAMENTO TEÓRICO ................................................................................................. 5
3.1. ADC ............................................................................... ¡Error! Marcador no definido.
3.2. RESOLUCIÓN ............................................................... ¡Error! Marcador no definido.
3.3. TASA DE MUESTREO .................................................. ¡Error! Marcador no definido.
3.4. CONFIGURACIÓN DEL ADC ....................................... ¡Error! Marcador no definido.
3.5. REFERENCIA DE VOLTAJE ........................................ ¡Error! Marcador no definido.
4. MATERIALES Y EQUIPOS ................................................................................................. 5
5. DISEÑO DEL CIRCUITO .................................................................................................... 5
5.1. CONFIGURACIÓN DEL PUERTO ADC....................................................................... 5
5.2. CÓDIGO ....................................................................................................................... 7
5.3. CONEXIONES............................................................... ¡Error! Marcador no definido.
5.4. RESULTADO EN FÍSICO ........................................................................................... 22
6. CONCLUSIONES ............................................................................................................. 23
7. BIBLIOGRAFÍA ................................................................................................................. 23
ÍNDICE DE FIGURAS
Figura 1. Diagrama de conexiones .......................................................................................... 22
Figura 2 Resultado en clase .................................................................................................... 23

ÍNDICE DE TABLAS
Tabla 1 Materiales y equipos ..................................................................................................... 5
LABORATORIO 6
COMUNICACIÓN MEDIANTE INTERFAZ I2C

1. INTRODUCCIÓN

La comunicación eficiente entre dispositivos electrónicos es esencial en el desarrollo de


sistemas embebidos y circuitos integrados modernos. La Inter-Integrated Circuit, comúnmente
conocida como I2C, se ha convertido en una interfaz estándar clave para facilitar la transferencia
de datos entre microcontroladores, sensores, memoria y otros componentes electrónicos.

La interfaz I2C, diseñada por Philips Semiconductor (ahora NXP Semiconductors), ofrece una
solución versátil y de bajo costo para establecer conexiones seriales entre múltiples dispositivos
en un sistema. Su arquitectura maestro-esclavo, combinada con su capacidad para soportar
múltiples dispositivos en el mismo bus, la convierte en una opción atractiva para aplicaciones
que requieren una comunicación fiable y eficiente.

En este informe, exploraremos a fondo los fundamentos de la interfaz I2C, analizando sus
características, protocolo de comunicación, ventajas y desafíos asociados. Además,
examinaremos casos de uso prácticos y ejemplos de implementación, destacando cómo la
interfaz I2C ha contribuido significativamente al desarrollo de sistemas embebidos modernos.
Este informe busca proporcionar una comprensión sólida de la interfaz I2C, su aplicación en el
mundo real y su relevancia continua en el ámbito de la electrónica y la ingeniería de sistemas.

2. OBJETIVOS
2.1. OBJETIVO GENERAL
• Diseñar e implementar un sistema de comunicación eficiente utilizando la interfaz I2C en
microcontroladores ARM Cortex-M3 de 32 bits, integrando sensores, configurando el
periférico de Conversión Analógico a Digital (ADC) y gestionando los puertos del
microcontrolador, con el propósito de lograr una comunicación fluida y confiable entre
dispositivos periféricos.

2.2. OBJETIVOS ESPECÍFICOS


• Investigar y comprender los principios fundamentales de la interfaz I2C y su
implementación en microcontroladores ARM Cortex-M3.
• Analizar las características y tipos de sensores relevantes para el proyecto, identificando
aquellos que serán integrados en el sistema.
• Configurar el periférico de Conversión Analógico a Digital (ADC) para garantizar una
adquisición precisa de señales analógicas provenientes de los sensores.

3. FUNDAMENTO TEÓRICO
3.1. Interfaz I2C
La Interfaz I2C (Inter-Integrated Circuit) es un protocolo de comunicación seriale diseñado
para la interconexión de microcontroladores, sensores, memoria y otros periféricos en
sistemas embebidos. Desarrollada por Philips Semiconductor (ahora NXP Semiconductors),
I2C opera sobre dos líneas: SDA (Serial Data Line) y SCL (Serial Clock Line), permitiendo
la comunicación simultánea de múltiples dispositivos en un mismo bus. Su estructura
maestro-esclavo y capacidad para soportar múltiples dispositivos hacen que sea una
elección común en sistemas embebidos.

3.2. Sensores en sistemas embebidos


Los sensores desempeñan un papel crucial en sistemas embebidos al proporcionar datos
del entorno físico. Desde sensores de temperatura hasta acelerómetros, estos dispositivos
convierten fenómenos físicos en señales eléctricas interpretables por el microcontrolador.
La selección adecuada de sensores es esencial para la precisión y relevancia de los datos
adquiridos.

4. MATERIALES Y EQUIPOS
MATERIAL CANTIDAD
Stm32F103C8T6 1
Protoboard 1
ST-LINK V2 1
Pantalla OLED 1
Tabla 1 Materiales y equipos

5. DISEÑO DEL CIRCUITO


Diseñar un programa aplicando la interfaz I2C e implementar el circuito que cumpla la siguiente
función: Se debe programar un Micro STM32F103C8T6 como maestro I2C para controlar dos
dispositivos esclavos I2C: Sensor de temperatura-I2C (DS1621) y un LCD-I2C. El maestro debe
recuperar la lectura de la temperatura ambiente del dispositivo esclavo y reenviarlo a un LC-I2C
para su visualización en tiempo real
5.1. PASOS
Paso 1: Configuración del Proyecto en STM32CubeIDE
• Creación del Proyecto:
Abre STM32CubeIDE y crea un nuevo proyecto para tu microcontrolador STM32F103.
Selecciona el tipo de proyecto y la placa de desarrollo adecuados.
• Configuración del Periférico I2C:
Configura el periférico I2C en el maestro para establecer la comunicación con el esclavo.
Configura la velocidad de transferencia y las direcciones de los dispositivos.
• Configuración del ADC:
Configura el periférico ADC para medir la temperatura. Define los pines de entrada analógica y
ajusta la resolución y la frecuencia de muestreo según sea necesario.

Paso 2: Programación del Maestro STM32F103


• Programación de la Medición de Temperatura:
Implementa el código para medir la temperatura utilizando el ADC. Convierte la lectura del ADC
a la temperatura real mediante la fórmula adecuada.
• Envío de Datos al Esclavo:
Utiliza el periférico I2C para enviar la información de temperatura al esclavo. Define un protocolo
de comunicación simple para transmitir datos.

Paso 3: Programación del Esclavo STM32F103


• Configuración del I2C:
Configura el periférico I2C en el esclavo para recibir datos del maestro. Define las direcciones
del esclavo y asegúrate de que esté en modo de escucha.
• Recepción de Datos:
Implementa el código para recibir los datos de temperatura del maestro a través de la interfaz
I2C. Adecua el código para interpretar y mostrar la temperatura en la pantalla OLED.
Paso 4: Integración con Pantalla OLED
• Conexión Física:
Conecta la pantalla OLED al esclavo STM32F103, asegurándote de que los pines estén
correctamente conectados.
• Implementación del Código para la Pantalla OLED:
Desarrolla el código necesario para controlar la pantalla OLED desde el esclavo. Puedes utilizar
bibliotecas específicas para la pantalla OLED que faciliten esta tarea.
Paso 5: Compilación, Carga y Pruebas
• Compilación del Proyecto:
Compila tanto el código del maestro como del esclavo en STM32CubeIDE.
• Carga del Firmware:
Carga el firmware compilado en los microcontroladores maestro y esclavo utilizando el
programador ST-LINK/V2 o el método que prefieras.
• Pruebas:
Alimenta ambos microcontroladores y verifica que la temperatura se mide correctamente en el
maestro y se muestra en la pantalla OLED conectada al esclavo.
Notas Adicionales:
• Depuración:
Utiliza las herramientas de depuración de STM32CubeIDE para identificar y solucionar posibles
problemas durante el desarrollo.
• Optimización:
Optimiza el código según sea necesario y ajusta los parámetros de comunicación I2C y ADC
para obtener el rendimiento deseado.
• Documentación:
Documenta tu código y realiza comentarios para facilitar la comprensión y el mantenimiento
futuro.

5.2. CÓDIGO
PASO 4. GENERAR CÓDIGO

main.c
/* Natalia Berrocal Gamez Header */

/**

**************************

* @file : main.c

* @brief : Main program body

**************************

* @attention

* Copyright (c) 2023 STMicroelectronics.

* All rights reserved.

* This software is licensed under terms that can be found in the LICENSE file

* in the root directory of this software component.

* If no LICENSE file comes with this software, it is provided AS-IS.

**************************

*/

/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/

#include "main.h"

#include "i2c.h"

#include "tim.h"

#include "gpio.h"
#include "fonts.h"

#include "ssd1306_oled.h"

#include "stdio.h"

void SystemClock_Config(void);

#define DHT11_PORT GPIOB

#define DHT11_PIN GPIO_PIN_9

uint8_t RHI, RHD, TCI, TCD, SUM;

uint32_t pMillis, cMillis;

float tCelsius = 0;

float tFahrenheit = 0;

float RH = 0;

uint8_t TFI = 0;

uint8_t TFD = 0;

char strCopy[15];

void microDelay (uint16_t delay)

__HAL_TIM_SET_COUNTER(&htim1, 0);

while (__HAL_TIM_GET_COUNTER(&htim1) < delay);


}

uint8_t DHT11_Start (void)

uint8_t Response = 0;

GPIO_InitTypeDef GPIO_InitStructPrivate = {0};

GPIO_InitStructPrivate.Pin = DHT11_PIN;

GPIO_InitStructPrivate.Mode = GPIO_MODE_OUTPUT_PP;

GPIO_InitStructPrivate.Speed = GPIO_SPEED_FREQ_LOW;

GPIO_InitStructPrivate.Pull = GPIO_NOPULL;

HAL_GPIO_Init(DHT11_PORT, &GPIO_InitStructPrivate); // set the pin as output

HAL_GPIO_WritePin (DHT11_PORT, DHT11_PIN, 0); // pull the pin low

HAL_Delay(20); // wait for 20ms

HAL_GPIO_WritePin (DHT11_PORT, DHT11_PIN, 1); // pull the pin high

microDelay (30); // wait for 30us

GPIO_InitStructPrivate.Mode = GPIO_MODE_INPUT;

GPIO_InitStructPrivate.Pull = GPIO_PULLUP;

HAL_GPIO_Init(DHT11_PORT, &GPIO_InitStructPrivate); // set the pin as input

microDelay (40);

if (!(HAL_GPIO_ReadPin (DHT11_PORT, DHT11_PIN)))

microDelay (80);

if ((HAL_GPIO_ReadPin (DHT11_PORT, DHT11_PIN))) Response = 1;


}

pMillis = HAL_GetTick();

cMillis = HAL_GetTick();

while ((HAL_GPIO_ReadPin (DHT11_PORT, DHT11_PIN)) && pMillis + 2 > cMillis)

cMillis = HAL_GetTick();

return Response;

uint8_t DHT11_Read (void)

uint8_t a,b;

for (a=0;a<8;a++)

pMillis = HAL_GetTick();

cMillis = HAL_GetTick();

while (!(HAL_GPIO_ReadPin (DHT11_PORT, DHT11_PIN)) && pMillis + 2 > cMillis)

{ // wait for the pin to go high

cMillis = HAL_GetTick();

microDelay (40); // wait for 40 us

if (!(HAL_GPIO_ReadPin (DHT11_PORT, DHT11_PIN))) // if the pin is low


b&= ~(1<<(7-a));

else

b|= (1<<(7-a));

pMillis = HAL_GetTick();

cMillis = HAL_GetTick();

while ((HAL_GPIO_ReadPin (DHT11_PORT, DHT11_PIN)) && pMillis + 2 > cMillis)

{ // wait for the pin to go low

cMillis = HAL_GetTick();

return b;

int main(void)

HAL_Init();

SystemClock_Config();

MX_GPIO_Init();

MX_I2C1_Init();

MX_TIM1_Init();
HAL_TIM_Base_Start(&htim1);

SSD1306_Init();

while (1)

if(DHT11_Start())

RHI = DHT11_Read(); // Relative humidity integral

RHD = DHT11_Read(); // Relative humidity decimal

TCI = DHT11_Read(); // Celsius integral

TCD = DHT11_Read(); // Celsius decimal

SUM = DHT11_Read(); // Check sum

if (RHI + RHD + TCI + TCD == SUM)

// Can use RHI and TCI for any purposes if whole number only needed

tCelsius = (float)TCI + (float)(TCD/10.0);

tFahrenheit = tCelsius * 9/5 + 32;

RH = (float)RHI + (float)(RHD/10.0);

// Can use tCelsius, tFahrenheit and RH for any purposes

TFI = tFahrenheit; // Fahrenheit integral

TFD = tFahrenheit*10-TFI*10; // Fahrenheit decimal

sprintf(strCopy,"LABO I2C");

SSD1306_GotoXY (0, 0);


SSD1306_Puts (strCopy, &Font_11x18, 1);

sprintf(strCopy,"%d.%d C ", TCI, TCD);

SSD1306_GotoXY (0, 20);

SSD1306_Puts (strCopy, &Font_11x18, 1);

sprintf(strCopy,"%d.%d %% ", RHI, RHD);

SSD1306_GotoXY (0, 40);

SSD1306_Puts (strCopy, &Font_11x18, 1);

SSD1306_UpdateScreen();

HAL_Delay(2000);

void SystemClock_Config(void)

RCC_OscInitTypeDef RCC_OscInitStruct = {0};

RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

/** Initializes the RCC Oscillators according to the specified parameters

* in the RCC_OscInitTypeDef structure.

*/

RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;

RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;

RCC_OscInitStruct.HSIState = RCC_HSI_ON;

RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;

RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;

RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;

if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)

Error_Handler();

/** Initializes the CPU, AHB and APB buses clocks

*/

RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK

|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;

RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;

RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;

RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;

RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)

Error_Handler();
}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**

* @brief This function is executed in case of error occurrence.

* @retval None

*/

void Error_Handler(void)

/* USER CODE BEGIN Error_Handler_Debug */

/* User can add his own implementation to report the HAL error return state */

__disable_irq();

while (1)

/* USER CODE END Error_Handler_Debug */

#ifdef USE_FULL_ASSERT
/**

* @brief Reports the name of the source file and the source line number

* where the assert_param error has occurred.

* @param file: pointer to the source file name

* @param line: assert_param error line source number

* @retval None

*/

void assert_failed(uint8_t *file, uint32_t line)

/* USER CODE BEGIN 6 */

/* User can add his own implementation to report the file name and line number,

ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

/* USER CODE END 6 */

#endif /* USE_FULL_ASSERT */

I2C.c

/* USER CODE BEGIN Header */

/**

**************************

* @file i2c.c

* @brief This file provides code for the configuration

* of the I2C instances.


**************************

* @attention

* Copyright (c) 2023 STMicroelectronics.

* All rights reserved.

* This software is licensed under terms that can be found in the LICENSE file

* in the root directory of this software component.

* If no LICENSE file comes with this software, it is provided AS-IS.

**************************

*/

/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/

#include "i2c.h"

/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

I2C_HandleTypeDef hi2c1;

/* I2C1 init function */


void MX_I2C1_Init(void)

/* USER CODE BEGIN I2C1_Init 0 */

/* USER CODE END I2C1_Init 0 */

/* USER CODE BEGIN I2C1_Init 1 */

/* USER CODE END I2C1_Init 1 */

hi2c1.Instance = I2C1;

hi2c1.Init.ClockSpeed = 400000;

hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;

hi2c1.Init.OwnAddress1 = 0;

hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;

hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;

hi2c1.Init.OwnAddress2 = 0;

hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;

hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;

if (HAL_I2C_Init(&hi2c1) != HAL_OK)

Error_Handler();

}
/* USER CODE BEGIN I2C1_Init 2 */

/* USER CODE END I2C1_Init 2 */

void HAL_I2C_MspInit(I2C_HandleTypeDef* i2cHandle)

GPIO_InitTypeDef GPIO_InitStruct = {0};

if(i2cHandle->Instance==I2C1)

/* USER CODE BEGIN I2C1_MspInit 0 */

/* USER CODE END I2C1_MspInit 0 */

__HAL_RCC_GPIOB_CLK_ENABLE();

/**I2C1 GPIO Configuration

PB6 ------> I2C1_SCL

PB7 ------> I2C1_SDA

*/

GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;

GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;

HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

/* I2C1 clock enable */

__HAL_RCC_I2C1_CLK_ENABLE();

/* USER CODE BEGIN I2C1_MspInit 1 */

/* USER CODE END I2C1_MspInit 1 */

void HAL_I2C_MspDeInit(I2C_HandleTypeDef* i2cHandle)

if(i2cHandle->Instance==I2C1)

/* USER CODE BEGIN I2C1_MspDeInit 0 */

/* USER CODE END I2C1_MspDeInit 0 */

/* Peripheral clock disable */

__HAL_RCC_I2C1_CLK_DISABLE();

/**I2C1 GPIO Configuration


PB6 ------> I2C1_SCL

PB7 ------> I2C1_SDA

*/

HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6);

HAL_GPIO_DeInit(GPIOB, GPIO_PIN_7);

/* USER CODE BEGIN I2C1_MspDeInit 1 */

/* USER CODE END I2C1_MspDeInit 1 */

/* USER CODE BEGIN 1 */

/* USER CODE END 1 */

5.3. DIAGRAMA DE CONEXIONES

Figura 1. Diagrama de conexiones


5.4. RESULTADO EN FÍSICO

Figura 2 Resultado en clase

6. CONCLUSIONES
• Se ha adquirido la capacidad de realizar conversiones de señales analógicas a digitales
de manera efectiva, utilizando la configuración apropiada del I2C. Esto nos permite
obtener datos digitales de alta calidad de las señales analógicas que deseamos medir.
• En resumen, hemos alcanzado con éxito los objetivos planteados para el manejo de
puertos I2C en un STM32 Blue Pill. Hemos adquirido un sólido fundamento teórico y
práctico que nos permite configurar, utilizar y aprovechar eficazmente el I2C de este
microcontrolador en diversas aplicaciones electrónicas.

7. BIBLIOGRAFÍA
• https://www.carlospes.com/curso_de_lenguaje_c/01_09_01_02_especificadores_de_for
mato.php
• https://imt4blog.files.wordpress.com/2019/10/adc.pdf
• https://www.digikey.com/en/maker/projects/getting-started-with-stm32-working-with-adc-
and-dma/f5009db3a3ed4370acaf545a3370c30c

Vous aimerez peut-être aussi