Hardware platform: STM32F10X + MS5611 + JLink
Software platform: Keil 4
1. Basic knowledge
First of all, what is MS5611?
The MS5611 air pressure sensor is a high-resolution air pressure sensor that integrates SPI and I²C (up to 20 MHz) bus interfaces, with a resolution of up to 10 cm. It has a high-linearity pressure sensor and an ultra-low power 24-bit AD inside.
MS5611 is mainly used in smart phones, altitude measurement and navigation assistance, and friends who work with quad-axis are generally familiar with it.
Secondly, for the attitude control of the aircraft, we use the GY-86 10DOF module, which has MS5611 + MPU6050 + HMC5883, and reads data through the IIC protocol for operation. The MS5611 is hung on the slave I2C interface of the MPU5060. The I2C address of the MS5611 is 0b111011Cx, where the C bit is determined by the CSB pin and is the complement value of the CSB pin (inverted). The CSB pin of the MS5611 on the GY-86 is grounded, so the CSB pin value is 0, the 8-bit I2C address is 0b1110111x (0xEE), and the 7-bit I2C address is 0b1110111 (0x77).
Here, 0b indicates binary, 0x indicates hexadecimal, and a leading 0 indicates octal. For example:
'\077' // is octal representation of ' ', 0 can be omitted, because C and C++ do not allow the use of slash plus decimal numbers to represent characters;
'\0x3F' // is the hexadecimal representation. These are the basics of C language. If you don't understand, please search Baidu.
2. Operation Results
3. Corresponding modules
The modules involved in the program are:
RCC: reset and clock control module, used to initialize the STM32 USART peripheral clock and IO port multiplexing clock;
IIC: Simulate the IIC protocol. Many people say that the STM32 hardware IIC module cannot be used. This is mainly because the STM32 hardware IIC module has a natural BUG, which is that it cannot be interrupted, that is, IIC must be at the highest level of interruption. ST has confirmed this in its later DataSheet.
Delay: Delay module written using the system clock SysTick, also known as "tick";
USART: serial port module;
MS5611: MS5611 module configuration.
Four: Code
RCC
#include "Rcc.h"
void RCC_Init(void)
{
ErrorStatus HSEStartUpStatus;
//Define enumeration type error status variable
RCC_DeInit(); //Reset system clock settings
RCC_HSEConfig(RCC_HSE_ON);
//Turn on the external high-speed clock crystal and enable HSE
/*RCC_HSE_ON on
_off _bypass hse crystal oscillator is bypassed by external clock*/
HSEStartUpStatus = RCC_WaitForHSEStartUp();
/*RCC_WaitForHSEStartUp() returns an ErrorStatus enumeration value,
Success is good, error is not good*/
if(HSEStartUpStatus == SUCCESS) //HES is ready
{
RCC_HCLKConfig(RCC_SYSCLK_Div1);
//AHB clock (HCLK) = system clock
RCC_PCLK1Config(RCC_HCLK_Div2);
//Set the low-speed AHB clock (APB1) to 2 times the frequency of HCLK
RCC_PCLK2Config(RCC_HCLK_Div1);
//Set high-speed AHB clock (APB2) = HCLK clock
FLASH_SetLatency(FLASH_Latency_2);
//Set the FLASH delay cycle number to 2
// Enable receiving finger cache
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
//Set the PLL clock source and frequency multiplication factor to 9 times the HSE frequency 8MHz * 9 = 72MHz
/*void RCC_PLLConfig(u32 RCC_PLLSource, u32 RCC_PLLMul)
RCC_PLLSource_HSI_Div2 pll input clock = hsi/2;
RCC_PLLSource_HSE_Div1 PLL Input Clock = HSE
RCC_PLLSource_HSE_Div2 PLL input clock = hse/2
RCC_PLLMul_2 ------_16 pll input clock*2---16
PLL output clock must not exceed 72MHZ*/
RCC_PLLCmd(ENABLE);
//ENABLE / DISABLE
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); //Wait for PLL output to stabilize
/*FlagStatus RCC_GetFlagStatus(u8 RCC_FLAG) Check the specified RCC flag
Return SET OR RESET
RCC_FLAG_HSIRDY HSI crystal oscillator ready
RCC_FLAG_HSERDY
RCC_FLAG_PLLRDY
RCC_FLAG_LSERDY
RCC_FLAG_LSIRDY.......*/
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
//Set PLL as system clock source
/*void RCC_SYSCLKConfig(u32 RCC_SYSCLKSource) Set the system clock
RCC_SYSCLKSource_HSI
RCC_SYSCLKSource_HSE
RCC_SYSCLKSource_PLLCLK selects HSI HSE PLL as system clock*/
while(RCC_GetSYSCLKSource() != 0x08);
//Judge whether PLL is the system clock
/*u8 RCC_GetSYSCLKSource(void) Returns the clock source used as the system clock
0x00:HSI 0x04:HSE 0x08:PLL */
}
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |
RCC_APB2Periph_AFIO |
RCC_APB2Periph_GPIOB , ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
//U2 U3 clock is in APB1
//Turn on the GPIO clock, multiplexing function, the clock of serial port 1
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE); //Enable CAN1 clock
//How strange, is it because the official library function is updated?
//Doesn't it mean that the F10X series only has one CAN, while the F4 has CAN1 CAN2?
//Why is can1 in his system configuration file? ? ? ? ?
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //Clock enable
/*void RCC_APB2PeriphClockCmd(u32 RCC_APB2Periph, FunctionalState NewState)
Enable or disable apb2 peripheral clock
RCC_APB2Periph_AFIO function multiplexing IO clock
RCC_APB2Periph_GPIOA/B/C/D/E GPIOA/B/C/D/E Clock
RCC_APB2Periph_ADC1/ADC2 ADC1/2 clock
RCC_APB2Periph_TIM1
RCC_APB2Periph_SPI1
RCC_APB2Periph_USART1
RCC_APB2Periph_ALL All APB2 peripheral clocks*/
}
IIC
#include "myIIC.h"
unsigned char I2C_ReadByte(unsigned char DeviceAddr,unsigned char address); //Read a byte of data from the address address of 24c02
void I2C_WriteByte(unsigned char DeviceAddr,unsigned char address,unsigned char info);
void I2C_NoAddr_WriteByte(unsigned char DeviceAddr,unsigned char info);
void I2C_Read_MultiBytes(unsigned char DeviceAddr,unsigned char address,unsigned char BytesNum,unsigned char * OutDate );
uint16_t I2C_Read_2Bytes(unsigned char DeviceAddr,unsigned char address);
uint32_t I2C_Read_3Bytes(unsigned char DeviceAddr,unsigned char address);
void delay_nop(void);
void delay2(unsigned int x);
void iic_start(void);
void iic_stop(void);
void iic_writex(unsigned char j);
unsigned char iic_readx(void);
void iic_check_ACK(void);
void iic_SDA_Set_Dir(unsigned char io_set);
void I2C_GPIO_Configuration(void);
void delay2(unsigned int x)
{
unsigned int i;
for(i=0;i } void delay_nop(void) { unsigned int i=10; //i=10 delay 1.5us//The speed can be optimized here. After testing, it can still be written when the minimum is 5 while(i--); } void iic_start(void) { //SDA=1; GPIO_SetBits(GPIOB,SDA); delay_nop(); //SCL=1; GPIO_SetBits(GPIOB,SCL); delay_nop(); //SDA=0; GPIO_ResetBits(GPIOB, SDA); delay_nop(); //SCL=0; GPIO_ResetBits(GPIOB, SCL); delay_nop(); } void iic_stop(void) { //SDA=0; GPIO_ResetBits(GPIOB, SDA); delay_nop(); //SCL=1; GPIO_SetBits(GPIOB,SCL); delay_nop(); //SDA=1; GPIO_SetBits(GPIOB,SDA); delay_nop(); } void iic_writex(unsigned char j) { unsigned char i,temp,temp1; temp=j; //iic_SDA_Set_Dir(0); for (i=0;i<8;i++) { temp1=temp & 0x80; temp=temp<<1; //SCL=0; GPIO_ResetBits(GPIOB, SCL); delay_nop(); //SDA=CY; if(temp1==0x80) {GPIO_SetBits(GPIOB, SDA);} else {GPIO_ResetBits(GPIOB, SDA);} delay_nop(); // SCL=1; GPIO_SetBits(GPIOB,SCL); delay_nop(); } //iic_SDA_Set_Dir(0); //SCL=0; GPIO_ResetBits(GPIOB, SCL); delay_nop(); //SDA=1; GPIO_SetBits(GPIOB,SDA); delay_nop(); } unsigned char iic_readx(void) { unsigned char i,j,k=0; //SCL=0; GPIO_ResetBits(GPIOB, SCL); delay_nop(); //SDA=1; GPIO_SetBits(GPIOB,SDA); iic_SDA_Set_Dir(1); for (i=0;i<8;i++) { delay_nop(); //SCL=1; GPIO_SetBits(GPIOB,SCL); delay_nop(); //if (SDA==1) j=1; if( GPIO_ReadInputDataBit(GPIOB,SDA)==1 ) {j=1;} else {j=0;} k=(k<<1)|j; //SCL=0; GPIO_ResetBits(GPIOB, SCL); } iic_SDA_Set_Dir(0); delay_nop(); return(k); } void iic_check_ACK(void)//Detect slave response signal { unsigned int i=0; iic_SDA_Set_Dir(1); //SCL=1; GPIO_SetBits(GPIOB,SCL); delay_nop(); while ((GPIO_ReadInputDataBit(GPIOB,SDA)==1)&&(i<5000))i++; //SCL=0; GPIO_ResetBits(GPIOB, SCL); delay_nop(); iic_SDA_Set_Dir(0); } void I2C_Ack(void) { GPIO_ResetBits(GPIOB,SCL); delay_nop(); GPIO_ResetBits(GPIOB,SDA); delay_nop(); GPIO_SetBits(GPIOB,SCL); delay_nop(); GPIO_ResetBits(GPIOB,SCL); delay_nop(); } void I2C_NoAck(void) { GPIO_ResetBits(GPIOB,SCL); delay_nop(); GPIO_SetBits(GPIOB,SDA); delay_nop(); GPIO_SetBits(GPIOB,SCL); delay_nop(); GPIO_ResetBits(GPIOB,SCL); delay_nop(); } unsigned char I2C_ReadByte(unsigned char DeviceAddr,unsigned char address) { unsigned char i; iic_start(); iic_writex(DeviceAddr); iic_check_ACK(); iic_writex(address); iic_check_ACK(); iic_start(); iic_writex(DeviceAddr+1); iic_check_ACK(); i=iic_readx(); iic_stop(); //delay2(10); delay2(50); return(i); } void I2C_WriteByte(unsigned char DeviceAddr,unsigned char address,unsigned char info) { iic_start(); iic_writex(DeviceAddr); iic_check_ACK(); iic_writex(address); iic_check_ACK(); iic_writex(info); iic_check_ACK(); iic_stop(); //delay2(50); delay2(250); } void I2C_NoAddr_WriteByte(unsigned char DeviceAddr,unsigned char info) { iic_start(); iic_writex(DeviceAddr); iic_check_ACK(); iic_writex(info); iic_check_ACK(); iic_stop(); //delay2(50); delay2(250); } void I2C_Read_MultiBytes(unsigned char DeviceAddr,unsigned char address,unsigned char BytesNum,unsigned char * OutDate ) { unsigned char i; iic_start(); iic_writex(DeviceAddr); iic_check_ACK(); iic_writex(address); iic_check_ACK(); iic_start(); iic_writex(DeviceAddr+1); iic_check_ACK(); for(i=0;i { OutDate[i]=iic_readx(); if(i+1 } iic_stop(); delay2(250); } uint16_t I2C_Read_2Bytes(unsigned char DeviceAddr,unsigned char address) { unsigned char i,data_temp1,data_temp2; uint16_t data16; iic_start(); iic_writex(DeviceAddr); iic_check_ACK(); iic_writex(address); iic_check_ACK(); iic_start(); iic_writex(DeviceAddr+1); iic_check_ACK(); data_temp1=iic_readx(); I2C_Ack(); data_temp2=iic_readx(); I2C_NoAck(); //The last byte does not need to be responded iic_stop(); //delay2(10); delay2(250); data16=(data_temp1<<8)|data_temp2; return data16;} uint32_t I2C_Read_3Bytes(unsigned char DeviceAddr,unsigned char address) { unsigned char i,data_temp1,data_temp2,data_temp3; uint32_t data32; iic_start(); iic_writex(DeviceAddr); iic_check_ACK(); iic_writex(address); iic_check_ACK(); iic_start(); iic_writex(DeviceAddr+1); iic_check_ACK(); data_temp1=iic_readx(); I2C_Ack(); data_temp2=iic_readx(); I2C_Ack(); data_temp3=iic_readx(); I2C_NoAck(); //The last byte does not need to be responded iic_stop(); //delay2(10); delay2(250); data32=data_temp1*65535+data_temp2*256+data_temp3; return data32;} void I2C_GPIO_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB , ENABLE); GPIO_InitStructure.GPIO_Pin = SCL; //24C02 SCL GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = SDA; //24C02 SDA as output GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); } void iic_SDA_Set_Dir(unsigned char io_set) //SDA pin input and output settings { GPIO_InitTypeDef GPIO_InitStructure; if(io_set==0) { GPIO_InitStructure.GPIO_Pin = SDA; //24C02 SDA as output GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); } else if(io_set==1) { GPIO_InitStructure.GPIO_Pin = SDA; //24C02 SDA as input GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //Pull-up input GPIO_Init(GPIOB, &GPIO_InitStructure); } else {;} } DELAY #include "delay.h" static u8 fac_us=0; //us delay multiplier static u16 fac_ms=0; //ms delay multiplier, under ucos, represents the number of ms per beat // Initialize delay function //SYSTICK clock is fixed to 1/8 of HCLK clock //SYSCLK: system clock void delay_init() { SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //Select external clock HCLK/8 fac_us=SystemCoreClock/8000000; //1/8 of the system clock fac_ms=(u16)fac_us*1000; //Non-OS, represents the number of systick clocks required for each ms } //Delay nus //nus is the number of us to be delayed. void delay_us(u32 nus) { u32 temp; SysTick->LOAD=nus*fac_us; //Time loading SysTick->VAL=0x00; //Clear the counter SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk; //Start countdown do { temp=SysTick->CTRL; }while((temp&0x01)&&!(temp&(1<<16))); //Wait for time to arrive SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //Turn off the counter SysTick->VAL =0X00; //Clear the counter } //Delay nms //Note the range of nms //SysTick->LOAD is a 24-bit register, so the maximum delay is: //nms<=0xffffff*8*1000/SYSCLK //SYSCLK is in Hz, nms is in ms //Under 72M conditions, nms<=1864 void delay_ms(u16 nms) { u32 temp; SysTick->LOAD=(u32)nms*fac_ms; //Time loading (SysTick->LOAD is 24bit) SysTick->VAL =0x00; //Clear the counter SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk; //Start countdown do { temp=SysTick->CTRL; }while((temp&0x01)&&!(temp&(1<<16))); //Wait for time to arrive SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //Turn off the counter SysTick->VAL =0X00; //Clear the counter } MS5611 #include "MS5611.h" /*Macro definition------------------------------------------------------------------*/ //Define the slave address of the device in the IIC bus and modify it according to the different CSB pins //#define MS561101BA_ADDR 0xec //CBR=1 0x76 I2C address when CSB is connected to HIGH (VCC) #define MS561101BA_ADDR 0xee //CBR=0 0x77 I2C address when CSB is connected to LOW (GND) //Define the internal address of MS561101BA // registers of the device #define MS561101BA_D1 0x40 #define MS561101BA_D2 0x50 #define MS561101BA_RESET 0x1E // D1 and D2 result size (bytes) #define MS561101BA_D1D2_SIZE 3 // OSR (Over Sampling Ratio) constants #define MS561101BA_OSR_256 0x00 #define MS561101BA_OSR_512 0x02 #define MS561101BA_OSR_1024 0x04 #define MS561101BA_OSR_2048 0x06 #define MS561101BA_OSR_4096 0x08 //#define MS561101BA_D1_OSR_256 0x40 //#define MS561101BA_D1_OSR_512 0x42 //#define MS561101BA_D1_OSR_1024 0x44 //#define MS561101BA_D1_OSR_2048 0x46 #define MS561101BA_D1_OSR_4096 0x48 //#define MS561101BA_D2_OSR_256 0x50 //#define MS561101BA_D2_OSR_512 0x52 //#define MS561101BA_D2_OSR_1024 0x54 //#define MS561101BA_D2_OSR_2048 0x56 #define MS561101BA_D2_OSR_4096 0x58 #define MS561101BA_PROM_BASE_ADDR 0xA0 // by adding ints from 0 to 6 we can read all the prom configuration values. // C1 will be at 0xA2 and all the subsequent are multiples of 2 #define MS561101BA_PROM_REG_COUNT 6 // number of registers in the PROM #define MS561101BA_PROM_REG_SIZE 2 // size in bytes of a prom registry. /*Variable declaration----------------------------------------------------------------*/ uint16_t Cal_C[7]; //Used to store 6 groups of data in PROM uint32_t D1_Pres,D2_Temp; //Store digital pressure and temperature float Pressure; //Temperature compensation atmospheric pressure float dT,Temperature,Temperature2; //Difference between actual and reference temperature, actual temperature, intermediate value double OFF,SENS; //actual temperature offset, actual temperature sensitivity float Aux,OFF2,SENS2; //temperature calibration value uint32_t ex_Pressure; //Serial port reading conversion value uint8_t exchange_num[8]; /*Function declaration----------------------------------------------------------------*/ void MS561101BA_Reset(void); void MS561101BA_readPROM(void); uint32_t MS561101BA_DO_CONVERSION(u8 command); void MS561101BA_GetTemperature(u8 OSR_Temp); void MS561101BA_GetPressure(u8 OSR_Pres); void MS561101BA_Init(void); void SampleANDExchange(void); /************************************************************ * Function name:MS561101BA_Reset * Description: Reset * Input: None * Output: None */ void MS561101BA_Reset(void) { I2C_NoAddr_WriteByte(MS561101BA_ADDR,MS561101BA_RESET); } /************************************************************ * Function name:MS561101BA_readPROM * Description: Read factory calibration data from PROM * Input: None * Output: None */ void MS561101BA_readPROM(void) { uint16_t value=0;u8 temp1[2]={0}; u8 i; for (i=0;i<=MS561101BA_PROM_REG_COUNT;i++) { // I2C_Read_MultiBytes(MS561101BA_ADDR,MS561101BA_PROM_BASE_ADDR + (i * MS561101BA_PROM_REG_SIZE),2,temp1); //value=temp1[0]<<8|temp1[1]; //Cal_C[i]=value; Cal_C[i]=I2C_Read_2Bytes(MS561101BA_ADDR,MS561101BA_PROM_BASE_ADDR + (i * MS561101BA_PROM_REG_SIZE)); } printf("\n The MS561101BA is reading PROM : \r\n"); printf("\r\nC1 = %d\r\nC2 = %d\r\nC3 = %d\r\nC4 = %d\r\nC5 = %d\r\nC6 = %d\r\n",Cal_C[1],Cal_C[2],Cal_C[3],Cal_C[4],Cal_C[5],Cal_C[6]); } /************************************************************ * Function name:MS561101BA_DO_CONVERSION * describe: * Input: None * Output: None */ uint32_t MS561101BA_DO_CONVERSION(uint8_t command) { uint32_t conversion; I2C_NoAddr_WriteByte(MS561101BA_ADDR,command); delay_ms(10); //delay, remove data errors conversion=I2C_Read_3Bytes(MS561101BA_ADDR,0); return conversion; } /************************************************************ * Function name:MS561101BA_GetTemperature * Description: Read digital temperature * Input: Oversampling rate * Output: None */ void MS561101BA_GetTemperature(u8 OSR_Temp) { D2_Temp= MS561101BA_DO_CONVERSION(OSR_Temp); delay_ms(100); dT=D2_Temp - (((uint32_t)Cal_C[5])<<8); Temperature=2000+dT*((uint32_t)Cal_C[6])/8388608; //Calculate 100 times the temperature value, 2001 means 20.01° } /************************************************************ * Function name:MS561101BA_GetPressure * Description: Read digital air pressure * Input: Oversampling rate * Output: None */ void MS561101BA_GetPressure(u8 OSR_Pres) { D1_Pres= MS561101BA_DO_CONVERSION(OSR_Pres); delay_ms(100); OFF=(uint32_t)(Cal_C[2]<<16)+((uint32_t)Cal_C[4]*dT)/128.0; SENS=(uint32_t)(Cal_C[1]<<15)+((uint32_t)Cal_C[3]*dT)/256.0; //Temperature compensation if(Temperature < 2000)// second order temperature compensation when under 20 degrees C { Temperature2 = (dT*dT) / 0x80000000; Aux = (Temperature-2000)*(Temperature-2000); OFF2 = 2.5*Aux; SENS2 = 1.25*Aux; if(Temperature < -1500) { Aux = (Temperature+1500)*(Temperature+1500); OFF2 = OFF2 + 7*Aux; SENS2 = SENS + 5.5*Aux; } }else //(Temperature > 2000) { Temperature2 = 0; OFF2 = 0; SENS2 = 0; } Temperature = Temperature - Temperature2; OFF = OFF - OFF2; MEANING = MEANING - MEANING2; Pressure=(D1_Pres*SENS/2097152.0-OFF)/32768.0; } /************************************************************ * Function name:MS561101BA_Init * Description: MS561101BA initialization * Input: None * Output: None */ void MS561101BA_Init(void) { MS561101BA_Reset(); delay_ms(100); MS561101BA_readPROM(); delay_ms(100); } /************************************************************ * Function name:SampleANDExchange * Description: Read data and convert it to send via serial port * Input: None * Output: None */ void SampleANDExchange(void) { uint8_t i=0; MS561101BA_GetTemperature(MS561101BA_D2_OSR_4096);//0x58 MS561101BA_GetPressure(MS561101BA_D1_OSR_4096); //0x48 ex_Pressure=(long)(Pressure); if(Pressure<0) { ex_Pressure=-ex_Pressure; exchange_num[0]='-'; } else exchange_num[0]='\0'; exchange_num[1]=ex_Pressure/100000+0x30; ex_Pressure=ex_Pressure%100000; exchange_num[2]=ex_Pressure/10000+0x30; ex_Pressure=ex_Pressure%10000; exchange_num[3]=ex_Pressure/1000+0x30; ex_Pressure=ex_Pressure%1000; exchange_num[4]=ex_Pressure/100+0x30; ex_Pressure=ex_Pressure%100; exchange_num[5]='.'; exchange_num[6]=ex_Pressure/10+0x30; ex_Pressure=ex_Pressure%10; exchange_num[7]=ex_Pressure+0x30; printf("\nP : %c%c%c%c%c%c%c%c mbar \r\n",exchange_num[0],exchange_num[1],exchange_num[2],exchange_num[3],exchange_num[4],exchange_num[5],exchange_num[6],exchange_num[7]); // for(i=0;i<8;i++) // { // printf("%c",exchange_num[i]); // } // printf(" mbar \r\n"); printf("T : %4.3f °C\r\n ",Temperature/100); }
Previous article:stm32F4 encoder measures speed and prints through serial port --- program source code
Next article:stm32 timer pwm mode input capture
- Popular Resources
- Popular amplifiers
- Naxin Micro and Xinxian jointly launched the NS800RT series of real-time control MCUs
- How to learn embedded systems based on ARM platform
- Summary of jffs2_scan_eraseblock issues
- Application of SPCOMM Control in Serial Communication of Delphi7.0
- Using TComm component to realize serial communication in Delphi environment
- Bar chart code for embedded development practices
- Embedded Development Learning (10)
- Embedded Development Learning (8)
- Embedded Development Learning (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Intel promotes AI with multi-dimensional efforts in technology, application, and ecology
- ChinaJoy Qualcomm Snapdragon Theme Pavilion takes you to experience the new changes in digital entertainment in the 5G era
- Infineon's latest generation IGBT technology platform enables precise control of speed and position
- Two test methods for LED lighting life
- Don't Let Lightning Induced Surges Scare You
- Application of brushless motor controller ML4425/4426
- Easy identification of LED power supply quality
- World's first integrated photovoltaic solar system completed in Israel
- Sliding window mean filter for avr microcontroller AD conversion
- What does call mean in the detailed explanation of ABB robot programming instructions?
- RAQ #223: How to measure and determine soft-start timing without a soft-start equation?
- RAQ #223: How to measure and determine soft-start timing without a soft-start equation?
- GigaDevice's full range of automotive-grade SPI NOR Flash GD25/55 wins ISO 26262 ASIL D functional safety certification
- GigaDevice's full range of automotive-grade SPI NOR Flash GD25/55 wins ISO 26262 ASIL D functional safety certification
- New IsoVu™ Isolated Current Probes: Bringing a New Dimension to Current Measurements
- New IsoVu™ Isolated Current Probes: Bringing a New Dimension to Current Measurements
- Infineon Technologies Launches ModusToolbox™ Motor Kit to Simplify Motor Control Development
- Infineon Technologies Launches ModusToolbox™ Motor Kit to Simplify Motor Control Development
- STMicroelectronics IO-Link Actuator Board Brings Turnkey Reference Design to Industrial Monitoring and Equipment Manufacturers
- Melexis uses coreless technology to reduce the size of current sensing devices
- Which expert can give me a complete cadence project?
- [Repost] Popular Science of Components: How IC Chips Are Packaged
- Analysis of the uboot power meter driver for RK3288, a commercial display motherboard of Visiontron Technologies
- Working principle, functional characteristics and classification of photoelectric liquid level sensors
- EEWORLD University Hall--Detailed explanation of MATLAB image functions and their applications
- Get free high-speed digital design tips to avoid starting over with complex PCB designs
- Philips RF SiP sets new standard for GSM/GPRS/EDGE radio unit size
- What is the value of open source? Preliminary findings from a European Commission study
- [Erha Image Recognition Artificial Intelligence Vision Sensor] 1. Unboxing Experience
- 2006 EDN China Automotive Electronics Technology Seminar will be held at the end of August