// Write new value to BMP180 register // input: // reg - register number // value - new register value void BMP180_WriteReg(uint8_t reg, uint8_t value) { uint8_t buf[2]; buf[0] = reg; buf[1] = value; I2Cx_Write(BMP180_I2C_PORT,&buf[0],2,BMP180_ADDR,I2C_STOP); }
// Read BMP180 register // input: // reg - register number // return: // register value uint8_t BMP180_ReadReg(uint8_t reg) { uint8_t value = 0; // Initialize value in case of I2C timeout // Send register address I2Cx_Write(BMP180_I2C_PORT,®,1,BMP180_ADDR,I2C_NOSTOP); // Read register value I2Cx_Read(BMP180_I2C_PORT,&value,1,BMP180_ADDR); return value; }
// Read calibration registers void BMP180_ReadCalibration(void) { uint8_t buffer[BMP180_PROM_DATA_LEN]; buffer[0] = BMP180_PROM_START_ADDR; I2Cx_Write(BMP180_I2C_PORT,&buffer[0],1,BMP180_ADDR,I2C_NOSTOP); // Send calibration first register address I2Cx_Read(BMP180_I2C_PORT,&buffer[0],BMP180_PROM_DATA_LEN,BMP180_ADDR); BMP180_Calibration.AC1 = (buffer[0] << 8) | buffer[1]; BMP180_Calibration.AC2 = (buffer[2] << 8) | buffer[3]; BMP180_Calibration.AC3 = (buffer[4] << 8) | buffer[5]; BMP180_Calibration.AC4 = (buffer[6] << 8) | buffer[7]; BMP180_Calibration.AC5 = (buffer[8] << 8) | buffer[9]; BMP180_Calibration.AC6 = (buffer[10] << 8) | buffer[11]; BMP180_Calibration.B1 = (buffer[12] << 8) | buffer[13]; BMP180_Calibration.B2 = (buffer[14] << 8) | buffer[15]; BMP180_Calibration.MB = (buffer[16] << 8) | buffer[17]; BMP180_Calibration.MC = (buffer[18] << 8) | buffer[19]; BMP180_Calibration.MD = (buffer[20] << 8) | buffer[21]; }
// Get uncompensated pressure value // input: // PT = pointer to uncompensated pressure value // oss - oversampling level [0..3] // return: // BMP180_ERROR if it was an I2C timeout, BMP180_SUCCESS otherwise BMP180_RESULT BMP180_Read_PT(uint32_t *PT, uint8_t oss) { uint8_t buf[3]; // Start pressure measurement BMP180_WriteReg(BMP180_CTRL_MEAS_REG,BMP_OSS[oss].OSS_cmd); Delay_ms(BMP_OSS[oss].OSS_delay); // Read pressure value buf[0] = BMP180_ADC_OUT_MSB_REG; // Send ADC MSB register address if (!I2Cx_Write(BMP180_I2C_PORT,&buf[0],1,BMP180_ADDR,I2C_NOSTOP)) { *PT = 0; return BMP180_ERROR; } // Read MSB, LSB, XLSB bytes if (I2Cx_Read(BMP180_I2C_PORT,&buf[0],3,BMP180_ADDR)) { *PT = ((buf[0] << 16) | (buf[1] << 8) | buf[0]) >> (8 - oss); return BMP180_SUCCESS; } else {
// Get uncompensated temperature value // input: // UT = pointer to uncompensated temperature value // return: // BMP180_ERROR if it was an I2C timeout, BMP180_SUCCESS otherwise BMP180_RESULT BMP180_Read_UT(uint16_t *UT) { uint8_t buf[2]; BMP180_WriteReg(BMP180_CTRL_MEAS_REG,BMP180_T_MEASURE); Delay_ms(6); // Wait for 4.5ms by datasheet buf[0] = BMP180_ADC_OUT_MSB_REG; // Send ADC MSB register address if (!I2Cx_Write(BMP180_I2C_PORT,&buf[0],1,BMP180_ADDR,I2C_NOSTOP)) { *UT = 0; return BMP180_ERROR; } // Read ADC MSB and LSB if (I2Cx_Read(BMP180_I2C_PORT,&buf[0],2,BMP180_ADDR)) { *UT = (buf[0] << 8) | buf[1]; return BMP180_SUCCESS; } else { *UT = 0; return BMP180_ERROR; } }
/** * @brief Writes a single data. * @param Addr: I2C address * @param Reg: Reg address * @param Value: Data to be written * @retval None */ void AUDIO_IO_Write(uint8_t Addr, uint8_t Reg, uint8_t Value) { I2Cx_Write(Addr, Reg, Value); }
/** * @brief IOE writes single data. * @param Addr: I2C address * @param Reg: Reg address * @param Value: Data to be written * @retval None */ void IOE_Write(uint8_t Addr, uint8_t Reg, uint8_t Value) { I2Cx_Write(Addr, Reg, Value); }
/** * @brief Camera writes single data. * @param Addr: I2C address * @param Reg: Reg address * @param Value: Data to be written * @retval None */ void CAMERA_IO_Write(uint8_t Addr, uint8_t Reg, uint8_t Value) { I2Cx_Write(Addr, Reg, Value); }
int main(void) { Delay_Init((void *)0); UARTx_Init(USART2,1382400); UART_SendStr(USART2,"--------------------------------------\n"); if (I2Cx_Init(BMC050_I2C_PORT,400000) != I2C_SUCCESS) { UART_SendStr(USART2,"I2C2 init fail\n"); while(1); } UART_SendStr(USART2,"I2C2 init at 400kHz\n"); // Enable PORTA peripheral RCC->AHBENR |= RCC_AHBENR_GPIOAEN; // Configure PA6 as external interrupt GPIOA->MODER &= ~GPIO_MODER_MODER6; // Input mode (reset state) GPIOA->PUPDR &= ~GPIO_PUPDR_PUPDR6; // No pull-up, pull-down GPIOA->PUPDR |= GPIO_PUPDR_PUPDR6_1; // Pull-down // Configure priority group: 4 bits for preemption priority, 0 bits for subpriority. NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); // Enable the SYSCFG module clock RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN; // PA6 -> EXTI line 6 (INT1 from BMC050) EXTI->PR = INT1_EXTI_LINE; // Clear IT pending bit for EXTI line EXTI->IMR |= INT1_EXTI_LINE; // Enable interrupt request from EXTI line EXTI->EMR &= ~INT1_EXTI_LINE; // Disable event on EXTI line EXTI->RTSR |= INT1_EXTI_LINE; // Trigger rising edge enabled EXTI->FTSR &= ~INT1_EXTI_LINE; // Trigger falling edge disabled // Enable the USB interrupt NVICInit.NVIC_IRQChannel = EXTI9_5_IRQn; NVICInit.NVIC_IRQChannelPreemptionPriority = 2; NVICInit.NVIC_IRQChannelSubPriority = 0; NVICInit.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVICInit); ///* uint8_t buf[2]; uint8_t reg; uint8_t val; uint32_t i; //*/ ///* reg = 0x00; val = 0; UART_SendStr(USART2,"\nAccelerometer\n"); for (reg = 0; reg <= 0x3f; reg++) { I2Cx_Write(BMC050_I2C_PORT,®,1,0x18 << 1,I2C_NOSTOP); I2Cx_Read(BMC050_I2C_PORT,&val,1,0x18 << 1); UART_SendStr(USART2,"R"); UART_SendHex8(USART2,reg); UART_SendStr(USART2," = "); UART_SendHex8(USART2,val); UART_SendStr(USART2,"\t\t"); } UART_SendChar(USART2,'\n'); //*/ /* UART_SendStr(USART2,"\nMagnetometer\n"); // Magnetometer power enable buf[0] = 0x4b; buf[1] = 0x01; // Set power control bit I2Cx_Write(BMC050_I2C_PORT,&buf[0],2,0x10 << 1,I2C_STOP); for (reg = 0x40; reg <= 0x52; reg++) { I2Cx_Write(BMC050_I2C_PORT,®,1,0x10 << 1,I2C_NOSTOP); I2Cx_Read(BMC050_I2C_PORT,&val,1,0x10 << 1); UART_SendStr(USART2,"R"); UART_SendHex8(USART2,reg); UART_SendStr(USART2," = "); UART_SendHex8(USART2,val); UART_SendStr(USART2,"\t\t"); } UART_SendStr(USART2,"\n========================================\n"); */ BMC050_ACC_SoftReset(); Delay_ms(5); // must wait for start-up time of accelerometer (2ms) BMC050_Init(); // Enable I2C watchdog timer with 50ms BMC050_ACC_InterfaceConfig(ACC_IF_WDT_50ms); UART_SendStr(USART2,"BMC050 ACC device ID: "); UART_SendHex8(USART2,BMC050_ACC_GetDeviceID()); UART_SendChar(USART2,'\n'); UART_SendStr(USART2,"BMC050 MAG device ID: "); UART_SendHex8(USART2,BMC050_MAG_GetDeviceID()); UART_SendChar(USART2,'\n'); UART_SendStr(USART2,"BMC050 temperature: "); temp = BMC050_ReadTemp(); UART_SendInt(USART2,temp / 10); UART_SendChar(USART2,'.'); UART_SendInt(USART2,temp % 10); UART_SendStr(USART2,"C\n"); BMC050_ACC_SetBandwidth(ACC_BW8); // Accelerometer readings filtering (lower or higher better?) BMC050_ACC_SetIRQMode(ACC_IM_NOLATCH); // No IRQ latching BMC050_ACC_ConfigSlopeIRQ(0,16); // Motion detection sensitivity BMC050_ACC_IntPinMap(ACC_IM1_SLOPE); // Map slope interrupt to INT1 pin BMC050_ACC_SetIRQ(ACC_IE_SLOPEX | ACC_IE_SLOPEY | ACC_IE_SLOPEZ); // Detect motion by all axes BMC050_ACC_LowPower(ACC_SLEEP_100); // Low power with sleep duration 0.1s // BMC050_ACC_Suspend(); while(1); /* while(1) { while (!BMC050_ACC_GetIRQStatus()); // Wait for new data from accelerometer i8 = BMC050_ACC_GetTSIRQ(); BMC050_ACC_GetXYZ(&X,&Y,&Z); UART_SendStr(USART2,"Slope="); UART_SendHex8(USART2,i8); UART_SendChar(USART2,' '); if (i8 & ACC_TS_SLOPEZ) UART_SendStr(USART2,"SLOPEZ "); if (i8 & ACC_TS_SLOPEY) UART_SendStr(USART2,"SLOPEY "); if (i8 & ACC_TS_SLOPEX) UART_SendStr(USART2,"SLOPEX "); UART_SendStr(USART2," X="); UART_SendInt(USART2,X); UART_SendStr(USART2," Y="); UART_SendInt(USART2,Y); UART_SendStr(USART2," Z="); UART_SendInt(USART2,Z); UART_SendChar(USART2,'\n'); BMC050_ACC_SetIRQMode(ACC_IM_RESET); Delay_ms(100); } */ }