STM32cube HAL库两条命令实现i2c通信---Nucleo L476RG用I2C实现tmp117模块温度读取并串口打印

用stm32 cubemx默认配置i2c1和urart1,本例子是用硬件i2c非模拟i2c

  /* I2C1 GPIO Configuration    
    PB6     ------> I2C1_SCL
    PB7     ------> I2C1_SDA 
  * USART1 GPIO Configuration    
    PA9     ------> USART1_TX
    PA10     ------> USART1_RX 
  */

在这里插入图片描述
在main.c修改如下
温度读取流程:
1.STM32向TMP1117发送一个写命令HAL_I2C_Master_Transmit,其中包含TMP117中温度寄存器的地址(地址0x00)的1个字节。
2.使用读取命令HAL_I2C_Master_Receive从 TMP117 读取 2 个字节。这 2 个字节将包含温度数据。

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <stdio.h>
#include <string.h>
/* USER CODE END Includes */

/* Private variables ---------------------------------------------------------*/
I2C_HandleTypeDef hi2c1;
UART_HandleTypeDef huart1;
uint16_t count = 0;
/* USER CODE BEGIN PV */
static const uint8_t TMP117_ADDR = 0x48 << 1;  // Use 8-bit address
//I2C从机的地址最低为是读写标志位,1表示读,0表示写,剩下七位表示从机地址
static const uint8_t REG_TEMP = 0x00;
/* USER CODE END PV */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
int fputc(int ch ,FILE *f)
{
	HAL_UART_Transmit(&huart1,(uint8_t *)&ch,1,0xffff);
	return ch;
}
/* USER CODE END 0 */

int main(void)
{
  /* USER CODE BEGIN 1 */
  HAL_StatusTypeDef ret;
  uint8_t buf[12];
  int16_t val;
  float temp_c;
  /* USER CODE END 1 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    // Tell TMP117 that we want to read from the temperature register
    buf[0] = REG_TEMP;
    ret = HAL_I2C_Master_Transmit(&hi2c1, TMP117_ADDR, buf, 1, HAL_MAX_DELAY);//buf为数组,同函数&可省略。
    if ( ret != HAL_OK ) {
      strcpy((char*)buf, "Error Tx\r\n");
    } else {
      // Read 2 bytes from the temperature register
      ret = HAL_I2C_Master_Receive(&hi2c1, TMP117_ADDR, &buf[0], 2, HAL_MAX_DELAY);
      if ( ret != HAL_OK ) 
      {
      strcpy((char*)buf, "Error Rx\r\n");
      } 
      else {
        //Combine the bytes
        val = ((int16_t)buf[0] << 8| buf[1];
        // Convert to float temperature value (Celsius)
        temp_c = val * 0.0078125;
		printf("%d---Temp: %0.3f\r\n", count++, temp_c);
     }
    }
    // Send out buffer (temperature or error message)
    HAL_UART_Transmit(&huart1, buf, strlen((char*)buf), HAL_MAX_DELAY);
    // Wait
    HAL_Delay(1000);
    /* USER CODE END WHILE */
    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

在这里插入图片描述

在这里插入图片描述

/*I2C写数据的函数*/
 HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout);
 /*
I2C_HandleTypeDef *hi2c :就是设置的实例,比如I2C1 &hi2c1
uint16_t DevAddress : 从机设备地址,比如0x48
uint8_t *pData :存放你要写的数据
uint16_t Size :数据的大小
uint32_t Timeout :最大的传输时间
例如
HAL_I2C_Master_Transmit(&hi2c1,0xA1,(uint8_t*)TxData,2,1000)
*/
/*I2C读数据的函数*/
HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout);
/*
I2C_HandleTypeDef *hi2c :就是设置的实例,比如I2C1 &hi2c1
uint16_t DevAddress : 从机设备地址,比如0x48
uint8_t *pData :存放你要读的数据
uint16_t Size :数据的大小
uint32_t Timeout :最大的传输时间
*/

void HAL_IIC_WriteByte_ToSlave(uint8_t I2C_Command)
{
//  uint8_t  *pData;
//  pData = &I2C_Command;
  HAL_I2C_Mem_Write(&hi2c1, TMP117_ADDR, reg, I2C_MEMADD_SIZE_8BIT, &I2C_Command, 1, 100);
}
void HALIIC_ReadByte_FromSlave(uint8_t *RXbuf)
{
  HAL_I2C_Mem_Read(&hi2c1, TMP117_ADDR, reg, I2C_MEMADD_SIZE_8BIT, RXbuf, 1, 100);
}
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是使用STM32CubeIDE编写的示例代码: ```c #include "stm32l4xx_hal.h" #include "stdio.h" /* Define I2C interface */ #define I2C_HANDLER hi2c1 #define I2C_ADDRESS 0x48 /* Define TMP102 registers */ #define TEMP_REGISTER 0x00 #define CONFIG_REGISTER 0x01 /* Define TMP102 configuration bits */ #define SHUTDOWN_BIT 0x0100 #define SLEEP_BIT 0x0400 /* Define ADC interface */ #define ADC_HANDLER hadc1 /* Define ADC channel */ #define ADC_CHANNEL ADC_CHANNEL_5 /* Define external interrupt pin */ #define EXTI_PIN GPIO_PIN_0 #define EXTI_PORT GPIOA /* Define external interrupt handler */ void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { if (GPIO_Pin == EXTI_PIN) { // Handle external interrupt } } int main(void) { HAL_Init(); __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_I2C1_CLK_ENABLE(); __HAL_RCC_ADC_CLK_ENABLE(); /* Initialize I2C interface */ I2C_HandleTypeDef hi2c1; hi2c1.Instance = I2C1; hi2c1.Init.Timing = 0x00C0EAFF; hi2c1.Init.OwnAddress1 = 0; hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; hi2c1.Init.OwnAddress2 = 0; hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK; hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; if (HAL_I2C_Init(&hi2c1) != HAL_OK) { Error_Handler(); } /* Initialize ADC interface */ ADC_HandleTypeDef hadc1; hadc1.Instance = ADC1; hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4; hadc1.Init.Resolution = ADC_RESOLUTION_12B; hadc1.Init.ScanConvMode = DISABLE; hadc1.Init.ContinuousConvMode = DISABLE; hadc1.Init.DiscontinuousConvMode = DISABLE; hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START; hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT; hadc1.Init.NbrOfConversion = 1; hadc1.Init.DMAContinuousRequests = DISABLE; hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV; if (HAL_ADC_Init(&hadc1) != HAL_OK) { Error_Handler(); } /* Configure GPIO pin for external interrupt */ GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.Pin = EXTI_PIN; GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(EXTI_PORT, &GPIO_InitStruct); /* Enable external interrupt */ HAL_NVIC_SetPriority(EXTI0_IRQn, 0, 0); HAL_NVIC_EnableIRQ(EXTI0_IRQn); /* Enable ADC channel */ ADC_ChannelConfTypeDef sConfig; sConfig.Channel = ADC_CHANNEL; sConfig.Rank = 1; sConfig.SamplingTime = ADC_SAMPLETIME_640CYCLES; if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) { Error_Handler(); } /* Configure TMP102 */ uint8_t config[2]; config[0] = CONFIG_REGISTER; config[1] = SHUTDOWN_BIT | SLEEP_BIT; if (HAL_I2C_Master_Transmit(&I2C_HANDLER, I2C_ADDRESS, (uint8_t *)config, 2, HAL_MAX_DELAY) != HAL_OK) { Error_Handler(); } /* Read temperature from TMP102 */ uint8_t temp_reg[2]; temp_reg[0] = TEMP_REGISTER; uint16_t temp_raw; if (HAL_I2C_Master_Transmit(&I2C_HANDLER, I2C_ADDRESS, (uint8_t *)temp_reg, 1, HAL_MAX_DELAY) != HAL_OK) { Error_Handler(); } if (HAL_I2C_Master_Receive(&I2C_HANDLER, I2C_ADDRESS, (uint8_t *)&temp_raw, 2, HAL_MAX_DELAY) != HAL_OK) { Error_Handler(); } float temperature = (float)((int16_t)temp_raw >> 4) * 0.0625; /* Read ADC value */ if (HAL_ADC_Start(&ADC_HANDLER) != HAL_OK) { Error_Handler(); } if (HAL_ADC_PollForConversion(&ADC_HANDLER, HAL_MAX_DELAY) != HAL_OK) { Error_Handler(); } uint16_t adc_value = HAL_ADC_GetValue(&ADC_HANDLER); /* Average temperature and ADC value */ float temperature_sum = 0; uint32_t adc_sum = 0; for (int i = 0; i < 10; i++) { /* Read temperature from TMP102 */ if (HAL_I2C_Master_Transmit(&I2C_HANDLER, I2C_ADDRESS, (uint8_t *)temp_reg, 1, HAL_MAX_DELAY) != HAL_OK) { Error_Handler(); } if (HAL_I2C_Master_Receive(&I2C_HANDLER, I2C_ADDRESS, (uint8_t *)&temp_raw, 2, HAL_MAX_DELAY) != HAL_OK) { Error_Handler(); } temperature_sum += (float)((int16_t)temp_raw >> 4) * 0.0625; /* Read ADC value */ if (HAL_ADC_Start(&ADC_HANDLER) != HAL_OK) { Error_Handler(); } if (HAL_ADC_PollForConversion(&ADC_HANDLER, HAL_MAX_DELAY) != HAL_OK) { Error_Handler(); } adc_sum += HAL_ADC_GetValue(&ADC_HANDLER); } float average_temperature = temperature_sum / 10; uint32_t average_adc_value = adc_sum / 10; /* Enter sleep mode */ HAL_PWR_EnableSleepOnExit(); HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI); while (1) { /* Main loop */ } } ``` 这个示例代码使用STM32CubeIDE开发工具编写,用于读取TMP102温度传感器和ADC电流传感器的值,并实现了外部中断。首先,我们初始化了I2C和ADC的接口,并配置了GPIO引脚用于外部中断。然后,我们配置了TMP102,以便在读取温度值之前将其置于关机和睡眠模式。接下来,我们读取了一次温度值和ADC值,并对它们进行平均化。最后,我们进入了睡眠模式,直到外部中断触发为止。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值