You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
475 lines
15 KiB
475 lines
15 KiB
// 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"
|
|
};
|
|
|
|
|
|
I2C_HELPER_TypeDef *ads1115_i2c_helper;
|
|
|
|
// uint16_t resultbuf[1] = {0};
|
|
// double result_double = 0;
|
|
|
|
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,
|
|
0,
|
|
0,
|
|
{ 0, 0, 0 },
|
|
ADS1115_OUTPUT_UNIT_mv, // 默认输出毫伏
|
|
0,
|
|
0.0, // coeff 放大1000
|
|
0.0, // voltage——mv
|
|
ADS1115_WORK_STATE_WAITING,
|
|
0,
|
|
};
|
|
|
|
void ads1115_task(void)
|
|
{
|
|
uint8_t rx_data[2] = {0};
|
|
my_ads1115.event_flag = 0;
|
|
uint64_t ticks;
|
|
int err_con = 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_TEST:
|
|
log_e( " ADS1115 test ********** %d" ,pADS1115_I2C->State );
|
|
ads1115_get_reg_data( );
|
|
|
|
I2C_HELPER_Set_mem_addr( ads1115_i2c_helper, 0x01 );
|
|
st = I2C_HELPER_Trans( ads1115_i2c_helper, my_ads1115.reg_data, 2 );
|
|
if ( st != HAL_OK)
|
|
{
|
|
log_w( " ADS1115 init ********** trans error " );
|
|
my_ads1115.state = ADS1115_WORK_STATE_ERROR;;
|
|
break;
|
|
}
|
|
ticks = osKernelGetTickCount();
|
|
err_con = 0;
|
|
my_ads1115.state = ADS1115_WORK_STATE_TESTING;
|
|
continue;
|
|
case ADS1115_WORK_STATE_TESTING:
|
|
if ( osKernelGetTickCount() - ticks > 1000 )
|
|
{
|
|
err_con++;
|
|
if( err_con >3)
|
|
{
|
|
log_w( " ADS1115 testing ******** error " );
|
|
my_ads1115.state = ADS1115_WORK_STATE_ERROR;
|
|
}
|
|
my_ads1115.state = ADS1115_WORK_STATE_TEST;
|
|
}
|
|
osDelay(1);
|
|
continue;
|
|
case ADS1115_WORK_STATE_TEST_OK:
|
|
log_w( " ADS1115 TEST_OK ********** %d" ,pADS1115_I2C->State );
|
|
my_ads1115.state = ADS1115_WORK_STATE_GET_DATA_READY;
|
|
// TODO Stop DMA
|
|
continue;
|
|
|
|
case ADS1115_WORK_STATE_GET_DATA_READY:
|
|
osDelay(1);
|
|
continue;
|
|
|
|
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 ;
|
|
ads1115_get_reg_data( );
|
|
ads1115_get_coeff( );
|
|
my_ads1115.state = ADS1115_WORK_STATE_GET_DATA_SET_REG01;
|
|
continue;
|
|
case ADS1115_WORK_STATE_GET_DATA_SET_REG01:
|
|
I2C_HELPER_Set_mem_addr( ads1115_i2c_helper, 0x01 );
|
|
st = I2C_HELPER_Trans( ads1115_i2c_helper, my_ads1115.reg_data, 2 );
|
|
if ( st != HAL_OK)
|
|
{
|
|
log_w( " ADS1115 init ********** trans error " );
|
|
my_ads1115.state = ADS1115_WORK_STATE_ERROR;;
|
|
break;
|
|
}
|
|
ticks = osKernelGetTickCount();
|
|
err_con = 0;
|
|
my_ads1115.state = ADS1115_WORK_STATE_GET_DATA_SET_REG01_Wait;
|
|
continue;
|
|
case ADS1115_WORK_STATE_GET_DATA_SET_REG01_Wait:
|
|
if ( osKernelGetTickCount() - ticks > 1000 )
|
|
{
|
|
err_con++;
|
|
if( err_con >3)
|
|
{
|
|
log_w( " ADS1115 set reg ******** error " );
|
|
my_ads1115.state = ADS1115_WORK_STATE_ERROR;
|
|
}
|
|
my_ads1115.state = ADS1115_WORK_STATE_GET_DATA_START;
|
|
}
|
|
osDelay(1);
|
|
continue;
|
|
case ADS1115_WORK_STATE_GET_DATA_RCV:
|
|
log_i( " ADS1115 Ready ********** _DATA_RCV " );
|
|
memset( rx_data,0,2);
|
|
I2C_HELPER_Set_mem_addr(ads1115_i2c_helper, 0x00);
|
|
st = I2C_HELPER_Start_Rcv(ads1115_i2c_helper, rx_data, 2);
|
|
if ( st != HAL_OK)
|
|
{
|
|
log_w( " ADS1115 init ********** trans error " );
|
|
my_ads1115.state = ADS1115_WORK_STATE_ERROR;;
|
|
break;
|
|
}
|
|
ticks = osKernelGetTickCount();
|
|
err_con = 0;
|
|
my_ads1115.state = ADS1115_WORK_STATE_GET_DATA_RCV_Wait;
|
|
continue;
|
|
case ADS1115_WORK_STATE_GET_DATA_RCV_Wait:
|
|
if ( osKernelGetTickCount() - ticks > 1000 )
|
|
{
|
|
err_con++;
|
|
if( err_con >3)
|
|
{
|
|
log_w( " ADS1115 data rcv ******** error " );
|
|
my_ads1115.state = ADS1115_WORK_STATE_ERROR;
|
|
}
|
|
my_ads1115.state = ADS1115_WORK_STATE_GET_DATA_START;
|
|
}
|
|
osDelay(1);
|
|
continue;
|
|
case ADS1115_WORK_STATE_GET_DATA_OK:
|
|
log_i( " ADS1115 ********** DATA_OK %d" ,my_ads1115.result_int16 );
|
|
double val;
|
|
my_ads1115.result_int16 = rx_data[0] * 256 + rx_data[1];
|
|
if ( (my_ads1115.result_int16 == 0x7FFF) | (my_ads1115.result_int16 == 0X8000)) // 是否超量程了
|
|
{
|
|
my_ads1115.result_int16 = 0;
|
|
}
|
|
my_ads1115.voltage_mv = ((double)my_ads1115.result_int16 *(double) my_ads1115.coeff)/1000.0;;
|
|
log_i( " voltage mv : %06f",my_ads1115.voltage_mv);
|
|
my_ads1115.state = ADS1115_WORK_STATE_STOP ;
|
|
break;
|
|
case ADS1115_WORK_STATE_ERROR:
|
|
log_w( " ADS1115 error ..... " );
|
|
// my_ads1115.state = ADS1115_WORK_STATE_WAITING ;
|
|
osDelay(10);
|
|
continue;
|
|
case ADS1115_WORK_STATE_STOP:
|
|
log_w( " ADS1115 stop..... " );
|
|
// my_ads1115.state = ADS1115_WORK_STATE_WAITING ;
|
|
osDelay(10);
|
|
continue;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
osDelay(200);
|
|
}
|
|
}
|
|
|
|
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)
|
|
{
|
|
ads1115_i2c_helper = I2C_HELPER_Init( );
|
|
I2C_HELPER_Set_Hi2c( ads1115_i2c_helper, pADS1115_I2C );
|
|
I2C_HELPER_Set_dev_addr( ads1115_i2c_helper, ADS1115_WRITE_ADDRESS);
|
|
I2C_HELPER_Set_mem_addr_size( ads1115_i2c_helper, I2C_MEMADD_SIZE_8BIT ); //I2C_MEMADD_SIZE_16BIT
|
|
// I2C_HELPER_Set_mem_addr(ads1115_i2c_helper, uint16_t mem_addr);
|
|
|
|
I2C_HELPER_Setup_Trans_mode( ads1115_i2c_helper, I2C_Trans_IT );
|
|
|
|
// 设置回调
|
|
I2C_HELPER_Set_Callback( ads1115_i2c_helper, (void *)&my_ads1115, (i2c_callback_fun) ads1115_callback);
|
|
|
|
// ads1115_get_reg_data( );
|
|
// // polling mode test, cfg register : 0x01
|
|
// int st = 0;
|
|
// st = HAL_I2C_Mem_Write( ads1115_i2c_helper->hi2c, ADS1115_WRITE_ADDRESS, 0x01,
|
|
// ads1115_i2c_helper->mem_addr_size, my_ads1115.reg_data, 2, 0xFFFF );
|
|
|
|
// if (st != HAL_OK)
|
|
// {
|
|
// return -1;
|
|
// }
|
|
return 0;
|
|
}
|
|
|
|
int ads1115_test(void)
|
|
{
|
|
my_ads1115.state = ADS1115_WORK_STATE_TEST;
|
|
}
|
|
|
|
void ads1115_start(void)
|
|
{
|
|
my_ads1115.state =ADS1115_WORK_STATE_GET_DATA_START;
|
|
// osEventFlagsSet( ads1115TaskHandle, ADS1115_Event_Get_Data );
|
|
}
|
|
|
|
void ads1115_stop(void)
|
|
{
|
|
}
|
|
|
|
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_coeff( )
|
|
{
|
|
my_ads1115.coeff = 1.0;
|
|
switch ((0x0E & my_ads1115.config_H) >> 1) // 量程对应的分辨率
|
|
{
|
|
case (0x00):
|
|
my_ads1115.coeff =my_ads1115.coeff * 187.5 ; //
|
|
break;
|
|
case (0x01):
|
|
my_ads1115.coeff = my_ads1115.coeff * 125 ;
|
|
break;
|
|
case (0x02):
|
|
my_ads1115.coeff = my_ads1115.coeff * 62.5;
|
|
break;
|
|
case (0x03):
|
|
my_ads1115.coeff = my_ads1115.coeff * 31.25 ;
|
|
break;
|
|
case (0x04):
|
|
my_ads1115.coeff = my_ads1115.coeff * 15.625;
|
|
break;
|
|
case (0x05):
|
|
my_ads1115.coeff = my_ads1115.coeff * 7.8125;
|
|
break;
|
|
}
|
|
}
|
|
|
|
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");
|
|
}
|
|
ads1115_get_coeff( );
|
|
val = ad_val * my_ads1115.coeff/1000.0;
|
|
|
|
if (my_ads1115.unit == ADS1115_OUTPUT_UNIT_v)
|
|
{
|
|
val = val/1000.0;
|
|
}
|
|
return val;
|
|
}
|
|
|
|
|
|
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 ads1115_callback(ADS1115_TypeDef *pAds1115, uint8_t *buf, uint16_t size)
|
|
{
|
|
switch (my_ads1115.state)
|
|
{
|
|
case ADS1115_WORK_STATE_TESTING :
|
|
my_ads1115.state++;
|
|
break;
|
|
case ADS1115_WORK_STATE_GET_DATA_SET_REG01_Wait :
|
|
my_ads1115.state++;
|
|
break;
|
|
case ADS1115_WORK_STATE_GET_DATA_RCV_Wait :
|
|
// TODO Check data?
|
|
my_ads1115.state++;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
// 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); /* 指定超时事件,无限等待 */
|
|
// TODO 阻塞式 仅init 使用
|
|
// my_ads1115.state = ADS1115_WORK_STATE_INIT;
|
|
// osEventFlagsSet ( ads1115TaskHandle, ADS1115_Event_INIT );
|
|
|
|
// I2C_HELPER_Set_mem_addr(ads1115_i2c_helper, 0x01);
|
|
// st = I2C_HELPER_Trans(ads1115_i2c_helper, reg_data,2);
|
|
|
|
// I2C_HELPER_Set_mem_addr(ads1115_i2c_helper, 0x00);
|
|
// st = I2C_HELPER_Start_Rcv(ads1115_i2c_helper, rx_data, 2);
|
|
|
|
|
|
|
|
|
|
|
|
// st = HAL_I2C_Mem_Write(ads1115_i2c_helper->hi2c, ads1115_i2c_helper->dev_addr, my_ads1115.reg_data[0],ads1115_i2c_helper->mem_addr_type , reg_data,2,0xFFFF);
|
|
// if (HAL_I2C_Master_Transmit(pADS1115_I2C, ADS1115_WRITE_ADDRESS, my_ads1115.reg_data, 3,1000 ) != HAL_OK)
|
|
// {
|
|
// return -1;
|
|
// }
|
|
// 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");
|
|
// }
|
|
// }
|
|
|
|
|
|
|
|
|
|
// 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;
|