在过往的实验中,串口数据的正确传输问题一直都没有解决,所以电赛的复习我准备从USART串口的应用开始,以JY61模块为实践客体,尝试掌握熟练收发数据的能力。倘若成功,串行总线电机PID以及openmv联动都能够有较大的突破。
串口间数据的传送是十六进制的形式,JY61模块的主要通讯协议如下:
1.默认波特率为115200,也可设为9600 |
2.默认使用UART模式,也可设为I2C模式 |
3.角度初始化指令:0xFF 0xAA 0x52 |
4.输出角度的数据格式如下: |
角度计算公式:
滚转角(x轴)Roll=((RollH<<8)|RollL)/32768*180(°)
俯仰角(y轴)Pitch=((PitchH<<8)|PitchL)/32768*180(°)
偏航角(z轴)Yaw=((YawH<<8)|YawL)/32768*180(°)
校验和:
Sum=0x55+0x53+RollH+RollL+PitchH+PitchL+YawH+YawL+TH+TL
整合数据的函数如下:
void getData(unsigned char ucData) { static unsigned char ucRxBuffer[250]; static unsigned char ucRxCnt = 0; ucRxBuffer[ucRxCnt++]=ucData; //将收到的数据存入缓冲区中 if (ucRxBuffer[0]!=0x55) //数据头不对,则重新开始寻找0x55数据头 { ucRxCnt=0; return; } if (ucRxCnt<11) {return;}//数据不满11个,则返回 else { switch(ucRxBuffer[1])//判断数据是哪种数据,然后将其拷贝到对应的结构体中,有些数据包需要通过上位机打开对应的输出后,才能接收到这个数据包的数据 { //memcpy为编译器自带的内存拷贝函数,需引用"string.h",将接收缓冲区的字符拷贝到数据结构体里面,从而实现数据的解析。 case 0x51: memcpy(&stcAcc,&ucRxBuffer[2],8);break; case 0x52: memcpy(&stcGyro,&ucRxBuffer[2],8);break; case 0x53: memcpy(&stcAngle,&ucRxBuffer[2],8);break; } ucRxCnt=0;//清空缓存区 } }
串口1的中断函数如下:
void DEBUG_USART_IRQHandler1(void) { if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET) { USART_SendData(USART1, TxBuffer[TxCounter++]); if(TxCounter == count) { USART_ITConfig(USART1, USART_IT_TXE, DISABLE);// 全部发送完成 } USART_ClearITPendingBit(USART1, USART_IT_TXE); } else if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) { CopeSerial2Data((unsigned char)USART1->DR);//处理数据 USART_ClearITPendingBit(USART1, USART_IT_RXNE); } USART_ClearITPendingBit(USART1,USART_IT_ORE); }
串口1至3都已配置完成,测试通过,收发都能触发中断。
此时,发现旧的模块可能坏了,反正没有亮灯,无法得知其内部状况。且新旧模块的协议略有差异,待明日新模块到了,即可测试。
May the force be with us!
资料引自网络