stm32cubemx hal学习记录:JY901S串口

一、配置过程

1、配置RCC、SYS、USART1、时钟84MHz

2、配置TIM6,10ms,允许中断,作为控制周期

3、配置USART3,允许中断,其他默认

二、代码编写

1、移植入jy901s的c与h文件

#include "jy901s.h"
#include <string.h>
#include "usart.h"


struct STime		stcTime;
struct SAcc 		stcAcc;
struct SGyro 		stcGyro;
struct SAngle 	stcAngle;
struct SMag 		stcMag;
struct SDStatus stcDStatus;
struct SPress 	stcPress;
struct SLonLat 	stcLonLat;
struct SGPSV 		stcGPSV;
struct SQ       stcQ;

char ACCCALSW[5] = {0XFF,0XAA,0X01,0X01,0X00};//进入加速度校准模式
char SAVACALSW[5]= {0XFF,0XAA,0X00,0X00,0X00};//保存当前配置

char MAGNETICCALAM[5] = {0XFF,0XAA,0X01,0X07,0X00};
char SAVEMAGNETICCALAM[5] = {0XFF,0XAA,0X00,0X00,0X00};

//用串口3给JY模块发送指令
void sendcmd(char cmd[])
{
	char i;
	for(i=0;i<5;i++)
		UART3_send_char(cmd[i]);
}



void uart3_read_data(unsigned char ucData)
{
	static unsigned char ucRxBuffer[256];
	static unsigned char ucRxCount = 0;	
	
	
	ucRxBuffer[ucRxCount++]=ucData;	//将收到的数据存入缓冲区中
	if (ucRxBuffer[0]!=0x55) 				//数据头
	{
		ucRxCount=0;
		return;
	}
	if (ucRxCount<11) {return;}			//数据不满11个,则返回
	else
	{
		switch(ucRxBuffer[1])//判断数据是哪种数据,然后将其拷贝到对应的结构体中,有些数据包需要通过上位机打开对应的输出后,才能接收到这个数据包的数据
		{
			//memcpy为编译器自带的内存拷贝函数,需引用"string.h",将接收缓冲区的字符拷贝到数据结构体里面,从而实现数据的解析。
			case 0x50:	memcpy(&stcTime,&ucRxBuffer[2],8);break;
			case 0x51:	memcpy(&stcAcc,&ucRxBuffer[2],8);break;
			case 0x52:	memcpy(&stcGyro,&ucRxBuffer[2],8);break;
			case 0x53:	memcpy(&stcAngle,&ucRxBuffer[2],8);break;
			case 0x54:	memcpy(&stcMag,&ucRxBuffer[2],8);break;
			case 0x55:	memcpy(&stcDStatus,&ucRxBuffer[2],8);break;
			case 0x56:	memcpy(&stcPress,&ucRxBuffer[2],8);break;
			case 0x57:	memcpy(&stcLonLat,&ucRxBuffer[2],8);break;
			case 0x58:	memcpy(&stcGPSV,&ucRxBuffer[2],8);break;
			case 0x59:	memcpy(&stcQ,&ucRxBuffer[2],8);break;
		}
		ucRxCount=0;	//清空缓存区
	}
}
#ifndef _JY901S_H
#define _JY901S_H


#include "stm32f4xx_hal.h"


void sendcmd(char cmd[]);
void uart3_read_data(unsigned char ucData);


#define SAVE 			0x00
#define CALSW 		0x01
#define RSW 			0x02
#define RRATE			0x03
#define BAUD 			0x04
#define AXOFFSET	0x05
#define AYOFFSET	0x06
#define AZOFFSET	0x07
#define GXOFFSET	0x08
#define GYOFFSET	0x09
#define GZOFFSET	0x0a
#define HXOFFSET	0x0b
#define HYOFFSET	0x0c
#define HZOFFSET	0x0d
#define D0MODE		0x0e
#define D1MODE		0x0f
#define D2MODE		0x10
#define D3MODE		0x11
#define D0PWMH		0x12
#define D1PWMH		0x13
#define D2PWMH		0x14
#define D3PWMH		0x15
#define D0PWMT		0x16
#define D1PWMT		0x17
#define D2PWMT		0x18
#define D3PWMT		0x19
#define IICADDR		0x1a
#define LEDOFF 		0x1b
#define GPSBAUD		0x1c

#define YYMM				0x30
#define DDHH				0x31
#define MMSS				0x32
#define MS					0x33
#define AX					0x34
#define AY					0x35
#define AZ					0x36
#define GX					0x37
#define GY					0x38
#define GZ					0x39
#define HX					0x3a
#define HY					0x3b
#define HZ					0x3c			
#define Roll				0x3d
#define Pitch				0x3e
#define Yaw					0x3f
#define TEMP				0x40
#define D0Status		0x41
#define D1Status		0x42
#define D2Status		0x43
#define D3Status		0x44
#define PressureL		0x45
#define PressureH		0x46
#define HeightL			0x47
#define HeightH			0x48
#define LonL				0x49
#define LonH				0x4a
#define LatL				0x4b
#define LatH				0x4c
#define GPSHeight   0x4d
#define GPSYAW      0x4e
#define GPSVL				0x4f
#define GPSVH				0x50
#define q0          0x51
#define q1          0x52
#define q2          0x53
#define q3          0x54
      
#define DIO_MODE_AIN 0
#define DIO_MODE_DIN 1
#define DIO_MODE_DOH 2
#define DIO_MODE_DOL 3
#define DIO_MODE_DOPWM 4
#define DIO_MODE_GPS 5		

struct STime
{
	unsigned char ucYear;
	unsigned char ucMonth;
	unsigned char ucDay;
	unsigned char ucHour;
	unsigned char ucMinute;
	unsigned char ucSecond;
	unsigned short usMiliSecond;
};

struct SAcc
{
	short a[3];
	short T;
};

struct SGyro
{
	short w[3];
	short T;
};

struct SAngle
{
	short Angle[3];
	short T;
};

struct SMag
{
	short h[3];
	short T;
};

struct SDStatus
{
	short sDStatus[4];
};

struct SPress
{
	long lPressure;
	long lAltitude;
};

struct SLonLat
{
	long lLon;
	long lLat;
};

struct SGPSV
{
	short sGPSHeight;
	short sGPSYaw;
	long lGPSVelocity;
};

struct SQ
{ short q[4];
};

#endif

2、串口读取数据代码

static unsigned char TxBuffer[256];
static unsigned char TxCounter=0;
static unsigned char count=0; 

void UART3_send_char(unsigned char data)
{
	TxBuffer[count++] = data;   
}

void UART3_send_string(unsigned char *str)
{
	while(*str)
	{
		if(*str=='\r')UART3_send_char(0x0d);
			else if(*str=='\n')UART3_send_char(0x0a);
				else UART3_send_char(*str);
		str++;
	}
}

uint8_t Rxdata;
extern void uart3_read_data(unsigned char ucData);
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if (huart->Instance==USART3)
	{
		HAL_UART_Receive_IT(&huart3,&Rxdata,1);
		uart3_read_data(Rxdata);	//处理数据
	}	
}

3、main中代码

extern char ACCCALSW[5];//进入加速度校准模式
extern char SAVACALSW[5];//保存当前配置
extern char MAGNETICCALAM[5];      //磁力计校准
extern char SAVEMAGNETICCALAM[5];  //保存配置

extern uint8_t Rxdata;


HAL_TIM_Base_Start_IT(&htim6);
HAL_UART_Receive_IT(&huart3,&Rxdata,1);

sendcmd(ACCCALSW);HAL_Delay(100); //加速度计校准
sendcmd(SAVACALSW);HAL_Delay(100);//保存当前配置

sendcmd(MAGNETICCALAM);	HAL_Delay(100);   //磁力计校准
sendcmd(SAVEMAGNETICCALAM);HAL_Delay(100);//保存当前配置

4、定时器积分得到航向角

感谢大家支持,很久没看没想到这么多朋友需要代码,不好意思没有及时回复,我把网盘连接放下边了,各位请自取

链接:https://pan.baidu.com/s/12AEUTWJnLenOnc-hvd91SQ?pwd=l1r3 
提取码:l1r3

### 维特智能 JY901B HAL 集成与使用说明 #### 一、HAL 层概述 硬件抽象层(Hardware Abstraction Layer, HAL)是一种软件架构设计模式,用于屏蔽底层硬件的具体实现细节。通过 HAL,上层应用无需关心具体的硬件接口差异即可完成操作。对于 Android 平台而言,HAL 的主要作用是提供标准化的 API 接口供框架调用。 在 Android 中,HAL 是由 C/C++ 编写的库文件组成,并遵循特定的标准定义。为了将维特智能 JY901B 集成到 Android 系统中,需要为其编写对应的 HAL 实现并注册到系统服务中[^1]。 --- #### 二、JY901B 数据通信基础 根据官方文档以及相关资料描述,JY901B 支持 UART 和 SPI 协议进行数据传输。其默认波特率为 115200 bps,在实际开发过程中可以通过配置命令调整波特率或其他参数设置[^3]。 以下是基于 UART 的典型初始化流程: ```cpp void initUART() { // 假设已知串口号为 /dev/ttyS0 或其他设备路径 int fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY); struct termios options; tcgetattr(fd, &options); // 获取当前选项 cfsetispeed(&options, B115200); // 设置输入波特率 cfsetospeed(&options, B115200); // 设置输出波特率 options.c_cflag |= (CLOCAL | CREAD); // 启用接收器 options.c_cflag &= ~PARENB; // 关闭校验位 options.c_cflag &= ~CSTOPB; // 只需停止一位 options.c_cflag &= ~CSIZE; // 清除字符大小掩码 options.c_cflag |= CS8; // 设定每字节8比特 tcsetattr(fd, TCSANOW, &options); // 应用新配置 } ``` 上述代码片段展示了如何针对 Linux/Android 下的串口设备进行基本配置[^2]。 --- #### 三、HAL 文件结构分析 在一个典型的 Android HAL 模块中,通常会包含以下几个部分: 1. **Module Definition**: 定义模块名称及其版本号; 2. **Interface Implementation**: 提供具体功能函数实现; 3. **Device Structure**: 描述设备属性及回调机制。 下面是一个简化版的 HAL 头文件模板示例: ```c // jy901b_hal.h #ifndef ANDROID_JY901B_HAL_H_ #define ANDROID_JY901B_HAL_H_ #include <hardware/hardware.h> __attribute__((visibility("default"))) struct jy901b_device_t : public hw_device_t { int (*readData)(const char* buffer, size_t length); }; #endif /*ANDROID_JY901B_HAL_H_*/ ``` 对应源文件则负责填充这些声明的实际逻辑处理过程。 --- #### 四、数据解析与封装 由于 JY901B 返回的数据是以固定帧格式呈现出来的,因此必须先对其进行解码才能进一步利用。例如加速度计数值位于某一偏移位置处,则可通过如下方式提取出来: ```c int parseAcceleration(const uint8_t *frameBuffer) { float accX = ((float)frameBuffer[OFFSET_ACC_X]) / SCALE_FACTOR; return round(accX * MULTIPLIER); } // OFFSET_ACC_X 和 SCALE_FACTOR 根据实际情况设定 ``` 值得注意的是,不同类型的传感器可能具有不同的更新频率或者精度范围,所以在最终交付前还需要经过充分测试验证准确性。 --- ### 结论 综上所述,要成功把维特智能 JY901B 整合进 Android 环境下的 HAL 架构里边,开发者不仅需要熟悉目标平台的技术栈特点,同时也得掌握该型号产品的通讯协议详情。只有两者相结合才能够构建出稳定可靠的应用场景解决方案。
评论 30
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值