这个问题可是如雷贯耳,但是今天还是碰上了,折腾了两小时才发现问题所在。
最近在给前东家开发一款BLE产品,采集两种传感器数据,压力数据3byte,温度数据2byte
最开始的时候压力与温度数据都来自压力传感器GZP6869D,10ms采集一次,然后通过蓝牙和串口发送出去。
数据采集函数如下:
void gzp6869_data_adc(uint8_t * recv_buf)
{
gzp6869_register_read(0x06, recv_buf, 5);
}
//寄存器0x06到0x08是压力数据,0x09-0x0A是温度数据
上周 末接到甲方新需求:
压力传感器只采集压力数据,10ms采集一次,采集70次后打包通过BLE和串口发出;温度数据来至传感器M1601Z,5s采集一次,采集后通过BLE和串口发出。
struct{
uint32_t time_count ; //采集发送计时
uint32_t index; //包号
uint8_t buf[3*70] ; //压力数据3字节,10ms采集一次,采集70次发一包
}acq_press;
struct{
uint32_t time_count ; //采集发送计时
uint32_t index; //包号
uint8_t buf[2] ; //温度数据,5s采集一次并发送
}acq_temp;
//在主循环判断定时器1发生10ms中断后执行该函数
void acq_updata_timeout_10ms(void)
{
//读取压力adc原始数据
gzp6869_data_adc(acq_press.buf + acq_press.time_count*3);
acq_press.time_count ++;
if (acq_press.time_count > 70){//70包
acq_press.time_count = 0;
uint16_t length = 214;
if(bleConnectFlag){
ble_uarts_data_send(&m_uarts, (uint8_t*)&acq_press.index,
&length, m_conn_handle);
}
app_uart_send((uint8_t*)&acq_press, length);
acq_press.index ++;
}
acq_temp.time_count ++;
if (acq_temp.time_count > 500){//5s
acq_temp.time_count = 0;
//采集温度
//传感器驱动代码还未写
uint16_t length = 6;
if(bleConnectFlag){
ble_uarts_data_send(&m_uarts, (uint8_t*)&(acq_temp.index),
&length, m_conn_handle);
}
app_uart_send((uint8_t*)&(acq_temp.index), length);
acq_temp.index ++;
}
}
上边这段代码按照最初的设想应该温度和压力数据的发送周期相差很大,但是在实际测试中总是压力数据和温度数据发送周期都是700ms,也就是acq_temp.time_count被篡改了。
进入调试后发现,当压力数据采集一次后,acq_press.buf[3]和acq_press.buf[4]的值也进行了修改,然后转到函数 gzp6869_data_adc 中才发现,该函数内部也会采集温度数据,
//也就是说尽管我的press的buf大小只有3*70byte,但是指针在第70次采集数据后,
//*(acq_press.buf + 3*70 +1)和*(acq_press.buf + 3*70 +2)的值会是压力传感器的温度数据
//变量acq_press,acq_temp定义内容如下,工程代码中他两的位置关系也是这样的
//那可不acq_press.buf + 3*70 +1 acq_press.buf + 3*70 +2刚好是acq_temp.time_count 的前两个字节
struct{
uint32_t time_count ; //采集发送计时
uint32_t index; //包号
uint8_t buf[3*70] ; //压力数据3字节,10ms采集一次,采集70次发一包
}acq_press;
struct{
uint32_t time_count ; //采集发送计时
uint32_t index; //包号
uint8_t buf[2] ; //温度数据,5s采集一次并发送
}acq_temp;
还算幸运,指针指向了acq_temp.time_count。
要是指向其他地方,来个偶发bug,那可够我喝一壶的了