一、基础知识
首先,ms5611是什么
ms5611气压传感器是由meas(瑞士)推出的一款spi和i²c总线接口的新一代高分辨率气压传感器,分辨率可达到10cm。该传感器模块包括一个高线性度的压力传感器和一个超低功耗的24位σ模数转换器(工厂校准系数)。
计算温度:
d2 = ms5611_do_conversion(osr_temp);
delay_ms(10);
dt = d2 - (((u32)c5)*256) ;
temperature = 2000 + dt*((float)c6)/8388608 ;
计算大气压:
d1 = ms5611_do_conversion(osr_pressure) ;
delay_ms(10) ;
off = (((int64_t)c2)*65536 + (((int64_t)c4*dt)/128)) ;
sens = (((int64_t)c1)*32768) + (((int64_t)c3*dt)/256) ;
if(temperature 《 2000) //µ±îâ¶èöµtempð¡óú2000ê±ðèòª×öîâ¶è²¹³¥
{
t2 = (float)(dt*dt)/0x80000000 ;
aux = (temperature - 2000)*(temperature - 2000) ;
off2 = 2.5f*aux ;
sens2 = 1.25f*aux ;
if(temperature 《 -1500) //µ±îâ¶èöµtempð¡óú-1500ê±ðèòª×öîâ¶è²¹³¥
{
aux = (temperature+1500)*(temperature+1500);
off2 = off2 + 7*aux;
sens2 = sens2 + 5.5f*aux;
}
}
else
{
t2 = 0 ;
off2 = 0 ;
sens2= 0 ;
}
temperature = temperature - t2 ;
off = off - off2 ;
sens = sens - sens2 ;
pressure = ((d1*sens)/2097152 - off)/32768 ;
海拔计算:
altitude = (44330.0f*(1.0f - pow((float)pressure/101325.0f, 0.190295f))) ;
ms5611主要用于智能手机、海拔高度测量和导航辅助,做四轴的朋友一般都了解。
其次,对于飞行器的姿态控制,我们使用gy-86 10dof 的模块,里面带有ms5611 + mpu6050 + hmc5883,通过iic协议读取数据进行操作。ms5611挂在mpu5060的从i2c接口上。ms5611的i2c地址为0b111011cx,其中c比特位由csb引脚决定,为csb引脚的补码值(取反)。gy-86上 ms5611的csb引脚接地,所以csb引脚值为0,8位i2c地址为0b1110111x(0xee),7位i2c地址为 0b1110111(0x77)。
这里,0b表示二进制,0x表示十六进制,数字前加0表示八进制。例如:
‘\077’ //是8进制表示‘ ’,0可以省略,因为c,c++规定不允许使用斜杠加10进制数来表示字符;
‘\0x3f’ //是16进制表示。这些都是c语言中的基础
二、运行结果
三、相应模块
程序涉及的模块有:
rcc:复位及时钟控制模块,用于初始化stm32 usart外设时钟及io口复用时钟;
iic:模拟iic 协议,好多人都说stm32的硬件iic模块用不了,主要是因为stm32 的硬件 iic 模块有个天生的 bug,就是不能被中断,也就是iic要处于中断的最高级,st在自己后来的 datasheet 中已经证实了这一点。
delay:利用系统时钟systick,也号称“滴答”,写的延时模块;
usart:串口模块;
ms5611:ms5611模块配置。
四:代码
rcc
#include “rcc.h”
void rcc_init(void)
{
errorstatus hsestartupstatus;
//定义枚举类型错误状态变量
rcc_deinit();//复位系统时钟设置
rcc_hseconfig(rcc_hse_on);
//打开外部高速时钟晶振,使能hse
/*rcc_hse_on 开
_off 关 _bypass hse晶振被外部时钟旁路*/
hsestartupstatus = rcc_waitforhsestartup();
/*rcc_waitforhsestartup()返回一个errorstatus枚举值,
success好,error未好*/
if(hsestartupstatus == success)//hes就绪
{
rcc_hclkconfig(rcc_sysclk_div1);
//ahb时钟(hclk)=系统时钟
rcc_pclk1config(rcc_hclk_div2);
//设置低速ahb时钟(apb1)为hclk的2分频
rcc_pclk2config(rcc_hclk_div1);
//设置高速ahb时钟(apb2)=hclk时钟
flash_setlatency(flash_latency_2);
//设置flash延时周期数为2
//使能领取指缓存
flash_prefetchbuffercmd(flash_prefetchbuffer_enable);
rcc_pllconfig(rcc_pllsource_hse_div1, rcc_pllmul_9);
//设置pll时钟源及倍频系数,为hse的9倍频 8mhz * 9 = 72mhz
/*void rcc_pllconfig(u32 rcc_pllsource, u32 rcc_pllmul)
rcc_pllsource_hsi_div2 pll输入时钟=hsi/2;
rcc_pllsource_hse_div1 pll输入时钟 =hse
rcc_pllsource_hse_div2 pll输入时钟=hse/2
rcc_pllmul_2 ------_16 pll输入时钟*2---16
pll输出时钟不得超过72mhz*/
rcc_pllcmd(enable);
//enable / disable
while(rcc_getflagstatus(rcc_flag_pllrdy) == reset);//等待pll输出稳定
/*flagstatus rcc_getflagstatus(u8 rcc_flag) 检查指定rcc标志位
返回set or reset
rcc_flag_hsirdy hsi晶振就绪
rcc_flag_hserdy
rcc_flag_pllrdy
rcc_flag_lserdy
rcc_flag_lsirdy.。。。。。.*/
rcc_sysclkconfig(rcc_sysclksource_pllclk);
//设置pll为系统时钟源
/*void rcc_sysclkconfig(u32 rcc_sysclksource) 设置系统时钟
rcc_sysclksource_hsi
rcc_sysclksource_hse
rcc_sysclksource_pllclk 选hsi hse pll 作为系统时钟*/
while(rcc_getsysclksource() != 0x08);
//判断pll是否是系统时钟
/*u8 rcc_getsysclksource(void) 返回用作系统时钟的时钟源
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 时钟在apb1
//打开gpio时钟,复用功能,串口1的时钟
rcc_apb1periphclockcmd(rcc_apb1periph_can1, enable);//使能can1时钟
//好奇怪,是因为官方的库函数更新?
//不是说f10x系列只有一个can,而f4有can1 can2 吗?
//怎么他的系统配置文件里面是can1?????
rcc_apb1periphclockcmd(rcc_apb1periph_tim2, enable); //时钟使能
/*void rcc_apb2periphclockcmd(u32 rcc_apb2periph, functionalstate newstate)
enable 或 disable apb2 外设时钟
rcc_apb2periph_afio 功能复用io 时钟
rcc_apb2periph_gpioa/b/c/d/e gpioa/b/c/d/e 时钟
rcc_apb2periph_adc1/adc2 adc1/2 时钟
rcc_apb2periph_tim1
rcc_apb2periph_spi1
rcc_apb2periph_usart1
rcc_apb2periph_all 全部apb2外设时钟*/
}
iic
#include “myiic.h”
unsigned char i2c_readbyte(unsigned char deviceaddr,unsigned char address); //从24c02的地址address中读取一个字节数据
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《x;i++);
}
void delay_nop(void)
{
unsigned int i=10; //i=10延时1.5us//这里可以优化速度 ,经测试最低到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)//检测从机应答信号
{
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《bytesnum;i++)
{
outdate[i]=iic_readx();
if(i+1《bytesnum) i2c_ack();else i2c_noack();//最后一个字节无需应答
}
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();//最后一个字节无需应答
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();//最后一个字节无需应答
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 作为输出
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引脚输入输出设置
{
gpio_inittypedef gpio_initstructure;
if(io_set==0)
{
gpio_initstructure.gpio_pin = sda; //24c02 sda 作为输出
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 作为输入
gpio_initstructure.gpio_mode = gpio_mode_ipu; //上拉输入
gpio_init(gpiob, &gpio_initstructure);
}
else
{;}
}
delay
#include “delay.h”
static u8 fac_us=0; //us延时倍乘数
static u16 fac_ms=0; //ms延时倍乘数,在ucos下,代表每个节拍的ms数
//初始化延迟函数
//systick的时钟固定为hclk时钟的1/8
//sysclk:系统时钟
void delay_init()
{
systick_clksourceconfig(systick_clksource_hclk_div8); //选择外部时钟 hclk/8
fac_us=systemcoreclock/8000000; //为系统时钟的1/8
fac_ms=(u16)fac_us*1000; //非os下,代表每个ms需要的systick时钟数
}
//延时nus
//nus为要延时的us数。
void delay_us(u32 nus)
{
u32 temp;
systick-》load=nus*fac_us; //时间加载
systick-》val=0x00; //清空计数器
systick-》ctrl|=systick_ctrl_enable_msk ; //开始倒数
do
{
temp=systick-》ctrl;
}while((temp&0x01)&&!(temp&(1《《16))); //等待时间到达
systick-》ctrl&=~systick_ctrl_enable_msk; //关闭计数器
systick-》val =0x00; //清空计数器
}
//延时nms
//注意nms的范围
//systick-》load为24位寄存器,所以,最大延时为:
//nms《=0xffffff*8*1000/sysclk
//sysclk单位为hz,nms单位为ms
//对72m条件下,nms《=1864
void delay_ms(u16 nms)
{
u32 temp;
systick-》load=(u32)nms*fac_ms; //时间加载(systick-》load为24bit)
systick-》val =0x00; //清空计数器
systick-》ctrl|=systick_ctrl_enable_msk ; //开始倒数
do
{
temp=systick-》ctrl;
}while((temp&0x01)&&!(temp&(1《《16))); //等待时间到达
systick-》ctrl&=~systick_ctrl_enable_msk; //关闭计数器
systick-》val =0x00; //清空计数器
}
ms5611
#include “ms5611.h”
/*宏定义------------------------------------------------------------------*/
//定义器件在iic总线中的从地址,根据csb引脚不同修改
//#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)
// 定义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.
/*变量声明----------------------------------------------------------------*/
uint16_t cal_c[7]; //用于存放prom中的6组数据
uint32_t d1_pres,d2_temp; // 存放数字压力和温度
float pressure; //温度补偿大气压
float dt,temperature,temperature2;//实际和参考温度之间的差异,实际温度,中间值
double off,sens; //实际温度抵消,实际温度灵敏度
float aux,off2,sens2; //温度校验值
uint32_t ex_pressure; //串口读数转换值
uint8_t exchange_num[8];
/*函数声明----------------------------------------------------------------*/
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);
/************************************************************
* 函数名:ms561101ba_reset
* 描述 : 复位
* 输入 :无
* 输出 :无
*/
void ms561101ba_reset(void)
{
i2c_noaddr_writebyte(ms561101ba_addr,ms561101ba_reset);
}
/************************************************************
* 函数名:ms561101ba_readprom
* 描述 : 从prom读取出厂校准数据
* 输入 :无
* 输出 :无
*/
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]);
}
/************************************************************
* 函数名:ms561101ba_do_conversion
* 描述 :
* 输入 :无
* 输出 :无
*/
uint32_t ms561101ba_do_conversion(uint8_t command)
{
uint32_t conversion;
i2c_noaddr_writebyte(ms561101ba_addr,command);
delay_ms(10);//延时,去掉数据错误
conversion=i2c_read_3bytes(ms561101ba_addr,0);
return conversion;
}
/************************************************************
* 函数名:ms561101ba_gettemperature
* 描述 : 读取数字温度
* 输入 :过采样率
* 输出 :无
*/
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; //算出温度值的100倍,2001表示20.01°
}
/************************************************************
* 函数名:ms561101ba_getpressure
* 描述 : 读取数字气压
* 输入 :过采样率
* 输出 :无
*/
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;
//温度补偿
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;
sens = sens - sens2;
pressure=(d1_pres*sens/2097152.0-off)/32768.0;
}
/************************************************************
* 函数名:ms561101ba_init
* 描述 : ms561101ba初始化
* 输入 :无
* 输出 :无
*/
void ms561101ba_init(void)
{
ms561101ba_reset();
delay_ms(100);
ms561101ba_readprom();
delay_ms(100);
}
/************************************************************
* 函数名:sampleandexchange
* 描述 : 读取数据并转换串口发送
* 输入 :无
* 输出 :无
*/
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);
}
研究表明可使用超声波技术来测量肺部的液体
海康威视发布2019年度业绩快报
数字人第一剑,先斩“尹天仇”
浅析螺纹铣削相对攻丝的优劣势
Read系统调用在用户空间中的处理过程
STM32+MS5611测气压温度例程详解
已通过 AEC-Q200 认证的 TT Electronics 微型电感器属于低剖面电感器
领先全球!新华三集团Wi-Fi 7AP新品发布
dfrobot蓝牙4.0无线手柄 V2.0简介
无线网络电磁干扰屏蔽技术及应用
巧用面包板搭建实验电路的经验分享
双向晶闸管(TRIAC)结构及原理
荣耀手机怎么升级鸿蒙系统 具体方法
爱因斯坦,手机和你
基于WinCE 5.O操作系统实现工业绣花机人机界面的设计
蒸汽拖把好用吗?轻轻松松让地面一尘不染
如何才能让企业信息安全更加稳固?
研究人员正“教”机器人如何像人类一样思考并做梦
时频域信号分析技术解析
英特尔都收购两家FPGA公司了,你该做点啥?