STM32维特智能JY60HAL库读取

维特智能JY60 STM32F103C8T6 HAL库实现读取(基于cubemx)

  • JY60六轴简介
  • 移植准备工作
  • 开始移植
  • 最近帮同学做毕设,要用维特智能家的JY60来读角度,本来以为非常简单,像mpu6050一样改个IIC就移植好了,结果发现维特智能家的陀螺仪协议都是差不多的,但是官方的SDK注释很少,网上也没有几个资料,遂将移植代码的经验分享出来。

    JY60六轴简介

    感觉JY60是维特智能家出口的最拉的陀螺仪了,别的都支持115200波特率,甚至是IIC,就它是9600。

    其实也可以按照官方给的协议自己在串口中断里面接受陀螺仪数据,反正就是一个起始位加三个标志位,最后再来一个校验位,不过我很懒,直接移官方的啦。

    移植准备工作

    首先肯定要下载官方SDK,网站在这。其实也可以直接下载我的程序,不过都无所谓。
    然后就是用cubemx生成代码了,波特率一定是9600,然后串口中断也要打开,我的参考如下:

    开始移植

    直接将官方例程中的wit_c_sdk文件夹下的所有内容copy到你的工程里面,什么都不用改。然后就是将官方程序里面main文件进行修改了,这里面的例程大概就是通过串口2接受陀螺仪数据,然后通过串口1打印到你的电脑中,也可以通过电脑串口来修改陀螺仪数据,不过这些都无所谓,反正JY60有够垃圾的,根本不需要修改,所以真正有效的内容就以下几行,主要就是将回调函数改成你自己的,然后更新数据就行了。

    	WitInit(WIT_PROTOCOL_NORMAL, 0x50);
    //注册回调函数
    	WitSerialWriteRegister(SensorUartSend);
    	WitRegisterCallBack(SensorDataUpdata);
    	WitDelayMsRegister(Delayms);
    
    //更新数据
    		if(s_cDataUpdate)
    		{
    			for(i = 0; i < 3; i++)
    			{
    				fAcc[i] = sReg[AX+i] / 32768.0f * 16.0f;
    				fGyro[i] = sReg[GX+i] / 32768.0f * 2000.0f;
    				fAngle[i] = sReg[Roll+i] / 32768.0f * 180.0f;
    			}
    			if(s_cDataUpdate & ACC_UPDATE)
    			{
    				printf("acc:%.3f %.3f %.3f\r\n", fAcc[0], fAcc[1], fAcc[2]);
    				s_cDataUpdate &= ~ACC_UPDATE;
    			}
    			if(s_cDataUpdate & GYRO_UPDATE)
    			{
    				printf("gyro:%.3f %.3f %.3f\r\n", fGyro[0], fGyro[1], fGyro[2]);
    				s_cDataUpdate &= ~GYRO_UPDATE;
    			}
    			if(s_cDataUpdate & ANGLE_UPDATE)
    			{
    				printf("angle:%.3f %.3f %.3f\r\n", fAngle[0], fAngle[1], fAngle[2]);
    				s_cDataUpdate &= ~ANGLE_UPDATE;
    			}
    			if(s_cDataUpdate & MAG_UPDATE)
    			{
    				printf("mag:%d %d %d\r\n", sReg[HX], sReg[HY], sReg[HZ]);
    				s_cDataUpdate &= ~MAG_UPDATE;
    			}
    		}
    

    虽然说更新数据,数据从哪来呢,因此需要在串口中断回调函数中将数据添加进官方缓存区中,如下:

    void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
    {
    	
    	if(huart->Instance == USART1)
    	{
    			WitSerialDataIn(RxBuffer);
    			HAL_UART_Receive_IT(&huart1, &RxBuffer, 1);   //再开启接收中断
    	}
    }
    
    

    现在就移植完成啦,下面是完整的移植代码,我直接创建了一个文件,将所有函数都包含进去了,大概思路就是在串口初始化后调用jy60_init,然后在循环中一直调用jy60_read(),这样数据就会填入 fAcc[3], fGyro[3], fAngle[3] 中,直接读就行,有想看完整工程的可以来这里。

    #include "main.h"
    #include "stm32f1xx_it.h"
    #include "usart.h"
    #include "wit_c_sdk.h"
    #include "OLED_I2C.h"
    
    #define ACC_UPDATE		0x01
    #define GYRO_UPDATE		0x02
    #define ANGLE_UPDATE	0x04
    #define MAG_UPDATE		0x08
    #define READ_UPDATE		0x80
    static volatile char s_cDataUpdate = 0, s_cCmd = 0xff;
    const uint32_t c_uiBaud[10] = {0, 4800, 9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600};
    float fAcc[3], fGyro[3], fAngle[3];
    
    static void CmdProcess(void);
    static void AutoScanSensor(void);
    static void SensorUartSend(uint8_t *p_data, uint32_t uiSize);
    static void SensorDataUpdata(uint32_t uiReg, uint32_t uiRegNum);
    static void Delayms(uint16_t ucMs);
    
    
    uint8_t RxBuffer;
    
    
    static void SensorUartSend(uint8_t *p_data, uint32_t uiSize)
    {
    	HAL_UART_Transmit(&huart1, p_data,uiSize, 999);
    }
    
    static void Delayms(uint16_t ucMs)
    {
    	HAL_Delay(ucMs);
    }
    
    static void SensorDataUpdata(uint32_t uiReg, uint32_t uiRegNum)
    {
    	int i;
        for(i = 0; i < uiRegNum; i++)
        {
            switch(uiReg)
            {
    //            case AX:
    //            case AY:
                case AZ:
    				s_cDataUpdate |= ACC_UPDATE;
                break;
    //            case GX:
    //            case GY:
                case GZ:
    				s_cDataUpdate |= GYRO_UPDATE;
                break;
    //            case HX:
    //            case HY:
                case HZ:
    				s_cDataUpdate |= MAG_UPDATE;
                break;
    //            case Roll:
    //            case Pitch:
                case Yaw:
    				s_cDataUpdate |= ANGLE_UPDATE;
                break;
                default:
    				s_cDataUpdate |= READ_UPDATE;
    			break;
            }
    		uiReg++;
        }
    }
    
    void jy60_init()
    {
    		WitInit(WIT_PROTOCOL_NORMAL, 0x50);
    		WitSerialWriteRegister(SensorUartSend);
    		WitRegisterCallBack(SensorDataUpdata);
    		WitDelayMsRegister(Delayms);
    		HAL_UART_Receive_IT(&huart1, &RxBuffer, 1); //开启串口中断接受1字节
    		HAL_Delay(100);
    }
    
    void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
    {
    	
    	if(huart->Instance == USART1)
    	{
    			WitSerialDataIn(RxBuffer);
    			HAL_UART_Receive_IT(&huart1, &RxBuffer, 1);   //再开启接收中断
    	}
    }
    
    
    
    void jy60_read()
    {
    		if(s_cDataUpdate)
    		{
    			for(uint8_t i = 0; i < 3; i++)
    			{
    				fAcc[i] = sReg[AX+i] / 32768.0f * 16.0f;
    				fGyro[i] = sReg[GX+i] / 32768.0f * 2000.0f;
    				fAngle[i] = sReg[Roll+i] / 32768.0f * 180.0f;
    			}
    //			uint8_t strff[21];
    //			
    //			sprintf(strff,"%.2f",fAngle[2]);
    //			
    //			OLED_ShowStr(0,3,strff,1);
    			if(s_cDataUpdate & ACC_UPDATE)
    			{
    //				printf("acc:%.3f %.3f %.3f\r\n", fAcc[0], fAcc[1], fAcc[2]);
    				s_cDataUpdate &= ~ACC_UPDATE;
    			}
    			if(s_cDataUpdate & GYRO_UPDATE)
    			{
    //				printf("gyro:%.3f %.3f %.3f\r\n", fGyro[0], fGyro[1], fGyro[2]);
    				s_cDataUpdate &= ~GYRO_UPDATE;
    			}
    			if(s_cDataUpdate & ANGLE_UPDATE)
    			{
    //				printf("angle:%.3f %.3f %.3f\r\n", fAngle[0], fAngle[1], fAngle[2]);
    				s_cDataUpdate &= ~ANGLE_UPDATE;
    			}
    			if(s_cDataUpdate & MAG_UPDATE)
    			{
    //				printf("mag:%d %d %d\r\n", sReg[HX], sReg[HY], sReg[HZ]);
    				s_cDataUpdate &= ~MAG_UPDATE;
    			}
    		}
    		
    }
    	
    

    作者:accentd

    物联沃分享整理
    物联沃-IOTWORD物联网 » STM32维特智能JY60HAL库读取

    发表回复