在过往的实验中,串口数据的正确传输问题一直都没有解决,所以电赛的复习我准备从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!
资料引自网络