---
# System prepended metadata

title: I2C code

---

# 功能與程式
主函式
```c=
int main(void)
{
	
	RETARGET_Configuration();	
  I2CMaster_Configuration();

	Who_Am_I_Value = MPU6500_I2C_Read_OneByte(0x75);
	printf("Who am I Value : %02x\r\n", Who_Am_I_Value); 
	while(!(Who_Am_I_Value ==  0x70));
	
	Set_Acc_Scale_Select(mpu6500_range_2G);
	Show_Acc_Scale_Select();
  while (1){
	
		Acc_Raw_Value[0] = Get_HL_Value(AccXH_Reg , AccXL_Reg);
		Acc_Raw_Value[1] = Get_HL_Value(AccYH_Reg , AccYL_Reg);
		Acc_Raw_Value[2] = Get_HL_Value(AccZH_Reg , AccZL_Reg);
		
		printf("Acc%c --> Raw_Value_DEC: %05d , Raw_Value_HEX: %04x , Acc_Scale: %f\r\n",
							Axis[0], Acc_Raw_Value[0], Acc_Raw_Value[0], Acc_Scale(Acc_Raw_Value[0]));
		printf("Acc%c --> Raw_Value_DEC: %05d , Raw_Value_HEX: %04x , Acc_Scale: %f\r\n",
							Axis[1], Acc_Raw_Value[1], Acc_Raw_Value[1], Acc_Scale(Acc_Raw_Value[1]));
		printf("Acc%c --> Raw_Value_DEC: %05d , Raw_Value_HEX: %04x , Acc_Scale: %f\r\n",
							Axis[2], Acc_Raw_Value[2], Acc_Raw_Value[2], Acc_Scale(Acc_Raw_Value[2]));

		printf("\r\n");
		
		for(i=0 ; i<0xFFFFF ; i++);
	}
}
```
I2C設定
```c=
void I2CMaster_Configuration(void)
{
	I2C_InitTypeDef  I2C_InitStructure;
  CKCU_PeripClockConfig_TypeDef CKCUClock = {{0}};
	

CKCUClock.Bit.I2C0 = 1;
CKCUClock.Bit.AFIO = 1;
CKCUClock.Bit.PB   = 1;
CKCU_PeripClockConfig(CKCUClock, ENABLE);
 
AFIO_GPxConfig(GPIO_PB, AFIO_PIN_0, AFIO_MODE_7);
AFIO_GPxConfig(GPIO_PB, AFIO_PIN_1, AFIO_MODE_7);
	
GPIO_PullResistorConfig(HT_GPIOB, GPIO_PIN_0, GPIO_PR_UP);
GPIO_PullResistorConfig(HT_GPIOB, GPIO_PIN_1, GPIO_PR_UP);
	
	
  
  I2C_InitStructure.I2C_GeneralCall = DISABLE;
  I2C_InitStructure.I2C_AddressingMode = I2C_ADDRESSING_7BIT;
  I2C_InitStructure.I2C_Acknowledge = DISABLE;
  I2C_InitStructure.I2C_OwnAddress = I2C_MASTER_ADDRESS;
  I2C_InitStructure.I2C_Speed = ClockSpeed;
  I2C_InitStructure.I2C_SpeedOffset = 0;
  I2C_Init(HT_I2C0, &I2C_InitStructure);
  
	
  I2C_Cmd(HT_I2C0, ENABLE);
}
```
#### 根據MPU Datasheet 設置參數
1. 讀取資料

```c=
u8 MPU6500_I2C_Read_OneByte(u8 reg_addr)
{
	u8 receive_data = 0;
	
	
  while (I2C_ReadRegister(HT_I2C0, I2C_REGISTER_SR)&0x80000);
	
  I2C_AckCmd(HT_I2C0, ENABLE);
	
  I2C_TargetAddressConfig(HT_I2C0, I2C_SLAVE_ADDRESS, I2C_MASTER_WRITE);
	
  while (!I2C_CheckStatus(HT_I2C0, I2C_MASTER_SEND_START));

  while (!I2C_CheckStatus(HT_I2C0, I2C_MASTER_TRANSMITTER_MODE));
	
  while (!I2C_CheckStatus(HT_I2C0, I2C_MASTER_TX_EMPTY));
	
	I2C_SendData(HT_I2C0, reg_addr); 
	
	I2C_TargetAddressConfig(HT_I2C0, I2C_SLAVE_ADDRESS, I2C_MASTER_READ);
	
  while (!I2C_CheckStatus(HT_I2C0, I2C_MASTER_SEND_START));
	
  while (!I2C_CheckStatus(HT_I2C0, I2C_MASTER_RECEIVER_MODE));
	
  I2C_AckCmd(HT_I2C0, DISABLE);
	
	while (!I2C_CheckStatus(HT_I2C0, I2C_MASTER_RX_NOT_EMPTY));
	
	receive_data = I2C_ReceiveData(HT_I2C0);
	
	I2C_GenerateSTOP(HT_I2C0);
	return receive_data;
}

```
2. 寫出資料
```c=
void MPU6500_I2C_Write_OneByte(u8 reg_addr, u8 register_value)
{
	
	while (I2C_ReadRegister(HT_I2C0,  I2C_REGISTER_SR)&0x80000);
	
	I2C_AckCmd(HT_I2C0, ENABLE);
	
  I2C_TargetAddressConfig(HT_I2C0,  I2C_SLAVE_ADDRESS, I2C_MASTER_WRITE);
	
        while (!I2C_CheckStatus(HT_I2C0, I2C_MASTER_SEND_START));
	
        while (!I2C_CheckStatus(HT_I2C0, I2C_MASTER_TRANSMITTER_MODE));
	
	while (!I2C_CheckStatus(HT_I2C0, I2C_MASTER_TX_EMPTY));
	
	I2C_SendData(HT_I2C0, reg_addr); 
	
	while (!I2C_CheckStatus(HT_I2C0, I2C_MASTER_TX_EMPTY));
	
	I2C_SendData(HT_I2C0, register_value); 
	
	I2C_GenerateSTOP(HT_I2C0);
}
```


```c=
oid Set_Acc_Scale_Select(u8 scale)
{
	u8 scale_data;
	
	scale_data = (MPU6500_I2C_Read_OneByte(Acc_Config_Reg) & 0xE7) | scale;
	MPU6500_I2C_Write_OneByte(Acc_Config_Reg, scale_data); 
}

void Show_Acc_Scale_Select(void)
{
	u8 scale;
	
	scale = MPU6500_I2C_Read_OneByte(Acc_Config_Reg) & 0x18;
	
	switch(scale)
	{
		case mpu6500_range_2G:
			printf("Acc_Scale_Status: +-2G\r\n");
			break;
		case mpu6500_range_4G:
			printf("Acc_Scale_Status: +-4G\r\n");
			break;
		case mpu6500_range_8G:
			printf("Acc_Scale_Status: +-8G\r\n");
			break;
		case mpu6500_range_16G:
			printf("Acc_Scale_Status: +-16G\r\n");
			break;
		default:
			printf("Acc_Scale_Status: error\r\n");
			break;
	}
}

u16 Get_HL_Value(u8 high_reg, u8 low_reg)
{
	u8 h_Value, l_Value;
	
	h_Value = MPU6500_I2C_Read_OneByte(high_reg);
	l_Value = MPU6500_I2C_Read_OneByte(low_reg);
	
	/* h_value left 8 bits or l_value = (h_value+l_value)*/
	return (((u16)h_Value << 8) | l_Value);
}
```

```c=
double Acc_Scale(u16 raw_value)
{
	u8 scale;
	double per_digit;
	
	scale = MPU6500_I2C_Read_OneByte(Acc_Config_Reg) & 0x18;
	switch(scale)
	{
		case mpu6500_range_2G:
			per_digit = 2.0/0x8000;
			break;
		case mpu6500_range_4G:
			per_digit = 4.0/0x8000;
			break;
		case mpu6500_range_8G:
			per_digit = 8.0/0x8000;
			break;
		case mpu6500_range_16G:
			per_digit = 16.0/0x8000;
			break;
		default:
			break;
	}
	return ((signed short)raw_value * per_digit);
}
```