// Read data from eeprom. BOOL I2C_ReadNByte(BYTE DevAddr, WORD Addr, BYTE* Buf, BYTE Len, BYTE I2cDevice) { BOOL Ack = FALSE; #if (defined(FUNC_BREAK_POINT_EN) && (FUNC_RESTORE_DEVICE_SELECE == FUNC_RESTORE_DEVICE_EEPROM)) if(((gSys.SystemMode == SYS_MODE_USB) || (gSys.SystemMode == SYS_MODE_SD)) && (I2cDevice == EEPROM_IIC)) { #if (I2C_PIN_CONFIGURE == SDIO_TO_A3A4A5) SET_CARD_TO_A3A4A5(); #if defined(SD_DETECT_PIN_USE_A4) ClrGpioRegBit(CARD_DETECT_PORT_PD, CARD_DETECT_BIT); #endif #endif //写E2PROM时快速响应需要读卡时需要重新将复用IO设置回总线模式 SongPlayDo(); #if (I2C_PIN_CONFIGURE == SDIO_TO_A3A4A5) #if defined(SD_DETECT_PIN_USE_A4) SetGpioRegBit(CARD_DETECT_PORT_PD, CARD_DETECT_BIT); #endif SET_CARD_NOT_TO_GPIO(); #endif } #endif Ack = I2C_SendAddr(DevAddr, Addr, IIC_READ, I2cDevice); if(Ack == TRUE) { Ack = I2C_ReadBytes(Buf, Len, I2cDevice); } I2C_Stop(I2cDevice); return Ack; }
I2C_Status AccelerometerRegRead(uint8_t reg, uint8_t* val) { I2C_Status retVal = I2C_OK; do { I2C_Start(ALB_I2C, LIS2DH_ADDR, 0); retVal = I2C_WriteByte(ALB_I2C, reg); if(retVal != I2C_OK) { break; } retVal = I2C_WaitForTX(ALB_I2C); if(retVal != I2C_OK) { break; } I2C_Start(ALB_I2C, LIS2DH_ADDR, 1); if((retVal = I2C_ReadBytes(ALB_I2C, val, 1)) != I2C_OK) { break; } I2C_Stop(ALB_I2C); } while(0); return retVal; }
I2C_Status PressureSensorRegRead(uint8_t reg, uint8_t* val) { I2C_Status retVal = I2C_OK; do { I2C_Start(ALB_I2C, MPL311_ADDR, 0); retVal = I2C_WriteByte(ALB_I2C, reg); if(retVal != I2C_OK) { break; } retVal = I2C_WaitForTX(ALB_I2C); if(retVal != I2C_OK) { break; } I2C_Start(ALB_I2C, MPL311_ADDR, 1); if((retVal = I2C_ReadBytes(ALB_I2C, val, 1)) != I2C_OK) { break; } I2C_Stop(ALB_I2C); } while(0); return retVal; }
// Read the altimeter. This function will // block the calling task until the entire sensor read has been completed I2C_Status ReadPressureSensor(uint32_t* altOut) { I2C_Status retVal = I2C_OK; uint32_t temp = 0; taskENTER_CRITICAL(); do { retVal = PressureSensorRegWrite(MPL3115A2_CTRL_REG1, MPL3115A2_CTRL_REG1_SBYB | MPL3115A2_CTRL_REG1_OS128 | MPL3115A2_CTRL_REG1_ALT); if(retVal != I2C_OK) { break; } uint8_t sta = 0; while (! (sta & MPL3115A2_REGISTER_STATUS_PDR)) { retVal = PressureSensorRegRead(MPL3115A2_REGISTER_STATUS, &sta); // TODO: a delay here would be nice to prevent slamming the I2C bus } I2C_Start(ALB_I2C, MPL311_ADDR, 0); retVal = I2C_WriteByte(ALB_I2C, MPL3115A2_REGISTER_PRESSURE_MSB); if(retVal != I2C_OK) { break; } retVal = I2C_WaitForTX(ALB_I2C); if(retVal != I2C_OK) { break; } I2C_Start(ALB_I2C, MPL311_ADDR, 1); if((retVal = I2C_ReadBytes(ALB_I2C, i2cRxBuffer, 3)) != I2C_OK) { break; } I2C_Stop(ALB_I2C); // Process returned data temp = i2cRxBuffer[0] << 24; temp |= i2cRxBuffer[1] << 16; temp |= i2cRxBuffer[2] << 8; *altOut = temp; } while(0); taskEXIT_CRITICAL(); return retVal; }
/** * @ Opis Pobiera wartosc UP z rejestru czujnika. * @ Parametry Brak. * @ Zwracana wartosc Surowa wartosc pomiaru cisnienia (UT). */ int32_t BMP180_GetUP() { int32_t UP = 0; uint8_t OSS = ((BMP180_Struct.BMP180_Mode) & 0xC0) >> 6; uint8_t buffer[3]; I2C_ReadBytes(BMP180_SLA, BMP180_ADC_MSB_REG, 3, buffer); UP = ((((int32_t) buffer[0]) << 16) | (((int32_t) buffer[1]) << 8) | (((int32_t) buffer[2]))) >> (8 - OSS); return UP; }
/** * @ Opis Pobiera wartosc UT z rejestru czujnika. * @ Parametry Brak. * @ Zwracana wartosc Surowa wartosc pomiaru temperatury (UT). */ int32_t BMP180_GetUT() { int32_t UT = 0; uint8_t buffer[2]; I2C_ReadBytes(BMP180_SLA, BMP180_ADC_MSB_REG, 2, buffer); //BMP180_Struct.UT = 0; BMP180_Struct.UT = (((int32_t) buffer[0]) << 8) | ((int32_t) buffer[1]); return UT; }
I2C_Status InitTempSensor(uint8_t index) { I2C_Status retVal = I2C_OK; // Write the config values into the TX buffer i2cTxBuffer[0] = TMP102_CONFIG_1_VAL; i2cTxBuffer[1] = TMP102_CONFIG_2_VAL; taskENTER_CRITICAL(); // TODO: log something if the sensor fails to initialize do { // I2C Write I2C_Start(SLB_I2C, GetTmp102Addr(index), 0); retVal = I2C_WriteByte(SLB_I2C, TMP102_CONFIG_ADDR); if(retVal != I2C_OK) { break; } retVal = I2C_WaitForTX(SLB_I2C); if(retVal != I2C_OK) { break; } I2C_Stop(SLB_I2C); // I2C Write I2C_Start(SLB_I2C, GetTmp102Addr(index), 0); retVal = I2C_WriteBytes(SLB_I2C, i2cTxBuffer, 2); if(retVal != I2C_OK) { break; } retVal = I2C_WaitForTX(SLB_I2C); if(retVal != I2C_OK) { break; } I2C_Stop(SLB_I2C); // I2C Read I2C_Start(SLB_I2C, GetTmp102Addr(index), 1); if((retVal = I2C_ReadBytes(SLB_I2C, i2cRxBuffer, 2)) != I2C_OK) { break; } I2C_Stop(SLB_I2C); }while(0); taskEXIT_CRITICAL(); return retVal; }
// Send a command to the humidity sensor to start a humidity value conversion // This process takes about 15 miliseconds, and the sensor will NACK all I2C // transactions that are initiated until the conversion is complete // This function will block the OS from operating until it has completed, meaning // the SysTick timer will be out of sync by 15ms once this operation has completed. I2C_Status ReadHumiditySensor(float* humidOut) { uint16_t humidity = 0; I2C_Status retVal = I2C_OK; // This is a critical section: if the device is interrupted during an I2C transaction, it will probably fail. // Disable all interrupts during this transaction to ensure that it completes sucessfully. // NOTE: This means that the system clock will be wrong by ~15 ms (15 ticks) after this section of code is executed taskENTER_CRITICAL(); // Use a do {} while(0); loop to allow the use of the "break" statement. // In C++ / Java this would be accomplished with a "try {} catch() {} finally {}" section, but C does not support this construct. do { // I2C Write I2C_Start(ALB_I2C, HTU21D_ADDR, 0); retVal = I2C_WriteByte(ALB_I2C, HTU21D_HUMID_MEAS_HOLD); if(retVal != I2C_OK) { break; } retVal = I2C_WaitForTX(ALB_I2C); if(retVal != I2C_OK) { break; } // I2C Read I2C_Start(ALB_I2C, HTU21D_ADDR, 1); retVal = I2C_ReadBytes(ALB_I2C, i2cRxBuffer, 3); if(retVal != I2C_OK) { break; } I2C_Stop(ALB_I2C); humidity |= i2cRxBuffer[0] << 8; humidity |= i2cRxBuffer[1]; *humidOut = HTU21D_Humid_To_Float(humidity); }while(0); taskEXIT_CRITICAL(); return retVal; }
/** * @ Opis: Inicjalizuje BMP180 do pracy. * @ Parametry: BMP180Mode_TypeDef: tryb pomiaru. * @ Zwracana wartosc: Brak. */ void BMP180_Init(BMP180Mode_TypeDef BMP180_Mode) { BMP180_Struct.BMP180_Mode = BMP180_Mode; uint8_t buffer[22]; /* Pobranie parametrow kalibracyjnych */ I2C_ReadBytes(BMP180_SLA, BMP180_MEM_START, 22, buffer); /* Zapis parametrow kalibracyjnych */ BMP180_Struct.AC1 = ((short) buffer[0] << 8 | ((short) buffer[1])); BMP180_Struct.AC2 = ((short) buffer[2] << 8 | ((short) buffer[3])); BMP180_Struct.AC3 = ((short) buffer[4] << 8 | ((short) buffer[5])); BMP180_Struct.AC4 = ((unsigned int) buffer[6] << 8 | ((unsigned int) buffer[7])); BMP180_Struct.AC5 = ((unsigned int) buffer[8] << 8 | ((unsigned int) buffer[9])); BMP180_Struct.AC6 = ((unsigned int) buffer[10] << 8 | ((unsigned int) buffer[11])); BMP180_Struct.B1 = ((short) buffer[12] << 8 | ((short) buffer[13])); BMP180_Struct.B2 = ((short) buffer[14] << 8 | ((short) buffer[15])); BMP180_Struct.MB = ((short) buffer[16] << 8 | ((short) buffer[17])); BMP180_Struct.MC = ((short) buffer[18] << 8 | ((short) buffer[19])); BMP180_Struct.MD = ((short) buffer[20] << 8 | ((short) buffer[21])); }
/* ************************************************************ * 函数名称: ADXL345_GetValue * * 函数功能: 读取ADXL345的三轴加速值 * * 入口参数: 无 * * 返回参数: 无 * * 说明: 结果存放于adxl345结构体中 ************************************************************ */ void ADXL345_GetValue(void) { unsigned char devid = 0; unsigned char dataTemp[6]; IIC_SpeedCtl(5); //控制IIC速度 DelayUs(200); I2C_ReadByte(ADXL345_ADDRESS, 0x00, &devid); //读ID 且每次读写之前都需要读ID DelayUs(200); I2C_ReadBytes(ADXL345_ADDRESS, 0x32, dataTemp, 6); //读取原始加速值(4mg/LSB) adxlInfo.incidence_X = (short)(dataTemp[0] + ((unsigned short)dataTemp[1] << 8)); adxlInfo.incidence_Y = (short)(dataTemp[2] + ((unsigned short)dataTemp[3] << 8)); adxlInfo.incidence_Z = (short)(dataTemp[4] + ((unsigned short)dataTemp[5] << 8)); adxlInfo.incidence_Xf = (float)(adxlInfo.incidence_X + ofz_X) * 0.0039; //换算为g adxlInfo.incidence_Yf = (float)(adxlInfo.incidence_Y + ofz_Y) * 0.0039; //每一个LSB代表3.9mg adxlInfo.incidence_Zf = (float)(adxlInfo.incidence_Z + ofz_Z) * 0.0039; //有多少个LSB,就乘以0.0039g就得到了以g为单位的加速值 }
// Read one of the temperature sensors. This function will // block the calling task until the entire sensor read has been completed I2C_Status ReadTempSensor(uint8_t index, uint16_t* tempOut) { I2C_Status retVal = I2C_OK; uint16_t temp = 0; taskENTER_CRITICAL(); do { // Write to the i2cTxBuffer i2cTxBuffer[0] = TMP102_CONFIG_1_ONESHOT_VAL; i2cTxBuffer[1] = TMP102_CONFIG_2_VAL; // Write to the config register to begin a one-shot temperature conversion // I2C Write I2C_Start(SLB_I2C, GetTmp102Addr(index), 0); if((retVal = I2C_WriteByte(SLB_I2C, TMP102_CONFIG_ADDR)) != I2C_OK) { break; } if((retVal = I2C_WaitForTX(SLB_I2C)) != I2C_OK) { break; } I2C_Stop(SLB_I2C); // I2C Write I2C_Start(SLB_I2C, GetTmp102Addr(index), 0); if((retVal = I2C_WriteBytes(SLB_I2C, i2cTxBuffer, 2)) != I2C_OK) { break; } if((retVal = I2C_WaitForTX(SLB_I2C)) != I2C_OK) { break; } I2C_Stop(SLB_I2C); // Read the temperature registers from the sensor // I2C Write I2C_Start(SLB_I2C, GetTmp102Addr(index), 0); if((retVal = I2C_WriteByte(SLB_I2C, TMP102_TEMP_ADDR)) != I2C_OK) { break; } if((retVal = I2C_WaitForTX(SLB_I2C)) != I2C_OK) { break; } I2C_Stop(SLB_I2C); // I2C Read I2C_Start(SLB_I2C, GetTmp102Addr(index), 1); if((retVal = I2C_ReadBytes(SLB_I2C, i2cRxBuffer, 2)) != I2C_OK) { break; } I2C_Stop(SLB_I2C); // Process returned data temp = (((uint16_t)i2cRxBuffer[0]) << 4) & 0xFFF0; temp |= (((uint16_t)i2cRxBuffer[1]) >> 4) & 0x000F; *tempOut = temp; } while(0); taskEXIT_CRITICAL(); return retVal; }
int main(void) { #warning change clock hse_value to 25m SYSTIM_Init(); LEDInit(LED_ACT); LEDInit(LED_COM); LEDInit(LED_ERR); LEDOn(LED_ACT); LEDOff(LED_COM); LEDOff(LED_ERR); SYSTIM_DelayTms(1000); LEDOff(LED_ACT); // USBD_Init(&USB_OTG_dev, // USB_OTG_FS_CORE_ID, // &USR_desc, // &USBD_CDC_cb, // &USR_cb); usart_init(); UART_DMAInit(); if (!CheckXCLK()) { XCLK_ON(); SYSTIM_DelayTms(100); } #ifdef USE_MT9V034 MT9V034_Init(); #endif #ifdef USE_MT9D111 MT9D111_Init(); #endif #warning already enable i2c when init camera //mpu6050_enable(); memset(Cam_Capture,'1',FULL_IMAGE_SIZE); Cam_Capture[FULL_IMAGE_SIZE] = 's'; Cam_Capture[FULL_IMAGE_SIZE + 1] = 't'; Cam_Capture[FULL_IMAGE_SIZE + 2] = 'p'; DCMI_CaptureCmd(ENABLE); while(1) { int i=0; #ifdef TEST_MPU6050 bool res; res = I2C_ReadBytes(I2C2,data,MPU_ADDR, MPU_DATA, 14); if (!res) { LEDOn(LED_ERR); } ax = (double)(data[1] + (data[0]<<8)); ay = (double)(data[3] + (data[2]<<8)); az = (double)(data[5] + (data[4]<<8)); wx = (double)(data[9] + (data[8]<<8)); wy = (double)(data[11] + (data[10]<<8)); wz = (double)(data[13] + (data[12]<<8)); SYSTIM_DelayTms(100); #endif if (DCMI_Flag) { DCMI_Flag = 0; LEDToggle(LED_ACT); // SendImageDMA((uint32_t*)&Cam_Capture[0], FULL_IMAGE_SIZE); // for (i=0;i<FULL_IMAGE_SIZE;i++) // { // Cam_Buffer[i] = Cam_Capture[i]; // } VCP_DataTx(Cam_Capture,FULL_IMAGE_SIZE+3); SYSTIM_DelayTms(5000); DCMI_CaptureCmd(ENABLE); } } }