因为课题有要使用这个传感器读取姿态的要求,所以试了一下使用AIR32的USART读取了一下

首先是使用AIR32f103的USART这个和stm32f103是一样的,这里用的标准库来初始化

void USART1_Init(uint32_t bound)
{
	GPIO_InitTypeDef 		GPIO_InitStructure;
	USART_InitTypeDef               USART_InitStructure;
#if USART_RX_INT_ENABLE
	NVIC_InitTypeDef  		NVIC_InitStructure;
#endif
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOB
        |RCC_APB2Periph_AFIO,ENABLE);
	
	GPIO_PinRemapConfig(GPIO_Remap_USART1,ENABLE);
	
	//TX
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//复用推挽
	GPIO_Init(GPIOB, &GPIO_InitStructure);			//初始化IO
	//RX
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;	//上拉输入
	GPIO_Init(GPIOB, &GPIO_InitStructure);			//初始化IO
	
	USART_InitStructure.USART_BaudRate = bound;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
	USART_InitStructure.USART_Parity = USART_Parity_No;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_Init(USART1,&USART_InitStructure);
	
#if USART_RX_INT_ENABLE
	USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_Init(&NVIC_InitStructure);
#endif
	
	USART_Cmd(USART1,ENABLE);
}

这里是在头文件写了个标志位使能了接收中断(也是埋坑的开始)

然后是写一下维特私有协议的数据包接收函数

/*
发送特定带数据头数据尾的数据
Long:要发的数据字节长度
*/
void USART1_SendPacket(uint16_t Long)
{
	//如果使能了自定义数据包包头
	#if USART_PackHand
	USART1_Sendbyte(PackHand);
	#endif
	USART1_SendArray(USART1_TxPacket,Long);
	//如果使能了自定义数据包包尾
	#if USART_PackEnd
	USART1_Sendbyte(PackEnd);
	#endif
	//如果使能了维特私有协议数据包包尾
	#if WIT_PackEnd
	static uint8_t JWIT;
	JWIT = 0x55+USART1_TxPacket[0]+USART1_TxPacket[1]+USART1_TxPacket[2]+USART1_TxPacket[3]+USART1_TxPacket[4]+USART1_TxPacket[5]+USART1_TxPacket[6]+USART1_TxPacket[7]+USART1_TxPacket[8]+USART1_TxPacket[9];
	USART1_Sendbyte(JWIT);
	#endif
}
//接收中断函数
void USART1_IRQHandler(void)
{
	static uint8_t RxState = 0;
	static uint8_t pRxPacket = 0;
	if (USART_GetITStatus(USART1, USART_IT_RXNE) == SET)
	{
		uint8_t RxData = USART_ReceiveData(USART1);
		
		if (RxState == 0)
		{
			if (RxData == PackHand)
			{
				RxState = 1;
				pRxPacket = 0;
			}
		}
		else if (RxState == 1)
		{
			USART1_RxPacket[pRxPacket] = RxData;
			pRxPacket ++;
			if (pRxPacket >= PackLenght)
			{
				
				RxState = 2;
			}
			
		}
		else if (RxState == 2)
		{
			#if USART_PackEnd
			if (RxData == PackEnd)
			{
				RxState = 0;
				USART1_RxFlag = 1;
			}
			#endif
			#if WIT_PackEnd
			static uint8_t JWIT;
			JWIT = 0x55+USART1_RxPacket[0]+USART1_RxPacket[1]+USART1_RxPacket[2]+USART1_RxPacket[3]+USART1_RxPacket[4]+USART1_RxPacket[5]+USART1_RxPacket[6]+USART1_RxPacket[7]+USART1_RxPacket[8];
			if (RxData == JWIT)
			{

				if(witbuf == 0)
				{
					for(uint8_t i; i<PackLenght;i++)
					{
						WITBKPPacket[i] = USART1_RxPacket[i];
					}
				}
				RxState = 0;
				witbuf = 1;
				USART1_RxFlag = 1;
			}
			else
			{
				for(uint8_t i; i<PackLenght; i++)
				{
					USART1_RxPacket[i] = 0;
				}
			}
			#endif
		}
		
		USART_ClearITPendingBit(USART1, USART_IT_RXNE);
	}
}

这里面有几个变量是在之前定义过的

  • USART1_TxPacket 发送数据包缓冲
  • USART1_RxPacket 接收数据包缓冲
  • WITBKPPacket 维特接收数据包缓冲
  • USART1接收中断
  • USART_RX_INT_ENABLE 1 //0,不使能; 1,使能;
  • 是否使用自定义数据包包头
  • USART_PackHand 1 //0,不使能; 1,使能;
  • 是否使用自定义数据包包尾
  • USART_PackEnd 0 //0,不使能; 1,使能;
  • 是否使用维特数据包包尾
  • WIT_PackEnd 1 //0,不使能; 1,使能;
  • 自定义数据包包头
  • PackHand 0x55 //数据包头部字节
  • 自定义数据包包尾
  • PackEnd 0x4E //数据包尾部字节
  • 自定义数据包载荷数据长度
  • PackLenght 9 //数据包数据长度

这些缓冲数据到时候一定要extern出去哈,不然外部数据就无法调用了

然后就是讲一些我遇到的坑,我一开始写的完接收代码核对接收的数据都没有问题以后就开始着手写数据处理函数

从上面的图片看着接收没问题是吧,但是当我写完数据处理看处理出来的数据就不对劲了。。。。。

这里的-0.015是正常值,13.459是异常值,我一开始以为是通讯有问题可能有干扰,加了一个简单的滤波函数试试能不能管用,但是测试下来问题依旧,我以为是程序跑飞了因为中断太频繁,因为这个传感器是一直在发送数据的,就加了在计算时关闭全局中断,计算完毕再打开全局中断,但是还是问题依旧,但是问题大概是找到了,就是当单片机在数据数据或是在读取数据的时候进了中断,可能高八位还是上一个数据的但是低八位已经是下一个数据的了这其实影响也不大,因为数据的变化是线性的,应该也不会出现那么大的跳变,最致命的是因为好几种数据叠加在一起了,所以可能是计算是加速度的数据,高八位是本帧的但是在读取低八位时进了中断,导致低八位可能是角速度的低八位,数据就混乱了,最后解决的方法就是给数据加上写保护或读保护,让在处理数据时即使进入中断,我的数据也是不会变的,只有在我处理完这个数据以后才可以将新的数据缓存进来。

然后放一下修改后程序的读数

数据基本稳定,不会有大的波动了。

最后放一下程序,初学者写的很烂,见谅。。。。

#ifndef __USART1_H
#define __USART1_H 			   
#include 	"air32f10x.h"


//USART1接收RX中断使能
#define USART_RX_INT_ENABLE	      1		             //0,不使能; 1,使能;	
//是否使用自定义数据包包头
#define USART_PackHand  	      1		             //0,不使能; 1,使能;
//是否使用自定义数据包包尾
#define USART_PackEnd   	      0		             //0,不使能; 1,使能;	
//是否使用维特数据包包尾
#define WIT_PackEnd  	          1		             //0,不使能; 1,使能;	
//自定义数据包包头
#define PackHand                  0x55               //数据包头部字节
//自定义数据包包尾
#define PackEnd                   0x4E               //数据包尾部字节
//自定义数据包载荷数据长度
#define PackLenght                 9                 //数据包数据长度

extern uint8_t USART1_TxPacket[];				//数据包中的数据部分
extern uint8_t USART1_RxPacket[];


extern uint8_t WITBKPPacket[9];				//维特接收数据包缓冲

/*
使用示例:将USART1接收到的数据包通过USART1发送出来
if(UASRT1_GetRxFlag() ==1)
{
	USART1_SendArray(USART1_RxPacket,9);
}
*/


void USART1_Init(uint32_t bound);


void USART1_Sendbyte(uint8_t Byte);
void USART1_SendArray(uint8_t *Array, uint16_t Length);
void USART1_SendString(char *String);
void USART1_SendNumber(uint32_t Number, uint8_t Length);
void USART1_Printf(char *format, ...);
uint8_t UASRT1_GetRxFlag(void);

void USART1_SendPacket(uint16_t Long);

	

#endif
#include "usart1.h"
#include "witttl.h"
#include <stdio.h>
#include <stdarg.h>





uint8_t USART1_RxData;                   	//USART1接收到的数据
uint8_t USART1_RxFlag;                   	//USART1接收到数标志位

uint8_t USART1_TxPacket[11];				//发送数据包缓冲
uint8_t USART1_RxPacket[9];				//接收数据包缓冲
uint8_t WITBKPPacket[9];				//维特接收数据包缓冲

void USART1_Init(uint32_t bound)
{
	GPIO_InitTypeDef 		GPIO_InitStructure;
	USART_InitTypeDef       USART_InitStructure;
#if USART_RX_INT_ENABLE
	NVIC_InitTypeDef  		NVIC_InitStructure;
#endif
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO,ENABLE);
	
	GPIO_PinRemapConfig(GPIO_Remap_USART1,ENABLE);
	
	//TX
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//复用推挽
	GPIO_Init(GPIOB, &GPIO_InitStructure);			//初始化IO
	//RX
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;	//上拉输入
	GPIO_Init(GPIOB, &GPIO_InitStructure);			//初始化IO
	
	USART_InitStructure.USART_BaudRate = bound;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
	USART_InitStructure.USART_Parity = USART_Parity_No;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_Init(USART1,&USART_InitStructure);
	
#if USART_RX_INT_ENABLE
	USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_Init(&NVIC_InitStructure);
#endif
	
	USART_Cmd(USART1,ENABLE);
}

void USART1_Sendbyte(uint8_t Byte)
{
	USART_SendData(USART1,Byte);
	while (USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);
}

void USART1_SendArray(uint8_t *Array, uint16_t Length)
{
	uint16_t i;
	for(i=0; i<Length; i++)
	{
		USART1_Sendbyte(Array[i]);
	}
}

void USART1_SendString(char *String)
{
	uint8_t i;
	for(i=0; String[i] != '\0'; i++)
	{
		USART1_Sendbyte(String[i]);
	}
}

uint32_t USART1_Pow(uint32_t X, uint32_t Y)
{
	uint32_t Result = 1;
	while (Y --)
	{
		Result *= X;
	}
	return Result;
}

void USART1_SendNumber(uint32_t Number, uint8_t Length)
{
	uint8_t i;
	for (i = 0; i < Length; i ++)
	{
		USART1_Sendbyte(Number / USART1_Pow(10, Length - i - 1) % 10 + '0');
	}
}

int fputc(int ch, FILE *f)
{
	USART1_Sendbyte(ch);
	return ch;
}

void USART1_Printf(char *format, ...)
{
	char String[100];
	va_list arg;
	va_start(arg, format);
	vsprintf(String, format, arg);
	va_end(arg);
	USART1_SendString(String);
}

uint8_t UASRT1_GetRxFlag(void)
{
	if(USART1_RxFlag == 1)
	{
		USART1_RxFlag = 0;
		return 1;
	}
	return 0;
}

uint8_t UASRT1_RxData(void)
{
	return USART1_RxData;
}
/*
发送特定带数据头数据尾的数据
Long:要发的数据字节长度
*/
void USART1_SendPacket(uint16_t Long)
{
	//如果使能了自定义数据包包头
	#if USART_PackHand
	USART1_Sendbyte(PackHand);
	#endif
	USART1_SendArray(USART1_TxPacket,Long);
	//如果使能了自定义数据包包尾
	#if USART_PackEnd
	USART1_Sendbyte(PackEnd);
	#endif
	//如果使能了维特私有协议数据包包尾
	#if WIT_PackEnd
	static uint8_t JWIT;
	JWIT = 0x55+USART1_TxPacket[0]+USART1_TxPacket[1]+USART1_TxPacket[2]+USART1_TxPacket[3]+USART1_TxPacket[4]+USART1_TxPacket[5]+USART1_TxPacket[6]+USART1_TxPacket[7]+USART1_TxPacket[8]+USART1_TxPacket[9];
	USART1_Sendbyte(JWIT);
	#endif
}
//接收中断函数
void USART1_IRQHandler(void)
{
	static uint8_t RxState = 0;
	static uint8_t pRxPacket = 0;
	if (USART_GetITStatus(USART1, USART_IT_RXNE) == SET)
	{
		uint8_t RxData = USART_ReceiveData(USART1);
		
		if (RxState == 0)
		{
			if (RxData == PackHand)
			{
				RxState = 1;
				pRxPacket = 0;
			}
		}
		else if (RxState == 1)
		{
			USART1_RxPacket[pRxPacket] = RxData;
			pRxPacket ++;
			if (pRxPacket >= PackLenght)
			{
				
				RxState = 2;
			}
			
		}
		else if (RxState == 2)
		{
			#if USART_PackEnd
			if (RxData == PackEnd)
			{
				RxState = 0;
				USART1_RxFlag = 1;
			}
			#endif
			#if WIT_PackEnd
			static uint8_t JWIT;
			JWIT = 0x55+USART1_RxPacket[0]+USART1_RxPacket[1]+USART1_RxPacket[2]+USART1_RxPacket[3]+USART1_RxPacket[4]+USART1_RxPacket[5]+USART1_RxPacket[6]+USART1_RxPacket[7]+USART1_RxPacket[8];
			if (RxData == JWIT)
			{

				if(witbuf == 0)
				{
					for(uint8_t i; i<PackLenght;i++)
					{
						WITBKPPacket[i] = USART1_RxPacket[i];
					}
				}
				RxState = 0;
				witbuf = 1;
				USART1_RxFlag = 1;
			}
			else
			{
				for(uint8_t i; i<PackLenght; i++)
				{
					USART1_RxPacket[i] = 0;
				}
			}
			#endif
		}
		
		USART_ClearITPendingBit(USART1, USART_IT_RXNE);
	}
}
#ifndef __WITTTL_H
#define __WITTTL_H
#include "air32f10x.h"

//陀螺仪静止不动时本库读数容易出现细微跳变
//加速度X
extern float ACC_X;
//加速度Y
extern float ACC_Y;
//加速度Z
extern float ACC_Z;
//维特传感器温度
extern float WIT_Temp;
//角速度X
extern float AGLSPEED_X;
//角速度Y
extern float AGLSPEED_Y;
//角速度Z
extern float AGLSPEED_Z;
//角度X
extern float AGL_X;
//角度Y
extern float AGL_Y;
//角度Z
extern float AGL_Z;
//四元数
extern float q0;
extern float q1;
extern float q2;
extern float q3;
//传感器接收数据缓存写保护标志位
extern uint8_t witbuf;

void WIT_GET_Date(void);



#endif
#include "witttl.h"
#include "usart1.h"
#include "delay.h"

//获取到的数据
//加速度单位:    g     | 默认值9.8m/s2
//温度单位:    °C     | 摄氏度
//角速度单位:  °/s    | 度/秒
//角度单位:    °      | 度
//加速度X
float ACC_X;
//加速度Y
float ACC_Y;
//加速度Z
float ACC_Z;
//维特传感器温度
float WIT_Temp;
//角速度X
float AGLSPEED_X;
//角速度Y
float AGLSPEED_Y;
//角速度Z
float AGLSPEED_Z;
//角度X
float AGL_X;
//角度Y
float AGL_Y;
//角度Z
float AGL_Z;
//四元数
float q0;
float q1;
float q2;
float q3;
//传感器接收数据缓存写保护标志位
uint8_t witbuf =0;

void WIT_GET_Date(void)
{
	if(UASRT1_GetRxFlag() ==1)
	{
		witbuf = 1;
	
		static int16_t AXBUF,AYBUF,AZBUF,WITTBUF,AGSBUF_X,AGSBUF_Y,AGSBUF_Z,AGLXBUF,AGLYBUF,AGLZBUF,q0BUF,q1BUF,q2BUF,q3BUF;      //创建数据运算缓存
		switch(WITBKPPacket[0])
		{
			case 0x51:
				AXBUF = (int16_t)((int16_t)(WITBKPPacket[2] << 8) | WITBKPPacket[1]);
				AYBUF = (int16_t)((int16_t)(WITBKPPacket[4] << 8) | WITBKPPacket[3]);
				AZBUF = (int16_t)((int16_t)(WITBKPPacket[6] << 8) | WITBKPPacket[5]);
				WITTBUF = (int16_t)((int16_t)(WITBKPPacket[8] << 8) | WITBKPPacket[7]);
				ACC_X = (float)AXBUF / 32768 * 16;
				ACC_Y = (float)AYBUF / 32768 * 16;
				ACC_Z = (float)AZBUF / 32768 * 16;
				WIT_Temp = (float)WITTBUF / 100;
				witbuf = 0;
				break;
			case 0x52:
				AGSBUF_X = (int16_t)((int16_t)(WITBKPPacket[2] << 8) | WITBKPPacket[1]);
				AGSBUF_Y = (int16_t)((int16_t)(WITBKPPacket[4] << 8) | WITBKPPacket[3]);
				AGSBUF_Z = (int16_t)((int16_t)(WITBKPPacket[6] << 8) | WITBKPPacket[5]);
				AGLSPEED_X = (float)AGSBUF_X / 32768 * 2000;
				AGLSPEED_Y = (float)AGSBUF_Y / 32768 * 2000;
				AGLSPEED_Z = (float)AGSBUF_Z / 32768 * 2000;
			case 0x53:
				AGLXBUF = (int16_t)((int16_t)(WITBKPPacket[2] << 8) | WITBKPPacket[1]);
				AGLYBUF = (int16_t)((int16_t)(WITBKPPacket[4] << 8) | WITBKPPacket[3]);
				AGLZBUF = (int16_t)((int16_t)(WITBKPPacket[6] << 8) | WITBKPPacket[5]);
				AGL_X = (float)AGLXBUF * 180 / 32768;
				AGL_Y = (float)AGLYBUF * 180 / 32768;
				AGL_Z = (float)AGLZBUF * 180 / 32768;
				witbuf = 0;
				break;
			case 0x59:
				q0BUF = (int16_t)((int16_t)(WITBKPPacket[2] << 8) | WITBKPPacket[1]);
				q1BUF = (int16_t)((int16_t)(WITBKPPacket[4] << 8) | WITBKPPacket[3]);
				q2BUF = (int16_t)((int16_t)(WITBKPPacket[6] << 8) | WITBKPPacket[5]);
				q3BUF = (int16_t)((int16_t)(WITBKPPacket[8] << 8) | WITBKPPacket[7]);
				q0 = (float)q0BUF / 32768;
				q1 = (float)q1BUF / 32768;
				q2 = (float)q2BUF / 32768;
				q3 = (float)q3BUF / 32768;
			default:
				witbuf = 0;
				break;
		}
	}
}