STM32F103STM32F103 hardware IIC reads temperature sensor EMC1314

STM32F103 hardware I2C reading temperature sensor

In the previous article, I wrote about STM32F103 using hardware IIC to read the classic peripheral EEPROM. It was only designed with a process of writing data and reading data. This article mainly introduces the case of reading and writing a temperature sensor EMC1314 model.
An important step in reading and writing sensor data is to learn to understand its manual (datasheet). From the manual, we need to obtain several types of key information. One is the physical address of the sensor (especially important), because the same sensor may be Small differences in capacity or model will lead to large differences in physical addresses. The second is the initial configuration register of the sensor. The third is the register that stores data. The sensor data you want to read is stored here. Some can be read directly, while some require conversion and calculation. These require careful reading of the register to understand.

1. Initialization before temperature sensor reading

The initialization of the EMC temperature sensor mainly involves some initialization configurations of the I2C2 port pins, as well as some register configurations of the sensor itself. These configurations are performed together with the configuration of the I2C2 port during initialization. The configuration of the EMC register initialization mainly includes the operations of EMC reset before each data reading and EMC opening to read these two registers.
Use the encapsulated EMC to write a one-byte interface to operate on the addresses of the two registers, for example

u16 EMC_Rst()
{<!-- -->
    printf("EMC_Rst\r\\
");
    EMC_WriteByte(0x22, 0xF0); //EMC reset
delay_ms(50);
return RET_SUCC;
}

u16 EMC_Start()
{<!-- -->
printf("EMC_Start\r\\
");
EMC_WriteByte(0x03,0x80); //EMC starts reading
printf("EMC Start end");
return RET_SUCC;
}

u16 EMC_Initializes(void)
{<!-- -->
I2C2_GPIO_Configuration();
I2C2_Configuration();
delay_ms(50);
return RET_SUCC;
}```

u16 EMC_Init()
{<!-- -->
EMC_Initializes();
EMC_Rst();
printf("EMC Init end");
return RET_SUCC;
}
```c
//EMC writes one byte
u16 EMC_WriteByte(uint16_t Addr, uint16_t Data)
{<!-- -->
    
I2C_AcknowledgeConfig(I2C2,ENABLE);
  
\t  
while(I2C_GetFlagStatus(I2C2, I2C_FLAG_BUSY));
 
/* 1. Start */
\t\t
I2C_GenerateSTART(I2C2, ENABLE);
while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT));
/* 2. Device address/write */
I2C_Send7bitAddress(I2C2, EMC_DEV_ADDR, I2C_Direction_Transmitter); //Data address
\t\t\t 
while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
  
/* 3. Data address */
I2C_SendData(I2C2, Addr); //Register data address (8 bits)
while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
    
/* 4. Write one byte of data */
I2C_SendData(I2C2, Data); //Send data
while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
    
/* 5. Stop */
I2C_GenerateSTOP(I2C2, ENABLE);
return RET_SUCC;
\t\t
}


//EMC reads one byte
u16 EMC_ReadByte(uint16_t Addr, uint16_t *Data)
{<!-- -->

I2C_AcknowledgeConfig(I2C2,ENABLE);
  
while(I2C_GetFlagStatus(I2C2, I2C_FLAG_BUSY));
   
/* 1. Start */
I2C_GenerateSTART(I2C2, ENABLE);
while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT));
   
/* 2. Device address/write */
I2C_Send7bitAddress(I2C2, EMC_DEV_ADDR, I2C_Direction_Transmitter);
\t
while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
\t\t 
    
/* 3. Data address */
\t
I2C_SendData(I2C2, Addr); //Data address (8 bits)
while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
     
/* 4. Start again */
I2C_GenerateSTART(I2C2, ENABLE);
while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT));
    
/* 5. Device address/read */
I2C_Send7bitAddress(I2C2, EMC_READ_ADDR, I2C_Direction_Receiver);
while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
    
/* 6. Read one byte of data */
I2C_AcknowledgeConfig(I2C2, DISABLE); //Generate non-response
while(I2C_GetFlagStatus(I2C2, I2C_FLAG_RXNE) == RESET);
\t\t
*Data = I2C_ReceiveData(I2C2); //Read data

/* 7. Stop */
I2C_GenerateSTOP(I2C2, ENABLE);
return RET_SUCC;
}

2. Read the data of the EMC register

Before reading the temperature data in this part, in order to test the accuracy of the hardware I2C reading interface, we can first find a register with a fixed value in the EMC register and read it, and compare the read data with the real data to see if it is consistent. . For example, the register that stores the device ID should be read first to check the accuracy of the interface.
The reading process is also very simple. Pass in the corresponding register address and read the value directly, such as

u16 EMC_ID_Get(u16 *ID)
{<!-- -->
EMC_Init();
EMC_Start();
     delay_ms(50);
EMC_ReadByte(0xFE, ID);
printf("EMC_ID = %d\r\\
", *ID);
return RET_SUCC;
}

After reading, it is found that the read value is 85, which is the same as the actual stored value, indicating that there is no problem with the read interface.
The next step is to directly read the register storing the temperature data. The EMC temperature sensor is different from other temperature sensors. First, the data it reads is composed of two parts, namely the integer bit and the decimal bit. The integer part is the eight-digit number of one register, and the decimal part is the three-digit number of another register, and there is a The high three digits of the byte. When we read the decimal place register, we need to shift it to the left by five bits and move it up to 0x7 to get the decimal place value correctly. Then the correct value is to combine these two parts into an 11-digit number. Temperature data; secondly, the 11-digit number is not the final temperature value. It needs to be converted and multiplied by a conversion factor. The temperature table read in the register manual clearly divides each digit in the 11-digit number to represent 0.125. Therefore, the conversion coefficient is 0.125, because it is necessary to convert the 11 binary digits into decimal and then multiply them by 0.125. Third, the temperature sensor does not introduce positive and negative bits. Some temperature sensors specifically set aside high bits to represent the positive data. In the negative case, the temperature sensor here has no requirement to express positive or negative values.

//Standard reading temperature interface
u16 EMC_Temp_Get(float *temperature)
{<!-- -->
u16TL,TH;
u32 tem,tem1;
EMC_Init();
EMC_Start();
  delay_ms(50);
EMC_ReadByte(0x01, & TH); //Integer part of external temperature
EMC_ReadByte(0x10, & TL); //Fractional part of external temperature
tem = (TL>>5) & amp;0x7;
printf("tem = %d\\
", tem);
      tem1=(TH<<3)|tem;//Get the lower three digits, a total of eleven digits
printf("tem1 = %d\\
", tem1);
     *temperature = tem1*0.125; // Multiply decimal by 0.125 to get the final degree.
if(*temperature>=LIMIT_MAX)
{<!-- -->
*temperature = LIMIT_MAX;
}
     printf("temperature = %f\\
", *temperature);
return RET_SUCC;
}

There is also a judgment added here that the maximum reading threshold of the temperature sensor is 127.875. If it exceeds that, the read data can only be this value. Of course, generally the value read by the temperature sensor will not exceed the temperature reading. The range is completely sufficient. The last read data is printed out, and the floating point number is more than 30 degrees. After long-term reading, it is normal and stable, and there is no sudden change. It shows that the data read is accurate and reliable.

Summary

There are two important points when reading this kind of sensor that requires data conversion. One is to understand its manual, which contains the final physical address and registers for related operations. The other is to understand the temperature conversion mechanism. , what is the original data, and how to process it to get the final real data, these two points are very important. Everyone is welcome to leave a message for discussion. If you have any questions, you can actively discuss them.