// i2c_ads1115.c #include "i2c_ads1115.h" #include "stdlib.h" #include "stdio.h" /* 多路测量的话, 需要配置不同的 config_H config_L */ static I2C_HandleTypeDef *pADS1115_I2C = &hi2c1; osThreadId_t ads1115TaskHandle; const osThreadAttr_t ads1115Task_attributes = { .name = "ads1115Task", .stack_size = 256 * 4, .priority = (osPriority_t) osPriorityNormal, }; osEventFlagsId_t ads1115EventHandle; const osEventFlagsAttr_t ads1115Event_attributes = { .name = "ads1115Event" }; // ads1115EventHandle = osEventFlagsNew (&ads1115Event_attributes); // typedef enum // { // EV_READY, /*!< Startup finished. */ // EV_FRAME_RECEIVED, /*!< Frame received. */ // EV_EXECUTE, /*!< Execute function. */ // EV_FRAME_SENT /*!< Frame sent. */ // } eMBEventType; // osEventFlagsSet(modbusEventHandle,eEvent); // osEventFlagsClear (osEventFlagsId_t ef_id, uint32_t flags) // recvedEvent = osEventFlagsWait (modbusEventHandle, // EV_READY | EV_FRAME_RECEIVED | EV_EXECUTE | // EV_FRAME_SENT, /* 接收任务感兴趣的事件 */ // 0, // portMAX_DELAY); /* 指定超时事件,无限等待 */ ADS1115_TypeDef my_ads1115 = { ads1115_init, NULL, ADS1115_REG_CONFIG_OS_START, ADS1115_REG_CONFIG_MUX_SINGLE_0, ADS1115_REG_CONFIG_PGA_4, ADS1115_REG_CONFIG_MODE_SINGLE, ADS1115_REG_CONFIG_DR_128, ADS1115_REG_CONFIG_COMP_MODE_TRADITIONAL, ADS1115_REG_CONFIG_COMP_POL_LOW, ADS1115_REG_CONFIG_COMP_LAT_NONLATCH, ADS1115_REG_CONFIG_COMP_QUE_DIS, 0, 0, 0, { 0, 0, 0 }, ADS1115_OUTPUT_UNIT_mv, // 默认输出毫伏 }; void ads1115_task(void) { uint32_t event_flags; for (;;) { // 启用中断发送,判断状态, // 地址中断, 确认是哪I2C 设备通讯 /* code */ /* TODO 统一的超时机制 */ /* 事件来管理 */ event_flags = osEventFlagsWait ( ads1115EventHandle , ADS1115_Event_READY|ADS1115_Event_INIT|ADS1115_Event_TRANS_ONLY|ADS1115_Event_DATA_RCV , 0 , portMAX_DELAY ); if ( event_flags & (ADS1115_Event_READY|ADS1115_Event_INIT) == (ADS1115_Event_READY|ADS1115_Event_INIT) ) { // if (HAL_I2C_GetError(&hi2c1)!= HAL_I2C_ERROR_AF) // { // Error_Handler(); // } // if (HAL_I2C_GetState(&hi2c1)!= HAL_I2C_STATE_READY) // { // Error_Handler(); // } osEventFlagsClear(ads1115EventHandle, ADS1115_Event_INIT); osEventFlagsSet(ads1115EventHandle, ADS1115_Event_INIT_SUCCESS); } if ( event_flags & ( ADS1115_Event_READY|ADS1115_Event_TRANS_ONLY ) == (ADS1115_Event_READY|ADS1115_Event_TRANS_ONLY) ) { osEventFlagsClear(ads1115EventHandle, ADS1115_Event_TRANS_ONLY); } if ( event_flags & ( ADS1115_Event_READY|ADS1115_Event_TRANS_FOR_DATA ) == (ADS1115_Event_READY|ADS1115_Event_TRANS_FOR_DATA) ) { osEventFlagsClear(ads1115EventHandle, ADS1115_Event_TRANS_FOR_DATA); osEventFlagsSet(ads1115EventHandle, ADS1115_Event_DATA_RCV); } if ( event_flags & ( ADS1115_Event_READY|ADS1115_Event_DATA_RCV ) == ( ADS1115_Event_READY|ADS1115_Event_DATA_RCV ) ) { osEventFlagsClear( ads1115EventHandle, ADS1115_Event_DATA_RCV ); } // __HAL_I2C_GET_FLAG(&hi2c1, I2C_FLAG_TXE) ; osDelay(20); } } void ads1115_port(void) { ads1115TaskHandle = osThreadNew(ads1115_task, NULL, &ads1115Task_attributes); ads1115EventHandle = osEventFlagsNew (&ads1115Event_attributes); } /** * @brief * @param [in] ads1115_I2cHandle * @param [in] pointADD -- 读的寄存器地址 * @param [in] configH * @param [in] configL * * @details */ int ads1115_init() { uint8_t reg_data[3]; my_ads1115.hi2c= pADS1115_I2C; my_ads1115.config_H = my_ads1115.config_os|my_ads1115.config_mux |my_ads1115.config_PGA|my_ads1115.config_MODE; my_ads1115.config_L = my_ads1115.config_DR|my_ads1115.config_COMP_MODE|my_ads1115.config_COMP_POL |my_ads1115.config_COMP_LAT|my_ads1115.config_COMP_QUE ; reg_data[0] = 0x01; // point addr 8bit 配置寄存器 reg_data[1] = my_ads1115.config_H; // config_reg 高位 reg_data[2] = my_ads1115.config_L; // config_reg 低位 // TODO 阻塞式, 改为 DMA 中断模式, 配合定时器 , 或启用中断等待 // while (HAL_I2C_Master_Transmit(pADS1115_I2C, ADS1115_WRITE_ADDRESS, reg_data, 3, 2000) != HAL_OK) // { // if (HAL_I2C_GetError(pADS1115_I2C) != HAL_I2C_ERROR_AF) // { // printf("ads1115 Config Register error!!!\r\n"); // } // } osEventFlagsSet ( ads1115TaskHandle, ADS1115_Event_INIT ); if (HAL_I2C_Master_Transmit_IT(pADS1115_I2C, ADS1115_WRITE_ADDRESS, reg_data, 3 ) != HAL_OK) { return -1; } return 0; } int ads1115_setup(ADS1115_REG_CONFIG_MUX_Diff_TypeDef mux) { my_ads1115.config_H &= ~0x70; my_ads1115.config_H &= mux; return 0; } int16_t ads1115_read_data( ) { int16_t data; uint8_t rx_data[2] = {0}; // TODO 阻塞式, 改为 DMA 中断模式 // 读寄存器 0x00 十六位 while (HAL_I2C_Master_Transmit(pADS1115_I2C, ADS1115_WRITE_ADDRESS, 0x00, 1, 2000) != HAL_OK) { if (HAL_I2C_GetError(pADS1115_I2C) != HAL_I2C_ERROR_AF) { printf("ads1115 convert Register error!!!\r\n"); } } // 读两位 while (HAL_I2C_Master_Receive(pADS1115_I2C, ADS1115_READ_ADDRESS, rx_data, 2, 2000) != HAL_OK) { if ( HAL_I2C_GetError(pADS1115_I2C) != HAL_I2C_ERROR_AF ) { printf("ads1115 read data error!!!\r\n"); } } data = rx_data[0] * 256 + rx_data[1]; return data; } double ads1115_get_voltage_val( ) { double val; int16_t ad_val; // TODO 去掉延时,使用寄存器的指示, setup 和读取数据分开执行 // ads1115_setup( pADS1115_I2C, pointADD, configH, configL ); ads1115_setup( ADS1115_REG_CONFIG_MUX_SINGLE_0 ); HAL_Delay(10); ad_val = ads1115_read_data( pADS1115_I2C ); if ( (ad_val == 0x7FFF) | (ad_val == 0X8000)) // 是否超量程了 { ad_val = 0; // printf("over PGA\r\n"); } switch ((0x0E & my_ads1115.config_H) >> 1) // 量程对应的分辨率 { case (0x00): val = (double)ad_val * 187.5 / 1000.0; // break; case (0x01): val = (double)ad_val * 125 / 1000.0; break; case (0x02): val = (double)ad_val * 62.5 / 1000.0; break; case (0x03): val = (double)ad_val * 31.25 / 1000.0; break; case (0x04): val = (double)ad_val * 15.625 / 1000.0; break; case (0x05): val = (double)ad_val * 7.8125 / 1000.0; break; } return (my_ads1115.unit == ADS1115_OUTPUT_UNIT_mv)?val:(val/1000.0); }