// i2c_ads1115.c #include "bsp_i2c_ads1115.h" #include "stdlib.h" #include "stdio.h" #include "elog.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" }; uint16_t resultbuf[1] = {0}; double result_double = 0; // 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, ads1115_port, ads1115_get_data_start, 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, // 默认输出毫伏 0, 0.0, ADS1115_WORK_STATE_WAITING, }; void ads1115_task(void) { uint8_t rx_data[2] = {0}; uint32_t event_flags = 0; int st; for ( ; ; ) { switch (my_ads1115.state) { case ADS1115_WORK_STATE_WAITING: // log_e( " ADS1115 waiting ********** " ); osDelay(20); break; case ADS1115_WORK_STATE_START: break; case ADS1115_WORK_STATE_INIT: log_e( " ADS1115 init ********** %d" ,pADS1115_I2C->State ); 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 ; my_ads1115.reg_data[0] = 0x01; // point addr 8bit 配置寄存器 my_ads1115.reg_data[1] = my_ads1115.config_H; // config_reg 高位 my_ads1115.reg_data[2] = my_ads1115.config_L; // config_reg 低位 // while( HAL_I2C_Master_Transmit(pADS1115_I2C, ADS1115_WRITE_ADDRESS, my_ads1115.reg_data, 3 ,1000)!= HAL_OK) // { // if (HAL_I2C_GetError(pADS1115_I2C) != HAL_I2C_ERROR_AF) // { // log_w("ads1115 0x01 Reg error!!!\r\n"); // } // } st = HAL_I2C_Master_Transmit(pADS1115_I2C, ADS1115_WRITE_ADDRESS, my_ads1115.reg_data, 3 ,1000); // st = HAL_I2C_Master_Transmit_IT(pADS1115_I2C, ADS1115_WRITE_ADDRESS, my_ads1115.reg_data, 3 ); if ( st != HAL_OK) { log_w( " ADS1115 init ********** trans error " ); my_ads1115.state = ADS1115_WORK_STATE_ERROR;; break; } my_ads1115.state =ADS1115_WORK_STATE_GET_DATA_READY; // event_flags = osEventFlagsWait ( ads1115EventHandle, ADS1115_Event_INIT, 0 , portMAX_DELAY ); // if (event_flags && ADS1115_Event_INIT) // { // my_ads1115.state =ADS1115_WORK_STATE_READY_GET_DATA; // } continue; case ADS1115_WORK_STATE_GET_DATA_READY: // log_w( " ADS1115 Ready ********** %d" ,pADS1115_I2C->State ); osDelay(20); break; case ADS1115_WORK_STATE_GET_DATA_START: log_w( " ADS1115 GET_DATA_START ********** %d" ,pADS1115_I2C->State ); my_ads1115.result_int16 = 0; my_ads1115.voltage_mv = 0.0; while( HAL_I2C_Master_Transmit(pADS1115_I2C, ADS1115_WRITE_ADDRESS, my_ads1115.reg_data, 3 ,1000)!= HAL_OK) { if (HAL_I2C_GetError(pADS1115_I2C) != HAL_I2C_ERROR_AF) { log_w("ads1115 01 Register error!!!\r\n"); } } my_ads1115.state = ADS1115_WORK_STATE_GET_DATA_Convert_Register; continue; case ADS1115_WORK_STATE_GET_DATA_Convert_Register: log_i( " ADS1115 Ready ********** Convert_Register " ); 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"); } } my_ads1115.state = ADS1115_WORK_STATE_GET_DATA_RCV; // // osEventFlagsClear( ads1115TaskHandle, ADS1115_Event_Get_Data ); // st = HAL_I2C_Master_Transmit (pADS1115_I2C, ADS1115_WRITE_ADDRESS, 0x00, 1 ,1000); // if ( st != HAL_OK) // { // log_e( " ADS1115 init ********** Convert_Register error " ); // my_ads1115.state = ADS1115_WORK_STATE_ERROR; // break; // } // if ( HAL_I2C_GetError(pADS1115_I2C) != HAL_I2C_ERROR_AF ) // { // log_e("ads1115 read data error!!!\r\n"); // break; // } // my_ads1115.state =ADS1115_WORK_STATE_GET_DATA_RCV; // if (HAL_I2C_Master_Transmit_IT(pADS1115_I2C, ADS1115_WRITE_ADDRESS, 0x00, 1 ) != HAL_OK) { // my_ads1115.state =ADS1115_WORK_STATE_ERROR; // } // if ( HAL_I2C_GetError(pADS1115_I2C) != HAL_I2C_ERROR_AF ) // { // printf("ads1115 convert Register error!!!\r\n"); // } // event_flags = osEventFlagsWait ( ads1115EventHandle, // ADS1115_Event_Get_Data_Convert_Register, 0 , portMAX_DELAY ); // if (event_flags && ADS1115_Event_Get_Data_Convert_Register) // { // my_ads1115.state = ADS1115_WORK_STATE_GET_DATA_RCV; // } continue; case ADS1115_WORK_STATE_GET_DATA_RCV: log_i( " ADS1115 Ready ********** _DATA_RCV " ); int16_t data; // uint8_t rx_data[2] = {0}; memset( rx_data,0,2); // 读两位 // while (HAL_I2C_Master_Receive(pADS1115_I2C, ADS1115_READ_ADDRESS, (uint8_t*)resultbuf, 2, 2000) != HAL_OK) 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 ) { log_e("ads1115 read data error!!!\r\n"); } } my_ads1115.result_int16 = rx_data[0] * 256 + rx_data[1]; log_w( " readout : %d %02X %02X %04X",my_ads1115.result_int16 , rx_data[0], rx_data[1],*(uint16_t*)rx_data); my_ads1115.state = ADS1115_WORK_STATE_GET_DATA_FLOAT; continue; osDelay(80); // st=HAL_I2C_Master_Receive_IT(pADS1115_I2C, ADS1115_READ_ADDRESS, (uint8_t*)resultbuf, 2 ); // if ( st != HAL_OK) // { // log_e( " ADS1115 init ********** _DATA_RCV error " ); // my_ads1115.state = ADS1115_WORK_STATE_ERROR; // break; // } // if ( HAL_I2C_GetError(pADS1115_I2C) != HAL_I2C_ERROR_AF ) // { // log_e("ads1115 read data error!!!\r\n"); // break; // } // my_ads1115.state =ADS1115_WORK_STATE_GET_DATA_OK; // osEventFlagsClear( ads1115TaskHandle, ADS1115_Event_Get_Data_Convert_Register ); // if ( HAL_I2C_Master_Receive_IT(pADS1115_I2C, ADS1115_READ_ADDRESS, (uint8_t*)resultbuf, 2 ) != HAL_OK ) // { // my_ads1115.state =ADS1115_WORK_STATE_ERROR; // } // if ( HAL_I2C_GetError(pADS1115_I2C) != HAL_I2C_ERROR_AF ) // { // printf("ads1115 read data error!!!\r\n"); // } // event_flags = osEventFlagsWait ( ads1115EventHandle, // ADS1115_Event_Get_Data_RCV, 0 , portMAX_DELAY ); // if (event_flags && ADS1115_Event_Get_Data_RCV) // { // my_ads1115.state = ADS1115_WORK_STATE_GET_DATA_OK; // } continue; case ADS1115_WORK_STATE_GET_DATA_FLOAT: log_i( " ADS1115 Ready ********** DATA_FLOAT %d" ,my_ads1115.result_int16 ); // osEventFlagsClear( ads1115TaskHandle, ADS1115_Event_Get_Data_RCV ); double val; if ( (my_ads1115.result_int16 == 0x7FFF) | (my_ads1115.result_int16 == 0X8000)) // 是否超量程了 { resultbuf[0] = 0; // printf("over PGA\r\n"); } switch ((0x0E & my_ads1115.config_H) >> 1) // 量程对应的分辨率 { case (0x00): val = (double)my_ads1115.result_int16 * 187.5 / 1000.0; // break; case (0x01): val = (double)my_ads1115.result_int16 * 125 / 1000.0; break; case (0x02): val = (double)my_ads1115.result_int16 * 62.5 / 1000.0; break; case (0x03): val = (double)my_ads1115.result_int16 * 31.25 / 1000.0; break; case (0x04): val = (double)my_ads1115.result_int16 * 15.625 / 1000.0; break; case (0x05): val = (double)my_ads1115.result_int16 * 7.8125 / 1000.0; break; } my_ads1115.voltage_mv = (my_ads1115.unit == ADS1115_OUTPUT_UNIT_mv)?val:(val/1000.0); log_i( " f %06f",my_ads1115.voltage_mv); my_ads1115.state = ADS1115_WORK_STATE_GET_DATA_OK ; break; case ADS1115_WORK_STATE_GET_DATA_OK: osDelay(10); break; case ADS1115_WORK_STATE_ERROR: log_w( " ADS1115 error ..... " ); // my_ads1115.state = ADS1115_WORK_STATE_WAITING ; osDelay(10); break; case ADS1115_WORK_STATE_STOP: log_w( " ADS1115 stop..... " ); // my_ads1115.state = ADS1115_WORK_STATE_WAITING ; osDelay(10); break; default: break; } osDelay(200); } // 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(void) { 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 ; // log_i( " %02X %02X %02X", 0x01,my_ads1115.config_H,my_ads1115.config_L ); my_ads1115.reg_data[0] = 0x01; // point addr 8bit 配置寄存器 my_ads1115.reg_data[1] = my_ads1115.config_H; // config_reg 高位 my_ads1115.reg_data[2] = my_ads1115.config_L; // config_reg 低位 // log_i( " %02X %02X %02X", my_ads1115.reg_data[0],my_ads1115.reg_data[1],my_ads1115.reg_data[2] ); // TODO 阻塞式 仅init 使用 // my_ads1115.state = ADS1115_WORK_STATE_INIT; // osEventFlagsSet ( ads1115TaskHandle, ADS1115_Event_INIT ); if (HAL_I2C_Master_Transmit(pADS1115_I2C, ADS1115_WRITE_ADDRESS, my_ads1115.reg_data, 3,1000 ) != 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); } void ads1115_get_data_start(void) { // log_w( " ADS1115 ********** start.. " ); // osEventFlagsSet( ads1115TaskHandle, ADS1115_Event_Get_Data ); my_ads1115.state =ADS1115_WORK_STATE_GET_DATA_START; } void I2C1_EV_IRQHandler(void) { // if (__HAL_I2C_GET_FLAG(&hi2c1, I2C_FLAG_TC) != RESET) // { // log_i( " i2c master send cplt ******"); // } log_i( " i2c master send cplt ******"); HAL_I2C_EV_IRQHandler(&hi2c1); } void I2C1_ER_IRQHandler(void) { HAL_I2C_ER_IRQHandler(&hi2c1); } // void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c) // { // log_i( " i2c master send cplt ------------------- "); // if (my_ads1115.state = ADS1115_WORK_STATE_INIT) // { // osEventFlagsSet( ads1115TaskHandle, ADS1115_Event_INIT ); // } // if (my_ads1115.state = ADS1115_WORK_STATE_GET_DATA_Convert_Register) // { // osEventFlagsSet( ads1115TaskHandle, ADS1115_Event_Get_Data_Convert_Register ); // } // // //发送完成回调函数 // // { // // //一些其他操作 // // } // // HAL_I2C_Master_Receive_IT(&I2cHandle,i2c_slave_recv,I2C_REC_BYTES); // // { // // //一些其他操作 // // } // } // void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c) // { // log_i( " i2c master rx cplt ------------------- "); // // //接收完成回调函数 // // { // // //一些其他操作 // // } // // HAL_I2C_Slave_Transmit_IT(&I2cHandle,send_buffer,send_cnt); // // { // // //一些其他操作 // // } // } // void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c) // { // //错误异常回调函数 // }