虽然是坟贴,但是路过回答一波,刚解决了这个问题。楼上的应该没有这种需求过,MS5611读数分两个阶段,即 send command()-> delay(10ms) -> read data()。 其中delay(10ms)是手册写的芯片OSR=4096有大概9.04ms的延迟做ADDA,这10毫秒的延迟对需要100hz以上采样率的IMU应用来说是绝对不允许的。我的解决方案是这样的:
代码段1:
if(svr->baro.step<3&&getsystime_us()-svr->MS5611_step_ltime_us>10000){
process_MS5611(svr);
/* end collecting data */
if(svr->baro.step==3){
//printf("%d %d\r\n",svr->baro.raw_pres,svr->baro.raw_temp);
}
}
代码段2:
extern void process_MS5611(svr_t *svr){
switch(svr->baro.step){
case 0:
/* send pressure commond */
MS5611_send_command(CMD_CONVERT_D1_OSR_4096);
svr->MS5611_ltime_us=getsystime_us();
svr->baro.tow=localt2tow(svr->MS5611_ltime_us+5000);/* it takes about 9.04 ms to get data ready */
break;
case 1:
/* read pressure */
svr->baro.raw_pres=MS5611_read_data();
/* send temperature commond */
MS5611_send_command(CMD_CONVERT_D2_OSR_4096);
break;
case 2:
/* get temperature */
svr->baro.raw_temp=MS5611_read_data();
break;
default:
break;
}
svr->MS5611_step_ltime_us=getsystime_us();
svr->baro.step++;
}
即把网上的例子教程驱动给拆了,分为MS5611_send_command和MS5611_read_data两个函数,然后分次执行,用一个step变量表示现在执行到了哪一步,并且每一步之间需要间隔getsystime_us()-svr->MS5611_step_ltime_us>10000即10ms,然后每次执行一步step++。主函数循环疯狂执行代码段1,当发送完命令之后单片机就去做别的事情了,不在这耗着死等。每次需要读取数据的时候直接把step置为0重新执行即可。
这样一来,这个驱动程序只会被读取数据真正的时间耽误,而不会因为芯片的延迟耽误处理器周期。