// i2c_ads1115.c #include "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", }; // 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_test, ads1115_start, ads1115_stop, 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, // point addr 0, // config_H 0, // config_L { 0, 0, 0 }, // reg_data[3] ADS1115_OUTPUT_UNIT_mv, // 默认输出毫伏 0, // event_flags 0, // state {0,0}, // result }; void ads1115_task(void) { uint8_t event_flags; uint8_t reg_data[3] ={0}; for (;;) { switch ( my_ads1115.state ) { case ADS1115_WORK_STATE_WAITING: osDelay(20); break; // Init case ADS1115_WORK_STATE_INIT: // log_i("ads1115 init .... %d ", osEventFlagsGet( ads1115EventHandle)); if ( osEventFlagsGet( ads1115EventHandle) == 0 ) { osEventFlagsSet( ads1115EventHandle, ADS1115_Event_INIT ); my_ads1115.reg_data[0] = 0x01; // point addr 8bit 配置寄存器 my_ads1115.reg_data[1] = my_ads1115.config_H; // config_reg 高位 my_ads1115.time_ticks = osKernelGetTickCount( ); if ( HAL_I2C_Master_Transmit_IT( pADS1115_I2C, ADS1115_WRITE_ADDRESS, my_ads1115.reg_data, 3 ) != HAL_OK) { // log_e( "ads1115 set register failure while reading!!!" ); my_ads1115.state == ADS1115_WORK_STATE_ERROR ; } } if ( (osKernelGetTickCount() - my_ads1115.time_ticks) > 5 *1000) { my_ads1115.state == ADS1115_WORK_STATE_TIMEOUT ; } break; case ADS1115_WORK_STATE_INIT_SUCCESS: // log_i("ads1115 init success ... " ); osEventFlagsClear( ads1115EventHandle, ADS1115_Event_INIT ); osEventFlagsSet( ads1115EventHandle, ADS1115_Event_READY ); break; // SET REGISTER case ADS1115_WORK_STATE_SET_REGISTER: // log_i("ads1115 set register .... %d ", osEventFlagsGet( ads1115EventHandle)); if ( osEventFlagsGet( ads1115EventHandle) == 0 ) { osEventFlagsSet( ads1115EventHandle, ADS1115_Event_SET_REGISTER ); my_ads1115.reg_data[0] = 0x01; // point addr 8bit 配置寄存器 my_ads1115.reg_data[1] = my_ads1115.config_H; // config_reg 高位 my_ads1115.time_ticks = osKernelGetTickCount( ); if ( HAL_I2C_Master_Transmit_IT( pADS1115_I2C, ADS1115_WRITE_ADDRESS, my_ads1115.reg_data, 3 ) != HAL_OK) { // log_e("ads1115 set register failure while reading!!!"); my_ads1115.state = ADS1115_WORK_STATE_ERROR ; } } if ( (osKernelGetTickCount() - my_ads1115.time_ticks) > 5 *1000) { my_ads1115.state = ADS1115_WORK_STATE_TIMEOUT ; } break; case ADS1115_WORK_STATE_SET_REGISTER_SUCCESS: // log_e("ads1115 set register.....succ"); osEventFlagsClear( ads1115EventHandle, ADS1115_Event_SET_REGISTER ); osEventFlagsSet( ads1115EventHandle, ADS1115_Event_READY ); my_ads1115.state = ADS1115_WORK_STATE_SET_POINT_ADDR ; break; // SET POINT ADDR case ADS1115_WORK_STATE_SET_POINT_ADDR: // log_i("ads1115 set point addr .... %d ", osEventFlagsGet( ads1115EventHandle)); if ( osEventFlagsGet( ads1115EventHandle) == 0 ) { osEventFlagsSet( ads1115EventHandle, ADS1115_Event_SET_POINT_ADDR ); my_ads1115.time_ticks = osKernelGetTickCount( ); if ( HAL_I2C_Master_Transmit_IT(pADS1115_I2C, ADS1115_WRITE_ADDRESS, 0x00, 1 ) != HAL_OK ) { // log_e("ads1115 set register failure while reading!!!"); my_ads1115.state = ADS1115_WORK_STATE_ERROR ; } } if ( (osKernelGetTickCount() - my_ads1115.time_ticks) > 5 *1000 ) { my_ads1115.state = ADS1115_WORK_STATE_TIMEOUT ; } break; case ADS1115_WORK_STATE_SET_POINT_ADDR_SUCCESS: // log_e("ads1115 set point addr.....succ"); osEventFlagsClear( ads1115EventHandle, ADS1115_Event_SET_POINT_ADDR ); osEventFlagsSet( ads1115EventHandle, ADS1115_Event_READY ); my_ads1115.state = ADS1115_WORK_STATE_RCV_DATA ; break; // RCV DATA case ADS1115_WORK_STATE_RCV_DATA: // log_i("ads1115 rcv data .... %d ", osEventFlagsGet( ads1115EventHandle)); if ( osEventFlagsGet( ads1115EventHandle) == 0 ) { // log_e("ads1115 set rcv data *** ....."); my_ads1115.time_ticks = osKernelGetTickCount( ); osEventFlagsSet( ads1115EventHandle, ADS1115_Event_RCV_DATA ); if ( HAL_I2C_Master_Receive_IT( pADS1115_I2C, ADS1115_READ_ADDRESS, my_ads1115.result , 2 ) != HAL_OK ) { // log_e("ads1115 set register failure while reading!!!"); my_ads1115.state = ADS1115_WORK_STATE_ERROR ; } } if ( (osKernelGetTickCount() - my_ads1115.time_ticks) > 5 *1000 ) { my_ads1115.state = ADS1115_WORK_STATE_TIMEOUT ; } break; case ADS1115_WORK_STATE_RCV_DATA_SUCCESS: // log_w("ads1115 rcv data .....succ result : %d ", my_ads1115.result ); osEventFlagsClear( ads1115EventHandle, ADS1115_Event_RCV_DATA ); osEventFlagsSet( ads1115EventHandle, ADS1115_Event_READY ); my_ads1115.state = ADS1115_WORK_STATE_DATA_OK ; // log_i( "ad val : %d ", 256*my_ads1115.result[0] +my_ads1115.result[1] ); break; case ADS1115_WORK_STATE_DATA_OK: osDelay(20); break; case ADS1115_WORK_STATE_ERROR: log_e("ads1115 error!!!"); break; case ADS1115_WORK_STATE_TIMEOUT: log_e("ads1115 timeout!!!"); break; case ADS1115_WORK_STATE_STOP: break; default: break; } 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 ; my_ads1115.reg_data[0] = 0x01; // point addr 8bit 配置寄存器 0x01 my_ads1115.reg_data[1] = my_ads1115.config_H; // config_reg 高位 my_ads1115.reg_data[2] = my_ads1115.config_L; // config_reg 低位 ads1115_set_state( ADS1115_WORK_STATE_INIT ); // osEventFlagsSet ( ads1115EventHandle, ADS1115_Event_INIT ); // if (HAL_I2C_Master_Transmit_IT(pADS1115_I2C, ADS1115_WRITE_ADDRESS, my_ads1115.reg_data, 3 ) != HAL_OK) // { // return -1; // } return 0; } int ads1115_test() { return 0; } void ads1115_start( ) // set register开始测量 { osEventFlagsSet( ads1115EventHandle, ADS1115_Event_READY ); ads1115_set_state( ADS1115_WORK_STATE_SET_REGISTER ); } void ads1115_stop( ) // 结束测量 等待 { ads1115_set_state( ADS1115_WORK_STATE_WAITING ); } int ads1115_setup(ADS1115_REG_CONFIG_MUX_Diff_TypeDef mux) { my_ads1115.config_mux &= mux; my_ads1115.config_H =my_ads1115.config_os|my_ads1115.config_mux |my_ads1115.config_PGA|my_ads1115.config_MODE; my_ads1115.reg_data[1] = my_ads1115.config_H; return 0; } void ads1115_set_event_flags(ADS1115_Event_TypeDef evt) { osEventFlagsSet ( ads1115EventHandle, evt ); } void ads1115_set_state(ADS1115_WORK_STATE_TypeDef state) { my_ads1115.state = state; } 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) // while ( HAL_I2C_Master_Transmit_IT(pADS1115_I2C, ADS1115_WRITE_ADDRESS, 0x00, 1 ) != 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) while ( HAL_I2C_Master_Receive_IT(pADS1115_I2C, ADS1115_READ_ADDRESS, rx_data, 2 ) != 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 ); ad_val = my_ads1115.result[0] * 256 + my_ads1115.result[1]; 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); } uint16_t ADS1115_Get_Coeff_BY_128( ) { uint16_t val; switch ((0x0E & my_ads1115.config_H) >> 1) // 量程对应的分辨率 { case (0x00): val = (int)( 187.5 * 128.0); // break; case (0x01): val = (int)( 125.5 * 128.0); break; case (0x02): val = (int)( 62.5 * 128.0); break; case (0x03): val = (int)( 31.25 * 128.0); break; case (0x04): val = (int)( 15.625 * 128.0); break; case (0x05): val = (int)( 7.8125 * 128.0); break; } return val; } double ADS1115_Get_Voltage_From_U16( uint16_t voltage) { double val; if ( ( voltage == 0x7FFF) | (voltage == 0X8000)) // 是否超量程了 { voltage = 0; // printf("over PGA\r\n"); } switch ((0x0E & my_ads1115.config_H) >> 1) // 量程对应的分辨率 { case (0x00): val = (double)voltage * 187.5 / 1000.0; // break; case (0x01): val = (double)voltage * 125 / 1000.0; break; case (0x02): val = (double)voltage * 62.5 / 1000.0; break; case (0x03): val = (double)voltage * 31.25 / 1000.0; break; case (0x04): val = (double)voltage * 15.625 / 1000.0; break; case (0x05): val = (double)voltage * 7.8125 / 1000.0; break; } return val; } //主机模式发送回调函数 void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *I2cHandle) { if (I2cHandle == pADS1115_I2C) { log_i("ads1115 send cplt..."); if ( my_ads1115.state == ADS1115_WORK_STATE_INIT ) { my_ads1115.state = ADS1115_WORK_STATE_INIT_SUCCESS; // osEventFlagsSet( ads1115EventHandle, ADS1115_Event_INIT_SUCCESS ); // osEventFlagsClear( ads1115EventHandle, ADS1115_Event_INIT ); } if ( my_ads1115.state == ADS1115_WORK_STATE_SET_REGISTER ) { my_ads1115.state = ADS1115_WORK_STATE_SET_REGISTER_SUCCESS; // osEventFlagsSet( ads1115EventHandle, ADS1115_Event_SET_REGISTER_SUCCESS ); } if ( my_ads1115.state == ADS1115_WORK_STATE_SET_POINT_ADDR ) { my_ads1115.state = ADS1115_WORK_STATE_SET_POINT_ADDR_SUCCESS; // osEventFlagsSet( ads1115EventHandle, ADS1115_Event_TRANS_SUCCESS ); } } } //主机模式接收回调函数 void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *I2cHandle) { if (I2cHandle == pADS1115_I2C) { log_i("ads1115 rcv cplt..."); if ( my_ads1115.state == ADS1115_WORK_STATE_RCV_DATA ) { my_ads1115.state = ADS1115_WORK_STATE_RCV_DATA_SUCCESS; // osEventFlagsSet( ads1115EventHandle, ADS1115_Event_RCV_DATA_SUCCESS ); } } } // int ads1115_test() // { // log_i( "ads1115_test -> " ); // uint32_t flag; // flag = osEventFlagsWait ( ads1115EventHandle, // ADS1115_Event_READY|ADS1115_Event_INIT|ADS1115_Event_SET_REGISTER|ADS1115_Event_SET_POINT_ADDR|ADS1115_Event_RCV_DATA, // 0, // 10); // log_i( "flag -> %d ", flag ); // log_i( " -> %d ", osEventFlagsGet( ads1115EventHandle) ); // osEventFlagsSet( ads1115EventHandle, ADS1115_Event_READY ) ; // log_i( " ready -> %d ", osEventFlagsGet( ads1115EventHandle) ); // osEventFlagsSet( ads1115EventHandle, ADS1115_Event_INIT ) ; // log_i( " init -> %d ", osEventFlagsGet( ads1115EventHandle) ); // osEventFlagsSet( ads1115EventHandle, ADS1115_Event_RCV_DATA ) ; // log_i( " set register -> %d ", osEventFlagsGet( ads1115EventHandle) ); // osEventFlagsSet( ads1115EventHandle, ADS1115_Event_SET_REGISTER ) ; // osEventFlagsSet( ads1115EventHandle, ADS1115_Event_SET_POINT_ADDR ) ; // log_i( " set register -> %d ", osEventFlagsGet( ads1115EventHandle) ); // osEventFlagsClear( ads1115EventHandle, ADS1115_Event_SET_POINT_ADDR ) ; // log_i( " clear -> %d ", osEventFlagsGet( ads1115EventHandle) ); // flag = osEventFlagsWait ( ads1115EventHandle, // ADS1115_Event_READY|ADS1115_Event_INIT|ADS1115_Event_SET_REGISTER|ADS1115_Event_SET_POINT_ADDR|ADS1115_Event_RCV_DATA, // 0, // 10); // log_i( "flag 2 -> %d ", flag ); // if (flag&ADS1115_Event_SET_POINT_ADDR == 0) // { // log_i("get ...... "); // }else{ // log_i(" not get ... "); // } // return 0; // }