init:初始框架

This commit is contained in:
SkyLi
2026-06-06 20:50:54 +08:00
commit b5be64b642
685 changed files with 398844 additions and 0 deletions
@@ -0,0 +1,226 @@
/*********************************************************************************************************************
* MSPM0G3507 Opensource Library 即(MSPM0G3507 开源库)是一个基于官方 SDK 接口的第三方开源库
* Copyright (c) 2022 SEEKFREE 逐飞科技
*
* 本文件是 MSPM0G3507 开源库的一部分
*
* MSPM0G3507 开源库 是免费软件
* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款
* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它
*
* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证
* 甚至没有隐含的适销性或适合特定用途的保证
* 更多细节请参见 GPL
*
* 您应该在收到本开源库的同时收到一份 GPL 的副本
* 如果没有,请参阅<https://www.gnu.org/licenses/>
*
* 额外注明:
* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本
* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中
* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件
* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明)
*
* 文件名称 zf_device_absolute_encoder
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 MDK 5.37
* 适用平台 MSPM0G3507
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2025-06-1 SeekFree first version
********************************************************************************************************************/
/*********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* SCLK 查看 zf_device_absolute_encoder.h 中 ABSOLUTE_ENCODER_SCLK_PIN 宏定义
* MOSI 查看 zf_device_absolute_encoder.h 中 ABSOLUTE_ENCODER_MOSI_PIN 宏定义
* MISO 查看 zf_device_absolute_encoder.h 中 ABSOLUTE_ENCODER_MISO_PIN 宏定义
* CS 查看 zf_device_absolute_encoder.h 中 ABSOLUTE_ENCODER_CS_PIN 宏定义
* VCC 3.3V电源
* GND 电源地
* ------------------------------------
********************************************************************************************************************/
#include "zf_common_clock.h"
#include "zf_common_debug.h"
#include "zf_common_function.h"
#include "zf_driver_delay.h"
#include "zf_driver_spi.h"
#include "zf_device_absolute_encoder.h"
static int16 now_location[4] = {0};
static int16 last_location[4] = {0};
gpio_pin_enum absolute_encoder_cs_list[ABSOLUTE_ENCODER_CS_PIN_MAX] = ABSOLUTE_ENCODER_CS_PIN_LIST;
#define absolute_encoder_read() (spi_read_8bit(ABSOLUTE_ENCODER_SPI))
#define absolute_encoder_write(data) (spi_write_8bit(ABSOLUTE_ENCODER_SPI, (data)))
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 绝对值编码器写寄存器
// 参数说明 index 编码器索引
// 参数说明 reg 寄存器地址
// 参数说明 data 数据
// 返回参数 void
// 使用示例 absolute_encoder_write_register(i + 1, dat[i]);
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
static void absolute_encoder_write_register(uint8 index, uint8 reg, uint8 data)
{
ABSOLUTE_ENCODER_CS(index, 0); // 片选拉低选中
absolute_encoder_write(reg | ABSOLUTE_ENCODER_SPI_W); // 寄存器
absolute_encoder_write(data); // 数据
ABSOLUTE_ENCODER_CS(index, 1); // 片选拉高释放
system_delay_us(1); // 必要操作
ABSOLUTE_ENCODER_CS(index, 0); // 片选拉低选中
absolute_encoder_read(); // 这里会返回写入是否成功 但不作判断
absolute_encoder_read(); // 必要操作
ABSOLUTE_ENCODER_CS(index, 1); // 片选拉高释放
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 绝对值编码器读寄存器 内部调用
// 参数说明 index 编码器索引
// 参数说明 reg 寄存器地址
// 返回参数 uint8 数据
// 使用示例 absolute_encoder_read_register(6);
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
static uint8 absolute_encoder_read_register (uint8 index, uint8 reg)
{
uint8 data = 0;
ABSOLUTE_ENCODER_CS(index, 0); // 片选拉低选中
absolute_encoder_write(reg | ABSOLUTE_ENCODER_SPI_R); // 寄存器
absolute_encoder_write(0x00); // 占位
ABSOLUTE_ENCODER_CS(index, 1); // 片选拉高释放
system_delay_us(1); // 必要操作
ABSOLUTE_ENCODER_CS(index, 0); // 片选拉低选中
data = absolute_encoder_read(); // 获取读取的数据
absolute_encoder_read(); // 必要操作
ABSOLUTE_ENCODER_CS(index, 1); // 片选拉高释放
return data;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 绝对值编码器读位置 内部调用
// 参数说明 index 编码器索引
// 返回参数 uint16 位置值
// 使用示例 absolute_encoder_read_data();
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
static uint16 absolute_encoder_read_data (uint8 index)
{
uint16 data = 0;
ABSOLUTE_ENCODER_CS(index, 0); // 片选拉低选中
data = absolute_encoder_read(); // 获取高八位数据
data = (data & 0x00FF) << 8; // 数据位移
data |= absolute_encoder_read(); // 获取低八位数据
ABSOLUTE_ENCODER_CS(index, 1); // 片选拉高释放
return data;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 绝对值编码器自检 内部调用
// 参数说明 index 编码器索引
// 返回参数 uint8 自检状态
// 使用示例 absolute_encoder_self_check();
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
static uint8 absolute_encoder_self_check (uint8 index)
{
uint8 i = 0, return_state = 0;
uint8 dat[6] = {0, 0, 0, 0xC0, 0xFF, 0x1C};
uint16 time_count = 0;
while(0x1C != absolute_encoder_read_register(index, 6)) // 获取状态寄存器
{
for(i = 0; 6 > i; i ++)
{
absolute_encoder_write_register(index, i + 1, dat[i]); // 写入默认配置参数
system_delay_ms(1);
}
if(ABSOLUTE_ENCODER_TIMEOUT_COUNT < time_count ++) // 等待超时
{
return_state = 1;
break;
}
}
return return_state;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 绝对值编码器获取当前角度值
// 参数说明 index 编码器索引
// 返回参数 int16 角度值
// 使用示例 absolute_encoder_get_location();
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
int16 absolute_encoder_get_location (uint8 index)
{
last_location[index] = now_location[index];
now_location[index] = absolute_encoder_read_data(index) >> 4;
return now_location[index];
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 绝对值编码器获取相较上次位置的偏移值
// 参数说明 index 编码器索引
// 返回参数 int16 偏移值
// 使用示例 absolute_encoder_get_offset();
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
int16 absolute_encoder_get_offset (uint8 index)
{
int16 result_data = 0;
if(2048 < func_abs(now_location[index] - last_location[index]))
{
result_data = (2048 < now_location[index] ? (now_location[index] - 4096 - last_location[index]) : (now_location[index] + 4096 - last_location[index]));
}
else
{
result_data = (now_location[index] - last_location[index]);
}
return result_data;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 绝对值编码器初始化
// 参数说明 index 编码器索引
// 返回参数 uint8 初始化状态 0-成功 1-失败
// 使用示例 absolute_encoder_init(index);
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
uint8 absolute_encoder_init (uint8 index)
{
uint8 return_state = 0;
uint16 zero_position = ABSOLUTE_ENCODER_DEFAULT_ZERO;
spi_init(ABSOLUTE_ENCODER_SPI, SPI_MODE0, ABSOLUTE_ENCODER_SPI_SPEED, ABSOLUTE_ENCODER_SCLK_PIN, ABSOLUTE_ENCODER_MOSI_PIN, ABSOLUTE_ENCODER_MISO_PIN, SPI_CS_NULL);
gpio_init(absolute_encoder_cs_list[index], GPO, GPIO_LOW, GPO_PUSH_PULL);
do
{
if(absolute_encoder_self_check(index))
{
// 如果程序在输出了断言信息 并且提示出错位置在这里
// 那么就是绝对值编码器自检出错并超时退出了
// 检查一下接线有没有问题 如果没问题可能就是坏了
return_state = 1;
zf_log(0, "absolute encoder init errror.");
break;
}
absolute_encoder_write_register(index, ABSOLUTE_ENCODER_DIR_REG, 0x00); // 设置旋转方向 正转数值变小:0x00 反转数值变大:0x80
zero_position = (uint16)(4096 - zero_position);
zero_position = zero_position << 4;
absolute_encoder_write_register(index, ABSOLUTE_ENCODER_ZERO_L_REG, (uint8)zero_position); // 设置零位
absolute_encoder_write_register(index, ABSOLUTE_ENCODER_ZERO_H_REG, zero_position >> 8);
}while(0);
return return_state;
}
@@ -0,0 +1,105 @@
/*********************************************************************************************************************
* MSPM0G3507 Opensource Library 即(MSPM0G3507 开源库)是一个基于官方 SDK 接口的第三方开源库
* Copyright (c) 2022 SEEKFREE 逐飞科技
*
* 本文件是 MSPM0G3507 开源库的一部分
*
* MSPM0G3507 开源库 是免费软件
* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款
* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它
*
* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证
* 甚至没有隐含的适销性或适合特定用途的保证
* 更多细节请参见 GPL
*
* 您应该在收到本开源库的同时收到一份 GPL 的副本
* 如果没有,请参阅<https://www.gnu.org/licenses/>
*
* 额外注明:
* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本
* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中
* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件
* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明)
*
* 文件名称 zf_device_absolute_encoder
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 MDK 5.37
* 适用平台 MSPM0G3507
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2025-06-1 SeekFree first version
********************************************************************************************************************/
/*********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* SCLK 查看 zf_device_absolute_encoder.h 中 ABSOLUTE_ENCODER_SCLK_PIN 宏定义
* MOSI 查看 zf_device_absolute_encoder.h 中 ABSOLUTE_ENCODER_MOSI_PIN 宏定义
* MISO 查看 zf_device_absolute_encoder.h 中 ABSOLUTE_ENCODER_MISO_PIN 宏定义
* CS 查看 zf_device_absolute_encoder.h 中 ABSOLUTE_ENCODER_CS_PIN 宏定义
* VCC 3.3V电源
* GND 电源地
* ------------------------------------
********************************************************************************************************************/
#ifndef _zf_device_absolute_encoder_h_
#define _zf_device_absolute_encoder_h_
#include "zf_common_typedef.h"
//====================================================硬件 SPI 驱动====================================================
#define ABSOLUTE_ENCODER_SPI_SPEED ( 8 * 1000 * 1000 ) // 硬件 SPI 速率
#define ABSOLUTE_ENCODER_SPI ( SPI_1 ) // 硬件 SPI 号
#define ABSOLUTE_ENCODER_SCLK_PIN ( SPI1_SCK_B23 ) // 硬件 SPI SCK 引脚
#define ABSOLUTE_ENCODER_MOSI_PIN ( SPI1_MOSI_B22 ) // 硬件 SPI MOSI 引脚
#define ABSOLUTE_ENCODER_MISO_PIN ( SPI1_MISO_B21 ) // 硬件 SPI MISO 引脚
//====================================================硬件 SPI 驱动====================================================
#define ABSOLUTE_ENCODER_CS_PIN_MAX ( 4 )
#define ABSOLUTE_ENCODER_CS_PIN_LIST { B17, B18, B26, B27 }
#define ABSOLUTE_ENCODER_CS(index, state) ((state) ? (gpio_high(absolute_encoder_cs_list[index])): (gpio_low(absolute_encoder_cs_list[index])))
#define ABSOLUTE_ENCODER_TIMEOUT_COUNT ( 100 )
#define ABSOLUTE_ENCODER_DEFAULT_ZERO ( 0 )
//====================================================角度传感器参数====================================================
#define ABSOLUTE_ENCODER_SPI_W ( 0x80 )
#define ABSOLUTE_ENCODER_SPI_R ( 0x40 )
#define ABSOLUTE_ENCODER_ZERO_L_REG ( 0x00 )
#define ABSOLUTE_ENCODER_ZERO_H_REG ( 0x01 )
#define ABSOLUTE_ENCODER_DIR_REG ( 0X09 )
//====================================================角度传感器参数====================================================
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 绝对值编码器获取当前角度值
// 参数说明 index 编码器索引
// 返回参数 int16 角度值
// 使用示例 absolute_encoder_get_location();
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
int16 absolute_encoder_get_location (uint8 index);
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 绝对值编码器获取相较上次位置的偏移值
// 参数说明 index 编码器索引
// 返回参数 int16 偏移值
// 使用示例 absolute_encoder_get_offset();
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
int16 absolute_encoder_get_offset (uint8 index);
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 绝对值编码器初始化
// 参数说明 index 编码器索引
// 返回参数 uint8 初始化状态 0-成功 1-失败
// 使用示例 absolute_encoder_init(index);
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
uint8 absolute_encoder_init (uint8 index);
#endif
+45
View File
@@ -0,0 +1,45 @@
/*********************************************************************************************************************
* MSPM0G3507 Opensource Library 即(MSPM0G3507 开源库)是一个基于官方 SDK 接口的第三方开源库
* Copyright (c) 2022 SEEKFREE 逐飞科技
*
* 本文件是 MSPM0G3507 开源库的一部分
*
* MSPM0G3507 开源库 是免费软件
* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款
* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它
*
* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证
* 甚至没有隐含的适销性或适合特定用途的保证
* 更多细节请参见 GPL
*
* 您应该在收到本开源库的同时收到一份 GPL 的副本
* 如果没有,请参阅<https://www.gnu.org/licenses/>
*
* 额外注明:
* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本
* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中
* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件
* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明)
*
* 文件名称 zf_device_absolute_encoder
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 MDK 5.37
* 适用平台 MSPM0G3507
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2025-06-1 SeekFree first version
********************************************************************************************************************/
#ifndef _zf_device_config_h_
#define _zf_device_config_h_
extern const unsigned char image_frame_header[4];
extern const unsigned char imu660ra_config_file[8192];
extern const unsigned char dl1b_config_file[135];
#endif
Binary file not shown.
+770
View File
@@ -0,0 +1,770 @@
/*********************************************************************************************************************
* MSPM0G3507 Opensource Library 即(MSPM0G3507 开源库)是一个基于官方 SDK 接口的第三方开源库
* Copyright (c) 2022 SEEKFREE 逐飞科技
*
* 本文件是 MSPM0G3507 开源库的一部分
*
* MSPM0G3507 开源库 是免费软件
* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款
* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它
*
* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证
* 甚至没有隐含的适销性或适合特定用途的保证
* 更多细节请参见 GPL
*
* 您应该在收到本开源库的同时收到一份 GPL 的副本
* 如果没有,请参阅<https://www.gnu.org/licenses/>
*
* 额外注明:
* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本
* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中
* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件
* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明)
*
* 文件名称 zf_device_dl1a
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 MDK 5.37
* 适用平台 MSPM0G3507
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2025-06-1 SeekFree first version
********************************************************************************************************************/
/*********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* SCL 查看 zf_device_dl1a.h 中 DL1A_SCL_PIN 宏定义
* SDA 查看 zf_device_dl1a.h 中 DL1A_SDA_PIN 宏定义
* VCC 5V 电源
* GND 电源地
* ------------------------------------
********************************************************************************************************************/
#include "zf_common_debug.h"
#include "zf_driver_delay.h"
#include "zf_driver_exti.h"
#include "zf_driver_soft_iic.h"
#include "zf_device_dl1a.h"
uint8 dl1a_finsh_flag = 0; // 定义采集完成标志位
uint16 dl1a_distance_mm = 8192; // 定义距离数据存放变量
#if DL1A_USE_SOFT_IIC
static soft_iic_info_struct dl1a_iic_struct; // 定义软件IIC结构体
#define dl1a_write_array(data, len) (soft_iic_write_8bit_array(&dl1a_iic_struct, (data), (len)))
#define dl1a_write_register(reg, data) (soft_iic_write_8bit_register(&dl1a_iic_struct, (reg), (data)))
#define dl1a_read_register(reg) (soft_iic_read_8bit_register(&dl1a_iic_struct, (reg)))
#define dl1a_read_registers(reg, data, len) (soft_iic_read_8bit_registers(&dl1a_iic_struct, (reg), (data), (len)))
#else
#error "暂不支持硬件IIC通讯"
#endif
// 这个速率表示从目标反射并被设备检测到的信号的振幅
// 设置此限制可以确定传感器报告有效读数所需的最小测量值
// 设置一个较低的限制可以增加传感器的测量范围
// 但似乎也增加了 <由于来自目标以外的物体的不需要的反射导致> 得到不准确读数的可能性
// 默认为 0.25 MCPS 可预设范围为 0 - 511.99
#define DL1A_DEFAULT_RATE_LIMIT (0.25)
// 从寄存器数据解码 PCLKs 中 VCSEL (vertical cavity surface emitting laser) 的脉宽周期
#define decode_vcsel_period(reg_val) (((reg_val) + 1) << 1)
// 从 PCLK 中的 VCSEL 周期计算宏周期 (以 *纳秒为单位)
// PLL_period_ps = 1655
// macro_period_vclks = 2304
#define calc_macro_period(vcsel_period_pclks) ((((uint32)2304 * (vcsel_period_pclks) * 1655) + 500) / 1000)
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 获取设备 SPAD 信息
// 参数说明 index 索引
// 参数说明 type 类型值
// 返回参数 uint8 是否成功 0-成功 1-失败
// 使用示例 dl1a_get_spad_info(index, type_is_aperture);
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
static uint8 dl1a_get_spad_info (uint8 *index, uint8 *type_is_aperture)
{
uint8 tmp = 0;
uint8 return_state = 0;
volatile uint16 loop_count = 0;
do
{
dl1a_write_register(0x80, 0x01);
dl1a_write_register(0xFF, 0x01);
dl1a_write_register(0x00, 0x00);
dl1a_write_register(0xFF, 0x06);
dl1a_read_registers(0x83, &tmp, 1);
dl1a_write_register(0x83, tmp | 0x04);
dl1a_write_register(0xFF, 0x07);
dl1a_write_register(0x81, 0x01);
dl1a_write_register(0x80, 0x01);
dl1a_write_register(0x94, 0x6b);
dl1a_write_register(0x83, 0x00);
tmp = 0x00;
while(0x00 == tmp || 0xFF == tmp)
{
system_delay_ms(1);
dl1a_read_registers(0x83, &tmp, 1);
if(DL1A_TIMEOUT_COUNT < loop_count ++)
{
return_state = 1;
break;
}
}
if(return_state)
{
break;
}
dl1a_write_register(0x83, 0x01);
dl1a_read_registers(0x92, &tmp, 1);
*index = tmp & 0x7f;
*type_is_aperture = (tmp >> 7) & 0x01;
dl1a_write_register(0x81, 0x00);
dl1a_write_register(0xFF, 0x06);
dl1a_read_registers(0x83, &tmp, 1);
dl1a_write_register(0x83, tmp);
dl1a_write_register(0xFF, 0x01);
dl1a_write_register(0x00, 0x01);
dl1a_write_register(0xFF, 0x00);
dl1a_write_register(0x80, 0x00);
}while(0);
return return_state;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 将超时数值从 MCLKs 转换到对应的 ms
// 参数说明 timeout_period_mclks 超时周期 MCLKs
// 参数说明 vcsel_period_pclks PCLK 值
// 返回参数 uint32 返回超时数值
// 使用示例 dl1a_timeout_mclks_to_microseconds(timeout_period_mclks, vcsel_period_pclks);
// 备注信息 将序列步骤超时从具有给定 VCSEL 周期的 MCLK (以 PCLK 为单位)转换为微秒
//-------------------------------------------------------------------------------------------------------------------
static uint32 dl1a_timeout_mclks_to_microseconds (uint16 timeout_period_mclks, uint8 vcsel_period_pclks)
{
uint32 macro_period_ns = calc_macro_period(vcsel_period_pclks);
return ((timeout_period_mclks * macro_period_ns) + (macro_period_ns / 2)) / 1000;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 将超时数值从 ms 转换到对应的 MCLKs
// 参数说明 timeout_period_us 超时周期 微秒单位
// 参数说明 vcsel_period_pclks PCLK 值
// 返回参数 uint32 返回超时数值
// 使用示例 dl1a_timeout_microseconds_to_mclks(timeout_period_us, vcsel_period_pclks);
// 备注信息 将序列步骤超时从微秒转换为具有给定 VCSEL 周期的 MCLK (以 PCLK 为单位)
//-------------------------------------------------------------------------------------------------------------------
static uint32 dl1a_timeout_microseconds_to_mclks (uint32 timeout_period_us, uint8 vcsel_period_pclks)
{
uint32 macro_period_ns = calc_macro_period(vcsel_period_pclks);
return (((timeout_period_us * 1000) + (macro_period_ns / 2)) / macro_period_ns);
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 对超时数值进行解码
// 参数说明 reg_val 超时时长 寄存器值
// 返回参数 uint16 返回超时数值
// 使用示例 dl1a_decode_timeout(reg_val);
// 备注信息 从寄存器值解码 MCLK 中的序列步骤超时
//-------------------------------------------------------------------------------------------------------------------
static uint16 dl1a_decode_timeout (uint16 reg_val)
{
// 格式: (LSByte * 2 ^ MSByte) + 1
return (uint16)((reg_val & 0x00FF) <<
(uint16)((reg_val & 0xFF00) >> 8)) + 1;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 对超时数值进行编码
// 参数说明 timeout_mclks 超时时长 -MCLKs 值
// 返回参数 uint16 返回编码值
// 使用示例 dl1a_encode_timeout(timeout_mclks);
// 备注信息 在 MCLK 中对超时的序列步骤超时寄存器值进行编码
//-------------------------------------------------------------------------------------------------------------------
static uint16 dl1a_encode_timeout (uint16 timeout_mclks)
{
uint32 ls_byte = 0;
uint16 ms_byte = 0;
uint16 return_data = 0;
if(0 < timeout_mclks)
{
// 格式: (LSByte * 2 ^ MSByte) + 1
ls_byte = timeout_mclks - 1;
while(0 < (ls_byte & 0xFFFFFF00))
{
ls_byte >>= 1;
ms_byte++;
}
return_data = (ms_byte << 8) | ((uint16)ls_byte & 0xFF);
}
return return_data;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 获取序列步骤使能设置
// 参数说明 enables 序列使能步骤结构体
// 返回参数 void
// 使用示例 dl1a_get_sequence_step_enables(enables);
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
static void dl1a_get_sequence_step_enables(dl1a_sequence_enables_step_struct *enables)
{
uint8 sequence_config = 0;
dl1a_read_registers(DL1A_SYSTEM_SEQUENCE_CONFIG, &sequence_config, 1);
enables->tcc = (sequence_config >> 4) & 0x1;
enables->dss = (sequence_config >> 3) & 0x1;
enables->msrc = (sequence_config >> 2) & 0x1;
enables->pre_range = (sequence_config >> 6) & 0x1;
enables->final_range = (sequence_config >> 7) & 0x1;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 获取脉冲周期
// 参数说明 type 预量程类型
// 返回参数 uint8 返回的周期值
// 使用示例 dl1a_get_vcsel_pulse_period(DL1A_VCSEL_PERIOD_PER_RANGE);
// 备注信息 在 PCLKs 中获取给定周期类型的 VCSEL 脉冲周期
//-------------------------------------------------------------------------------------------------------------------
static uint8 dl1a_get_vcsel_pulse_period (dl1a_vcsel_period_type_enum type)
{
uint8 data_buffer = 0;
if(DL1A_VCSEL_PERIOD_PER_RANGE == type)
{
dl1a_read_registers(DL1A_PRE_RANGE_CONFIG_VCSEL_PERIOD, &data_buffer, 1);
data_buffer = decode_vcsel_period(data_buffer);
}
else if(DL1A_VCSEL_PERIOD_FINAL_RANGE == type)
{
dl1a_read_registers(DL1A_FINAL_RANGE_CONFIG_VCSEL_PERIOD, &data_buffer, 1);
data_buffer = decode_vcsel_period(data_buffer);
}
else
{
data_buffer = 255;
}
return data_buffer;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 获取序列步骤超时设置
// 参数说明 enables 序列使能步骤结构体
// 参数说明 timeouts 序列超时步骤结构体
// 返回参数 void
// 使用示例 dl1a_get_sequence_step_timeouts(enables, timeouts);
// 备注信息 获取所有超时而不仅仅是请求的超时 并且还存储中间值
//-------------------------------------------------------------------------------------------------------------------
static void dl1a_get_sequence_step_timeouts (dl1a_sequence_enables_step_struct const *enables, dl1a_sequence_timeout_step_struct *timeouts)
{
uint8 reg_buffer[2];
uint16 reg16_buffer = 0;
timeouts->pre_range_vcsel_period_pclks = dl1a_get_vcsel_pulse_period(DL1A_VCSEL_PERIOD_PER_RANGE);
dl1a_read_registers(DL1A_MSRC_CONFIG_TIMEOUT_MACROP, reg_buffer, 1);
timeouts->msrc_dss_tcc_mclks = reg_buffer[0] + 1;
timeouts->msrc_dss_tcc_us = dl1a_timeout_mclks_to_microseconds(timeouts->msrc_dss_tcc_mclks, (uint8)timeouts->pre_range_vcsel_period_pclks);
dl1a_read_registers(DL1A_PRE_RANGE_CONFIG_TIMEOUT_MACROP_HI, reg_buffer, 2);
reg16_buffer = ((uint16) reg_buffer[0] << 8) | reg_buffer[1];
timeouts->pre_range_mclks = dl1a_decode_timeout(reg16_buffer);
timeouts->pre_range_us = dl1a_timeout_mclks_to_microseconds(timeouts->pre_range_mclks, (uint8)timeouts->pre_range_vcsel_period_pclks);
timeouts->final_range_vcsel_period_pclks = dl1a_get_vcsel_pulse_period(DL1A_VCSEL_PERIOD_FINAL_RANGE);
dl1a_read_registers(DL1A_FINAL_RANGE_CONFIG_TIMEOUT_MACROP_HI, reg_buffer, 2);
reg16_buffer = ((uint16) reg_buffer[0] << 8) | reg_buffer[1];
timeouts->final_range_mclks = dl1a_decode_timeout(reg16_buffer);
if(enables->pre_range)
{
timeouts->final_range_mclks -= timeouts->pre_range_mclks;
}
timeouts->final_range_us = dl1a_timeout_mclks_to_microseconds(timeouts->final_range_mclks, (uint8)timeouts->final_range_vcsel_period_pclks);
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 执行单次参考校准
// 参数说明 vhv_init_byte 预设校准值
// 返回参数 uint8 操作是否成功 0-成功 1-失败
// 使用示例 dl1a_get_vcsel_pulse_period(DL1A_VCSEL_PERIOD_PER_RANGE);
// 备注信息 在 PCLKs 中获取给定周期类型的 VCSEL 脉冲周期
//-------------------------------------------------------------------------------------------------------------------
static uint8 dl1a_perform_single_ref_calibration (uint8 vhv_init_byte)
{
uint8 return_state = 0;
uint8 data_buffer = 0;
volatile uint16 loop_count = 0;
do
{
dl1a_write_register(DL1A_SYSRANGE_START, 0x01 | vhv_init_byte);
dl1a_read_registers(DL1A_MSRC_CONFIG_TIMEOUT_MACROP, &data_buffer, 1);
while(0 == (data_buffer & 0x07))
{
system_delay_ms(1);
dl1a_read_registers(DL1A_MSRC_CONFIG_TIMEOUT_MACROP, &data_buffer, 1);
if(DL1A_TIMEOUT_COUNT < loop_count ++)
{
return_state = 1;
break;
}
}
if(return_state)
{
break;
}
dl1a_write_register(DL1A_SYSTEM_INTERRUPT_CLEAR, 0x01);
dl1a_write_register(DL1A_SYSRANGE_START, 0x00);
}while(0);
return return_state;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 设置测量定时预算 (以微秒为单位)
// 参数说明 budget_us 设定的测量允许的时间
// 返回参数 uint8 操作结果 0-成功 1-失败
// 使用示例 dl1a_set_measurement_timing_budget(measurement_timing_budget_us);
// 备注信息 这是一次测量允许的时间
// 即在测距序列的子步骤之间分配时间预算
// 更长的时间预算允许更精确的测量
// 增加一个N倍的预算可以减少一个sqrt(N)倍的范围测量标准偏差
// 默认为33毫秒 最小值为20 ms
//-------------------------------------------------------------------------------------------------------------------
static uint8 dl1a_set_measurement_timing_budget (uint32 budget_us)
{
uint8 return_state = 0;
uint8 data_buffer[3];
uint16 data = 0;
dl1a_sequence_enables_step_struct enables;
dl1a_sequence_timeout_step_struct timeouts;
do
{
if(DL1A_MIN_TIMING_BUDGET > budget_us)
{
return_state = 1;
break;
}
uint32 used_budget_us = DL1A_SET_START_OVERHEAD + DL1A_END_OVERHEAD;
dl1a_get_sequence_step_enables(&enables);
dl1a_get_sequence_step_timeouts(&enables, &timeouts);
if (enables.tcc)
{
used_budget_us += (timeouts.msrc_dss_tcc_us + DL1A_TCC_OVERHEAD);
}
if (enables.dss)
{
used_budget_us += 2 * (timeouts.msrc_dss_tcc_us + DL1A_DSS_OVERHEAD);
}
else if (enables.msrc)
{
used_budget_us += (timeouts.msrc_dss_tcc_us + DL1A_MSRC_OVERHEAD);
}
if (enables.pre_range)
{
used_budget_us += (timeouts.pre_range_us + DL1A_PRERANGE_OVERHEAD);
}
if (enables.final_range)
{
// 请注意 最终范围超时由计时预算和序列中所有其他超时的总和决定
// 如果没有空间用于最终范围超时 则将设置错误
// 否则 剩余时间将应用于最终范围
used_budget_us += DL1A_FINALlRANGE_OVERHEAD;
if (used_budget_us > budget_us)
{
// 请求的超时太大
return_state = 1;
break;
}
// 对于最终超时范围 必须添加预量程范围超时
// 为此 最终超时和预量程超时必须以宏周期 MClks 表示
// 因为它们具有不同的 VCSEL 周期
uint32 final_range_timeout_us = budget_us - used_budget_us;
uint16 final_range_timeout_mclks =
(uint16)dl1a_timeout_microseconds_to_mclks(final_range_timeout_us,
(uint8)timeouts.final_range_vcsel_period_pclks);
if (enables.pre_range)
{
final_range_timeout_mclks += timeouts.pre_range_mclks;
}
data = dl1a_encode_timeout(final_range_timeout_mclks);
data_buffer[0] = DL1A_FINAL_RANGE_CONFIG_TIMEOUT_MACROP_HI;
data_buffer[1] = ((data >> 8) & 0xFF);
data_buffer[2] = (data & 0xFF);
dl1a_write_array(data_buffer, 3);
}
}while(0);
return return_state;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 获取测量定时预算 (以微秒为单位)
// 参数说明 void
// 返回参数 uint32 已设定的测量允许的时间
// 使用示例 dl1a_get_measurement_timing_budget();
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
static uint32 dl1a_get_measurement_timing_budget (void)
{
dl1a_sequence_enables_step_struct enables;
dl1a_sequence_timeout_step_struct timeouts;
// 开始和结束开销时间始终存在
uint32 budget_us = DL1A_GET_START_OVERHEAD + DL1A_END_OVERHEAD;
dl1a_get_sequence_step_enables(&enables);
dl1a_get_sequence_step_timeouts(&enables, &timeouts);
if (enables.tcc)
{
budget_us += (timeouts.msrc_dss_tcc_us + DL1A_TCC_OVERHEAD);
}
if (enables.dss)
{
budget_us += 2 * (timeouts.msrc_dss_tcc_us + DL1A_DSS_OVERHEAD);
}
else if (enables.msrc)
{
budget_us += (timeouts.msrc_dss_tcc_us + DL1A_MSRC_OVERHEAD);
}
if (enables.pre_range)
{
budget_us += (timeouts.pre_range_us + DL1A_PRERANGE_OVERHEAD);
}
if (enables.final_range)
{
budget_us += (timeouts.final_range_us + DL1A_FINALlRANGE_OVERHEAD);
}
return budget_us;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 设置返回信号速率限制 该值单位为 MCPS (百万次每秒)
// 参数说明 limit_mcps 设置的最小速率
// 返回参数 void
// 使用示例 dl1a_set_signal_rate_limit(0.25);
// 备注信息 这个速率表示从目标反射并被设备检测到的信号的振幅
// 设置此限制可以确定传感器报告有效读数所需的最小测量值
// 设置一个较低的限制可以增加传感器的测量范围
// 但似乎也增加了 <由于来自目标以外的物体的不需要的反射导致> 得到不准确读数的可能性
// 默认为 0.25 MCPS 可预设范围为 0 - 511.99
//-------------------------------------------------------------------------------------------------------------------
static void dl1a_set_signal_rate_limit (float limit_mcps)
{
zf_assert(limit_mcps >= 0 || limit_mcps <= 511.99f);
uint8 data_buffer[3];
uint16 limit_mcps_16bit = (uint16)(limit_mcps * (1 << 7));
data_buffer[0] = DL1A_FINAL_RANGE_CONFIG_MIN_COUNT_RATE_RTN_LIMIT;
data_buffer[1] = ((limit_mcps_16bit >> 8) & 0xFF);
data_buffer[2] = (limit_mcps_16bit & 0xFF);
dl1a_write_array(data_buffer, 3);
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 返回以毫米为单位的范围读数
// 参数说明 void
// 返回参数 void
// 使用示例 dl1a_get_distance();
// 备注信息 在开始单次射程测量后也调用此函数
//-------------------------------------------------------------------------------------------------------------------
void dl1a_get_distance (void)
{
uint8 reg_databuffer[3];
dl1a_read_registers(DL1A_RESULT_INTERRUPT_STATUS, reg_databuffer, 1);
if((reg_databuffer[0] & 0x07) != 0)
{
// 假设线性度校正增益为默认值 1000 且未启用分数范围
dl1a_read_registers(DL1A_RESULT_RANGE_STATUS + 10, reg_databuffer, 2);
dl1a_distance_mm = ((uint16_t)reg_databuffer[0] << 8);
dl1a_distance_mm |= reg_databuffer[1];
dl1a_write_register(DL1A_SYSTEM_INTERRUPT_CLEAR, 0x01);
dl1a_finsh_flag = 1;
}
if(reg_databuffer[0] & 0x10)
{
dl1a_read_registers(DL1A_RESULT_RANGE_STATUS + 10, reg_databuffer, 2);
dl1a_write_register(DL1A_SYSTEM_INTERRUPT_CLEAR, 0x01);
}
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 DL1A INT 中断响应处理函数
// 参数说明 void
// 返回参数 void
// 使用示例 dl1a_int_handler();
// 备注信息 本函数需要在 DL1A_INT_PIN 对应的外部中断处理函数中调用
//-------------------------------------------------------------------------------------------------------------------
void dl1a_int_handler (void)
{
#if DL1A_INT_ENABLE
dl1a_get_distance();
#endif
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 初始化 DL1A
// 参数说明 void
// 返回参数 uint8 1-初始化失败 0-初始化成功
// 使用示例 dl1a_init();
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
uint8 dl1a_init (void)
{
uint32 measurement_timing_budget_us;
uint8 stop_variable = 0;
uint8 return_state = 0;
uint8 reg_data_buffer = 0;
uint8 ref_spad_map[6];
uint8 data_buffer[7];
uint8 i = 0;
memset(ref_spad_map, 0, 6);
memset(data_buffer, 0, 7);
#if DL1A_USE_SOFT_IIC
soft_iic_init(&dl1a_iic_struct, DL1A_DEV_ADDR, DL1A_SOFT_IIC_DELAY, DL1A_SCL_PIN, DL1A_SDA_PIN);
#else
iic_init(DL1A_IIC, DL1A_DEV_ADDR, DL1A_IIC_SPEED, DL1A_SCL_PIN, DL1A_SDA_PIN);
#endif
gpio_init(DL1A_XS_PIN, GPO, GPIO_HIGH, GPO_PUSH_PULL);
do
{
system_delay_ms(100);
gpio_low(DL1A_XS_PIN);
system_delay_ms(50);
gpio_high(DL1A_XS_PIN);
system_delay_ms(100);
// -------------------------------- DL1A 启动初始化 --------------------------------
reg_data_buffer = dl1a_read_register(DL1A_IO_VOLTAGE_CONFIG); // 传感器默认 IO 为 1.8V 模式
dl1a_write_register(DL1A_IO_VOLTAGE_CONFIG, reg_data_buffer | 0x01); // 配置 IO 为 2.8V 模式
dl1a_write_register(0x88, 0x00); // 设置为标准 IIC 模式
dl1a_write_register(0x80, 0x01);
dl1a_write_register(0xFF, 0x01);
dl1a_write_register(0x00, 0x00);
dl1a_read_registers(0x91, &stop_variable , 1);
dl1a_write_register(0x00, 0x01);
dl1a_write_register(0xFF, 0x00);
dl1a_write_register(0x80, 0x00);
// 禁用 SIGNAL_RATE_MSRC(bit1) 和 SIGNAL_RATE_PRE_RANGE(bit4) 限制检查
reg_data_buffer = dl1a_read_register(DL1A_MSRC_CONFIG);
dl1a_write_register(DL1A_MSRC_CONFIG, reg_data_buffer | 0x12);
dl1a_set_signal_rate_limit(DL1A_DEFAULT_RATE_LIMIT); // 设置信号速率限制
dl1a_write_register(DL1A_SYSTEM_SEQUENCE_CONFIG, 0xFF);
// -------------------------------- DL1A 启动初始化 --------------------------------
// -------------------------------- DL1A 配置初始化 --------------------------------
if(dl1a_get_spad_info(&data_buffer[0], &data_buffer[1]))
{
return_state = 1;
zf_log(0, "DL1A self check error.");
break;
}
// 从 GLOBAL_CONFIG_SPAD_ENABLES_REF_[0-6] 获取 SPAD map (RefGoodSpadMap) 数据
dl1a_read_registers(DL1A_GLOBAL_CONFIG_SPAD_ENABLES_REF_0, ref_spad_map, 6);
dl1a_write_register(0xFF, 0x01);
dl1a_write_register(DL1A_DYNAMIC_SPAD_REF_EN_START_OFFSET, 0x00);
dl1a_write_register(DL1A_DYNAMIC_SPAD_NUM_REQUESTED_REF_SPAD, 0x2C);
dl1a_write_register(0xFF, 0x00);
dl1a_write_register(DL1A_GLOBAL_CONFIG_REF_EN_START_SELECT, 0xB4);
data_buffer[2] = data_buffer[1] ? 12 : 0; // 12 is the first aperture spad
for(i = 0; 48 > i; i ++)
{
if(i < data_buffer[2] || data_buffer[3] == data_buffer[0])
{
// 此位低于应启用的第一个位
// 或者 (eference_spad_count) 位已启用
// 因此此位为零
ref_spad_map[i / 8] &= ~(1 << (i % 8));
}
else if((ref_spad_map[i / 8] >> (i % 8)) & 0x1)
{
data_buffer[3] ++;
}
}
data_buffer[0] = DL1A_GLOBAL_CONFIG_SPAD_ENABLES_REF_0;
for(i = 1; 7 > i; i ++)
{
data_buffer[1] = ref_spad_map[i - 1];
}
dl1a_write_array(data_buffer, 7);
// 默认转换设置 version 02/11/2015_v36
dl1a_write_register(0xFF, 0x01);
dl1a_write_register(0x00, 0x00);
dl1a_write_register(0xFF, 0x00);
dl1a_write_register(0x09, 0x00);
dl1a_write_register(0x10, 0x00);
dl1a_write_register(0x11, 0x00);
dl1a_write_register(0x24, 0x01);
dl1a_write_register(0x25, 0xFF);
dl1a_write_register(0x75, 0x00);
dl1a_write_register(0xFF, 0x01);
dl1a_write_register(0x4E, 0x2C);
dl1a_write_register(0x48, 0x00);
dl1a_write_register(0x30, 0x20);
dl1a_write_register(0xFF, 0x00);
dl1a_write_register(0x30, 0x09);
dl1a_write_register(0x54, 0x00);
dl1a_write_register(0x31, 0x04);
dl1a_write_register(0x32, 0x03);
dl1a_write_register(0x40, 0x83);
dl1a_write_register(0x46, 0x25);
dl1a_write_register(0x60, 0x00);
dl1a_write_register(0x27, 0x00);
dl1a_write_register(0x50, 0x06);
dl1a_write_register(0x51, 0x00);
dl1a_write_register(0x52, 0x96);
dl1a_write_register(0x56, 0x08);
dl1a_write_register(0x57, 0x30);
dl1a_write_register(0x61, 0x00);
dl1a_write_register(0x62, 0x00);
dl1a_write_register(0x64, 0x00);
dl1a_write_register(0x65, 0x00);
dl1a_write_register(0x66, 0xA0);
dl1a_write_register(0xFF, 0x01);
dl1a_write_register(0x22, 0x32);
dl1a_write_register(0x47, 0x14);
dl1a_write_register(0x49, 0xFF);
dl1a_write_register(0x4A, 0x00);
dl1a_write_register(0xFF, 0x00);
dl1a_write_register(0x7A, 0x0A);
dl1a_write_register(0x7B, 0x00);
dl1a_write_register(0x78, 0x21);
dl1a_write_register(0xFF, 0x01);
dl1a_write_register(0x23, 0x34);
dl1a_write_register(0x42, 0x00);
dl1a_write_register(0x44, 0xFF);
dl1a_write_register(0x45, 0x26);
dl1a_write_register(0x46, 0x05);
dl1a_write_register(0x40, 0x40);
dl1a_write_register(0x0E, 0x06);
dl1a_write_register(0x20, 0x1A);
dl1a_write_register(0x43, 0x40);
dl1a_write_register(0xFF, 0x00);
dl1a_write_register(0x34, 0x03);
dl1a_write_register(0x35, 0x44);
dl1a_write_register(0xFF, 0x01);
dl1a_write_register(0x31, 0x04);
dl1a_write_register(0x4B, 0x09);
dl1a_write_register(0x4C, 0x05);
dl1a_write_register(0x4D, 0x04);
dl1a_write_register(0xFF, 0x00);
dl1a_write_register(0x44, 0x00);
dl1a_write_register(0x45, 0x20);
dl1a_write_register(0x47, 0x08);
dl1a_write_register(0x48, 0x28);
dl1a_write_register(0x67, 0x00);
dl1a_write_register(0x70, 0x04);
dl1a_write_register(0x71, 0x01);
dl1a_write_register(0x72, 0xFE);
dl1a_write_register(0x76, 0x00);
dl1a_write_register(0x77, 0x00);
dl1a_write_register(0xFF, 0x01);
dl1a_write_register(0x0D, 0x01);
dl1a_write_register(0xFF, 0x00);
dl1a_write_register(0x80, 0x01);
dl1a_write_register(0x01, 0xF8);
dl1a_write_register(0xFF, 0x01);
dl1a_write_register(0x8E, 0x01);
dl1a_write_register(0x00, 0x01);
dl1a_write_register(0xFF, 0x00);
dl1a_write_register(0x80, 0x00);
// 将中断配置设置为新样品就绪
dl1a_write_register(DL1A_SYSTEM_INTERRUPT_GPIO_CONFIG, 0x04);
reg_data_buffer = dl1a_read_register(DL1A_GPIO_HV_MUX_ACTIVE_HIGH);
dl1a_write_register(DL1A_GPIO_HV_MUX_ACTIVE_HIGH, reg_data_buffer & ~0x10);
dl1a_write_register(DL1A_SYSTEM_INTERRUPT_CLEAR, 0x01);
measurement_timing_budget_us = dl1a_get_measurement_timing_budget();
// 默认情况下禁用 MSRC 和 TCC
// MSRC = Minimum Signal Rate Check
// TCC = Target CentreCheck
dl1a_write_register(DL1A_SYSTEM_SEQUENCE_CONFIG, 0xE8);
dl1a_set_measurement_timing_budget(measurement_timing_budget_us); // 重新计算时序预算
// -------------------------------- DL1A 配置初始化 --------------------------------
dl1a_write_register(DL1A_SYSTEM_SEQUENCE_CONFIG, 0x01);
if(dl1a_perform_single_ref_calibration(0x40))
{
return_state = 1;
zf_log(0, "DL1A perform single reference calibration error.");
break;
}
dl1a_write_register(DL1A_SYSTEM_SEQUENCE_CONFIG, 0x02);
if(dl1a_perform_single_ref_calibration(0x00))
{
return_state = 1;
zf_log(0, "DL1A perform single reference calibration error.");
break;
}
dl1a_write_register(DL1A_SYSTEM_SEQUENCE_CONFIG, 0xE8); // 恢复以前的序列配置
system_delay_ms(100);
dl1a_write_register(0x80, 0x01);
dl1a_write_register(0xFF, 0x01);
dl1a_write_register(0x00, 0x00);
dl1a_write_register(0x91, stop_variable);
dl1a_write_register(0x00, 0x01);
dl1a_write_register(0xFF, 0x00);
dl1a_write_register(0x80, 0x00);
dl1a_write_register(DL1A_SYSRANGE_START, 0x02);
}while(0);
#if DL1A_INT_ENABLE
exti_init(DL1A_INT_PIN, EXTI_TRIGGER_FALLING);
dl1a_int_handler();
dl1a_finsh_flag = 0;
#endif
return return_state;
}
+214
View File
@@ -0,0 +1,214 @@
/*********************************************************************************************************************
* MSPM0G3507 Opensource Library 即(MSPM0G3507 开源库)是一个基于官方 SDK 接口的第三方开源库
* Copyright (c) 2022 SEEKFREE 逐飞科技
*
* 本文件是 MSPM0G3507 开源库的一部分
*
* MSPM0G3507 开源库 是免费软件
* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款
* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它
*
* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证
* 甚至没有隐含的适销性或适合特定用途的保证
* 更多细节请参见 GPL
*
* 您应该在收到本开源库的同时收到一份 GPL 的副本
* 如果没有,请参阅<https://www.gnu.org/licenses/>
*
* 额外注明:
* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本
* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中
* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件
* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明)
*
* 文件名称 zf_device_dl1a
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 MDK 5.37
* 适用平台 MSPM0G3507
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2025-06-1 SeekFree first version
********************************************************************************************************************/
/*********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* SCL 查看 zf_device_dl1a.h 中 DL1A_SCL_PIN 宏定义
* SDA 查看 zf_device_dl1a.h 中 DL1A_SDA_PIN 宏定义
* VCC 5V 电源
* GND 电源地
* ------------------------------------
* ------------------------------------
********************************************************************************************************************/
#ifndef _ZF_DEVICE_DL1A_H_
#define _ZF_DEVICE_DL1A_H_
#include "zf_common_typedef.h"
// 需要注意的是 DL1A 最高支持 400KHz 的 IIC 通信速率
// 需要注意的是 DL1A 最高支持 400KHz 的 IIC 通信速率
// 需要注意的是 DL1A 最高支持 400KHz 的 IIC 通信速率
//=================================================定义 DL1A测距模块 基本配置================================================
#define DL1A_USE_SOFT_IIC (1) // 默认使用软件 IIC 方式驱动 建议使用软件 IIC 方式
#if DL1A_USE_SOFT_IIC // 这两段 颜色正常的才是正确的 颜色灰的就是没有用的
//====================================================软件 IIC 驱动====================================================
#define DL1A_SOFT_IIC_DELAY ( 10 ) // 软件 IIC 的时钟延时周期 数值越小 IIC 通信速率越快
#define DL1A_SCL_PIN ( A1 ) // 软件 IIC SCL 引脚 连接 VL53L0X 的 SCL 引脚
#define DL1A_SDA_PIN ( A0 ) // 软件 IIC SDA 引脚 连接 VL53L0X 的 SDA 引脚
//====================================================软件 IIC 驱动====================================================
#else
#error "暂不支持硬件IIC通讯"
#endif
#define DL1A_XS_PIN (B14)
#define DL1A_INT_ENABLE ( 0 ) // 是否启用 INT 引脚 启用则会自动更新数据
#if DL1A_INT_ENABLE
#define DL1A_INT_PIN (P07_3)
#endif
#define DL1A_TIMEOUT_COUNT (0x00FF) // VL53L0X 超时计数
#define DL1A_MIN_TIMING_BUDGET (20000)
#define DL1A_GET_START_OVERHEAD (1910)
#define DL1A_SET_START_OVERHEAD (1320)
#define DL1A_END_OVERHEAD (960 )
#define DL1A_TCC_OVERHEAD (590 )
#define DL1A_DSS_OVERHEAD (690 )
#define DL1A_MSRC_OVERHEAD (660 )
#define DL1A_PRERANGE_OVERHEAD (660 )
#define DL1A_FINALlRANGE_OVERHEAD (550 )
//=================================================定义 DL1A测距模块 基本配置================================================
//=================================================定义 DL1A测距模块 内部地址================================================
#define DL1A_DEV_ADDR (0x52 >> 1) // 0b0101001
#define DL1A_SYSRANGE_START (0x00)
#define DL1A_SYSTEM_SEQUENCE_CONFIG (0x01)
#define DL1A_SYSTEM_INTERMEASUREMENT_PERIOD (0x04)
#define DL1A_SYSTEM_RANGE_CONFIG (0x09)
#define DL1A_SYSTEM_INTERRUPT_GPIO_CONFIG (0x0A)
#define DL1A_SYSTEM_INTERRUPT_CLEAR (0x0B)
#define DL1A_SYSTEM_THRESH_HIGH (0x0C)
#define DL1A_SYSTEM_THRESH_LOW (0x0E)
#define DL1A_SYSTEM_HISTOGRAM_BIN (0x81)
#define DL1A_RESULT_INTERRUPT_STATUS (0x13)
#define DL1A_RESULT_RANGE_STATUS (0x14)
#define DL1A_RESULT_PEAK_SIGNAL_RATE_REF (0xB6)
#define DL1A_RESULT_CORE_AMBIENT_WINDOW_EVENTS_RTN (0xBC)
#define DL1A_RESULT_CORE_RANGING_TOTAL_EVENTS_RTN (0xC0)
#define DL1A_RESULT_CORE_AMBIENT_WINDOW_EVENTS_REF (0xD0)
#define DL1A_RESULT_CORE_RANGING_TOTAL_EVENTS_REF (0xD4)
#define DL1A_PRE_RANGE_CONFIG_MIN_SNR (0x27)
#define DL1A_PRE_RANGE_CONFIG_VCSEL_PERIOD (0x50)
#define DL1A_PRE_RANGE_CONFIG_TIMEOUT_MACROP_HI (0x51)
#define DL1A_PRE_RANGE_CONFIG_TIMEOUT_MACROP_LO (0x52)
#define DL1A_PRE_RANGE_CONFIG_VALID_PHASE_LOW (0x56)
#define DL1A_PRE_RANGE_CONFIG_VALID_PHASE_HIGH (0x57)
#define DL1A_PRE_RANGE_CONFIG_SIGMA_THRESH_HI (0x61)
#define DL1A_PRE_RANGE_CONFIG_SIGMA_THRESH_LO (0x62)
#define DL1A_PRE_RANGE_MIN_COUNT_RATE_RTN_LIMIT (0x64)
#define DL1A_FINAL_RANGE_CONFIG_VALID_PHASE_LOW (0x47)
#define DL1A_FINAL_RANGE_CONFIG_VALID_PHASE_HIGH (0x48)
#define DL1A_FINAL_RANGE_CONFIG_MIN_COUNT_RATE_RTN_LIMIT (0x44)
#define DL1A_FINAL_RANGE_CONFIG_MIN_SNR (0x67)
#define DL1A_FINAL_RANGE_CONFIG_VCSEL_PERIOD (0x70)
#define DL1A_FINAL_RANGE_CONFIG_TIMEOUT_MACROP_HI (0x71)
#define DL1A_FINAL_RANGE_CONFIG_TIMEOUT_MACROP_LO (0x72)
#define DL1A_GLOBAL_CONFIG_VCSEL_WIDTH (0x32)
#define DL1A_GLOBAL_CONFIG_SPAD_ENABLES_REF_0 (0xB0)
#define DL1A_GLOBAL_CONFIG_SPAD_ENABLES_REF_1 (0xB1)
#define DL1A_GLOBAL_CONFIG_SPAD_ENABLES_REF_2 (0xB2)
#define DL1A_GLOBAL_CONFIG_SPAD_ENABLES_REF_3 (0xB3)
#define DL1A_GLOBAL_CONFIG_SPAD_ENABLES_REF_4 (0xB4)
#define DL1A_GLOBAL_CONFIG_SPAD_ENABLES_REF_5 (0xB5)
#define DL1A_GLOBAL_CONFIG_REF_EN_START_SELECT (0xB6)
#define DL1A_ALGO_PART_TO_PART_RANGE_OFFSET_MM (0x28)
#define DL1A_ALGO_PHASECAL_LIM (0x30)
#define DL1A_ALGO_PHASECAL_CONFIG_TIMEOUT (0x30)
#define DL1A_HISTOGRAM_CONFIG_INITIAL_PHASE_SELECT (0x33)
#define DL1A_HISTOGRAM_CONFIG_READOUT_CTRL (0x55)
#define DL1A_DYNAMIC_SPAD_NUM_REQUESTED_REF_SPAD (0x4E)
#define DL1A_DYNAMIC_SPAD_REF_EN_START_OFFSET (0x4F)
#define DL1A_MSRC_CONFIG_TIMEOUT_MACROP (0x46)
#define DL1A_MSRC_CONFIG (0x60)
#define DL1A_IDENTIFICATION_MODEL_ID (0xC0)
#define DL1A_IDENTIFICATION_REVISION_ID (0xC2)
#define DL1A_CROSSTALK_COMPENSATION_PEAK_RATE_MCPS (0x20)
#define DL1A_POWER_MANAGEMENT_GO1_POWER_FORCE (0x80)
#define DL1A_GPIO_HV_MUX_ACTIVE_HIGH (0x84)
#define DL1A_I2C_SLAVE_DEVICE_ADDRESS (0x8A)
#define DL1A_SOFT_RESET_GO2_SOFT_RESET_N (0xBF)
#define DL1A_OSC_CALIBRATE_VAL (0xF8)
#define DL1A_IO_VOLTAGE_CONFIG (0x89) // IO 电压设置寄存器地址 默认 1V8 使用修改为 2V8
//=================================================定义 DL1A测距模块 内部地址================================================
//================================================定义 DL1A测距模块 参数结构体================================================
typedef enum
{
DL1A_VCSEL_PERIOD_PER_RANGE,
DL1A_VCSEL_PERIOD_FINAL_RANGE,
}dl1a_vcsel_period_type_enum;
typedef struct
{
uint8 tcc;
uint8 msrc;
uint8 dss;
uint8 pre_range;
uint8 final_range;
}dl1a_sequence_enables_step_struct;
typedef struct
{
uint16 pre_range_vcsel_period_pclks;
uint16 final_range_vcsel_period_pclks;
uint16 msrc_dss_tcc_mclks;
uint16 pre_range_mclks;
uint16 final_range_mclks;
uint32 msrc_dss_tcc_us;
uint32 pre_range_us;
uint32 final_range_us;
}dl1a_sequence_timeout_step_struct;
//================================================定义 DL1A测距模块 参数结构体================================================
//=================================================声明 DL1A测距模块 全局变量================================================
extern uint8 dl1a_finsh_flag; // 声明采集完成标志位
extern uint16 dl1a_distance_mm; // 声明距离数据存放变量
//=================================================声明 DL1A测距模块 全局变量================================================
//=================================================声明 DL1A测距模块 基础函数================================================
void dl1a_get_distance (void); // 返回以毫米为单位的范围读数
void dl1a_int_handler (void); // DL1A INT 中断响应处理函数
uint8 dl1a_init (void); // 初始化 DL1A
//=================================================声明 DL1A测距模块 基础函数================================================
#endif
+217
View File
@@ -0,0 +1,217 @@
/*********************************************************************************************************************
* MSPM0G3507 Opensource Library 即(MSPM0G3507 开源库)是一个基于官方 SDK 接口的第三方开源库
* Copyright (c) 2022 SEEKFREE 逐飞科技
*
* 本文件是 MSPM0G3507 开源库的一部分
*
* MSPM0G3507 开源库 是免费软件
* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款
* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它
*
* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证
* 甚至没有隐含的适销性或适合特定用途的保证
* 更多细节请参见 GPL
*
* 您应该在收到本开源库的同时收到一份 GPL 的副本
* 如果没有,请参阅<https://www.gnu.org/licenses/>
*
* 额外注明:
* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本
* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中
* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件
* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明)
*
* 文件名称 zf_device_dl1b
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 MDK 5.37
* 适用平台 MSPM0G3507
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2025-06-1 SeekFree first version
********************************************************************************************************************/
/*********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* SCL 查看 zf_device_dl1b.h 中 DL1B_SCL_PIN 宏定义
* SDA 查看 zf_device_dl1b.h 中 DL1B_SDA_PIN 宏定义
* XS 查看 zf_device_dl1b.h 中 DL1B_XS_PIN 宏定义
* VCC 5V 电源
* GND 电源地
* ------------------------------------
********************************************************************************************************************/
#include "zf_common_debug.h"
#include "zf_driver_delay.h"
#include "zf_driver_exti.h"
#include "zf_driver_soft_iic.h"
#include "zf_device_dl1b.h"
#include "zf_device_config.h"
#include "zf_device_type.h"
static uint8 dl1b_init_flag = 0;
uint8 dl1b_finsh_flag = 0;
uint16 dl1b_distance_mm = 8192;
#if DL1B_USE_SOFT_IIC
static soft_iic_info_struct dl1b_iic_struct;
#define dl1b_transfer_8bit_array(tdata, tlen, rdata, rlen) (soft_iic_transfer_8bit_array(&dl1b_iic_struct, (tdata), (tlen), (rdata), (rlen)))
#else
#define dl1b_transfer_8bit_array(tdata, tlen, rdata, rlen) (iic_transfer_8bit_array(DL1B_IIC, DL1B_DEV_ADDR, (tdata), (tlen), (rdata), (rlen)))
#endif
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 返回以毫米为单位的范围读数
// 参数说明 void
// 返回参数 void
// 使用示例 dl1b_get_distance();
// 备注信息 在开始单次射程测量后也调用此函数
//-------------------------------------------------------------------------------------------------------------------
void dl1b_get_distance (void)
{
if(dl1b_init_flag)
{
uint8 data_buffer[3];
int16 dl1b_distance_temp = 0;
data_buffer[0] = DL1B_GPIO__TIO_HV_STATUS >> 8;
data_buffer[1] = DL1B_GPIO__TIO_HV_STATUS & 0xFF;
dl1b_transfer_8bit_array(data_buffer, 2, &data_buffer[2], 1);
if(data_buffer[2])
{
data_buffer[0] = DL1B_SYSTEM__INTERRUPT_CLEAR >> 8;
data_buffer[1] = DL1B_SYSTEM__INTERRUPT_CLEAR & 0xFF;
data_buffer[2] = 0x01;
dl1b_transfer_8bit_array(data_buffer, 3, data_buffer, 0);// clear Interrupt
data_buffer[0] = DL1B_RESULT__RANGE_STATUS >> 8;
data_buffer[1] = DL1B_RESULT__RANGE_STATUS & 0xFF;
dl1b_transfer_8bit_array(data_buffer, 2, &data_buffer[2], 1);
if(0x89 == data_buffer[2])
{
data_buffer[0] = DL1B_RESULT__FINAL_CROSSTALK_CORRECTED_RANGE_MM_SD0 >> 8;
data_buffer[1] = DL1B_RESULT__FINAL_CROSSTALK_CORRECTED_RANGE_MM_SD0 & 0xFF;
dl1b_transfer_8bit_array(data_buffer, 2, data_buffer, 2);
dl1b_distance_temp = data_buffer[0];
dl1b_distance_temp = (dl1b_distance_temp << 8) | data_buffer[1];
if(dl1b_distance_temp > 4000 || dl1b_distance_temp < 0)
{
dl1b_distance_mm = 8192;
dl1b_finsh_flag = 0;
}
else
{
dl1b_distance_mm = dl1b_distance_temp;
dl1b_finsh_flag = 1;
}
}
else
{
dl1b_distance_mm = 8192;
dl1b_finsh_flag = 0;
}
}
else
{
dl1b_distance_mm = 8192;
dl1b_finsh_flag = 0;
}
}
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 DL1B INT 中断响应处理函数
// 参数说明 void
// 返回参数 void
// 使用示例 dl1b_int_handler();
// 备注信息 本函数需要在 DL1B_INT_PIN 对应的外部中断处理函数中调用
//-------------------------------------------------------------------------------------------------------------------
void dl1b_int_handler (void)
{
#if DL1B_INT_ENABLE
dl1b_get_distance();
#endif
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 初始化 DL1B
// 参数说明 void
// 返回参数 uint8 1-初始化失败 0-初始化成功
// 使用示例 dl1b_init();
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
uint8 dl1b_init (void)
{
uint8 return_state = 0;
uint8 data_buffer[2 + sizeof(dl1b_config_file)];
uint16 time_out_count = 0;
#if DL1B_USE_SOFT_IIC
soft_iic_init(&dl1b_iic_struct, DL1B_DEV_ADDR, DL1B_SOFT_IIC_DELAY, DL1B_SCL_PIN, DL1B_SDA_PIN);
#else
iic_init(DL1B_IIC, DL1B_DEV_ADDR, DL1B_IIC_SPEED, DL1B_SCL_PIN, DL1B_SDA_PIN);
#endif
gpio_init(DL1B_XS_PIN, GPO, GPIO_HIGH, GPO_PUSH_PULL);
do
{
system_delay_ms(50);
gpio_low(DL1B_XS_PIN);
system_delay_ms(10);
gpio_high(DL1B_XS_PIN);
system_delay_ms(50);
data_buffer[0] = DL1B_FIRMWARE__SYSTEM_STATUS >> 8;
data_buffer[1] = DL1B_FIRMWARE__SYSTEM_STATUS & 0xFF;
dl1b_transfer_8bit_array(data_buffer, 2, &data_buffer[2], 1);
return_state = (0x01 == (data_buffer[2] & 0x01)) ? (0) : (1);
if(1 == return_state)
{
break;
}
data_buffer[0] = DL1B_I2C_SLAVE__DEVICE_ADDRESS >> 8;
data_buffer[1] = DL1B_I2C_SLAVE__DEVICE_ADDRESS & 0xFF;
memcpy(&data_buffer[2], (uint8 *)dl1b_config_file, sizeof(dl1b_config_file));
dl1b_transfer_8bit_array(data_buffer, 2 + sizeof(dl1b_config_file), data_buffer, 0);
while(1)
{
data_buffer[0] = DL1B_GPIO__TIO_HV_STATUS >> 8;
data_buffer[1] = DL1B_GPIO__TIO_HV_STATUS & 0xFF;
dl1b_transfer_8bit_array(data_buffer, 2, &data_buffer[2], 1);
if(0x00 == (data_buffer[2] & 0x01))
{
time_out_count = 0;
break;
}
if(DL1B_TIMEOUT_COUNT < time_out_count ++)
{
return_state = 1;
break;
}
system_delay_ms(1);
}
dl1b_init_flag = 1;
#if DL1B_INT_ENABLE
exti_init(DL1B_INT_PIN, EXTI_TRIGGER_FALLING);
dl1b_int_handler();
dl1b_finsh_flag = 0;
#endif
set_tof_type(TOF_DL1B, dl1b_int_handler);
}while(0);
return return_state;
}
+104
View File
@@ -0,0 +1,104 @@
/*********************************************************************************************************************
* MSPM0G3507 Opensource Library 即(MSPM0G3507 开源库)是一个基于官方 SDK 接口的第三方开源库
* Copyright (c) 2022 SEEKFREE 逐飞科技
*
* 本文件是 MSPM0G3507 开源库的一部分
*
* MSPM0G3507 开源库 是免费软件
* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款
* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它
*
* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证
* 甚至没有隐含的适销性或适合特定用途的保证
* 更多细节请参见 GPL
*
* 您应该在收到本开源库的同时收到一份 GPL 的副本
* 如果没有,请参阅<https://www.gnu.org/licenses/>
*
* 额外注明:
* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本
* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中
* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件
* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明)
*
* 文件名称 zf_device_dl1b
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 MDK 5.37
* 适用平台 MSPM0G3507
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2025-06-1 SeekFree first version
********************************************************************************************************************/
/*********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* SCL 查看 zf_device_dl1b.h 中 DL1B_SCL_PIN 宏定义
* SDA 查看 zf_device_dl1b.h 中 DL1B_SDA_PIN 宏定义
* XS 查看 zf_device_dl1b.h 中 DL1B_XS_PIN 宏定义
* VCC 5V 电源
* GND 电源地
* ------------------------------------
* ------------------------------------
********************************************************************************************************************/
#ifndef _ZF_DEVICE_DL1B_H_
#define _ZF_DEVICE_DL1B_H_
#include "zf_common_typedef.h"
// 需要注意的是 DL1B 最高支持 400KHz 的 IIC 通信速率
// 需要注意的是 DL1B 最高支持 400KHz 的 IIC 通信速率
// 需要注意的是 DL1B 最高支持 400KHz 的 IIC 通信速率
#define DL1B_USE_SOFT_IIC ( 1 ) // 默认使用软件 IIC 方式驱动 建议使用软件 IIC 方式
#if DL1B_USE_SOFT_IIC // 这两段 颜色正常的才是正确的 颜色灰的就是没有用的
//====================================================软件 IIC 驱动====================================================
#define DL1B_SOFT_IIC_DELAY ( 10 ) // 软件 IIC 的时钟延时周期 数值越小 IIC 通信速率越快
#define DL1B_SCL_PIN ( A1 ) // 软件 IIC SCL 引脚 连接 DL1B 的 SCL 引脚
#define DL1B_SDA_PIN ( A0 ) // 软件 IIC SDA 引脚 连接 DL1B 的 SDA 引脚
//====================================================软件 IIC 驱动====================================================
#else
//====================================================硬件 IIC 驱动====================================================
#define DL1B_IIC_SPEED ( 400 * 1000 ) // 硬件 IIC 通信速率 最高 400KHz 不建议低于 40KHz
#define DL1B_IIC ( IIC_1 ) // 硬件 IIC SCL 引脚 连接 DL1B 的 SCL 引脚
#define DL1B_SCL_PIN ( IIC1_SCL_B8 ) // 硬件 IIC SCL 引脚 连接 DL1B 的 SCL 引脚
#define DL1B_SDA_PIN ( IIC1_SDA_B9 ) // 硬件 IIC SDA 引脚 连接 DL1B 的 SDA 引脚
//====================================================硬件 IIC 驱动====================================================
#endif
#define DL1B_XS_PIN ( B14 )
#define DL1B_INT_ENABLE ( 0 ) // 是否启用 INT 引脚 启用则会自动更新数据
#if DL1B_INT_ENABLE
#define DL1B_INT_PIN ( 14 )
#endif
#define DL1B_TIMEOUT_COUNT ( 1000 ) // DL1B 超时计数
//================================================定义 DL1B 内部地址================================================
#define DL1B_DEV_ADDR ( 0x52 >> 1 ) // 0b0101001
#define DL1B_I2C_SLAVE__DEVICE_ADDRESS ( 0x0001 )
#define DL1B_GPIO__TIO_HV_STATUS ( 0x0031 )
#define DL1B_SYSTEM__INTERRUPT_CLEAR ( 0x0086 )
#define DL1B_RESULT__RANGE_STATUS ( 0x0089 )
#define DL1B_RESULT__FINAL_CROSSTALK_CORRECTED_RANGE_MM_SD0 ( 0x0096 )
#define DL1B_FIRMWARE__SYSTEM_STATUS ( 0x00E5 )
//================================================定义 DL1B 内部地址================================================
extern uint8 dl1b_finsh_flag;
extern uint16 dl1b_distance_mm;
void dl1b_get_distance (void);
void dl1b_int_handler (void);
uint8 dl1b_init (void);
#endif
+350
View File
@@ -0,0 +1,350 @@
/*********************************************************************************************************************
* MSPM0G3507 Opensource Library 即(MSPM0G3507 开源库)是一个基于官方 SDK 接口的第三方开源库
* Copyright (c) 2022 SEEKFREE 逐飞科技
*
* 本文件是 MSPM0G3507 开源库的一部分
*
* MSPM0G3507 开源库 是免费软件
* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款
* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它
*
* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证
* 甚至没有隐含的适销性或适合特定用途的保证
* 更多细节请参见 GPL
*
* 您应该在收到本开源库的同时收到一份 GPL 的副本
* 如果没有,请参阅<https://www.gnu.org/licenses/>
*
* 额外注明:
* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本
* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中
* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件
* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明)
*
* 文件名称 zf_device_imu660ra
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 MDK 5.37
* 适用平台 MSPM0G3507
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2025-06-1 SeekFree first version
********************************************************************************************************************/
/*********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* // 硬件 SPI 引脚
* SCL/SPC 查看 zf_device_imu660ra.h 中 IMU660RA_SPC_PIN 宏定义
* SDA/DSI 查看 zf_device_imu660ra.h 中 IMU660RA_SDI_PIN 宏定义
* SA0/SDO 查看 zf_device_imu660ra.h 中 IMU660RA_SDO_PIN 宏定义
* CS 查看 zf_device_imu660ra.h 中 IMU660RA_CS_PIN 宏定义
* VCC 3.3V电源
* GND 电源地
* 其余引脚悬空
*
* // 软件 IIC 引脚
* SCL/SPC 查看 zf_device_imu660ra.h 中 IMU660RA_SCL_PIN 宏定义
* SDA/DSI 查看 zf_device_imu660ra.h 中 IMU660RA_SDA_PIN 宏定义
* VCC 3.3V电源
* GND 电源地
* 其余引脚悬空
* ------------------------------------
********************************************************************************************************************/
#include "zf_common_debug.h"
#include "zf_device_config.h"
#include "zf_driver_delay.h"
#include "zf_driver_gpio.h"
#include "zf_driver_soft_iic.h"
#include "zf_driver_spi.h"
#include "zf_device_imu660ra.h"
int16 imu660ra_gyro_x = 0, imu660ra_gyro_y = 0, imu660ra_gyro_z = 0; // 三轴陀螺仪数据 gyro (陀螺仪)
int16 imu660ra_acc_x = 0, imu660ra_acc_y = 0, imu660ra_acc_z = 0; // 三轴加速度计数据 acc (accelerometer 加速度计)
float imu660ra_transition_factor[2] = {4096, 16.4};
#if IMU660RA_USE_IIC
#if IMU660RA_USE_SOFT_IIC
static soft_iic_info_struct imu660ra_iic_struct;
#define imu660ra_write_register(reg, data) (soft_iic_write_8bit_register(&imu660ra_iic_struct, (reg), (data)))
#define imu660ra_write_registers(reg, data, len) (soft_iic_write_8bit_registers(&imu660ra_iic_struct, (reg), (data), (len)))
#define imu660ra_read_register(reg) (soft_iic_read_8bit_register(&imu660ra_iic_struct, (reg)))
#define imu660ra_read_registers(reg, data, len) (soft_iic_read_8bit_registers(&imu660ra_iic_struct, (reg), (data), (len)))
#else
#define imu660ra_write_register(reg, data) (iic_write_8bit_register(IMU660RA_IIC_INDEX, IMU660RA_DEV_ADDR, (reg), (data)))
#define imu660ra_write_registers(reg, data, len) (iic_write_8bit_registers(IMU660RA_IIC_INDEX, IMU660RA_DEV_ADDR, (reg), (data), (len)))
#define imu660ra_read_register(reg) (iic_read_8bit_register(IMU660RA_IIC_INDEX, IMU660RA_DEV_ADDR, (reg)))
#define imu660ra_read_registers(reg, data, len) (iic_read_8bit_registers(IMU660RA_IIC_INDEX, IMU660RA_DEV_ADDR, (reg), (data), (len)))
#endif
#else
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IMU660RA 写寄存器
// 参数说明 reg 寄存器地址
// 参数说明 data 数据
// 返回参数 void
// 使用示例 imu660ra_write_register(IMU660RA_PWR_CONF, 0x00); // 关闭高级省电模式
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
static void imu660ra_write_register (uint8 reg, uint8 data)
{
IMU660RA_CS(0);
spi_write_8bit_register(IMU660RA_SPI, reg | IMU660RA_SPI_W, data);
IMU660RA_CS(1);
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IMU660RA 写数据
// 参数说明 reg 寄存器地址
// 参数说明 data 数据
// 返回参数 void
// 使用示例 imu660ra_write_registers(IMU660RA_INIT_DATA, imu660ra_config_file, sizeof(imu660ra_config_file));
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
static void imu660ra_write_registers (uint8 reg, const uint8 *data, uint32 len)
{
IMU660RA_CS(0);
spi_write_8bit_registers(IMU660RA_SPI, reg | IMU660RA_SPI_W, data, len);
IMU660RA_CS(1);
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IMU660RA 读寄存器
// 参数说明 reg 寄存器地址
// 返回参数 uint8 数据
// 使用示例 imu660ra_read_register(IMU660RA_CHIP_ID);
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
static uint8 imu660ra_read_register (uint8 reg)
{
uint8 data[2];
IMU660RA_CS(0);
spi_read_8bit_registers(IMU660RA_SPI, reg | IMU660RA_SPI_R, data, 2);
IMU660RA_CS(1);
return data[1];
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IMU660RA 读数据
// 参数说明 reg 寄存器地址
// 参数说明 data 数据缓冲区
// 参数说明 len 数据长度
// 返回参数 void
// 使用示例 imu660ra_read_registers(IMU660RA_ACC_ADDRESS, dat, 6);
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
static void imu660ra_read_registers (uint8 reg, uint8 *data, uint32 len)
{
uint8 temp_data[8];
IMU660RA_CS(0);
spi_read_8bit_registers(IMU660RA_SPI, reg | IMU660RA_SPI_R, temp_data, len + 1);
IMU660RA_CS(1);
for(int i = 0; i < len; i ++)
{
*(data ++) = temp_data[i + 1];
}
}
#endif
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IMU660RA 自检
// 参数说明 void
// 返回参数 uint8 1-自检失败 0-自检成功
// 使用示例 imu660ra_self_check();
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
static uint8 imu660ra_self_check (void)
{
uint8 dat = 0, return_state = 0;
uint16 timeout_count = 0;
do
{
if(IMU660RA_TIMEOUT_COUNT < timeout_count ++)
{
return_state = 1;
break;
}
dat = imu660ra_read_register(IMU660RA_CHIP_ID);
system_delay_ms(1);
}while(0x24 != dat); // 读取设备ID是否等于0X24,如果不是0X24则认为没检测到设备
return return_state;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 获取 IMU660RA 加速度计数据
// 参数说明 void
// 返回参数 void
// 使用示例 imu660ra_get_acc(); // 执行该函数后,直接查看对应的变量即可
// 备注信息 使用 SPI 的采集时间为69us
// 使用 IIC 的采集时间为126us 采集加速度计的时间与采集陀螺仪的时间一致的原因是都只是读取寄存器数据
//-------------------------------------------------------------------------------------------------------------------
void imu660ra_get_acc (void)
{
uint8 dat[6];
imu660ra_read_registers(IMU660RA_ACC_ADDRESS, dat, 6);
imu660ra_acc_x = (int16)(((uint16)dat[1] << 8 | dat[0]));
imu660ra_acc_y = (int16)(((uint16)dat[3] << 8 | dat[2]));
imu660ra_acc_z = (int16)(((uint16)dat[5] << 8 | dat[4]));
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 获取 IMU660RA 陀螺仪数据
// 参数说明 void
// 返回参数 void
// 使用示例 imu660ra_get_gyro(); // 执行该函数后,直接查看对应的变量即可
// 备注信息 使用 SPI 的采集时间为69us
// 使用 IIC 的采集时间为126us
//-------------------------------------------------------------------------------------------------------------------
void imu660ra_get_gyro (void)
{
uint8 dat[6];
imu660ra_read_registers(IMU660RA_GYRO_ADDRESS, dat, 6);
imu660ra_gyro_x = (int16)(((uint16)dat[1] << 8 | dat[0]));
imu660ra_gyro_y = (int16)(((uint16)dat[3] << 8 | dat[2]));
imu660ra_gyro_z = (int16)(((uint16)dat[5] << 8 | dat[4]));
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 初始化 IMU660RA
// 参数说明 void
// 返回参数 uint8 1-初始化失败 0-初始化成功
// 使用示例 imu660ra_init();
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
uint8 imu660ra_init (void)
{
uint8 return_state = 0;
system_delay_ms(20); // 等待设备上电成功
#if IMU660RA_USE_IIC
#if IMU660RA_USE_SOFT_IIC
gpio_init(IMU660RA_CS_PIN, GPO, GPIO_LOW, GPO_PUSH_PULL);
soft_iic_init(&imu660ra_iic_struct, IMU660RA_DEV_ADDR, IMU660RA_SOFT_IIC_DELAY, IMU660RA_SCL_PIN, IMU660RA_SDA_PIN); // 配置 IMU660RA 的 IIC 端口
#else
iic_init(IMU660RA_IIC_INDEX, IMU660RA_DEV_ADDR, IMU660RA_IIC_SPEED, IMU660RA_SCL_PIN, IMU660RA_SDA_PIN); // 配置 IMU660RA 的 IIC 端口
#endif
#else
spi_init(IMU660RA_SPI, SPI_MODE0, IMU660RA_SPI_SPEED, IMU660RA_SPC_PIN, IMU660RA_SDI_PIN, IMU660RA_SDO_PIN, SPI_CS_NULL); // 配置 IMU660RA 的 SPI 端口
gpio_init(IMU660RA_CS_PIN, GPO, GPIO_HIGH, GPO_PUSH_PULL); // 配置 IMU660RA 的CS端口
imu660ra_read_register(IMU660RA_CHIP_ID); // 读取一下设备ID 将设备设置为SPI模式
#endif
do{
if(imu660ra_self_check()) // IMU660RA 自检
{
// 如果程序在输出了断言信息 并且提示出错位置在这里
// 那么就是 IMU660RA 自检出错并超时退出了
// 检查一下接线有没有问题 如果没问题可能就是坏了
zf_log(0, "imu660ra self check error.");
return_state = 1;
break;
}
imu660ra_write_register(IMU660RA_PWR_CONF, 0x00); // 关闭高级省电模式
system_delay_ms(1);
imu660ra_write_register(IMU660RA_INIT_CTRL, 0x00); // 开始对模块进行初始化配置
imu660ra_write_registers(IMU660RA_INIT_DATA, imu660ra_config_file, sizeof(imu660ra_config_file)); // 输出配置文件
imu660ra_write_register(IMU660RA_INIT_CTRL, 0x01); // 初始化配置结束
system_delay_ms(20);
if(1 != imu660ra_read_register(IMU660RA_INT_STA)) // 检查是否配置完成
{
// 如果程序在输出了断言信息 并且提示出错位置在这里
// 那么就是 IMU660RA 配置初始化文件出错了
// 检查一下接线有没有问题 如果没问题可能就是坏了
zf_log(0, "imu660ra init error.");
return_state = 1;
break;
}
imu660ra_write_register(IMU660RA_PWR_CTRL, 0x0E); // 开启性能模式 使能陀螺仪、加速度、温度传感器
imu660ra_write_register(IMU660RA_ACC_CONF, 0xA7); // 加速度采集配置 性能模式 正常采集 50Hz 采样频率
imu660ra_write_register(IMU660RA_GYR_CONF, 0xA9); // 陀螺仪采集配置 性能模式 正常采集 200Hz 采样频率
// IMU660RA_ACC_SAMPLE 寄存器
// 设置为 0x00 加速度计量程为 ±2 g 获取到的加速度计数据除以 16384 可以转化为带物理单位的数据 (g 代表重力加速度 物理学名词 一般情况下 g 取 9.8 m/s^2 为标准值)
// 设置为 0x01 加速度计量程为 ±4 g 获取到的加速度计数据除以 8192 可以转化为带物理单位的数据 (g 代表重力加速度 物理学名词 一般情况下 g 取 9.8 m/s^2 为标准值)
// 设置为 0x02 加速度计量程为 ±8 g 获取到的加速度计数据除以 4096 可以转化为带物理单位的数据 (g 代表重力加速度 物理学名词 一般情况下 g 取 9.8 m/s^2 为标准值)
// 设置为 0x03 加速度计量程为 ±16 g 获取到的加速度计数据除以 2048 可以转化为带物理单位的数据 (g 代表重力加速度 物理学名词 一般情况下 g 取 9.8 m/s^2 为标准值)
switch(IMU660RA_ACC_SAMPLE_DEFAULT)
{
default:
{
zf_log(0, "IMU660RA_ACC_SAMPLE_DEFAULT set error.");
return_state = 1;
}break;
case IMU660RA_ACC_SAMPLE_SGN_2G:
{
imu660ra_write_register(IMU660RA_ACC_RANGE, 0x00);
imu660ra_transition_factor[0] = 16384;
}break;
case IMU660RA_ACC_SAMPLE_SGN_4G:
{
imu660ra_write_register(IMU660RA_ACC_RANGE, 0x01);
imu660ra_transition_factor[0] = 8192;
}break;
case IMU660RA_ACC_SAMPLE_SGN_8G:
{
imu660ra_write_register(IMU660RA_ACC_RANGE, 0x02);
imu660ra_transition_factor[0] = 4096;
}break;
case IMU660RA_ACC_SAMPLE_SGN_16G:
{
imu660ra_write_register(IMU660RA_ACC_RANGE, 0x03);
imu660ra_transition_factor[0] = 2048;
}break;
}
if(1 == return_state)
{
break;
}
// IMU660RA_GYR_RANGE 寄存器
// 设置为 0x04 陀螺仪量程为 ±125 dps 获取到的陀螺仪数据除以 262.4 可以转化为带物理单位的数据 单位为 °/s
// 设置为 0x03 陀螺仪量程为 ±250 dps 获取到的陀螺仪数据除以 131.2 可以转化为带物理单位的数据 单位为 °/s
// 设置为 0x02 陀螺仪量程为 ±500 dps 获取到的陀螺仪数据除以 65.6 可以转化为带物理单位的数据 单位为 °/s
// 设置为 0x01 陀螺仪量程为 ±1000 dps 获取到的陀螺仪数据除以 32.8 可以转化为带物理单位的数据 单位为 °/s
// 设置为 0x00 陀螺仪量程为 ±2000 dps 获取到的陀螺仪数据除以 16.4 可以转化为带物理单位的数据 单位为 °/s
switch(IMU660RA_GYRO_SAMPLE_DEFAULT)
{
default:
{
zf_log(0, "IMU660RA_GYRO_SAMPLE_DEFAULT set error.");
return_state = 1;
}break;
case IMU660RA_GYRO_SAMPLE_SGN_125DPS:
{
imu660ra_write_register(IMU660RA_GYR_RANGE, 0x04);
imu660ra_transition_factor[1] = 262.4;
}break;
case IMU660RA_GYRO_SAMPLE_SGN_250DPS:
{
imu660ra_write_register(IMU660RA_GYR_RANGE, 0x03);
imu660ra_transition_factor[1] = 131.2;
}break;
case IMU660RA_GYRO_SAMPLE_SGN_500DPS:
{
imu660ra_write_register(IMU660RA_GYR_RANGE, 0x02);
imu660ra_transition_factor[1] = 65.6;
}break;
case IMU660RA_GYRO_SAMPLE_SGN_1000DPS:
{
imu660ra_write_register(IMU660RA_GYR_RANGE, 0x01);
imu660ra_transition_factor[1] = 32.8;
}break;
case IMU660RA_GYRO_SAMPLE_SGN_2000DPS:
{
imu660ra_write_register(IMU660RA_GYR_RANGE, 0x00);
imu660ra_transition_factor[1] = 16.4;
}break;
}
if(1 == return_state)
{
break;
}
}while(0);
return return_state;
}
+166
View File
@@ -0,0 +1,166 @@
/*********************************************************************************************************************
* MSPM0G3507 Opensource Library 即(MSPM0G3507 开源库)是一个基于官方 SDK 接口的第三方开源库
* Copyright (c) 2022 SEEKFREE 逐飞科技
*
* 本文件是 MSPM0G3507 开源库的一部分
*
* MSPM0G3507 开源库 是免费软件
* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款
* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它
*
* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证
* 甚至没有隐含的适销性或适合特定用途的保证
* 更多细节请参见 GPL
*
* 您应该在收到本开源库的同时收到一份 GPL 的副本
* 如果没有,请参阅<https://www.gnu.org/licenses/>
*
* 额外注明:
* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本
* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中
* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件
* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明)
*
* 文件名称 zf_device_imu660ra
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 MDK 5.37
* 适用平台 MSPM0G3507
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2025-06-1 SeekFree first version
********************************************************************************************************************/
/*********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* // 硬件 SPI 引脚
* SCL/SPC 查看 zf_device_imu660ra.h 中 IMU660RA_SPC_PIN 宏定义
* SDA/DSI 查看 zf_device_imu660ra.h 中 IMU660RA_SDI_PIN 宏定义
* SA0/SDO 查看 zf_device_imu660ra.h 中 IMU660RA_SDO_PIN 宏定义
* CS 查看 zf_device_imu660ra.h 中 IMU660RA_CS_PIN 宏定义
* VCC 3.3V电源
* GND 电源地
* 其余引脚悬空
*
* // 软件 IIC 引脚
* SCL/SPC 查看 zf_device_imu660ra.h 中 IMU660RA_SCL_PIN 宏定义
* SDA/DSI 查看 zf_device_imu660ra.h 中 IMU660RA_SDA_PIN 宏定义
* VCC 3.3V电源
* GND 电源地
* 其余引脚悬空
* ------------------------------------
********************************************************************************************************************/
#ifndef _zf_device_imu660ra_h_
#define _zf_device_imu660ra_h_
#include "zf_common_typedef.h"
// IMU660RA_USE_IIC 定义为 0 表示使用硬件 SPI 驱动 定义为 1 表示使用 IIC 驱动
#define IMU660RA_USE_IIC ( 0 )
#if IMU660RA_USE_IIC
// 当 IMU660RA_USE_IIC 定义为 1 后 需要先编译并下载程序 然后单片机与模块需要断电重启才能正常通讯
// IMU660RA_USE_IIC 定义为 0 表示使用硬件 IIC 驱动 定义为 1 表示使用软件 IIC 驱动
#define IMU660RA_USE_SOFT_IIC ( 1 ) // 默认使用硬件 SPI 方式驱动
#if IMU660RA_USE_SOFT_IIC // 这两段 颜色正常的才是正确的 颜色灰的就是没有用的
//====================================================软件 IIC 驱动====================================================
//====================================================注意 注意 注意 使用IIC模式下不要接CS
//====================================================注意 注意 注意 使用IIC模式下不要接CS
//====================================================注意 注意 注意 使用IIC模式下不要接CS
#define IMU660RA_SOFT_IIC_DELAY ( 50 ) // 软件 IIC 的时钟延时周期 数值越小 IIC 通信速率越快
#define IMU660RA_SCL_PIN ( B23 ) // 软件 IIC SCL 引脚 连接 IMU660RA 的 SCL 引脚
#define IMU660RA_SDA_PIN ( B22 ) // 软件 IIC SDA 引脚 连接 IMU660RA 的 SDA 引脚
//====================================================软件 IIC 驱动====================================================
#else
//====================================================硬件 IIC 驱动====================================================
#define IMU660RA_IIC_INDEX ( IIC_1 ) // 硬件 IIC 模块号
#define IMU660RA_IIC_SPEED ( 400 * 1000 ) // 硬件 IIC 通信时钟速率
#define IMU660RA_SCL_PIN ( IIC1_SCL_C6 ) // 硬件 IIC SCL 引脚 连接 IMU660RA 的 SCL 引脚
#define IMU660RA_SDA_PIN ( IIC1_SDA_C7 ) // 硬件 IIC SDA 引脚 连接 IMU660RA 的 SDA 引脚
//====================================================硬件 IIC 驱动====================================================
#endif
#else
//====================================================硬件 SPI 驱动====================================================
#define IMU660RA_SPI_SPEED ( 8 * 1000 * 1000 ) // 硬件 SPI 速率
#define IMU660RA_SPI ( SPI_1 ) // 硬件 SPI 号
#define IMU660RA_SPC_PIN ( SPI1_SCK_B23 ) // 硬件 SPI SCK 引脚
#define IMU660RA_SDI_PIN ( SPI1_MOSI_B22 ) // 硬件 SPI MOSI 引脚
#define IMU660RA_SDO_PIN ( SPI1_MISO_B21 ) // 硬件 SPI MISO 引脚
//====================================================硬件 SPI 驱动====================================================
#endif
#define IMU660RA_CS_PIN ( B19 ) // 硬件 SPI CS 片选引脚
#define IMU660RA_CS(x) ((x) ? (gpio_high(IMU660RA_CS_PIN)) : (gpio_low(IMU660RA_CS_PIN)))
typedef enum
{
IMU660RA_ACC_SAMPLE_SGN_2G , // 加速度计量程 ±2 g (ACC = Accelerometer 加速度计) (SGN = signum 带符号数 表示正负范围) (g 代表重力加速度 物理学名词 一般情况下 g 取 9.8 m/s^2 为标准值)
IMU660RA_ACC_SAMPLE_SGN_4G , // 加速度计量程 ±4 g (ACC = Accelerometer 加速度计) (SGN = signum 带符号数 表示正负范围) (g 代表重力加速度 物理学名词 一般情况下 g 取 9.8 m/s^2 为标准值)
IMU660RA_ACC_SAMPLE_SGN_8G , // 加速度计量程 ±8 g (ACC = Accelerometer 加速度计) (SGN = signum 带符号数 表示正负范围) (g 代表重力加速度 物理学名词 一般情况下 g 取 9.8 m/s^2 为标准值)
IMU660RA_ACC_SAMPLE_SGN_16G, // 加速度计量程 ±16g (ACC = Accelerometer 加速度计) (SGN = signum 带符号数 表示正负范围) (g 代表重力加速度 物理学名词 一般情况下 g 取 9.8 m/s^2 为标准值)
}imu660ra_acc_sample_config;
typedef enum
{
IMU660RA_GYRO_SAMPLE_SGN_125DPS , // 陀螺仪量程 ±125DPS (GYRO = Gyroscope 陀螺仪) (SGN = signum 带符号数 表示正负范围) (DPS = Degree Per Second 角速度单位 °/S)
IMU660RA_GYRO_SAMPLE_SGN_250DPS , // 陀螺仪量程 ±250DPS (GYRO = Gyroscope 陀螺仪) (SGN = signum 带符号数 表示正负范围) (DPS = Degree Per Second 角速度单位 °/S)
IMU660RA_GYRO_SAMPLE_SGN_500DPS , // 陀螺仪量程 ±500DPS (GYRO = Gyroscope 陀螺仪) (SGN = signum 带符号数 表示正负范围) (DPS = Degree Per Second 角速度单位 °/S)
IMU660RA_GYRO_SAMPLE_SGN_1000DPS, // 陀螺仪量程 ±1000DPS (GYRO = Gyroscope 陀螺仪) (SGN = signum 带符号数 表示正负范围) (DPS = Degree Per Second 角速度单位 °/S)
IMU660RA_GYRO_SAMPLE_SGN_2000DPS, // 陀螺仪量程 ±2000DPS (GYRO = Gyroscope 陀螺仪) (SGN = signum 带符号数 表示正负范围) (DPS = Degree Per Second 角速度单位 °/S)
}imu660ra_gyro_sample_config;
#define IMU660RA_ACC_SAMPLE_DEFAULT ( IMU660RA_ACC_SAMPLE_SGN_8G ) // 在这设置默认的 加速度计 初始化量程
#define IMU660RA_GYRO_SAMPLE_DEFAULT ( IMU660RA_GYRO_SAMPLE_SGN_2000DPS ) // 在这设置默认的 陀螺仪 初始化量程
#define IMU660RA_TIMEOUT_COUNT ( 0x00FF ) // IMU660RA 超时计数
//================================================定义 IMU660RA 内部地址================================================
#define IMU660RA_DEV_ADDR ( 0x69 ) // SA0接地:0x68 SA0上拉:0x69 模块默认上拉
#define IMU660RA_SPI_W ( 0x00 )
#define IMU660RA_SPI_R ( 0x80 )
#define IMU660RA_CHIP_ID ( 0x00 )
#define IMU660RA_PWR_CONF ( 0x7C )
#define IMU660RA_PWR_CTRL ( 0x7D )
#define IMU660RA_INIT_CTRL ( 0x59 )
#define IMU660RA_INIT_DATA ( 0x5E )
#define IMU660RA_INT_STA ( 0x21 )
#define IMU660RA_ACC_ADDRESS ( 0x0C )
#define IMU660RA_GYRO_ADDRESS ( 0x12 )
#define IMU660RA_ACC_CONF ( 0x40 )
#define IMU660RA_ACC_RANGE ( 0x41 )
#define IMU660RA_GYR_CONF ( 0x42 )
#define IMU660RA_GYR_RANGE ( 0x43 )
//================================================定义 IMU660RA 内部地址================================================
extern int16 imu660ra_gyro_x, imu660ra_gyro_y, imu660ra_gyro_z; // 三轴陀螺仪数据 gyro (陀螺仪)
extern int16 imu660ra_acc_x, imu660ra_acc_y, imu660ra_acc_z; // 三轴加速度计数据 acc (accelerometer 加速度计)
extern float imu660ra_transition_factor[2];
void imu660ra_get_acc (void); // 获取 IMU660RA 加速度计数据
void imu660ra_get_gyro (void); // 获取 IMU660RA 陀螺仪数据
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 将 IMU660RA 加速度计数据转换为实际物理数据
// 参数说明 acc_value 任意轴的加速度计数据
// 返回参数 void
// 使用示例 float data = imu660ra_acc_transition(imu660ra_acc_x); // 单位为 g(m/s^2)
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
#define imu660ra_acc_transition(acc_value) ((float)(acc_value) / imu660ra_transition_factor[0])
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 将 IMU660RA 陀螺仪数据转换为实际物理数据
// 参数说明 gyro_value 任意轴的陀螺仪数据
// 返回参数 void
// 使用示例 float data = imu660ra_gyro_transition(imu660ra_gyro_x); // 单位为 °/s
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
#define imu660ra_gyro_transition(gyro_value) ((float)(gyro_value) / imu660ra_transition_factor[1])
uint8 imu660ra_init (void); // 初始化 IMU660RA
#endif
+313
View File
@@ -0,0 +1,313 @@
/*********************************************************************************************************************
* MSPM0G3507 Opensource Library 即(MSPM0G3507 开源库)是一个基于官方 SDK 接口的第三方开源库
* Copyright (c) 2022 SEEKFREE 逐飞科技
*
* 本文件是 MSPM0G3507 开源库的一部分
*
* MSPM0G3507 开源库 是免费软件
* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款
* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它
*
* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证
* 甚至没有隐含的适销性或适合特定用途的保证
* 更多细节请参见 GPL
*
* 您应该在收到本开源库的同时收到一份 GPL 的副本
* 如果没有,请参阅<https://www.gnu.org/licenses/>
*
* 额外注明:
* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本
* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中
* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件
* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明)
*
* 文件名称 zf_device_imu660rb
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 MDK 5.37
* 适用平台 MSPM0G3507
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2025-06-1 SeekFree first version
********************************************************************************************************************/
/*********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* // 硬件 SPI 引脚
* SCL/SPC 查看 zf_device_imu660rb.h 中 IMU660RB_SPC_PIN 宏定义
* SDA/DSI 查看 zf_device_imu660rb.h 中 IMU660RB_SDI_PIN 宏定义
* SA0/SDO 查看 zf_device_imu660rb.h 中 IMU660RB_SDO_PIN 宏定义
* CS 查看 zf_device_imu660rb.h 中 IMU660RB_CS_PIN 宏定义
* VCC 3.3V电源
* GND 电源地
* 其余引脚悬空
* // 软件 IIC 引脚
* SCL/SPC 查看 zf_device_imu660rb.h 中 IMU660RB_SCL_PIN 宏定义
* SDA/DSI 查看 zf_device_imu660rb.h 中 IMU660RB_SDA_PIN 宏定义
* VCC 3.3V电源
* GND 电源地
* 其余引脚悬空
* ------------------------------------
********************************************************************************************************************/
#include "zf_common_clock.h"
#include "zf_common_debug.h"
#include "zf_driver_delay.h"
#include "zf_driver_spi.h"
#include "zf_driver_soft_iic.h"
// 自身头文件
#include "zf_device_imu660rb.h"
const float imu660rb_acc_transition_factor[4] = {1000.0 / 0.061, 1000.0 / 0.122, 1000.0 / 0.244, 1000.0 / 0.488};
const float imu660rb_gyro_transition_factor[6] =
{
1000.0 / 4.375, 1000.0 / 8.75, 1000.0 / 17.5,
1000.0 / 35.0, 1000.0 / 70.0, 1000.0 / 140.0,
};
int16 imu660rb_acc_x, imu660rb_acc_y, imu660rb_acc_z;
int16 imu660rb_gyro_x, imu660rb_gyro_y, imu660rb_gyro_z;
#if IMU660RB_USE_SOFT_IIC
static soft_iic_info_struct imu660rb_iic_struct;
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IMU660RB 写寄存器
// 参数说明 reg 寄存器地址
// 参数说明 data 数据
// 返回参数 void
// 使用示例 imu660rb_write_register(IMU660RB_SLV0_CONFIG, 0x00);
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
#define imu660rb_write_register(reg,data) (soft_iic_write_8bit_register(&imu660rb_iic_struct,reg,data))
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IMU660RB 读寄存器
// 参数说明 reg 寄存器地址
// 返回参数 uint8 数据
// 使用示例 imu660rb_read_register(IMU660RB_STATUS_MASTER);
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
#define imu660rb_read_register(reg) (soft_iic_sccb_read_register(&imu660rb_iic_struct,reg))
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IMU660RB 读数据 内部调用
// 参数说明 reg 寄存器地址
// 参数说明 data 数据缓冲区
// 参数说明 len 数据长度
// 返回参数 void
// 使用示例 imu660rb_read_registers(IMU660RB_OUTX_L_A, dat, 6);
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
#define imu660rb_read_registers(reg,data,len) (soft_iic_read_8bit_registers(&imu660rb_iic_struct,reg,data,len))
#else
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IMU660RB 写寄存器
// 参数说明 reg 寄存器地址
// 参数说明 data 数据
// 返回参数 void
// 使用示例 imu660rb_write_register(IMU660RB_SLV0_CONFIG, 0x00);
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
static void imu660rb_write_register (uint8 reg, uint8 data)
{
IMU660RB_CS(0);
spi_write_8bit_register(IMU660RB_SPI, reg | IMU660RB_SPI_W, data);
IMU660RB_CS(1);
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IMU660RB 读寄存器
// 参数说明 reg 寄存器地址
// 返回参数 uint8 数据
// 使用示例 imu660rb_read_register(IMU660RB_STATUS_MASTER);
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
static uint8 imu660rb_read_register (uint8 reg)
{
uint8 data = 0;
IMU660RB_CS(0);
data = spi_read_8bit_register(IMU660RB_SPI, reg | IMU660RB_SPI_R);
IMU660RB_CS(1);
return data;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IMU660RB 读数据 内部调用
// 参数说明 reg 寄存器地址
// 参数说明 data 数据缓冲区
// 参数说明 len 数据长度
// 返回参数 void
// 使用示例 imu660rb_read_registers(IMU660RB_OUTX_L_A, dat, 6);
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
static void imu660rb_read_registers (uint8 reg, uint8 *data, uint32 len)
{
IMU660RB_CS(0);
spi_read_8bit_registers(IMU660RB_SPI, reg | IMU660RB_SPI_R, data, len);
IMU660RB_CS(1);
}
#endif
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IMU660RB 六轴 检测 ID 是否匹配 框架接口
// 参数说明 void
// 返回参数 uint8 1-自检失败 0-自检成功
// 使用示例 imu660rb_func_ckeck_id(interface);
// 备注信息 本接口为传感器框架接口 并不直接对用户开放
//-------------------------------------------------------------------------------------------------------------------
static uint8 imu660rb_func_ckeck_id (void)
{
uint8 return_state = 0;
uint8 dat = 0;
uint16 timeout_count = 0;
while(0x6B != dat) // 判断 ID 是否正确
{
if(IMU660RB_TIMEOUT_COUNT < timeout_count ++)
{
return_state = 1;
break;
}
dat = imu660rb_read_register(IMU660RB_CHIP_ID);
system_delay_ms(10);
}
return return_state;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 获取 IMU660RB 加速度计数据
// 参数说明 void
// 返回参数 void
// 使用示例 imu660rb_get_acc();
// 备注信息 执行该函数后,直接查看对应的变量即可
//-------------------------------------------------------------------------------------------------------------------
void imu660rb_get_acc (void)
{
uint8 dat[6] ={0};
imu660rb_read_registers(IMU660RB_ACC_ADDRESS, dat, 6);
imu660rb_acc_x = (int16)(((uint16)dat[1] << 8 | dat[0]));
imu660rb_acc_y = (int16)(((uint16)dat[3] << 8 | dat[2]));
imu660rb_acc_z = (int16)(((uint16)dat[5] << 8 | dat[4]));
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 获取IMU660RB陀螺仪数据
// 参数说明 void
// 返回参数 void
// 使用示例 imu660rb_get_gyro();
// 备注信息 执行该函数后,直接查看对应的变量即可
//-------------------------------------------------------------------------------------------------------------------
void imu660rb_get_gyro (void)
{
uint8 dat1[6]={0};
imu660rb_read_registers(IMU660RB_GYRO_ADDRESS, dat1, 6);
imu660rb_gyro_x = (int16)(((uint16)dat1[1] << 8 | dat1[0]));
imu660rb_gyro_y = (int16)(((uint16)dat1[3] << 8 | dat1[2]));
imu660rb_gyro_z = (int16)(((uint16)dat1[5] << 8 | dat1[4]));
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 初始化 IMU660RB
// 参数说明 void
// 返回参数 uint8 操作状态 ZF_NO_ERROR / IMU660RB_OPERATION_DONE - 完成 其余值为异常
// 使用示例 imu660rb_init();
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
uint8 imu660rb_init (void)
{
uint8 return_state = 0;
system_delay_ms(10); // 上电延时
#if IMU660RB_USE_SOFT_IIC
gpio_init(IMU660RB_CS_PIN, GPO, GPIO_LOW, GPO_PUSH_PULL);
soft_iic_init(&imu660rb_iic_struct, IMU660RB_DEV_ADDR, IMU660RB_SOFT_IIC_DELAY, IMU660RB_SCL_PIN, IMU660RB_SDA_PIN);
#else
spi_init(IMU660RB_SPI, SPI_MODE0, IMU660RB_SPI_SPEED, IMU660RB_SPC_PIN, IMU660RB_SDI_PIN, IMU660RB_SDO_PIN, SPI_CS_NULL);
gpio_init(IMU660RB_CS_PIN, GPO, GPIO_LOW, GPO_PUSH_PULL);
#endif
do
{
if(imu660rb_func_ckeck_id())
{
zf_log(0, "IMU660RB acc and gyro self check error.");
return_state = 1;
break;
}
imu660rb_write_register(IMU660RB_INT1_CTRL, 0x03); // 开启陀螺仪 加速度数据就绪中断
// IMU660RB_CTRL1_XL 寄存器
// 设置为 0x30 加速度量程为 ±2 g 获取到的加速度计数据除以 16393 可以转化为带物理单位的数据 (g 代表重力加速度 物理学名词 一般情况下 g 取 9.8 m/s^2 为标准值)
// 设置为 0x38 加速度量程为 ±4 g 获取到的加速度计数据除以 8197 可以转化为带物理单位的数据 (g 代表重力加速度 物理学名词 一般情况下 g 取 9.8 m/s^2 为标准值)
// 设置为 0x3C 加速度量程为 ±8 g 获取到的加速度计数据除以 4098 可以转化为带物理单位的数据 (g 代表重力加速度 物理学名词 一般情况下 g 取 9.8 m/s^2 为标准值)
// 设置为 0x34 加速度量程为 ±16 g 获取到的加速度计数据除以 2049 可以转化为带物理单位的数据 (g 代表重力加速度 物理学名词 一般情况下 g 取 9.8 m/s^2 为标准值)
switch(IMU660RB_ACC_SAMPLE_DEFAULT)
{
default:
{
zf_log(0, "IMU660RB_ACC_SAMPLE_DEFAULT set error.");
return_state = 1;
}break;
case IMU660RB_ACC_SAMPLE_SGN_2G: imu660rb_write_register(IMU660RB_CTRL1_XL, 0x30); break;
case IMU660RB_ACC_SAMPLE_SGN_4G: imu660rb_write_register(IMU660RB_CTRL1_XL, 0x38); break;
case IMU660RB_ACC_SAMPLE_SGN_8G: imu660rb_write_register(IMU660RB_CTRL1_XL, 0x3C); break;
case IMU660RB_ACC_SAMPLE_SGN_16G: imu660rb_write_register(IMU660RB_CTRL1_XL, 0x34); break;
}
if(1 == return_state)
{
break;
}
// IMU660RB_CTRL2_G 寄存器
// 设置为 0x52 陀螺仪量程为 ±125 dps 获取到的陀螺仪数据除以 228.6 可以转化为带物理单位的数据 单位为 °/s
// 设置为 0x50 陀螺仪量程为 ±250 dps 获取到的陀螺仪数据除以 114.3 可以转化为带物理单位的数据 单位为 °/s
// 设置为 0x54 陀螺仪量程为 ±500 dps 获取到的陀螺仪数据除以 57.1 可以转化为带物理单位的数据 单位为 °/s
// 设置为 0x58 陀螺仪量程为 ±1000 dps 获取到的陀螺仪数据除以 28.6 可以转化为带物理单位的数据 单位为 °/s
// 设置为 0x5C 陀螺仪量程为 ±2000 dps 获取到的陀螺仪数据除以 14.3 可以转化为带物理单位的数据 单位为 °/s
// 设置为 0x51 陀螺仪量程为 ±4000 dps 获取到的陀螺仪数据除以 7.1 可以转化为带物理单位的数据 单位为 °/s
switch(IMU660RB_GYRO_SAMPLE_DEFAULT)
{
default:
{
zf_log(0, "IMU660RB_GYRO_SAMPLE_DEFAULT set error.");
return_state = 1;
}break;
case IMU660RB_GYRO_SAMPLE_SGN_125DPS: imu660rb_write_register(IMU660RB_CTRL2_G, 0x52); break;
case IMU660RB_GYRO_SAMPLE_SGN_250DPS: imu660rb_write_register(IMU660RB_CTRL2_G, 0x50); break;
case IMU660RB_GYRO_SAMPLE_SGN_500DPS: imu660rb_write_register(IMU660RB_CTRL2_G, 0x54); break;
case IMU660RB_GYRO_SAMPLE_SGN_1000DPS: imu660rb_write_register(IMU660RB_CTRL2_G, 0x58); break;
case IMU660RB_GYRO_SAMPLE_SGN_2000DPS: imu660rb_write_register(IMU660RB_CTRL2_G, 0x5C); break;
case IMU660RB_GYRO_SAMPLE_SGN_4000DPS: imu660rb_write_register(IMU660RB_CTRL2_G, 0x51); break;
}
if(1 == return_state)
{
break;
}
imu660rb_write_register(IMU660RB_CTRL3_C, 0x44); // 使能陀螺仪数字低通滤波器
imu660rb_write_register(IMU660RB_CTRL4_C, 0x02); // 使能数字低通滤波器
imu660rb_write_register(IMU660RB_CTRL5_C, 0x00); // 加速度计与陀螺仪四舍五入
imu660rb_write_register(IMU660RB_CTRL6_C, 0x00); // 开启加速度计高性能模式 陀螺仪低通滤波 133hz
imu660rb_write_register(IMU660RB_CTRL7_G, 0x00); // 开启陀螺仪高性能模式 关闭高通滤波
imu660rb_write_register(IMU660RB_CTRL9_XL, 0x01); // 关闭I3C接口
}while(0);
return return_state;
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< Part End <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+181
View File
@@ -0,0 +1,181 @@
/*********************************************************************************************************************
* MSPM0G3507 Opensource Library 即(MSPM0G3507 开源库)是一个基于官方 SDK 接口的第三方开源库
* Copyright (c) 2022 SEEKFREE 逐飞科技
*
* 本文件是 MSPM0G3507 开源库的一部分
*
* MSPM0G3507 开源库 是免费软件
* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款
* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它
*
* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证
* 甚至没有隐含的适销性或适合特定用途的保证
* 更多细节请参见 GPL
*
* 您应该在收到本开源库的同时收到一份 GPL 的副本
* 如果没有,请参阅<https://www.gnu.org/licenses/>
*
* 额外注明:
* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本
* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中
* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件
* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明)
*
* 文件名称 zf_device_imu660ra
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 MDK 5.37
* 适用平台 MSPM0G3507
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2025-06-1 SeekFree first version
********************************************************************************************************************/
/*********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* // 硬件 SPI 引脚
* SCL/SPC 查看 zf_device_imu660rb.h 中 IMU660RB_SPC_PIN 宏定义
* SDA/DSI 查看 zf_device_imu660rb.h 中 IMU660RB_SDI_PIN 宏定义
* SA0/SDO 查看 zf_device_imu660rb.h 中 IMU660RB_SDO_PIN 宏定义
* CS 查看 zf_device_imu660rb.h 中 IMU660RB_CS_PIN 宏定义
* VCC 3.3V电源
* GND 电源地
* 其余引脚悬空
* // 软件 IIC 引脚
* SCL/SPC 查看 zf_device_imu660rb.h 中 IMU660RB_SCL_PIN 宏定义
* SDA/DSI 查看 zf_device_imu660rb.h 中 IMU660RB_SDA_PIN 宏定义
* VCC 3.3V电源
* GND 电源地
* 其余引脚悬空
* ------------------------------------
********************************************************************************************************************/
#ifndef _zf_device_imu660rb_h_
#define _zf_device_imu660rb_h_
// zf_common 层 类型定义 引用
#include "zf_common_typedef.h"
#define IMU660RB_USE_SOFT_IIC ( 0 ) // 默认使用硬件 SPI 方式驱动
#if IMU660RB_USE_SOFT_IIC // 这两段 颜色正常的才是正确的 颜色灰的就是没有用的
//====================================================软件 IIC 驱动====================================================
//====================================================注意 注意 注意 使用IIC模式下不要接CS
//====================================================注意 注意 注意 使用IIC模式下不要接CS
//====================================================注意 注意 注意 使用IIC模式下不要接CS
#define IMU660RB_SOFT_IIC_DELAY ( 10 ) // 软件 IIC 的时钟延时周期 数值越小 IIC 通信速率越快
#define IMU660RB_SCL_PIN ( B23 ) // 软件 IIC SCL 引脚 连接 IMU660RB 的 SCL 引脚
#define IMU660RB_SDA_PIN ( B22 ) // 软件 IIC SDA 引脚 连接 IMU660RB 的 SDA 引脚
//====================================================软件 IIC 驱动====================================================
#else
//====================================================硬件 SPI 驱动====================================================
#define IMU660RB_SPI_SPEED ( 8 * 1000 * 1000 ) // 硬件 SPI 速率
#define IMU660RB_SPI ( SPI_1 ) // 硬件 SPI 号
#define IMU660RB_SPC_PIN ( SPI1_SCK_B23 ) // 硬件 SPI SCK 引脚
#define IMU660RB_SDI_PIN ( SPI1_MOSI_B22 ) // 硬件 SPI MOSI 引脚
#define IMU660RB_SDO_PIN ( SPI1_MISO_B21 ) // 硬件 SPI MISO 引脚
//====================================================硬件 SPI 驱动====================================================
#endif
#define IMU660RB_CS_PIN ( B19 ) // CS 片选引脚
#define IMU660RB_CS(x) (x? (gpio_high(IMU660RB_CS_PIN)): (gpio_low(IMU660RB_CS_PIN)))
typedef enum
{
IMU660RB_ACC_SAMPLE_SGN_2G , // 加速度计量程 ±2 g (ACC = Accelerometer 加速度计) (SGN = signum 带符号数 表示正负范围) (g 代表重力加速度 物理学名词 一般情况下 g 取 9.8 m/s^2 为标准值)
IMU660RB_ACC_SAMPLE_SGN_4G , // 加速度计量程 ±4 g (ACC = Accelerometer 加速度计) (SGN = signum 带符号数 表示正负范围) (g 代表重力加速度 物理学名词 一般情况下 g 取 9.8 m/s^2 为标准值)
IMU660RB_ACC_SAMPLE_SGN_8G , // 加速度计量程 ±8 g (ACC = Accelerometer 加速度计) (SGN = signum 带符号数 表示正负范围) (g 代表重力加速度 物理学名词 一般情况下 g 取 9.8 m/s^2 为标准值)
IMU660RB_ACC_SAMPLE_SGN_16G, // 加速度计量程 ±16g (ACC = Accelerometer 加速度计) (SGN = signum 带符号数 表示正负范围) (g 代表重力加速度 物理学名词 一般情况下 g 取 9.8 m/s^2 为标准值)
}imu660rb_acc_sample_config;
typedef enum
{
IMU660RB_GYRO_SAMPLE_SGN_125DPS , // 陀螺仪量程 ±125DPS (GYRO = Gyroscope 陀螺仪) (SGN = signum 带符号数 表示正负范围) (DPS = Degree Per Second 角速度单位 °/S)
IMU660RB_GYRO_SAMPLE_SGN_250DPS , // 陀螺仪量程 ±250DPS (GYRO = Gyroscope 陀螺仪) (SGN = signum 带符号数 表示正负范围) (DPS = Degree Per Second 角速度单位 °/S)
IMU660RB_GYRO_SAMPLE_SGN_500DPS , // 陀螺仪量程 ±500DPS (GYRO = Gyroscope 陀螺仪) (SGN = signum 带符号数 表示正负范围) (DPS = Degree Per Second 角速度单位 °/S)
IMU660RB_GYRO_SAMPLE_SGN_1000DPS, // 陀螺仪量程 ±1000DPS (GYRO = Gyroscope 陀螺仪) (SGN = signum 带符号数 表示正负范围) (DPS = Degree Per Second 角速度单位 °/S)
IMU660RB_GYRO_SAMPLE_SGN_2000DPS, // 陀螺仪量程 ±2000DPS (GYRO = Gyroscope 陀螺仪) (SGN = signum 带符号数 表示正负范围) (DPS = Degree Per Second 角速度单位 °/S)
IMU660RB_GYRO_SAMPLE_SGN_4000DPS, // 陀螺仪量程 ±4000DPS (GYRO = Gyroscope 陀螺仪) (SGN = signum 带符号数 表示正负范围) (DPS = Degree Per Second 角速度单位 °/S)
}imu660rb_gyro_sample_config;
typedef enum
{
IMU660RB_MAG_SAMPLE_2G, // 磁力计量程 2G (MAG = Magnetometer 磁力计) (G = Gs 高斯)
IMU660RB_MAG_SAMPLE_8G, // 磁力计量程 8G (MAG = Magnetometer 磁力计) (G = Gs 高斯)
}imu660rb_mag_sample_config;
#define IMU660RB_ACC_SAMPLE_DEFAULT ( IMU660RB_ACC_SAMPLE_SGN_8G ) // 在这设置默认的 加速度计 初始化量程
#define IMU660RB_GYRO_SAMPLE_DEFAULT ( IMU660RB_GYRO_SAMPLE_SGN_2000DPS ) // 在这设置默认的 陀螺仪 初始化量程
#define IMU660RB_TIMEOUT_COUNT ( 32 ) // IMU660RB 超时计数
// 此处定义 IMU660RB 驱动所需的内部定义 这里不允许用户修改
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Part Start >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// 定义 IMU660RB 内部地址
#define IMU660RB_DEV_ADDR (0x6B) // SA0接地:0x68 SA0上拉:0x69 模块默认上拉
#define IMU660RB_SPI_W (0x00)
#define IMU660RB_SPI_R (0x80)
#define IMU660RB_CHIP_ID (0x0F)
#define IMU660RB_INT1_CTRL (0x0D)
#define IMU660RB_CTRL1_XL (0x10)
#define IMU660RB_CTRL2_G (0x11)
#define IMU660RB_CTRL3_C (0x12)
#define IMU660RB_CTRL4_C (0x13)
#define IMU660RB_CTRL5_C (0x14)
#define IMU660RB_CTRL6_C (0x15)
#define IMU660RB_CTRL7_G (0x16)
#define IMU660RB_CTRL9_XL (0x18)
#define IMU660RB_ACC_ADDRESS (0x28)
#define IMU660RB_GYRO_ADDRESS (0x22)
#define IMU660RB_ACC_SAMPLE (0x3C) // 加速度计量程
// 设置为:0x30 加速度量程为:±2G 获取到的加速度计数据 除以16393,可以转化为带物理单位的数据,单位:g(m/s^2)
// 设置为:0x38 加速度量程为:±4G 获取到的加速度计数据 除以8197, 可以转化为带物理单位的数据,单位:g(m/s^2)
// 设置为:0x3C 加速度量程为:±8G 获取到的加速度计数据 除以4098, 可以转化为带物理单位的数据,单位:g(m/s^2)
// 设置为:0x34 加速度量程为:±16G 获取到的加速度计数据 除以2049, 可以转化为带物理单位的数据,单位:g(m/s^2)
#define IMU660RB_GYR_SAMPLE (0x5C) // 陀螺仪量程
// 设置为:0x52 陀螺仪量程为:±125dps 获取到的陀螺仪数据除以228.6, 可以转化为带物理单位的数据,单位为:°/s
// 设置为:0x50 陀螺仪量程为:±250dps 获取到的陀螺仪数据除以114.3, 可以转化为带物理单位的数据,单位为:°/s
// 设置为:0x54 陀螺仪量程为:±500dps 获取到的陀螺仪数据除以57.1, 可以转化为带物理单位的数据,单位为:°/s
// 设置为:0x58 陀螺仪量程为:±1000dps 获取到的陀螺仪数据除以28.6, 可以转化为带物理单位的数据,单位为:°/s
// 设置为:0x5C 陀螺仪量程为:±2000dps 获取到的陀螺仪数据除以14.3, 可以转化为带物理单位的数据,单位为:°/s
// 设置为:0x51 陀螺仪量程为:±4000dps 获取到的陀螺仪数据除以7.1, 可以转化为带物理单位的数据,单位为:°/s
extern int16 imu660rb_acc_x, imu660rb_acc_y, imu660rb_acc_z;
extern int16 imu660rb_gyro_x, imu660rb_gyro_y, imu660rb_gyro_z;
extern const float imu660rb_acc_transition_factor[4];
extern const float imu660rb_gyro_transition_factor[6];
void imu660rb_get_acc (void);
void imu660rb_get_gyro (void);
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 将 IMU660RB 加速度计数据转换为实际物理数据
// 参数说明 acc_value 任意轴的加速度计数据
// 返回参数 void
// 使用示例 float data = imu660rb_acc_transition(imu660rb_acc_x); // 单位为 g(m/s^2)
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
#define imu660rb_acc_transition(acc_value) ((float)(acc_value) / imu660rb_acc_transition_factor[IMU660RB_ACC_SAMPLE_DEFAULT])
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 将 IMU660RB 陀螺仪数据转换为实际物理数据
// 参数说明 gyro_value 任意轴的陀螺仪数据
// 返回参数 void
// 使用示例 float data = imu660rb_gyro_transition(imu660rb_gyro_x); // 单位为 °/s
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
#define imu660rb_gyro_transition(gyro_value) ((float)(gyro_value) / imu660rb_gyro_transition_factor[IMU660RB_GYRO_SAMPLE_DEFAULT])
uint8 imu660rb_init (void);
#endif
+567
View File
@@ -0,0 +1,567 @@
/*********************************************************************************************************************
* RT1064DVL6A Opensourec Library 即(RT1064DVL6A 开源库)是一个基于官方 SDK 接口的第三方开源库
* Copyright (c) 2022 SEEKFREE 逐飞科技
*
* 本文件是 RT1064DVL6A 开源库的一部分
*
* RT1064DVL6A 开源库 是免费软件
* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款
* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它
*
* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证
* 甚至没有隐含的适销性或适合特定用途的保证
* 更多细节请参见 GPL
*
* 您应该在收到本开源库的同时收到一份 GPL 的副本
* 如果没有,请参阅<https://www.gnu.org/licenses/>
*
* 额外注明:
* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本
* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中
* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件
* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明)
*
* 文件名称 zf_device_imu660rc
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 MDK 5.37
* 适用平台 MSPM0G3507
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2025-12-12 SeekFree first version
********************************************************************************************************************/
/*********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* // 硬件 SPI 引脚
* SCL/SPC 查看 zf_device_imu660rc.h 中 IMU660RC_SPC_PIN 宏定义
* SDA/DSI 查看 zf_device_imu660rc.h 中 IMU660RC_SDI_PIN 宏定义
* SA0/SDO 查看 zf_device_imu660rc.h 中 IMU660RC_SDO_PIN 宏定义
* CS 查看 zf_device_imu660rc.h 中 IMU660RC_CS_PIN 宏定义
* INT2 查看 zf_device_imu660rc.h 中 IMU660RC_INT2_PIN 宏定义
* VCC 3.3V电源
* GND 电源地
* 其余引脚悬空
*
* // 软件 IIC 引脚
* SCL/SPC 查看 zf_device_imu660rc.h 中 IMU660RC_SCL_PIN 宏定义
* SDA/DSI 查看 zf_device_imu660rc.h 中 IMU660RC_SDA_PIN 宏定义
* VCC 3.3V电源
* GND 电源地
* 其余引脚悬空
* ------------------------------------
********************************************************************************************************************/
#include "math.h"
#include "zf_common_debug.h"
#include "zf_driver_delay.h"
#include "zf_driver_spi.h"
#include "zf_driver_gpio.h"
#include "zf_driver_soft_iic.h"
#include "zf_device_config.h"
#include "zf_driver_uart.h"
#include "zf_driver_exti.h"
#include "zf_device_imu660rc.h"
#ifndef M_PI
#define M_PI 3.1415926f
#endif
static uint8 imu660rc_quarternion_rate;
float imu660rc_transition_factor[2];
int16 imu660rc_gyro_x = 0, imu660rc_gyro_y = 0, imu660rc_gyro_z = 0; // 三轴陀螺仪数据 gyro (陀螺仪)
int16 imu660rc_acc_x = 0, imu660rc_acc_y = 0, imu660rc_acc_z = 0; // 三轴加速度计数据 acc (accelerometer 加速度计)
float imu660rc_roll = 0, imu660rc_pitch = 0, imu660rc_yaw = 0; // 欧拉角
float imu660rc_quarternion[4]; // 四元数
#if IMU660RC_USE_SOFT_IIC
static soft_iic_info_struct imu660rc_iic_struct;
#define imu660rc_write_register(reg, data) (soft_iic_write_8bit_register (&imu660rc_iic_struct, (reg), (data)))
#define imu660rc_write_registers(reg, data, len) (soft_iic_write_8bit_registers(&imu660rc_iic_struct, (reg), (data), (len)))
#define imu660rc_read_register(reg) (soft_iic_read_8bit_register (&imu660rc_iic_struct, (reg)))
#define imu660rc_read_registers(reg, data, len) (soft_iic_read_8bit_registers (&imu660rc_iic_struct, (reg), (data), (len)))
#else
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IMU660RC 写寄存器
// 参数说明 reg 寄存器地址
// 参数说明 data 数据
// 返回参数 void
// 使用示例
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
static void imu660rc_write_register (uint8 reg, uint8 data)
{
IMU660RC_CS(0);
spi_write_8bit_register(IMU660RC_SPI, reg | IMU660RC_SPI_W, data);
IMU660RC_CS(1);
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IMU660RC 读寄存器
// 参数说明 reg 寄存器地址
// 返回参数 uint8 数据
// 使用示例 imu660rc_read_register(IMU660RC_CHIP_ID);
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
static uint8 imu660rc_read_register (uint8 reg)
{
uint8 data;
IMU660RC_CS(0);
data = spi_read_8bit_register(IMU660RC_SPI, reg | IMU660RC_SPI_R);
IMU660RC_CS(1);
return data;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IMU660RC 读数据
// 参数说明 reg 寄存器地址
// 参数说明 data 数据缓冲区
// 参数说明 len 数据长度
// 返回参数 void
// 使用示例 imu660rc_read_registers(IMU660RC_ACC_ADDRESS, dat, 6);
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
static void imu660rc_read_registers (uint8 reg, uint8 *data, uint32 len)
{
IMU660RC_CS(0);
spi_read_8bit_registers(IMU660RC_SPI, reg | IMU660RC_SPI_R, data, len);
IMU660RC_CS(1);
}
#endif
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IMU660RC fp16转浮点数
// 参数说明 void
// 返回参数 uint8
// 使用示例
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
static uint32 fp16_to_float(uint16 h)
{
uint16 h_exp = (h & 0x7c00u);
uint32 f_sgn = ((uint32)h & 0x8000u) << 16;
switch (h_exp)
{
case 0x0000u: // 0 or subnormal
{
uint16 h_sig = (h & 0x03ffu);
// Signed zero
if (h_sig == 0)
{
return f_sgn;
}
// Subnormal
h_sig <<= 1;
while ((h_sig & 0x0400u) == 0)
{
h_sig <<= 1;
h_exp++;
}
uint32 f_exp = ((uint32)(127 - 15 - h_exp)) << 23;
uint32 f_sig = ((uint32)(h_sig & 0x03ffu)) << 13;
return f_sgn + f_exp + f_sig;
}
case 0x7c00u: // inf or NaN
{
// All-ones exponent and a copy of the significand
return f_sgn + 0x7f800000u + (((uint32)(h & 0x03ffu)) << 13);
}
default: // normalized
{
// Just need to adjust the exponent and shift
return f_sgn + (((uint32)(h & 0x7fffu) + 0x1c000u) << 13);
}
}
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IMU660RC 四元数归一化
// 参数说明 void
// 返回参数 uint8
// 使用示例
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
static void quarternion_normalize(float quat[4], uint16 *fp16)
{
float n = 0;
float temp[4];
*(uint32 *)(&temp[0]) = fp16_to_float(fp16[0]);
*(uint32 *)(&temp[1]) = fp16_to_float(fp16[1]);
*(uint32 *)(&temp[2]) = fp16_to_float(fp16[2]);
*(uint32 *)(&temp[3]) = fp16_to_float(fp16[3]);
n = temp[0] * temp[0] + temp[1] * temp[1] + temp[2] * temp[2] + temp[3] * temp[3];
n = sqrtf(n);
if(n > 0.001f) // 避免除以接近0的值
{
n = temp[3] < 0.0f ? -n : n;
quat[0] = temp[1] / n;
quat[1] = temp[2] / n;
quat[2] = temp[0] / n;
quat[3] = temp[3] / n;
}
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IMU660RC 四元数转欧拉角
// 参数说明 void
// 返回参数 uint8
// 使用示例
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
static void quarternion_to_euler(float quat[4], float *roll, float *pitch, float *yaw)
{
float euler[3];
float sqx = quat[0] * quat[0];
float sqy = quat[1] * quat[1];
float sqz = quat[2] * quat[2];
euler[0] = atan2f(2.0f * (quat[1] * quat[3] + quat[0] * quat[2]), 1.0f - 2.0f * (sqy + sqx));
euler[1] = -asinf(2.0f * (quat[0] * quat[3] - quat[1] * quat[2]));
euler[2] = atan2f(2.0f * (quat[0] * quat[1] + quat[2] * quat[3]), 1.0f - 2.0f * (sqx + sqz));
// 弧度转角度
euler[0] = 180 * (euler[0]) / M_PI;
euler[1] = 180 * (euler[1]) / M_PI;
euler[2] = 180 * (euler[2]) / M_PI;
// 角度调整
euler[2] = 0 > euler[2] ? euler[2] + 360 : euler[2];
*roll = euler[0];
*pitch = euler[1];
*yaw = euler[2];
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IMU660RC 设置访问区域
// 参数说明 void
// 返回参数 uint8
// 使用示例
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
static void imu660rc_set_mem_bank (imu660rc_mem_bank_enum bank)
{
imu660rc_write_register(IMU660RC_FUNC_CFG_ACCESS, bank);
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IMU660RC 自检
// 参数说明 void
// 返回参数 uint8 1-自检失败 0-自检成功
// 使用示例 imu660rc_self_check();
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
static uint8 imu660rc_self_check (void)
{
uint8 dat = 0, return_state = 0;
uint16 timeout_count = 0;
do
{
if(IMU660RC_TIMEOUT_COUNT < timeout_count ++)
{
return_state = 1;
break;
}
dat = imu660rc_read_register(IMU660RC_CHIP_ID);
system_delay_ms(1);
}while(0x70 != dat); // 读取设备ID是否等于0x70,如果不是0x70则认为没检测到设备
return return_state;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 获取 IMU660RC 加速度计数据
// 参数说明 void
// 返回参数 void
// 使用示例 imu660rc_get_acc(); // 执行该函数后,直接查看对应的变量即可
// 备注信息 使用 SPI 的采集时间为10us
//-------------------------------------------------------------------------------------------------------------------
void imu660rc_get_acc (void)
{
int16 dat[3];
if(IMU660RC_QUARTERNION_DISABLE == imu660rc_quarternion_rate)
{ // 仅在四元数关闭状态下支持调用此函数, 四元数开启时如果需要读取加速度信息则IMU660RC_QUARTERNION_GET_ACC设置为1
imu660rc_read_registers(IMU660RC_OUTX_L_A, (uint8 *)dat, 6);
imu660rc_acc_x = dat[0];
imu660rc_acc_y = dat[1];
imu660rc_acc_z = dat[2];
}
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 获取 IMU660RC 陀螺仪数据
// 参数说明 void
// 返回参数 void
// 使用示例 imu660rc_get_gyro(); // 执行该函数后,直接查看对应的变量即可
// 备注信息 使用 SPI 的采集时间为10us
//-------------------------------------------------------------------------------------------------------------------
void imu660rc_get_gyro (void)
{
int16 dat[3];
if(IMU660RC_QUARTERNION_DISABLE == imu660rc_quarternion_rate)
{ // 仅在四元数关闭状态下支持调用此函数, 四元数开启时如果需要读取加速度信息则IMU660RC_QUARTERNION_GET_GYRO设置为1
imu660rc_read_registers(IMU660RC_OUTX_L_G, (uint8 *)dat, 6);
imu660rc_gyro_x = dat[0];
imu660rc_gyro_y = dat[1];
imu660rc_gyro_z = dat[2];
}
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 获取 IMU660RC 四元数数据并转换为欧拉角
// 参数说明 void
// 返回参数 void
// 使用示例 imu660rc_get_quarternion(); // 执行该函数后,直接查看对应的变量即可
// 备注信息 需要在INT2引脚触发的上升沿中断调用此函数
//
//-------------------------------------------------------------------------------------------------------------------
void imu660rc_get_quarternion(void)
{
uint8 i;
uint16 buff[4];
uint8 *buff1_ptr;
int16 *buff2_ptr;
if(IMU660RC_QUARTERNION_DISABLE != imu660rc_quarternion_rate)
{
buff1_ptr = (uint8 *)buff;
imu660rc_set_mem_bank(IMU660RC_EMBED_MEM_BANK);
imu660rc_write_register(IMU660RC_PAGE_RW, 0x20);
imu660rc_write_register(IMU660RC_PAGE_SEL, 0x31);
for(i = 0; 8 > i; i++)
{
imu660rc_write_register(0x08, 0x4C + i);
buff1_ptr[i] = imu660rc_read_register(0x09);
}
imu660rc_write_register(IMU660RC_PAGE_RW, 0x0);
imu660rc_set_mem_bank(IMU660RC_MAIN_MEM_BANK);
// 四元数归一化
quarternion_normalize(imu660rc_quarternion, buff);
// 四元数转欧拉角
quarternion_to_euler(imu660rc_quarternion, &imu660rc_roll, &imu660rc_pitch, &imu660rc_yaw);
// 读取加速度与角速度信息
#if(1 == IMU660RC_QUARTERNION_GET_ACC)
{
buff2_ptr = (int16 *)buff;
imu660rc_read_registers(IMU660RC_OUTX_L_A, (uint8 *)buff2_ptr, 6);
imu660rc_acc_x = buff2_ptr[0];
imu660rc_acc_y = buff2_ptr[1];
imu660rc_acc_z = buff2_ptr[2];
}
#endif
#if(1 == IMU660RC_QUARTERNION_GET_GYRO)
{
buff2_ptr = (int16 *)buff;
imu660rc_read_registers(IMU660RC_OUTX_L_G, (uint8 *)buff2_ptr, 6);
imu660rc_gyro_x = buff2_ptr[0];
imu660rc_gyro_y = buff2_ptr[1];
imu660rc_gyro_z = buff2_ptr[2];
}
#endif
}
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IMU660RC中断回调函数,主要在中断内读取四元数
// 参数说明 void
// 返回参数 void
// 使用示例
// 备注信息
//
//-------------------------------------------------------------------------------------------------------------------
void imu660rc_callback(uint32 event, void *ptr)
{
imu660rc_get_quarternion();
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 初始化 IMU660RC
// 参数说明 quarternion_rate 选择四元数输出速率
// 返回参数 uint8 1-初始化失败 0-初始化成功
// 使用示例 imu660rc_init(IMU660RC_QUARTERNION_120HZ);
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
uint8 imu660rc_init(imu660rc_quarternion_rate_config quarternion_rate)
{
uint8 return_state = 0;
imu660rc_quarternion_rate = quarternion_rate;
#if IMU660RC_USE_IIC
#if IMU660RC_USE_SOFT_IIC
soft_iic_init(&imu660rc_iic_struct, IMU660RC_DEV_ADDR, IMU660RC_SOFT_IIC_DELAY, IMU660RC_SCL_PIN, IMU660RC_SDA_PIN); // 配置 IMU660RC 的 IIC 端口
#else
iic_init(IMU660RC_IIC_INDEX, IMU660RC_DEV_ADDR, IMU660RC_IIC_SPEED, IMU660RC_SCL_PIN, IMU660RC_SDA_PIN); // 配置 IMU660RC 的 IIC 端口
#endif
#else
spi_init(IMU660RC_SPI, SPI_MODE0, IMU660RC_SPI_SPEED, IMU660RC_SPC_PIN, IMU660RC_SDI_PIN, IMU660RC_SDO_PIN, SPI_CS_NULL); // 配置 IMU660RC 的 SPI 端口
gpio_init(IMU660RC_CS_PIN, GPO, GPIO_HIGH, GPO_PUSH_PULL); // 配置 IMU660RC 的CS端口
#endif
system_delay_ms(10);
imu660rc_read_register(IMU660RC_CHIP_ID);
do
{
if(imu660rc_self_check()) // IMU660RC 自检
{
// 如果程序在输出了断言信息 并且提示出错位置在这里
// 那么就是 IMU660RC 自检出错并超时退出了
// 检查一下接线有没有问题 如果没问题可能就是坏了
zf_log(0, "imu660rc self check error.");
return_state = 1;
break;
}
// 复位传感器
imu660rc_write_register(IMU660RC_FUNC_CFG_ACCESS, 0x04);
system_delay_ms(30);
// 启用块更新功能与地址递增
imu660rc_write_register(IMU660RC_CTRL3, 0x44);
switch(IMU660RC_ACC_SAMPLE_DEFAULT)
{
default:
{
zf_log(0, "IMU660RC_ACC_SAMPLE_DEFAULT set error.");
return_state = 1;
}break;
case IMU660RC_ACC_SAMPLE_SGN_2G:
{
imu660rc_write_register(IMU660RC_CTRL8, 0x00);
imu660rc_transition_factor[0] = 16393.44;
}break;
case IMU660RC_ACC_SAMPLE_SGN_4G:
{
imu660rc_write_register(IMU660RC_CTRL8, 0x01);
imu660rc_transition_factor[0] = 8196.72;
}break;
case IMU660RC_ACC_SAMPLE_SGN_8G:
{
imu660rc_write_register(IMU660RC_CTRL8, 0x02);
imu660rc_transition_factor[0] = 4098.36;
}break;
case IMU660RC_ACC_SAMPLE_SGN_16G:
{
imu660rc_write_register(IMU660RC_CTRL8, 0x03);
imu660rc_transition_factor[0] = 2049.18;
}break;
}
if(1 == return_state)
{
break;
}
switch(IMU660RC_GYRO_SAMPLE_DEFAULT)
{
default:
{
zf_log(0, "IMU660RC_GYRO_SAMPLE_DEFAULT set error.");
return_state = 1;
}break;
case IMU660RC_GYRO_SAMPLE_SGN_125DPS:
{
imu660rc_write_register(IMU660RC_CTRL6, 0x00);
imu660rc_transition_factor[1] = 228.5714;
}break;
case IMU660RC_GYRO_SAMPLE_SGN_250DPS:
{
imu660rc_write_register(IMU660RC_CTRL6, 0x01);
imu660rc_transition_factor[1] = 114.2857;
}break;
case IMU660RC_GYRO_SAMPLE_SGN_500DPS:
{
imu660rc_write_register(IMU660RC_CTRL6, 0x02);
imu660rc_transition_factor[1] = 57.1428;
}break;
case IMU660RC_GYRO_SAMPLE_SGN_1000DPS:
{
imu660rc_write_register(IMU660RC_CTRL6, 0x03);
imu660rc_transition_factor[1] = 28.5714;
}break;
case IMU660RC_GYRO_SAMPLE_SGN_2000DPS:
{
imu660rc_write_register(IMU660RC_CTRL6, 0x04);
imu660rc_transition_factor[1] = 14.2857;
}break;
case IMU660RC_GYRO_SAMPLE_SGN_4000DPS:
{
imu660rc_write_register(IMU660RC_CTRL6, 0x0C);
imu660rc_transition_factor[1] = 7.14285;
}break;
}
if(1 == return_state)
{
break;
}
// 设置传感器模式,设置为高精度模式以及输出速率
imu660rc_write_register(IMU660RC_CTRL1, 0x15);
imu660rc_write_register(IMU660RC_CTRL2, 0x18);
// 开启LPF1滤波器
imu660rc_write_register(IMU660RC_CTRL7, 0x01);
// 开启LPF2滤波器
imu660rc_write_register(IMU660RC_CTRL9, 0x08);
// 如果启用四元数输出,则配置相应数据
if(IMU660RC_QUARTERNION_DISABLE != quarternion_rate)
{
// 设置中断触发信号
imu660rc_write_register(IMU660RC_INT2_CTRL, 0x80);
imu660rc_write_register(IMU660RC_CTRL4, 0x08);
imu660rc_write_register(IMU660RC_EMB_FUNC_CFG, 0x30);
// 重新配置加速度、角速度输出速率
imu660rc_write_register(IMU660RC_CTRL1, 0x10 | (quarternion_rate + 3));
imu660rc_write_register(IMU660RC_CTRL2, 0x10 | (quarternion_rate + 3));
// 设置四元数输出速率并开启
imu660rc_set_mem_bank(IMU660RC_EMBED_MEM_BANK);
imu660rc_write_register(IMU660RC_SFLP_ODR, 0x43 | (quarternion_rate << 3));
imu660rc_write_register(IMU660RC_EMB_FUNC_EN_A, 0x02);
imu660rc_write_register(IMU660RC_PAGE_RW, 0x00);
imu660rc_set_mem_bank(IMU660RC_MAIN_MEM_BANK);
// 开启中断检测引脚
exti_init(IMU660RC_INT2_PIN, EXTI_TRIGGER_RISING, imu660rc_callback, NULL);
}
}while(0);
return return_state;
}
+212
View File
@@ -0,0 +1,212 @@
/*********************************************************************************************************************
* RT1064DVL6A Opensourec Library 即(RT1064DVL6A 开源库)是一个基于官方 SDK 接口的第三方开源库
* Copyright (c) 2022 SEEKFREE 逐飞科技
*
* 本文件是 RT1064DVL6A 开源库的一部分
*
* RT1064DVL6A 开源库 是免费软件
* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款
* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它
*
* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证
* 甚至没有隐含的适销性或适合特定用途的保证
* 更多细节请参见 GPL
*
* 您应该在收到本开源库的同时收到一份 GPL 的副本
* 如果没有,请参阅<https://www.gnu.org/licenses/>
*
* 额外注明:
* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本
* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中
* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件
* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明)
*
* 文件名称 zf_device_imu660rc
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 MDK 5.37
* 适用平台 MSPM0G3507
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2025-12-12 SeekFree first version
********************************************************************************************************************/
/*********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* // 硬件 SPI 引脚
* SCL/SPC 查看 zf_device_imu660rc.h 中 IMU660RC_SPC_PIN 宏定义
* SDA/DSI 查看 zf_device_imu660rc.h 中 IMU660RC_SDI_PIN 宏定义
* SA0/SDO 查看 zf_device_imu660rc.h 中 IMU660RC_SDO_PIN 宏定义
* CS 查看 zf_device_imu660rc.h 中 IMU660RC_CS_PIN 宏定义
* INT2 查看 zf_device_imu660rc.h 中 IMU660RC_INT2_PIN 宏定义
* VCC 3.3V电源
* GND 电源地
* 其余引脚悬空
*
* // 软件 IIC 引脚
* SCL/SPC 查看 zf_device_imu660rc.h 中 IMU660RC_SCL_PIN 宏定义
* SDA/DSI 查看 zf_device_imu660rc.h 中 IMU660RC_SDA_PIN 宏定义
* VCC 3.3V电源
* GND 电源地
* 其余引脚悬空
* ------------------------------------
********************************************************************************************************************/
#ifndef _zf_device_imu660rc_h_
#define _zf_device_imu660rc_h_
#include "zf_common_typedef.h"
// IMU660RC_USE_SOFT_IIC定义为0表示使用硬件SPI驱动 定义为1表示使用软件IIC驱动
// 当更改IMU660RC_USE_SOFT_IIC定义后,需要先编译并下载程序,单片机与模块需要断电重启才能正常通讯
#define IMU660RC_USE_SOFT_IIC ( 0 ) // 默认使用硬件 SPI 方式驱动
#define IMU660RC_USE_IIC ( 0 )
#if IMU660RC_USE_SOFT_IIC // 这两段 颜色正常的才是正确的 颜色灰的就是没有用的
//====================================================软件 IIC 驱动====================================================
#define IMU660RC_SOFT_IIC_DELAY ( 10 ) // 软件 IIC 的时钟延时周期 数值越小 IIC 通信速率越快
#define IMU660RC_SCL_PIN ( B23 ) // 软件 IIC SCL 引脚 连接 IMU660RC 的 SCL 引脚
#define IMU660RC_SDA_PIN ( B22 ) // 软件 IIC SDA 引脚 连接 IMU660RC 的 SDA 引脚
//====================================================软件 IIC 驱动====================================================
#else
//====================================================硬件 SPI 驱动====================================================
#define IMU660RC_SPI_SPEED ( 8 * 1000 * 1000) // 硬件 SPI 速率
#define IMU660RC_SPI ( SPI_1 ) // 硬件 SPI 号
#define IMU660RC_SPC_PIN ( SPI1_SCK_B23 ) // 硬件 SPI SCK 引脚
#define IMU660RC_SDI_PIN ( SPI1_MOSI_B22 ) // 硬件 SPI MOSI 引脚
#define IMU660RC_SDO_PIN ( SPI1_MISO_B21 ) // 硬件 SPI MISO 引脚
//====================================================硬件 SPI 驱动====================================================
#endif
#define IMU660RC_CS_PIN ( B19 ) // CS 片选引脚
#define IMU660RC_CS(x) ( (x) ? (gpio_high(IMU660RC_CS_PIN)) : (gpio_low(IMU660RC_CS_PIN)) )
#define IMU660RC_INT2_PIN ( B24 ) // 中断信号引脚,在读取四元数时需要使用
#define IMU660RC_QUARTERNION_GET_GYRO ( 1 ) // 1:在输出四元数的模式时,读取四元数时自动读取角速度 0:不自动读取
#define IMU660RC_QUARTERNION_GET_ACC ( 1 ) // 1:在输出四元数的模式时,读取四元数时自动读取加速度 0:不自动读取
#define IMU660RC_ACC_SAMPLE_DEFAULT ( IMU660RC_ACC_SAMPLE_SGN_8G ) // 在这设置默认的 加速度计 初始化量程
#define IMU660RC_GYRO_SAMPLE_DEFAULT ( IMU660RC_GYRO_SAMPLE_SGN_2000DPS ) // 在这设置默认的 陀螺仪 初始化量程
typedef enum
{
IMU660RC_MAIN_MEM_BANK = 0x00,
IMU660RC_HUB_MEM_BANK = 0x40,
IMU660RC_EMBED_MEM_BANK = 0x80,
}imu660rc_mem_bank_enum;
typedef enum
{
IMU660RC_ACC_SAMPLE_SGN_2G , // 加速度计量程 ±2G (ACC = Accelerometer 加速度计) (SGN = signum 带符号数 表示正负范围) (G = g 重力加速度 g≈9.80 m/s^2)
IMU660RC_ACC_SAMPLE_SGN_4G , // 加速度计量程 ±4G
IMU660RC_ACC_SAMPLE_SGN_8G , // 加速度计量程 ±8G
IMU660RC_ACC_SAMPLE_SGN_16G, // 加速度计量程 ±16G
}imu660rc_acc_sample_config;
typedef enum
{
IMU660RC_GYRO_SAMPLE_SGN_125DPS , // 陀螺仪量程 ±125DPS (GYRO = Gyroscope 陀螺仪) (SGN = signum 带符号数 表示正负范围) (DPS = Degree Per Second 角速度单位 °/S)
IMU660RC_GYRO_SAMPLE_SGN_250DPS , // 陀螺仪量程 ±250DPS
IMU660RC_GYRO_SAMPLE_SGN_500DPS , // 陀螺仪量程 ±500DPS
IMU660RC_GYRO_SAMPLE_SGN_1000DPS, // 陀螺仪量程 ±1000DPS
IMU660RC_GYRO_SAMPLE_SGN_2000DPS, // 陀螺仪量程 ±2000DPS
IMU660RC_GYRO_SAMPLE_SGN_4000DPS, // 陀螺仪量程 ±4000DPS
}imu660rc_gyro_sample_config;
typedef enum
{
IMU660RC_QUARTERNION_15HZ, // 15 Hz
IMU660RC_QUARTERNION_30HZ, // 30 Hz
IMU660RC_QUARTERNION_60HZ, // 60 Hz
IMU660RC_QUARTERNION_120HZ, // 120Hz
IMU660RC_QUARTERNION_240HZ, // 240Hz
IMU660RC_QUARTERNION_480HZ, // 480Hz
IMU660RC_QUARTERNION_DISABLE, // 禁用四元数输出
}imu660rc_quarternion_rate_config;
//================================================定义 IMU660RC 内部地址================================================
#define IMU660RC_DEV_ADDR ( 0x6B ) // SA0接地:0x6A SA0上拉:0x6B 模块默认上拉
#define IMU660RC_SPI_W ( 0x00 )
#define IMU660RC_SPI_R ( 0x80 )
#define IMU660RC_TIMEOUT_COUNT ( 0x00FF ) // IMU660RC 超时计数
//================================================定义 IMU660RC 寄存器地址================================================
#define IMU660RC_FUNC_CFG_ACCESS ( 0x01 )
#define IMU660RC_INT2_CTRL ( 0x0E )
#define IMU660RC_CHIP_ID ( 0x0F )
#define IMU660RC_CTRL1 ( 0x10 )
#define IMU660RC_CTRL2 ( 0x11 )
#define IMU660RC_CTRL3 ( 0x12 )
#define IMU660RC_CTRL4 ( 0x13 )
#define IMU660RC_CTRL5 ( 0x14 )
#define IMU660RC_CTRL6 ( 0x15 )
#define IMU660RC_CTRL7 ( 0x16 )
#define IMU660RC_CTRL8 ( 0x17 )
#define IMU660RC_CTRL9 ( 0x18 )
#define IMU660RC_CTRL10 ( 0x19 )
#define IMU660RC_CTRL_STATUS ( 0x1A )
#define IMU660RC_STATUS_REG ( 0x1E )
#define IMU660RC_OUT_TEMP_L ( 0x20 )
#define IMU660RC_OUT_TEMP_H ( 0x21 )
#define IMU660RC_OUTX_L_G ( 0x22 )
#define IMU660RC_OUTX_H_G ( 0x23 )
#define IMU660RC_OUTY_L_G ( 0x24 )
#define IMU660RC_OUTY_H_G ( 0x25 )
#define IMU660RC_OUTZ_L_G ( 0x26 )
#define IMU660RC_OUTZ_H_G ( 0x27 )
#define IMU660RC_OUTX_L_A ( 0x28 )
#define IMU660RC_OUTX_H_A ( 0x29 )
#define IMU660RC_OUTY_L_A ( 0x2A )
#define IMU660RC_OUTY_H_A ( 0x2B )
#define IMU660RC_OUTZ_L_A ( 0x2C )
#define IMU660RC_OUTZ_H_A ( 0x2D )
#define IMU660RC_PAGE_SEL ( 0x02 )
#define IMU660RC_EMB_FUNC_EN_A ( 0x04 )
#define IMU660RC_PAGE_RW ( 0x17 )
#define IMU660RC_SFLP_ODR ( 0x5E )
#define IMU660RC_EMB_FUNC_CFG ( 0x63 )
extern float imu660rc_transition_factor[2];
extern int16 imu660rc_gyro_x, imu660rc_gyro_y, imu660rc_gyro_z; // 三轴陀螺仪数据
extern int16 imu660rc_acc_x , imu660rc_acc_y , imu660rc_acc_z; // 三轴加速度计数据
extern float imu660rc_roll , imu660rc_pitch , imu660rc_yaw; // 欧拉角
extern float imu660rc_quarternion[4]; // 四元数
void imu660rc_get_acc (void);
void imu660rc_get_gyro (void);
void imu660rc_get_quarternion (void);
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 将 IMU660RC 加速度计数据转换为实际物理数据
// 参数说明 acc_value 任意轴的加速度计数据
// 返回参数 void
// 使用示例 float data = imu660rc_acc_transition(imu660rc_acc_x); // 单位为 g(m/s^2)
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
#define imu660rc_acc_transition(acc_value) ((float)(acc_value) / imu660rc_transition_factor[0])
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 将 IMU660RC 陀螺仪数据转换为实际物理数据
// 参数说明 gyro_value 任意轴的陀螺仪数据
// 返回参数 void
// 使用示例 float data = imu660rc_gyro_transition(imu660rc_gyro_x); // 单位为 °/s
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
#define imu660rc_gyro_transition(gyro_value) ((float)(gyro_value) / imu660rc_transition_factor[1])
uint8 imu660rc_init (imu660rc_quarternion_rate_config quarternion_rate);
#endif
+532
View File
@@ -0,0 +1,532 @@
/*********************************************************************************************************************
* MSPM0G3507 Opensource Library 即(MSPM0G3507 开源库)是一个基于官方 SDK 接口的第三方开源库
* Copyright (c) 2022 SEEKFREE 逐飞科技
*
* 本文件是 MSPM0G3507 开源库的一部分
*
* MSPM0G3507 开源库 是免费软件
* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款
* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它
*
* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证
* 甚至没有隐含的适销性或适合特定用途的保证
* 更多细节请参见 GPL
*
* 您应该在收到本开源库的同时收到一份 GPL 的副本
* 如果没有,请参阅<https://www.gnu.org/licenses/>
*
* 额外注明:
* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本
* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中
* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件
* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明)
*
* 文件名称 zf_device_imu963ra
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 MDK 5.37
* 适用平台 MSPM0G3507
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2025-06-1 SeekFree first version
********************************************************************************************************************/
/*********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* // 硬件 SPI 引脚
* SCL/SPC 查看 zf_device_imu963ra.h 中 IMU963RA_SPC_PIN 宏定义
* SDA/DSI 查看 zf_device_imu963ra.h 中 IMU963RA_SDI_PIN 宏定义
* SA0/SDO 查看 zf_device_imu963ra.h 中 IMU963RA_SDO_PIN 宏定义
* CS 查看 zf_device_imu963ra.h 中 IMU963RA_CS_PIN 宏定义
* VCC 3.3V电源
* GND 电源地
* 其余引脚悬空
*
* // 软件 IIC 引脚
* SCL/SPC 查看 zf_device_imu963ra.h 中 IMU963RA_SCL_PIN 宏定义
* SDA/DSI 查看 zf_device_imu963ra.h 中 IMU963RA_SDA_PIN 宏定义
* VCC 3.3V电源
* GND 电源地
* 其余引脚悬空
* ------------------------------------
********************************************************************************************************************/
#include "zf_common_clock.h"
#include "zf_common_debug.h"
#include "zf_driver_delay.h"
#include "zf_driver_spi.h"
#include "zf_driver_soft_iic.h"
#include "zf_device_imu963ra.h"
int16 imu963ra_gyro_x = 0, imu963ra_gyro_y = 0, imu963ra_gyro_z = 0;
int16 imu963ra_acc_x = 0, imu963ra_acc_y = 0, imu963ra_acc_z = 0;
int16 imu963ra_mag_x = 0, imu963ra_mag_y = 0, imu963ra_mag_z = 0;
float imu963ra_transition_factor[3] = {4098, 14.3, 3000};
#if IMU963RA_USE_SOFT_IIC
static soft_iic_info_struct imu963ra_iic_struct;
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IMU963RA 写寄存器
// 参数说明 reg 寄存器地址
// 参数说明 data 数据
// 返回参数 void
// 使用示例 imu963ra_write_acc_gyro_register(IMU963RA_SLV0_CONFIG, 0x00);
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
#define imu963ra_write_acc_gyro_register(reg,data) (soft_iic_write_8bit_register(&imu963ra_iic_struct,reg,data))
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IMU963RA 读寄存器
// 参数说明 reg 寄存器地址
// 返回参数 uint8 数据
// 使用示例 imu963ra_read_acc_gyro_register(IMU963RA_STATUS_MASTER);
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
#define imu963ra_read_acc_gyro_register(reg) (soft_iic_sccb_read_register(&imu963ra_iic_struct,reg))
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IMU963RA 读数据 内部调用
// 参数说明 reg 寄存器地址
// 参数说明 data 数据缓冲区
// 参数说明 len 数据长度
// 返回参数 void
// 使用示例 imu963ra_read_acc_gyro_registers(IMU963RA_OUTX_L_A, dat, 6);
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
#define imu963ra_read_acc_gyro_registers(reg,data,len) (soft_iic_read_8bit_registers(&imu963ra_iic_struct,reg,data,len))
#else
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IMU963RA 写寄存器
// 参数说明 reg 寄存器地址
// 参数说明 data 数据
// 返回参数 void
// 使用示例 imu963ra_write_acc_gyro_register(IMU963RA_SLV0_CONFIG, 0x00);
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
static void imu963ra_write_acc_gyro_register (uint8 reg, uint8 data)
{
IMU963RA_CS(0);
spi_write_8bit_register(IMU963RA_SPI, reg | IMU963RA_SPI_W, data);
IMU963RA_CS(1);
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IMU963RA 读寄存器
// 参数说明 reg 寄存器地址
// 返回参数 uint8 数据
// 使用示例 imu963ra_read_acc_gyro_register(IMU963RA_STATUS_MASTER);
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
static uint8 imu963ra_read_acc_gyro_register (uint8 reg)
{
uint8 data = 0;
IMU963RA_CS(0);
data = spi_read_8bit_register(IMU963RA_SPI, reg | IMU963RA_SPI_R);
IMU963RA_CS(1);
return data;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IMU963RA 读数据 内部调用
// 参数说明 reg 寄存器地址
// 参数说明 data 数据缓冲区
// 参数说明 len 数据长度
// 返回参数 void
// 使用示例 imu963ra_read_acc_gyro_registers(IMU963RA_OUTX_L_A, dat, 6);
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
static void imu963ra_read_acc_gyro_registers (uint8 reg, uint8 *data, uint32 len)
{
IMU963RA_CS(0);
spi_read_8bit_registers(IMU963RA_SPI, reg | IMU963RA_SPI_R, data, len);
IMU963RA_CS(1);
}
#endif
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IMU963RA 作为 IIC 主机向磁力计写数据
// 参数说明 addr 目标地址
// 参数说明 reg 目标寄存器
// 参数说明 data 数据
// 返回参数 uint8 1-失败 0-成功
// 使用示例 imu963ra_write_mag_register(IMU963RA_MAG_ADDR, IMU963RA_MAG_CONTROL2, 0x80);
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
static uint8 imu963ra_write_mag_register (uint8 addr, uint8 reg, uint8 data)
{
uint8 return_state = 0;
uint16 timeout_count = 0;
addr = addr << 1;
imu963ra_write_acc_gyro_register(IMU963RA_SLV0_CONFIG, 0x00); // 从机0配置清除
imu963ra_write_acc_gyro_register(IMU963RA_SLV0_ADD, addr | 0); // 设置地磁计地址(注意这里需要设置8位的I2C地址) 0x2C
imu963ra_write_acc_gyro_register(IMU963RA_SLV0_SUBADD, reg); // 需要写入的寄存器地址
imu963ra_write_acc_gyro_register(IMU963RA_DATAWRITE_SLV0, data); // 需要写入的数据
imu963ra_write_acc_gyro_register(IMU963RA_MASTER_CONFIG, 0x4C); // 仅在第一个周期启用通讯 开启上拉 I2C主机使能
// 等待通讯成功
while(0 == (0x80 & imu963ra_read_acc_gyro_register(IMU963RA_STATUS_MASTER)))
{
if(IMU963RA_TIMEOUT_COUNT < timeout_count ++)
{
return_state = 1;
break;
}
system_delay_ms(2);
}
return return_state;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IMU963RA 作为 IIC 主机向磁力计读数据
// 参数说明 addr 目标地址
// 参数说明 reg 目标寄存器
// 返回参数 uint8 读取的数据
// 使用示例 imu963ra_read_mag_register(IMU963RA_MAG_ADDR, IMU963RA_MAG_CHIP_ID);
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
static uint8 imu963ra_read_mag_register (uint8 addr, uint8 reg)
{
uint16 timeout_count = 0;
addr = addr << 1;
imu963ra_write_acc_gyro_register(IMU963RA_SLV0_ADD, addr | 1); // 设置地磁计地址(注意这里需要设置8位的I2C地址) 0x2C
imu963ra_write_acc_gyro_register(IMU963RA_SLV0_SUBADD, reg); // 需要读取的寄存器地址
imu963ra_write_acc_gyro_register(IMU963RA_SLV0_CONFIG, 0x01);
imu963ra_write_acc_gyro_register(IMU963RA_MASTER_CONFIG, 0x4C); // 仅在第一个周期启用通讯 开启上拉 I2C主机使能
// 等待通讯成功
while(0 == (0x01 & imu963ra_read_acc_gyro_register(IMU963RA_STATUS_MASTER)))
{
if(IMU963RA_TIMEOUT_COUNT < timeout_count ++)
{
break;
}
system_delay_ms(2);
}
return (imu963ra_read_acc_gyro_register(IMU963RA_SENSOR_HUB_1)); // 返回读取到的数据
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IMU963RA 作为 IIC 主机向磁力计自动写数据
// 参数说明 addr 目标地址
// 参数说明 reg 目标寄存器
// 返回参数 void
// 使用示例 imu963ra_connect_mag(IMU963RA_MAG_ADDR, IMU963RA_MAG_OUTX_L);
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
static void imu963ra_connect_mag (uint8 addr, uint8 reg)
{
addr = addr << 1;
imu963ra_write_acc_gyro_register(IMU963RA_SLV0_ADD, addr | 1); // 设置地磁计地址(注意这里需要设置8位的I2C地址) 0x2C
imu963ra_write_acc_gyro_register(IMU963RA_SLV0_SUBADD, reg); // 需要读取的寄存器地址
imu963ra_write_acc_gyro_register(IMU963RA_SLV0_CONFIG, 0x06);
imu963ra_write_acc_gyro_register(IMU963RA_MASTER_CONFIG, 0x6C); // 仅在第一个周期启用通讯 开启上拉 I2C主机使能
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IMU963RA 六轴自检 内部调用
// 参数说明 void
// 返回参数 uint8 1-自检失败 0-自检成功
// 使用示例 imu963ra_acc_gyro_self_check();
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
static uint8 imu963ra_acc_gyro_self_check (void)
{
uint8 return_state = 0;
uint8 dat = 0;
uint16 timeout_count = 0;
while(0x6B != dat) // 判断 ID 是否正确
{
if(IMU963RA_TIMEOUT_COUNT < timeout_count ++)
{
return_state = 1;
break;
}
dat = imu963ra_read_acc_gyro_register(IMU963RA_WHO_AM_I);
system_delay_ms(10);
}
return return_state;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IMU963RA 磁力计自检 内部调用
// 参数说明 void
// 返回参数 uint8 1-自检失败 0-自检成功
// 使用示例 imu963ra_mag_self_check();
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
static uint8 imu963ra_mag_self_check (void)
{
uint8 return_state = 0;
uint8 dat = 0;
uint16 timeout_count = 0;
while(0xff != dat) // 判断 ID 是否正确
{
if(IMU963RA_TIMEOUT_COUNT < timeout_count ++)
{
return_state = 1;
break;
}
dat = imu963ra_read_mag_register(IMU963RA_MAG_ADDR, IMU963RA_MAG_CHIP_ID);
system_delay_ms(10);
}
return return_state;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 获取 IMU963RA 加速度计数据
// 参数说明 void
// 返回参数 void
// 使用示例 imu963ra_get_acc();
// 备注信息 执行该函数后,直接查看对应的变量即可
//-------------------------------------------------------------------------------------------------------------------
void imu963ra_get_acc (void)
{
uint8 dat[6];
imu963ra_read_acc_gyro_registers(IMU963RA_OUTX_L_A, dat, 6);
imu963ra_acc_x = (int16)(((uint16)dat[1] << 8 | dat[0]));
imu963ra_acc_y = (int16)(((uint16)dat[3] << 8 | dat[2]));
imu963ra_acc_z = (int16)(((uint16)dat[5] << 8 | dat[4]));
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 获取IMU963RA陀螺仪数据
// 参数说明 void
// 返回参数 void
// 使用示例 imu963ra_get_gyro();
// 备注信息 执行该函数后,直接查看对应的变量即可
//-------------------------------------------------------------------------------------------------------------------
void imu963ra_get_gyro (void)
{
uint8 dat[6];
imu963ra_read_acc_gyro_registers(IMU963RA_OUTX_L_G, dat, 6);
imu963ra_gyro_x = (int16)(((uint16)dat[1] << 8 | dat[0]));
imu963ra_gyro_y = (int16)(((uint16)dat[3] << 8 | dat[2]));
imu963ra_gyro_z = (int16)(((uint16)dat[5] << 8 | dat[4]));
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 获取 IMU963RA 磁力计数据
// 参数说明 void
// 返回参数 void
// 使用示例 imu963ra_get_mag();
// 备注信息 执行该函数后,直接查看对应的变量即可
//-------------------------------------------------------------------------------------------------------------------
void imu963ra_get_mag (void)
{
uint8 temp_status;
uint8 dat[6];
imu963ra_write_acc_gyro_register(IMU963RA_FUNC_CFG_ACCESS, 0x40);
temp_status = imu963ra_read_acc_gyro_register(IMU963RA_STATUS_MASTER);
if(0x01 & temp_status)
{
imu963ra_read_acc_gyro_registers(IMU963RA_SENSOR_HUB_1, dat, 6);
imu963ra_mag_x = (int16)(((uint16)dat[1] << 8 | dat[0]));
imu963ra_mag_y = (int16)(((uint16)dat[3] << 8 | dat[2]));
imu963ra_mag_z = (int16)(((uint16)dat[5] << 8 | dat[4]));
}
imu963ra_write_acc_gyro_register(IMU963RA_FUNC_CFG_ACCESS, 0x00);
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 初始化 IMU963RA
// 参数说明 void
// 返回参数 uint8 1-初始化失败 0-初始化成功
// 使用示例 imu963ra_init();
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
uint8 imu963ra_init (void)
{
uint8 return_state = 0;
system_delay_ms(10); // 上电延时
#if IMU963RA_USE_SOFT_IIC
gpio_init(IMU963RA_CS_PIN, GPO, GPIO_LOW, GPO_PUSH_PULL);
soft_iic_init(&imu963ra_iic_struct, IMU963RA_DEV_ADDR, IMU963RA_SOFT_IIC_DELAY, IMU963RA_SCL_PIN, IMU963RA_SDA_PIN);
#else
spi_init(IMU963RA_SPI, SPI_MODE0, IMU963RA_SPI_SPEED, IMU963RA_SPC_PIN, IMU963RA_SDI_PIN, IMU963RA_SDO_PIN, SPI_CS_NULL);
gpio_init(IMU963RA_CS_PIN, GPO, GPIO_LOW, GPO_PUSH_PULL);
#endif
do
{
imu963ra_write_acc_gyro_register(IMU963RA_FUNC_CFG_ACCESS, 0x00); // 关闭HUB寄存器访问
imu963ra_write_acc_gyro_register(IMU963RA_CTRL3_C, 0x01); // 复位设备
system_delay_ms(2);
imu963ra_write_acc_gyro_register(IMU963RA_FUNC_CFG_ACCESS, 0x00); // 关闭HUB寄存器访问
if(imu963ra_acc_gyro_self_check())
{
zf_log(0, "IMU963RA acc and gyro self check error.");
return_state = 1;
break;
}
imu963ra_write_acc_gyro_register(IMU963RA_INT1_CTRL, 0x03); // 开启陀螺仪 加速度数据就绪中断
// IMU963RA_CTRL1_XL 寄存器
// 设置为 0x30 加速度量程为 ±2 g 获取到的加速度计数据除以 16393 可以转化为带物理单位的数据 (g 代表重力加速度 物理学名词 一般情况下 g 取 9.8 m/s^2 为标准值)
// 设置为 0x38 加速度量程为 ±4 g 获取到的加速度计数据除以 8197 可以转化为带物理单位的数据 (g 代表重力加速度 物理学名词 一般情况下 g 取 9.8 m/s^2 为标准值)
// 设置为 0x3C 加速度量程为 ±8 g 获取到的加速度计数据除以 4098 可以转化为带物理单位的数据 (g 代表重力加速度 物理学名词 一般情况下 g 取 9.8 m/s^2 为标准值)
// 设置为 0x34 加速度量程为 ±16 g 获取到的加速度计数据除以 2049 可以转化为带物理单位的数据 (g 代表重力加速度 物理学名词 一般情况下 g 取 9.8 m/s^2 为标准值)
switch(IMU963RA_ACC_SAMPLE_DEFAULT)
{
default:
{
zf_log(0, "IMU963RA_ACC_SAMPLE_DEFAULT set error.");
return_state = 1;
}break;
case IMU963RA_ACC_SAMPLE_SGN_2G:
{
imu963ra_write_acc_gyro_register(IMU963RA_CTRL1_XL, 0x30);
imu963ra_transition_factor[0] = 16393;
}break;
case IMU963RA_ACC_SAMPLE_SGN_4G:
{
imu963ra_write_acc_gyro_register(IMU963RA_CTRL1_XL, 0x38);
imu963ra_transition_factor[0] = 8197;
}break;
case IMU963RA_ACC_SAMPLE_SGN_8G:
{
imu963ra_write_acc_gyro_register(IMU963RA_CTRL1_XL, 0x3C);
imu963ra_transition_factor[0] = 4098;
}break;
case IMU963RA_ACC_SAMPLE_SGN_16G:
{
imu963ra_write_acc_gyro_register(IMU963RA_CTRL1_XL, 0x34);
imu963ra_transition_factor[0] = 2049;
}break;
}
if(1 == return_state)
{
break;
}
// IMU963RA_CTRL2_G 寄存器
// 设置为 0x52 陀螺仪量程为 ±125 dps 获取到的陀螺仪数据除以 228.6 可以转化为带物理单位的数据 单位为 °/s
// 设置为 0x50 陀螺仪量程为 ±250 dps 获取到的陀螺仪数据除以 114.3 可以转化为带物理单位的数据 单位为 °/s
// 设置为 0x54 陀螺仪量程为 ±500 dps 获取到的陀螺仪数据除以 57.1 可以转化为带物理单位的数据 单位为 °/s
// 设置为 0x58 陀螺仪量程为 ±1000 dps 获取到的陀螺仪数据除以 28.6 可以转化为带物理单位的数据 单位为 °/s
// 设置为 0x5C 陀螺仪量程为 ±2000 dps 获取到的陀螺仪数据除以 14.3 可以转化为带物理单位的数据 单位为 °/s
// 设置为 0x51 陀螺仪量程为 ±4000 dps 获取到的陀螺仪数据除以 7.1 可以转化为带物理单位的数据 单位为 °/s
switch(IMU963RA_GYRO_SAMPLE_DEFAULT)
{
default:
{
zf_log(0, "IMU963RA_GYRO_SAMPLE_DEFAULT set error.");
return_state = 1;
}break;
case IMU963RA_GYRO_SAMPLE_SGN_125DPS:
{
imu963ra_write_acc_gyro_register(IMU963RA_CTRL2_G, 0x52);
imu963ra_transition_factor[1] = 228.6;
}break;
case IMU963RA_GYRO_SAMPLE_SGN_250DPS:
{
imu963ra_write_acc_gyro_register(IMU963RA_CTRL2_G, 0x50);
imu963ra_transition_factor[1] = 114.3;
}break;
case IMU963RA_GYRO_SAMPLE_SGN_500DPS:
{
imu963ra_write_acc_gyro_register(IMU963RA_CTRL2_G, 0x54);
imu963ra_transition_factor[1] = 57.1;
}break;
case IMU963RA_GYRO_SAMPLE_SGN_1000DPS:
{
imu963ra_write_acc_gyro_register(IMU963RA_CTRL2_G, 0x58);
imu963ra_transition_factor[1] = 28.6;
}break;
case IMU963RA_GYRO_SAMPLE_SGN_2000DPS:
{
imu963ra_write_acc_gyro_register(IMU963RA_CTRL2_G, 0x5C);
imu963ra_transition_factor[1] = 14.3;
}break;
case IMU963RA_GYRO_SAMPLE_SGN_4000DPS:
{
imu963ra_write_acc_gyro_register(IMU963RA_CTRL2_G, 0x51);
imu963ra_transition_factor[1] = 7.1;
}break;
}
if(1 == return_state)
{
break;
}
imu963ra_write_acc_gyro_register(IMU963RA_CTRL3_C, 0x44); // 使能陀螺仪数字低通滤波器
imu963ra_write_acc_gyro_register(IMU963RA_CTRL4_C, 0x02); // 使能数字低通滤波器
imu963ra_write_acc_gyro_register(IMU963RA_CTRL5_C, 0x00); // 加速度计与陀螺仪四舍五入
imu963ra_write_acc_gyro_register(IMU963RA_CTRL6_C, 0x00); // 开启加速度计高性能模式 陀螺仪低通滤波 133hz
imu963ra_write_acc_gyro_register(IMU963RA_CTRL7_G, 0x00); // 开启陀螺仪高性能模式 关闭高通滤波
imu963ra_write_acc_gyro_register(IMU963RA_CTRL9_XL, 0x01); // 关闭I3C接口
imu963ra_write_acc_gyro_register(IMU963RA_FUNC_CFG_ACCESS, 0x40); // 开启HUB寄存器访问 用于配置地磁计
imu963ra_write_acc_gyro_register(IMU963RA_MASTER_CONFIG, 0x80); // 复位I2C主机
system_delay_ms(2);
imu963ra_write_acc_gyro_register(IMU963RA_MASTER_CONFIG, 0x00); // 清除复位标志
system_delay_ms(2);
imu963ra_write_mag_register(IMU963RA_MAG_ADDR, IMU963RA_MAG_CONTROL2, 0x80);// 复位连接的外设
system_delay_ms(2);
imu963ra_write_mag_register(IMU963RA_MAG_ADDR, IMU963RA_MAG_CONTROL2, 0x00);
system_delay_ms(2);
if(imu963ra_mag_self_check())
{
zf_log(0, "IMU963RA mag self check error.");
return_state = 1;
break;
}
// IMU963RA_MAG_ADDR 寄存器
// 设置为 0x09 磁力计量程为 2G 获取到的磁力计数据除以 12000 可以转化为带物理单位的数据 单位 G(高斯)
// 设置为 0x19 磁力计量程为 8G 获取到的磁力计数据除以 3000 可以转化为带物理单位的数据 单位 G(高斯)
switch(IMU963RA_MAG_SAMPLE_DEFAULT)
{
default:
{
zf_log(0, "IMU963RA_MAG_SAMPLE_DEFAULT set error.");
return_state = 1;
}break;
case IMU963RA_MAG_SAMPLE_2G:
{
imu963ra_write_mag_register(IMU963RA_MAG_ADDR, IMU963RA_MAG_CONTROL1, 0x09);
imu963ra_transition_factor[2] = 12000;
}break;
case IMU963RA_MAG_SAMPLE_8G:
{
imu963ra_write_mag_register(IMU963RA_MAG_ADDR, IMU963RA_MAG_CONTROL1, 0x19);
imu963ra_transition_factor[2] = 3000;
}break;
}
if(1 == return_state)
{
break;
}
imu963ra_write_mag_register(IMU963RA_MAG_ADDR, IMU963RA_MAG_FBR, 0x01);
imu963ra_connect_mag(IMU963RA_MAG_ADDR, IMU963RA_MAG_OUTX_L);
imu963ra_write_acc_gyro_register(IMU963RA_FUNC_CFG_ACCESS, 0x00); // 关闭HUB寄存器访问
system_delay_ms(20); // 等待磁力计获取数据
}while(0);
return return_state;
}
+218
View File
@@ -0,0 +1,218 @@
/*********************************************************************************************************************
* MSPM0G3507 Opensource Library 即(MSPM0G3507 开源库)是一个基于官方 SDK 接口的第三方开源库
* Copyright (c) 2022 SEEKFREE 逐飞科技
*
* 本文件是 MSPM0G3507 开源库的一部分
*
* MSPM0G3507 开源库 是免费软件
* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款
* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它
*
* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证
* 甚至没有隐含的适销性或适合特定用途的保证
* 更多细节请参见 GPL
*
* 您应该在收到本开源库的同时收到一份 GPL 的副本
* 如果没有,请参阅<https://www.gnu.org/licenses/>
*
* 额外注明:
* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本
* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中
* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件
* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明)
*
* 文件名称 zf_device_imu963ra
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 MDK 5.37
* 适用平台 MSPM0G3507
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2025-06-1 SeekFree first version
********************************************************************************************************************/
/********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* // 硬件 SPI 引脚
* SCL/SPC 查看 zf_device_imu963ra.h 中 IMU963RA_SPC_PIN 宏定义
* SDA/DSI 查看 zf_device_imu963ra.h 中 IMU963RA_SDI_PIN 宏定义
* SA0/SDO 查看 zf_device_imu963ra.h 中 IMU963RA_SDO_PIN 宏定义
* CS 查看 zf_device_imu963ra.h 中 IMU963RA_CS_PIN 宏定义
* VCC 3.3V电源
* GND 电源地
* 其余引脚悬空
*
* // 软件 IIC 引脚
* SCL/SPC 查看 zf_device_imu963ra.h 中 IMU963RA_SCL_PIN 宏定义
* SDA/DSI 查看 zf_device_imu963ra.h 中 IMU963RA_SDA_PIN 宏定义
* VCC 3.3V电源
* GND 电源地
* 其余引脚悬空
* ------------------------------------
********************************************************************************************************************/
#ifndef _zf_device_imu963ra_h_
#define _zf_device_imu963ra_h_
#include "zf_common_typedef.h"
//================================================定义 IMU963RA 基本配置================================================
#define IMU963RA_USE_SOFT_IIC (0) // 默认使用硬件 SPI 方式驱动
#if IMU963RA_USE_SOFT_IIC // 这两段 颜色正常的才是正确的 颜色灰的就是没有用的
//====================================================软件 IIC 驱动====================================================
//====================================================注意 注意 注意 使用IIC模式下不要接CS
//====================================================注意 注意 注意 使用IIC模式下不要接CS
//====================================================注意 注意 注意 使用IIC模式下不要接CS
#define IMU963RA_SOFT_IIC_DELAY ( 100 ) // 软件 IIC 的时钟延时周期 数值越小 IIC 通信速率越快
#define IMU963RA_SCL_PIN ( B23 ) // 软件 IIC SCL 引脚 连接 IMU963RA 的 SCL 引脚
#define IMU963RA_SDA_PIN ( B22 ) // 软件 IIC SDA 引脚 连接 IMU963RA 的 SDA 引脚
//====================================================软件 IIC 驱动====================================================
#else
//====================================================硬件 SPI 驱动====================================================
#define IMU963RA_SPI_SPEED ( 8 * 1000 * 1000 ) // 硬件 SPI 速率
#define IMU963RA_SPI ( SPI_1 ) // 硬件 SPI 号
#define IMU963RA_SPC_PIN ( SPI1_SCK_B23 ) // 硬件 SPI SCK 引脚
#define IMU963RA_SDI_PIN ( SPI1_MOSI_B22 ) // 硬件 SPI MOSI 引脚
#define IMU963RA_SDO_PIN ( SPI1_MISO_B21 ) // 硬件 SPI MISO 引脚
//====================================================硬件 SPI 驱动====================================================
#endif
#define IMU963RA_CS_PIN (B19) // CS 片选引脚
#define IMU963RA_CS(x) (x? (gpio_high(IMU963RA_CS_PIN)): (gpio_low(IMU963RA_CS_PIN)))
typedef enum
{
IMU963RA_ACC_SAMPLE_SGN_2G , // 加速度计量程 ±2G (ACC = Accelerometer 加速度计) (SGN = signum 带符号数 表示正负范围) (G = g 重力加速度 g≈9.80 m/s^2)
IMU963RA_ACC_SAMPLE_SGN_4G , // 加速度计量程 ±4G (ACC = Accelerometer 加速度计) (SGN = signum 带符号数 表示正负范围) (G = g 重力加速度 g≈9.80 m/s^2)
IMU963RA_ACC_SAMPLE_SGN_8G , // 加速度计量程 ±8G (ACC = Accelerometer 加速度计) (SGN = signum 带符号数 表示正负范围) (G = g 重力加速度 g≈9.80 m/s^2)
IMU963RA_ACC_SAMPLE_SGN_16G, // 加速度计量程 ±16G (ACC = Accelerometer 加速度计) (SGN = signum 带符号数 表示正负范围) (G = g 重力加速度 g≈9.80 m/s^2)
}imu963ra_acc_sample_config;
typedef enum
{
IMU963RA_GYRO_SAMPLE_SGN_125DPS , // 陀螺仪量程 ±125DPS (GYRO = Gyroscope 陀螺仪) (SGN = signum 带符号数 表示正负范围) (DPS = Degree Per Second 角速度单位 °/S)
IMU963RA_GYRO_SAMPLE_SGN_250DPS , // 陀螺仪量程 ±250DPS (GYRO = Gyroscope 陀螺仪) (SGN = signum 带符号数 表示正负范围) (DPS = Degree Per Second 角速度单位 °/S)
IMU963RA_GYRO_SAMPLE_SGN_500DPS , // 陀螺仪量程 ±500DPS (GYRO = Gyroscope 陀螺仪) (SGN = signum 带符号数 表示正负范围) (DPS = Degree Per Second 角速度单位 °/S)
IMU963RA_GYRO_SAMPLE_SGN_1000DPS, // 陀螺仪量程 ±1000DPS (GYRO = Gyroscope 陀螺仪) (SGN = signum 带符号数 表示正负范围) (DPS = Degree Per Second 角速度单位 °/S)
IMU963RA_GYRO_SAMPLE_SGN_2000DPS, // 陀螺仪量程 ±2000DPS (GYRO = Gyroscope 陀螺仪) (SGN = signum 带符号数 表示正负范围) (DPS = Degree Per Second 角速度单位 °/S)
IMU963RA_GYRO_SAMPLE_SGN_4000DPS, // 陀螺仪量程 ±4000DPS (GYRO = Gyroscope 陀螺仪) (SGN = signum 带符号数 表示正负范围) (DPS = Degree Per Second 角速度单位 °/S)
}imu963ra_gyro_sample_config;
typedef enum
{
IMU963RA_MAG_SAMPLE_2G, // 磁力计量程 2G (MAG = Magnetometer 磁力计) (G = Gs 高斯)
IMU963RA_MAG_SAMPLE_8G, // 磁力计量程 8G (MAG = Magnetometer 磁力计) (G = Gs 高斯)
}imu963ra_mag_sample_config;
#define IMU963RA_ACC_SAMPLE_DEFAULT ( IMU963RA_ACC_SAMPLE_SGN_8G ) // 在这设置默认的 加速度计 初始化量程
#define IMU963RA_GYRO_SAMPLE_DEFAULT ( IMU963RA_GYRO_SAMPLE_SGN_2000DPS ) // 在这设置默认的 陀螺仪 初始化量程
#define IMU963RA_MAG_SAMPLE_DEFAULT ( IMU963RA_MAG_SAMPLE_8G ) // 在这设置默认的 磁力计 初始化量程
#define IMU963RA_TIMEOUT_COUNT (0x00FF) // IMU963RA 超时计数
//================================================定义 IMU963RA 基本配置================================================
//================================================定义 IMU963RA 内部地址================================================
#define IMU963RA_DEV_ADDR (0x6B) // SA0接地:0x6A SA0上拉:0x6B 模块默认上拉
#define IMU963RA_SPI_W (0x00)
#define IMU963RA_SPI_R (0x80)
#define IMU963RA_FUNC_CFG_ACCESS (0x01)
#define IMU963RA_INT1_CTRL (0x0D)
#define IMU963RA_WHO_AM_I (0x0F)
#define IMU963RA_CTRL1_XL (0x10)
#define IMU963RA_CTRL2_G (0x11)
#define IMU963RA_CTRL3_C (0x12)
#define IMU963RA_CTRL4_C (0x13)
#define IMU963RA_CTRL5_C (0x14)
#define IMU963RA_CTRL6_C (0x15)
#define IMU963RA_CTRL7_G (0x16)
#define IMU963RA_CTRL9_XL (0x18)
#define IMU963RA_OUTX_L_G (0x22)
#define IMU963RA_OUTX_L_A (0x28)
//集线器功能相关寄存器 需要将FUNC_CFG_ACCESS的SHUB_REG_ACCESS位设置为1才能正确访问
#define IMU963RA_SENSOR_HUB_1 (0x02)
#define IMU963RA_MASTER_CONFIG (0x14)
#define IMU963RA_SLV0_ADD (0x15)
#define IMU963RA_SLV0_SUBADD (0x16)
#define IMU963RA_SLV0_CONFIG (0x17)
#define IMU963RA_DATAWRITE_SLV0 (0x21)
#define IMU963RA_STATUS_MASTER (0x22)
#define IMU963RA_MAG_ADDR (0x0D) // 7位IIC地址
#define IMU963RA_MAG_OUTX_L (0x00)
#define IMU963RA_MAG_CONTROL1 (0x09)
#define IMU963RA_MAG_CONTROL2 (0x0A)
#define IMU963RA_MAG_FBR (0x0B)
#define IMU963RA_MAG_CHIP_ID (0x0D)
#define IMU963RA_ACC_SAMPLE (0x3C) // 加速度计量程
// 设置为:0x30 加速度量程为:±2G 获取到的加速度计数据 除以16393,可以转化为带物理单位的数据,单位:g(m/s^2)
// 设置为:0x38 加速度量程为:±4G 获取到的加速度计数据 除以8197, 可以转化为带物理单位的数据,单位:g(m/s^2)
// 设置为:0x3C 加速度量程为:±8G 获取到的加速度计数据 除以4098, 可以转化为带物理单位的数据,单位:g(m/s^2)
// 设置为:0x34 加速度量程为:±16G 获取到的加速度计数据 除以2049, 可以转化为带物理单位的数据,单位:g(m/s^2)
#define IMU963RA_GYR_SAMPLE (0x5C) // 陀螺仪量程
// 设置为:0x52 陀螺仪量程为:±125dps 获取到的陀螺仪数据除以228.6, 可以转化为带物理单位的数据,单位为:°/s
// 设置为:0x50 陀螺仪量程为:±250dps 获取到的陀螺仪数据除以114.3, 可以转化为带物理单位的数据,单位为:°/s
// 设置为:0x54 陀螺仪量程为:±500dps 获取到的陀螺仪数据除以57.1, 可以转化为带物理单位的数据,单位为:°/s
// 设置为:0x58 陀螺仪量程为:±1000dps 获取到的陀螺仪数据除以28.6, 可以转化为带物理单位的数据,单位为:°/s
// 设置为:0x5C 陀螺仪量程为:±2000dps 获取到的陀螺仪数据除以14.3, 可以转化为带物理单位的数据,单位为:°/s
// 设置为:0x51 陀螺仪量程为:±4000dps 获取到的陀螺仪数据除以7.1, 可以转化为带物理单位的数据,单位为:°/s
#define IMU963RA_MAG_SAMPLE (0x19) // 地磁计量程
// 设置为:0x19 磁力计量程为:8G 获取到的加速度计数据 除以3000, 可以转化为带物理单位的数据,单位:G(高斯)
// 设置为:0x09 磁力计量程为:2G 获取到的加速度计数据 除以12000,可以转化为带物理单位的数据,单位:G(高斯)
//================================================定义 IMU963RA 内部地址================================================
//================================================声明 IMU963RA 全局变量================================================
extern int16 imu963ra_acc_x, imu963ra_acc_y, imu963ra_acc_z; // 三轴陀螺仪数据 GYRO (陀螺仪)
extern int16 imu963ra_gyro_x, imu963ra_gyro_y, imu963ra_gyro_z; // 三轴加速度计数据 ACC (accelerometer 加速度计)
extern int16 imu963ra_mag_x, imu963ra_mag_y, imu963ra_mag_z; // 三轴磁力计数据 MAG (magnetometer 磁力计)
extern float imu963ra_transition_factor[3]; // 转换实际值的比例
//================================================声明 IMU963RA 全局变量================================================
//================================================声明 IMU963RA 基础函数================================================
void imu963ra_get_acc (void); // 获取 IMU963RA 加速度计数据
void imu963ra_get_gyro (void); // 获取 IMU963RA 陀螺仪数据
void imu963ra_get_mag (void); // 获取 IMU963RA 磁力计数据
uint8 imu963ra_init (void); // 初始化 IMU963RA
//================================================声明 IMU963RA 基础函数================================================
//================================================声明 IMU963RA 拓展函数================================================
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 将 IMU963RA 加速度计数据转换为实际物理数据
// 参数说明 acc_value 任意轴的加速度计数据
// 返回参数 void
// 使用示例 float data = imu963ra_acc_transition(imu963ra_acc_x); // 单位为 g(m/s^2)
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
#define imu963ra_acc_transition(acc_value) ((float)acc_value / imu963ra_transition_factor[0])
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 将 IMU963RA 陀螺仪数据转换为实际物理数据
// 参数说明 gyro_value 任意轴的陀螺仪数据
// 返回参数 void
// 使用示例 float data = imu963ra_gyro_transition(imu963ra_gyro_x); // 单位为 °/s
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
#define imu963ra_gyro_transition(gyro_value) ((float)gyro_value / imu963ra_transition_factor[1])
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 将 IMU963RA 磁力计数据转换为实际物理数据
// 参数说明 mag_value 任意轴的磁力计数据
// 返回参数 void
// 使用示例 float data = imu963ra_mag_transition(imu963ra_mag_x); // 单位为 G
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
#define imu963ra_mag_transition(mag_value) ((float)mag_value / imu963ra_transition_factor[2])
//================================================声明 IMU963RA 拓展函数================================================
#endif
File diff suppressed because it is too large Load Diff
+173
View File
@@ -0,0 +1,173 @@
/*********************************************************************************************************************
* MSPM0G3507 Opensource Library 即(MSPM0G3507 开源库)是一个基于官方 SDK 接口的第三方开源库
* Copyright (c) 2022 SEEKFREE 逐飞科技
*
* 本文件是 MSPM0G3507 开源库的一部分
*
* MSPM0G3507 开源库 是免费软件
* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款
* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它
*
* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证
* 甚至没有隐含的适销性或适合特定用途的保证
* 更多细节请参见 GPL
*
* 您应该在收到本开源库的同时收到一份 GPL 的副本
* 如果没有,请参阅<https://www.gnu.org/licenses/>
*
* 额外注明:
* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本
* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中
* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件
* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明)
*
* 文件名称 zf_device_ips114
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 MDK 5.37
* 适用平台 MSPM0G3507
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2025-06-1 SeekFree first version
********************************************************************************************************************/
/********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* SCL 查看 zf_device_ips114.h 中 IPS114_SCL_PIN 宏定义
* SDA 查看 zf_device_ips114.h 中 IPS114_SDA_PIN 宏定义
* RST 查看 zf_device_ips114.h 中 IPS114_RST_PIN 宏定义
* DC 查看 zf_device_ips114.h 中 IPS114_DC_PIN 宏定义
* CS 查看 zf_device_ips114.h 中 IPS114_CS_PIN 宏定义
* BLK 查看 zf_device_ips114.h 中 IPS114_BLK_PIN 宏定义
* VCC 3 .3V电源
* GND 电源地
* 最大分辨率 135 * 240
* ------------------------------------
********************************************************************************************************************/
#ifndef _zf_device_ips114_h_
#define _zf_device_ips114_h_
#include "zf_common_typedef.h"
//=================================================定义 IPS114 基本配置================================================
#define IPS114_USE_SOFT_SPI (0) // 默认使用硬件 SPI 方式驱动 建议使用硬件 SPI 方式驱动
#if IPS114_USE_SOFT_SPI // 这两段 颜色正常的才是正确的 颜色灰的就是没有用的
//====================================================软件 SPI 驱动==================================================
#define IPS114_SOFT_SPI_DELAY ( 1 ) // 软件 SPI 的时钟延时周期 数值越小 SPI 通信速率越快
#define IPS114_SCL_PIN ( A12 ) // 软件 SPI SCK 引脚
#define IPS114_SDA_PIN ( A9 ) // 软件 SPI MOSI 引脚
//====================================================软件 SPI 驱动==================================================
#else
//====================================================硬件 SPI 驱动==================================================
#define IPS114_SPI_SPEED ( 30 * 1000 * 1000 ) // 硬件 SPI 速率
#define IPS114_SPI ( SPI_0 ) // 硬件 SPI 号
#define IPS114_SCL_PIN ( SPI0_SCK_A12 ) // 硬件 SPI SCK 引脚
#define IPS114_SDA_PIN ( SPI0_MOSI_A9 ) // 硬件 SPI MOSI 引脚
#define IPS114_SDA_IN_PIN (SPI_MISO_NULL ) // 定义SPI_MISO引脚 IPS没有MISO引脚,但是这里任然需要定义,在spi的初始化时需要使用
//====================================================硬件 SPI 驱动==================================================
#endif
#define IPS114_RST_PIN ( A7 ) // 液晶复位引脚定义
#define IPS114_DC_PIN ( A15 ) // 液晶命令位引脚定义
#define IPS114_CS_PIN ( A8 ) // CS 片选引脚
#define IPS114_BLK_PIN ( A13 ) // 液晶背光引脚定义
#define IPS114_DEFAULT_DISPLAY_DIR ( IPS114_PORTAIT ) // 默认的显示方向
#define IPS114_DEFAULT_PENCOLOR (RGB565_RED) // 默认的画笔颜色
#define IPS114_DEFAULT_BGCOLOR (RGB565_WHITE) // 默认的背景颜色
#define IPS114_DEFAULT_DISPLAY_FONT (IPS114_8X16_FONT) // 默认的字体模式
#define IPS114_DC(x) ((x) ? (gpio_high(IPS114_DC_PIN)) : (gpio_low(IPS114_DC_PIN)))
#define IPS114_RST(x) ((x) ? (gpio_high(IPS114_RST_PIN)) : (gpio_low(IPS114_RST_PIN)))
#define IPS114_CS(x) ((x) ? (gpio_high(IPS114_CS_PIN)) : (gpio_low(IPS114_CS_PIN)))
#define IPS114_BLK(x) ((x) ? (gpio_high(IPS114_BLK_PIN)) : (gpio_low(IPS114_BLK_PIN)))
//=================================================定义 IPS114 基本配置================================================
//=================================================定义 IPS114 参数结构体===============================================
typedef enum
{
IPS114_PORTAIT = 0, // 竖屏模式
IPS114_PORTAIT_180 = 1, // 竖屏模式 旋转180
IPS114_CROSSWISE = 2, // 横屏模式
IPS114_CROSSWISE_180 = 3, // 横屏模式 旋转180
}ips114_dir_enum;
typedef enum
{
IPS114_6X8_FONT = 0, // 6x8 字体
IPS114_8X16_FONT = 1, // 8x16 字体
IPS114_16X16_FONT = 2, // 16x16 字体 目前不支持
}ips114_font_size_enum;
extern uint16 ips114_width_max ;
extern uint16 ips114_height_max;
//=================================================定义 IPS114 参数结构体===============================================
//=================================================声明 IPS114 基础函数================================================
void ips114_clear (void); // IPS114 清屏函数
void ips114_full (const uint16 color); // IPS114 屏幕填充函数
void ips114_set_dir (ips114_dir_enum dir); // IPS114 设置显示方向
void ips114_set_font (ips114_font_size_enum font); // IPS114 设置显示字体
void ips114_set_color (const uint16 pen, const uint16 bgcolor); // IPS114 设置显示颜色
void ips114_draw_point (uint16 x, uint16 y, const uint16 color); // IPS114 画点函数
void ips114_draw_line (uint16 x_start, uint16 y_start, uint16 x_end, uint16 y_end, const uint16 color); // IPS114 画线函数
void ips114_show_char (uint16 x, uint16 y, const char dat); // IPS114 显示字符
void ips114_show_string (uint16 x, uint16 y, const char dat[]); // IPS114 显示字符串
void ips114_show_int (uint16 x,uint16 y, const int32 dat, uint8 num); // IPS114 显示32位有符号 (去除整数部分无效的0)
void ips114_show_uint (uint16 x,uint16 y, const uint32 dat, uint8 num); // IPS114 显示32位无符号 (去除整数部分无效的0)
void ips114_show_float (uint16 x,uint16 y, const double dat, uint8 num, uint8 pointnum);
void ips114_show_binary_image (uint16 x, uint16 y, const uint8 *image, uint16 width, uint16 height, uint16 dis_width, uint16 dis_height); // IPS114 显示二值图像 数据每八个点组成一个字节数据
void ips114_show_gray_image (uint16 x, uint16 y, const uint8 *image, uint16 width, uint16 height, uint16 dis_width, uint16 dis_height, uint8 threshold); // IPS114 显示 8bit 灰度图像 带二值化阈值
void ips114_show_rgb565_image (uint16 x, uint16 y, const uint16 *image, uint16 width, uint16 height, uint16 dis_width, uint16 dis_height, uint8 color_mode); // IPS114 显示 RGB565 彩色图像
void ips114_show_wave (uint16 x, uint16 y, const uint16 *wave, uint16 width, uint16 value_max, uint16 dis_width, uint16 dis_value_max); // IPS114 显示波形
void ips114_show_chinese (uint16 x, uint16 y, uint8 size, const uint8 *chinese_buffer, uint8 number, const uint16 color); // IPS114 汉字显示
void ips114_init (void); // 1.14寸 IPS液晶初始化
//=================================================声明 IPS114 基础函数================================================
//=================================================声明 IPS114 扩展函数================================================
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IPS114 显示小钻风图像
// 参数说明 p 图像数组指针
// 参数说明 width 图像实际宽度
// 参数说明 height 图像实际高度
// 返回参数 void
// 使用示例 ips114_displayimage7725(ov7725_image_binary[0], OV7725_W, OV7725_H);
// 备注信息 拓展的一键显示函数,默认无缩放,从屏幕坐标起始点开始显示
//-------------------------------------------------------------------------------------------------------------------
#define ips114_displayimage7725(p, width, height) (ips114_show_binary_image(0, 0, (p), OV7725_W, OV7725_H, (width), (height)))
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IPS114 显示总钻风图像
// 参数说明 p 图像数组指针
// 参数说明 width 图像实际宽度
// 参数说明 height 图像实际高度
// 返回参数 void
// 使用示例 ips114_displayimage03x(mt9v03x_image[0], MT9V03X_W, MT9V03X_H);
// 备注信息 拓展的一键显示函数,默认无缩放,从屏幕坐标起始点开始显示
//-------------------------------------------------------------------------------------------------------------------
#define ips114_displayimage03x(p, width, height) (ips114_show_gray_image(0, 0, (p), MT9V03X_W, MT9V03X_H, (width), (height), 0))
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IPS114 显示凌瞳图像
// 参数说明 p 图像数组指针
// 参数说明 width 图像实际宽度
// 参数说明 height 图像实际高度
// 返回参数 void
// 使用示例 ips114_displayimage8660(scc8660_image[0], SCC8660_W, SCC8660_H);
// 备注信息 拓展的一键显示函数,默认无缩放,从屏幕坐标起始点开始显示
//-------------------------------------------------------------------------------------------------------------------
#define ips114_displayimage8660(p, width, height) (ips114_show_rgb565_image(0, 0, (p), SCC8660_W, SCC8660_H, (width), (height), 1))
//=================================================声明 IPS114 扩展函数================================================
#endif
File diff suppressed because it is too large Load Diff
+196
View File
@@ -0,0 +1,196 @@
/*********************************************************************************************************************
* MSPM0G3507 Opensource Library 即(MSPM0G3507 开源库)是一个基于官方 SDK 接口的第三方开源库
* Copyright (c) 2022 SEEKFREE 逐飞科技
*
* 本文件是 MSPM0G3507 开源库的一部分
*
* MSPM0G3507 开源库 是免费软件
* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款
* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它
*
* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证
* 甚至没有隐含的适销性或适合特定用途的保证
* 更多细节请参见 GPL
*
* 您应该在收到本开源库的同时收到一份 GPL 的副本
* 如果没有,请参阅<https://www.gnu.org/licenses/>
*
* 额外注明:
* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本
* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中
* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件
* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明)
*
* 文件名称 zf_device_ips200
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 MDK 5.37
* 适用平台 MSPM0G3507
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2025-06-1 SeekFree first version
********************************************************************************************************************/
/*********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* // 双排排针 并口两寸屏 硬件引脚
* 不支持
*
* // 单排排针 SPI 两寸屏 硬件引脚
* SCL 查看 zf_device_ips200.h 中 IPS200_SCL_PIN_SPI 宏定义
* SDA 查看 zf_device_ips200.h 中 IPS200_SDA_PIN_SPI 宏定义
* RST 查看 zf_device_ips200.h 中 IPS200_RST_PIN_SPI 宏定义
* DC 查看 zf_device_ips200.h 中 IPS200_DC_PIN_SPI 宏定义
* CS 查看 zf_device_ips200.h 中 IPS200_CS_PIN_SPI 宏定义
* BLk 查看 zf_device_ips200.h 中 IPS200_BLk_PIN_SPI 宏定义
* VCC 3.3V电源
* GND 电源地
* 最大分辨率 320 * 240
* ------------------------------------
********************************************************************************************************************/
#ifndef _zf_device_ips200_h_
#define _zf_device_ips200_h_
#include "zf_common_typedef.h"
#define IPS200_USE_SOFT_SPI ( 0 ) // 默认使用硬件 SPI 方式驱动 建议使用硬件 SPI 方式驱动
#if IPS200_USE_SOFT_SPI // 这两段 颜色正常的才是正确的 颜色灰的就是没有用的
//====================================================软件 SPI 驱动====================================================
// 如果使用的是单排排针的两寸屏幕 SPI 驱动控制引脚 可以修改
#define IPS200_SOFT_SPI_DELAY ( 1 ) // 软件 SPI 的时钟延时周期 数值越小 SPI 通信速率越快
#define IPS200_SCL_PIN ( A12 ) // 软件 SPI SCK 引脚
#define IPS200_SDA_PIN ( A9 ) // 软件 SPI MOSI 引脚
//====================================================软件 SPI 驱动====================================================
#else
//====================================================硬件 SPI 驱动====================================================
// 如果使用的是单排排针的两寸屏幕 SPI 驱动控制引脚 可以修改
#define IPS200_SPI_SPEED ( 30 * 1000 * 1000 ) // 硬件 SPI 速率 这里设置为系统时钟二分频
#define IPS200_SPI ( SPI_0 ) // 硬件 SPI 号
#define IPS200_SCL_PIN_SPI ( SPI0_SCK_A12 ) // 硬件 SPI SCK 引脚
#define IPS200_SDA_PIN_SPI ( SPI0_MOSI_A9 ) // 硬件 SPI MOSI 引脚
//====================================================硬件 SPI 驱动====================================================
#endif
// 如果使用的是单排排针的两寸屏幕 SPI 驱动控制引脚 可以修改
#define IPS200_RST_PIN_SPI ( A7 ) // 液晶复位引脚定义
#define IPS200_DC_PIN_SPI ( A15 ) // 液晶命令位引脚定义
#define IPS200_CS_PIN_SPI ( A8 )
#define IPS200_BLk_PIN_SPI ( A13 )
//// 如果使用的是双排排针的两寸屏幕 并口驱动控制引脚 可以修改
//#define IPS200_RD_PIN_PARALLEL8 ( D4 )
//#define IPS200_WR_PIN_PARALLEL8 ( D6 )
//#define IPS200_RS_PIN_PARALLEL8 ( D14 )
//#define IPS200_RST_PIN_PARALLEL8 ( D5 )
//#define IPS200_CS_PIN_PARALLEL8 ( D7 )
//#define IPS200_BL_PIN_PARALLEL8 ( D15 )
//
//// 并口驱动数据引脚 可以修改 如果你的屏幕是双排排针 这里的引脚用得到 必须要连续八个引脚
//#define IPS200_D0_PIN_PARALLEL8 ( G8 )
//#define IPS200_D1_PIN_PARALLEL8 ( G9 )
//#define IPS200_D2_PIN_PARALLEL8 ( G10 )
//#define IPS200_D3_PIN_PARALLEL8 ( G11 )
//#define IPS200_D4_PIN_PARALLEL8 ( G12 )
//#define IPS200_D5_PIN_PARALLEL8 ( G13 )
//#define IPS200_D6_PIN_PARALLEL8 ( G14 )
//#define IPS200_D7_PIN_PARALLEL8 ( G15 )
#define IPS200_DEFAULT_DISPLAY_DIR ( IPS200_PORTAIT ) // 默认的显示方向
#define IPS200_DEFAULT_PENCOLOR ( RGB565_RED ) // 默认的画笔颜色
#define IPS200_DEFAULT_BGCOLOR ( RGB565_WHITE ) // 默认的背景颜色
#define IPS200_DEFAULT_DISPLAY_FONT ( IPS200_8X16_FONT ) // 默认的字体模式
// 数据对应地址 不可更改
//#define IPS200_DATA_ADD gpio_odr_addr(IPS200_D0_PIN_PARALLEL8)
// 控制语句
//#define IPS200_RD(x) ((x) ? (gpio_high(IPS200_RD_PIN_PARALLEL8)) : (gpio_low(IPS200_RD_PIN_PARALLEL8)))
//#define IPS200_WR(x) ((x) ? (gpio_high(IPS200_WR_PIN_PARALLEL8)) : (gpio_low(IPS200_WR_PIN_PARALLEL8)))
#define IPS200_RST(x) ((x) ? (gpio_high(ips_rst_pin)) : (gpio_low(ips_rst_pin)))
#define IPS200_BL(x) ((x) ? (gpio_high(ips_bl_pin)) : (gpio_low(ips_bl_pin)))
//#define IPS200_RS(x) ((x) ? (gpio_high(IPS200_RS_PIN_PARALLEL8)) : (gpio_low(IPS200_RS_PIN_PARALLEL8)))
#define IPS200_DC(x) ((x) ? (gpio_high(IPS200_DC_PIN_SPI)) : (gpio_low(IPS200_DC_PIN_SPI)))
#define IPS200_CS(x) ((x) ? (gpio_high(ips_cs_pin)) : (gpio_low(ips_cs_pin)))
typedef enum
{
IPS200_TYPE_SPI, // SPI 驱动
IPS200_TYPE_PARALLEL8, // 并口驱动
}ips200_type_enum;
typedef enum
{
IPS200_PORTAIT = 0, // 竖屏模式
IPS200_PORTAIT_180 = 1, // 竖屏模式 旋转180
IPS200_CROSSWISE = 2, // 横屏模式
IPS200_CROSSWISE_180 = 3, // 横屏模式 旋转180
}ips200_dir_enum;
typedef enum
{
IPS200_6X8_FONT = 0, // 6x8 字体
IPS200_8X16_FONT = 1, // 8x16 字体
IPS200_16X16_FONT = 2, // 16x16 字体 目前不支持
}ips200_font_size_enum;
void ips200_clear (void);
void ips200_full (const uint16 color);
void ips200_set_dir (ips200_dir_enum dir);
void ips200_set_font (ips200_font_size_enum font);
void ips200_set_color (const uint16 pen, const uint16 bgcolor);
void ips200_draw_point (uint16 x, uint16 y, const uint16 color);
void ips200_draw_line (uint16 x_start, uint16 y_start, uint16 x_end, uint16 y_end, const uint16 color);
void ips200_show_char (uint16 x, uint16 y, const char dat);
void ips200_show_string (uint16 x, uint16 y, const char dat[]);
void ips200_show_int (uint16 x, uint16 y, const int32 dat, uint8 num);
void ips200_show_uint (uint16 x, uint16 y, const uint32 dat, uint8 num);
void ips200_show_float (uint16 x, uint16 y, const double dat, uint8 num, uint8 pointnum);
void ips200_show_binary_image (uint16 x, uint16 y, const uint8 *image, uint16 width, uint16 height, uint16 dis_width, uint16 dis_height);
void ips200_show_gray_image (uint16 x, uint16 y, const uint8 *image, uint16 width, uint16 height, uint16 dis_width, uint16 dis_height, uint8 threshold);
void ips200_show_rgb565_image (uint16 x, uint16 y, const uint16 *image, uint16 width, uint16 height, uint16 dis_width, uint16 dis_height, uint8 color_mode);
void ips200_show_wave (uint16 x, uint16 y, const uint16 *wave, uint16 width, uint16 value_max, uint16 dis_width, uint16 dis_value_max);
void ips200_show_chinese (uint16 x, uint16 y, uint8 size, const uint8 *chinese_buffer, uint8 number, const uint16 color);
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IPS200 显示小钻风图像
// 参数说明 p 图像数组
// 参数说明 width 显示宽度
// 参数说明 height 显示高度
// 返回参数 void
// 使用示例 ips200_displayimage7725(ov7725_image_binary[0], 80, 60);
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
#define ips200_displayimage7725(p, width, height) (ips200_show_binary_image(0, 0, (p), OV7725_W, OV7725_H, (width), (height)))
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IPS200 显示总钻风图像 不带二值化 显示灰度图像
// 参数说明 p 图像数组
// 参数说明 width 显示宽度
// 参数说明 height 显示高度
// 返回参数 void
// 使用示例 ips200_displayimage03x(mt9v03x_image[0], 94, 60);
// 备注信息 如果要显示二值化图像就去调用 ips200_show_gray_image 函数
//-------------------------------------------------------------------------------------------------------------------
#define ips200_displayimage03x(p, width, height) (ips200_show_gray_image(0, 0, (p), MT9V03X_W, MT9V03X_H, (width), (height), 0))
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IPS200 显示凌瞳图像
// 参数说明 p 图像数组
// 参数说明 width 显示宽度
// 参数说明 height 显示高度
// 返回参数 void
// 使用示例 ips200_displayimage8660(scc8660_image[0], 80, 60);
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
#define ips200_displayimage8660(p, width, height) (ips200_show_rgb565_image(0, 0, (p), SCC8660_W, SCC8660_H, (width), (height), 1))
void ips200_init (ips200_type_enum type_select);
#endif
+985
View File
@@ -0,0 +1,985 @@
/*********************************************************************************************************************
* MSPM0G3507 Opensource Library 即(MSPM0G3507 开源库)是一个基于官方 SDK 接口的第三方开源库
* Copyright (c) 2022 SEEKFREE 逐飞科技
*
* 本文件是 MSPM0G3507 开源库的一部分
*
* MSPM0G3507 开源库 是免费软件
* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款
* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它
*
* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证
* 甚至没有隐含的适销性或适合特定用途的保证
* 更多细节请参见 GPL
*
* 您应该在收到本开源库的同时收到一份 GPL 的副本
* 如果没有,请参阅<https://www.gnu.org/licenses/>
*
* 额外注明:
* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本
* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中
* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件
* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明)
*
* 文件名称 zf_device_ips200pro
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 MDK 5.37
* 适用平台 MSPM0G3507
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2025-06-1 SeekFree first version
********************************************************************************************************************/
#include "zf_common_debug.h"
#include "zf_common_function.h"
#include "zf_driver_delay.h"
#include "zf_driver_spi.h"
#include "zf_device_type.h"
#include "zf_device_ips200pro.h"
#define IPS200PRO_SPI_LENGTH ( 4096 ) // 每次SPI通讯最大长度 不可修改
// 不可修改
#define MAX_ID_PAGE ( 30 )
#define MAX_ID_LABEL ( 50 )
#define MAX_ID_TABLE ( 20 )
#define MAX_ID_METER ( 10 )
#define MAX_ID_CLOCK ( 1 )
#define MAX_ID_PROGRESS_BAR ( 20 )
#define MAX_ID_CALENDAR ( 1 )
#define MAX_ID_WAVEFORM ( 5 )
#define MAX_ID_IMAGE ( 5 )
#define MAX_ID_IMAGE_LINE ( 10 )
#define MAX_ID_IMAGE_RECTANGLE ( 5 )
ips200pro_information_struct ips200pro_information;
ips200pro_time_struct ips200pro_time;
static uint8 ips200pro_page_num = 0;
static char ips200pro_printf_buffer[51];
typedef enum
{
IPS200PRO_PARAMETER_SET = 0x01, // 设置系统参数命令
IPS200PRO_PARAMETER_GET, // 获取系统参数命令
IPS200PRO_WIDGETS_PAGE = 0x10, // 页面组件
IPS200PRO_WIDGETS_LABEL, // 文本标签组件
IPS200PRO_WIDGETS_TABLE, // 表格组件
IPS200PRO_WIDGETS_METER, // 仪表组件
IPS200PRO_WIDGETS_CLOCK, // 时钟组件
IPS200PRO_WIDGETS_BAR, // 进度条组件
IPS200PRO_WIDGETS_CALENDAR, // 日历组件
IPS200PRO_WIDGETS_WAVEFORM, // 波形组件
IPS200PRO_WIDGETS_IMAGE, // 图像组件
IPS200PRO_WIDGETS_CONTAINER, // 容器组件
IPS200PRO_WIDGETS_MAX, // 占位使用
}ips200pro_command1_enum;
// 系统参数的子命令与屏幕组件的子命令
typedef enum
{
// 可读可写的参数
IPS200PRO_SYSTEM_DATE = 0x01,// 系统日期
IPS200PRO_SYSTEM_TIME, // 系统时间
IPS200PRO_SYSTEM_PARENT, // 父对象
IPS200PRO_SYSTEM_CODED_FORMAT, // 编码格式
IPS200PRO_SYSTEM_BACKLIGHT, // 背光亮度
IPS200PRO_SYSTEM_DIRECTION, // 屏幕显示方向
IPS200PRO_SYSTEM_CRC_STATE, // CRC使能状态
IPS200PRO_SYSTEM_FONT_SIZE, // 全局字体
SCREEN_SYSTEM_OPTIMIZE, // 优化 目前仅针对图像进行优化(默认优化开启)
IPS200PRO_SYSTEM_THEME, // 系统主题
IPS200PRO_SYSTEM_SET_MAX, // 占位使用
// 仅可读的参数
IPS200PRO_SYSTEM_INFORMATION = 0x10, // 屏幕ID编号、分辨率、固件版本
IPS200PRO_SYSTEM_FREE_STACK, // 系统空闲栈大小
IPS200PRO_SYSTEM_GET_MAX, // 占位使用
// 通用操作命令
IPS200PRO_COMMON_CREATE = 0x01, // 组件创建
IPS200PRO_COMMON_DELETE, // 组件删除
IPS200PRO_COMMON_FONT_SIZE, // 组件字体大小
IPS200PRO_COMMON_COLOR, // 组件颜色
IPS200PRO_COMMON_VALUE, // 组件数值 不同组件数据类型不同
IPS200PRO_COMMON_POSITION, // 组件位置
IPS200PRO_COMMON_HIDDEN, // 组件隐藏
IPS200PRO_COMMON_MAX, // 占位
// PAGE组件专用命令
IPS200PRO_PAGE_SWITCH = 0x10, // 切换页面
IPS200PRO_PAGE_TITLE, // 设置页面标题显示位置与宽度
IPS200PRO_PAGE_MAX,
// LABEL组件专用命令
IPS200PRO_LABEL_LONG_MODE = 0x10, // 长文本模式
IPS200PRO_LABEL_MAX,
// TABLE组件专用命令
IPS200PRO_TABLE_COL_WIDTH = 0x10, // 表格列宽度设置 行高由屏幕自动调整,无法设置
IPS200PRO_TABLE_SELECT, // 表格中单元格选中
IPS200PRO_TABLE_MAX,
// WAVEFORM组件专用命令
IPS200PRO_WAVEFORM_LINE_STATE = 0x10, // 隐藏指定线条
IPS200PRO_WAVEFORM_LINE_TYPE, // 设置组件中线条的类型
IPS200PRO_WAVEFORM_CLEAR, // 将所有数据清空
IPS200PRO_WAVEFORM_MAX,
// IMAGE组件专用命令
IPS200PRO_IMAGE_DRAW_LINE = 0x10, // 图像画线
IPS200PRO_IMAGE_DRAW_RECTANGLE, // 图像画框
IPS200PRO_IMAGE_MAX,
}ips200pro_command2_enum;
// 这里使用宏定义的方式,目的是为了避免使用匿名结构体,导致部分IDE无法在线调试的时候查看匿名结构体的数据
#define IPS200PRO_HEADER \
uint8 command1; /* 命令1 */ \
uint8 command2; /* 命令2 */ \
uint8 check_crc8; /* CRC校验、默认未启用 */ \
uint8 widgets_id; /* ID编号 */ \
uint32 length /* 数据包长度 */ \
typedef struct
{
IPS200PRO_HEADER;
}ips200pro_header_struct;
// 数据拆分联合体
typedef union
{
int8 int8_data[2]; // 有符号字节数据
uint8 uint8_data[2]; // 无符号字节数据
int16 int16_data; // 有符号半字数据
uint16 uint16_data; // 无符号半字数据
}data_split_union;
// 通用结构体
#define IPS200PRO_COMMON_STRUCT(name, num) \
struct common_packet\
{\
IPS200PRO_HEADER; \
data_split_union data[num]; \
}name;
#define ips200pro_write_8bit_data_spi_array(data, len) (spi_write_8bit_array(IPS200PRO_SPI_INDEX, (data), (len)))
#define ips200pro_transfer_8bit_data_spi_array(tx_data, rx_data, len) (spi_transfer_8bit(IPS200PRO_SPI_INDEX, (tx_data), (rx_data), (len)))
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 屏幕等待函数
// 参数说明 wait_time 等待时间
// 返回参数 uint8 1:超时退出 0:未超时
// 使用示例
// 备注信息 内部使用,用户无需关心
//-------------------------------------------------------------------------------------------------------------------
static uint8 ips200pro_wait_idle (uint32 wait_time)
{
wait_time = wait_time * 100;
while(0 == gpio_get_level(IPS200PRO_INT_PIN) && (0 != wait_time))
{
func_soft_delay(1000);
wait_time--;
}
return (!wait_time);
}
#if(1 == IPS200PRO_CRC_ENABLE)
static uint8 ips200pro_calculate_crc8(uint8 *data, uint32 length)
{
uint8 i, crc = 0;
while(length--)
{
crc ^= *data++;
for (i = 0; i < 8; i++)
{
crc = (crc & 0x80) ? ((crc << 1) ^ 0x07) : (crc <<= 1);
}
}
return crc;
}
#endif
uint8 ips200pro_send_buffer(const void *buffer, uint32 length, uint32 time_out, uint8 end_flag)
{
uint8 return_state = 1;
if( ((0 == time_out) || (0 == ips200pro_wait_idle(time_out))) // 等待未超时
&& (IPS200PRO_SPI_LENGTH >= length) // 数据量未超过限制
&& (NULL != buffer)) // 指针不为空
{
gpio_low(IPS200PRO_CS_PIN);
ips200pro_write_8bit_data_spi_array((const uint8 *)buffer, length);
if(1 == end_flag)
{
gpio_high(IPS200PRO_CS_PIN);
}
return_state = 0;
}
return return_state;
}
uint8 ips200pro_receive_buffer(void *buffer, uint32 length, uint32 time_out)
{
uint8 return_state = 1;
if( ((0 == time_out) || (0 == ips200pro_wait_idle(time_out))) // 等待未超时
&& (IPS200PRO_SPI_LENGTH >= length) // 数据量未超过限制
&& (NULL != buffer)) // 指针不为空
{
gpio_low(IPS200PRO_CS_PIN);
ips200pro_transfer_8bit_data_spi_array((const uint8 *)buffer, (uint8 *)buffer, length);
gpio_high(IPS200PRO_CS_PIN);
return_state = 0;
}
return return_state;
}
uint8 ips200pro_write_packet(ips200pro_command1_enum command1, ips200pro_command2_enum command2, uint8 widgets_id, ips200pro_header_struct *temp, uint32 length, const void *buffer, uint32 buffer_length)
{
uint8 return_state = 1;
temp->command1 = command1;
temp->command2 = command2;
temp->widgets_id = widgets_id;
temp->length = length + buffer_length;
#if(1 == IPS200PRO_CRC_ENABLE)
temp->check_crc8 = 0;
temp->check_crc8 = ips200pro_calculate_crc8((uint8 *)temp, length);
#endif
return_state = ips200pro_send_buffer(temp, length, IPS200PRO_WAIT_TIME, NULL == buffer);
if((0 == return_state) && (NULL != buffer) && (0 != buffer_length))
{
return_state = ips200pro_send_buffer(buffer, buffer_length, 0, 1);
}
else
{
gpio_high(IPS200PRO_CS_PIN);
}
return return_state;
}
uint8 ips200pro_read_parameter(ips200pro_command2_enum command2, ips200pro_header_struct *temp, uint8 length)
{
uint8 return_state;
temp->command1 = IPS200PRO_PARAMETER_GET;
temp->command2 = command2;
temp->length = length;
// 发送命令
return_state = ips200pro_send_buffer(temp, length, IPS200PRO_WAIT_TIME, 1);
// 读取数据
temp->command1 = 0x00;
return_state = ips200pro_receive_buffer(temp, length, IPS200PRO_WAIT_TIME);
//*parameter = temp.data[0].uint8_data[0];
return return_state;
}
uint8 ips200pro_set_date(uint16 year, uint8 month, uint8 day)
{
uint8 return_state;
IPS200PRO_COMMON_STRUCT(temp, 2);
temp.data[0].uint16_data = year;
temp.data[1].uint8_data[0] = month;
temp.data[1].uint8_data[1] = day;
return_state = ips200pro_write_packet(IPS200PRO_PARAMETER_SET, IPS200PRO_SYSTEM_DATE, 0, (ips200pro_header_struct *)&temp, sizeof(temp), NULL, 0);
return return_state;
}
uint8 ips200pro_set_time(uint8 hour, uint8 minute, uint8 second)
{
uint8 return_state;
IPS200PRO_COMMON_STRUCT(temp, 2);
temp.data[0].uint8_data[0] = hour;
temp.data[0].uint8_data[1] = minute;
temp.data[1].uint8_data[0] = second;
temp.data[1].uint8_data[1] = 0;
return_state = ips200pro_write_packet(IPS200PRO_PARAMETER_SET, IPS200PRO_SYSTEM_TIME, 0, (ips200pro_header_struct *)&temp, sizeof(temp), NULL, 0);
return return_state;
}
uint8 ips200pro_set_parent(uint16 child_id, uint16 parent_id)
{
uint8 return_state;
IPS200PRO_COMMON_STRUCT(temp, 2);
temp.data[0].uint8_data[0] = (uint8)child_id;
temp.data[0].uint8_data[1] = child_id >> 8;
temp.data[1].uint8_data[0] = (uint8)parent_id;
temp.data[1].uint8_data[1] = parent_id >> 8;
return_state = ips200pro_write_packet(IPS200PRO_PARAMETER_SET, IPS200PRO_SYSTEM_PARENT, 0, (ips200pro_header_struct *)&temp, sizeof(temp), NULL, 0);
return return_state;
}
uint8 ips200pro_set_format(ips200pro_format_enum format)
{
uint8 return_state;
IPS200PRO_COMMON_STRUCT(temp, 1);
temp.data[0].uint8_data[0] = format;
return_state = ips200pro_write_packet(IPS200PRO_PARAMETER_SET, IPS200PRO_SYSTEM_CODED_FORMAT, 0, (ips200pro_header_struct *)&temp, sizeof(temp), NULL, 0);
return return_state;
}
uint8 ips200pro_set_backlight(uint8 backlight)
{
uint8 return_state;
IPS200PRO_COMMON_STRUCT(temp, 1);
temp.data[0].uint8_data[0] = backlight;
return_state = ips200pro_write_packet(IPS200PRO_PARAMETER_SET, IPS200PRO_SYSTEM_BACKLIGHT, 0, (ips200pro_header_struct *)&temp, sizeof(temp), NULL, 0);
return return_state;
}
uint8 ips200pro_set_direction(ips200pro_display_direction_enum dir)
{
uint8 return_state;
IPS200PRO_COMMON_STRUCT(temp, 1);
temp.data[0].uint8_data[0] = dir;
return_state = ips200pro_write_packet(IPS200PRO_PARAMETER_SET, IPS200PRO_SYSTEM_DIRECTION, 0, (ips200pro_header_struct *)&temp, sizeof(temp), NULL, 0);
return return_state;
}
uint8 ips200pro_set_crc_state(uint8 crc_state)
{
uint8 return_state;
IPS200PRO_COMMON_STRUCT(temp, 1);
temp.data[0].uint8_data[0] = crc_state;
return_state = ips200pro_write_packet(IPS200PRO_PARAMETER_SET, IPS200PRO_SYSTEM_CRC_STATE, 0, (ips200pro_header_struct *)&temp, sizeof(temp), NULL, 0);
return return_state;
}
uint8 ips200pro_set_default_font(ips200pro_font_size_enum font)
{
uint8 return_state;
IPS200PRO_COMMON_STRUCT(temp, 1);
temp.data[0].uint8_data[0] = font;
return_state = ips200pro_write_packet(IPS200PRO_PARAMETER_SET, IPS200PRO_SYSTEM_FONT_SIZE, 0, (ips200pro_header_struct *)&temp, sizeof(temp), NULL, 0);
return return_state;
}
uint8 ips200pro_set_optimize(uint8 state)
{
uint8 return_state;
IPS200PRO_COMMON_STRUCT(temp, 1);
temp.data[0].uint8_data[0] = state;
return_state = ips200pro_write_packet(IPS200PRO_PARAMETER_SET, SCREEN_SYSTEM_OPTIMIZE, 0, (ips200pro_header_struct *)&temp, sizeof(temp), NULL, 0);
return return_state;
}
uint8 ips200pro_get_date(ips200pro_time_struct *time)
{
uint8 return_state;
IPS200PRO_COMMON_STRUCT(temp, 2);
return_state = ips200pro_read_parameter(IPS200PRO_SYSTEM_DATE, (ips200pro_header_struct *)&temp, sizeof(temp));
if(0 == return_state)
{
memcpy(&time->year, &(temp.data[0]), 4);
}
return return_state;
}
uint8 ips200pro_get_time(ips200pro_time_struct *time)
{
uint8 return_state;
IPS200PRO_COMMON_STRUCT(temp, 2);
return_state = ips200pro_read_parameter(IPS200PRO_SYSTEM_TIME, (ips200pro_header_struct *)&temp, sizeof(temp));
if(0 == return_state)
{
memcpy(&time->hour, &(temp.data[0]), 4);
}
return return_state;
}
uint8 ips200pro_get_information(ips200pro_information_struct *information)
{
uint8 return_state;
IPS200PRO_COMMON_STRUCT(temp, 4);
return_state = ips200pro_read_parameter(IPS200PRO_SYSTEM_INFORMATION, (ips200pro_header_struct *)&temp, sizeof(temp));
if(0 == return_state)
{
information->version_major = temp.widgets_id; // 主版本
memcpy(&information->id, &(temp.data[0]), 8);
}
return return_state;
}
uint8 ips200pro_get_free_stack_size(uint32 *stack_size)
{
uint8 return_state;
IPS200PRO_COMMON_STRUCT(temp, 2);
return_state = ips200pro_read_parameter(IPS200PRO_SYSTEM_FREE_STACK, (ips200pro_header_struct *)&temp, sizeof(temp));
if(0 == return_state)
{
*stack_size = *((uint32 *)&temp.data[0]);
}
return return_state;
}
uint8 ips200pro_create_widgets(uint16 widgets_id, int16 x, int16 y, uint16 width, uint16 height)
{
uint8 return_state = 1;
IPS200PRO_COMMON_STRUCT(temp, 4);
temp.data[0].int16_data = x;
temp.data[1].int16_data = y;
temp.data[2].uint16_data = width;
temp.data[3].uint16_data = height;
if(ips200pro_page_num || (IPS200PRO_WIDGETS_PAGE == (widgets_id >> 8)))
{
// 只有在页面已经创建后,才允许创建其他组件
return_state = ips200pro_write_packet(widgets_id >> 8, IPS200PRO_COMMON_CREATE, (uint8)widgets_id, (ips200pro_header_struct *)&temp, sizeof(temp), NULL, 0);
}
return return_state;
}
uint8 ips200pro_delete_widgets(uint16 widgets_id)
{
uint8 return_state;
ips200pro_header_struct temp;
return_state = ips200pro_write_packet(widgets_id >> 8, IPS200PRO_COMMON_DELETE, (uint8)widgets_id, (ips200pro_header_struct *)&temp, sizeof(temp), NULL, 0);
return return_state;
}
uint8 ips200pro_set_font(uint16 widgets_id, ips200pro_font_size_enum font_size)
{
uint8 return_state;
IPS200PRO_COMMON_STRUCT(temp, 1);
temp.data[0].uint16_data = font_size;
return_state = ips200pro_write_packet(widgets_id >> 8, IPS200PRO_COMMON_FONT_SIZE, (uint8)widgets_id, (ips200pro_header_struct *)&temp, sizeof(temp), NULL, 0);
return return_state;
}
uint8 ips200pro_set_color(uint16 widgets_id, ips200pro_widgets_color_type_enum color_type, uint16 color)
{
uint8 return_state;
IPS200PRO_COMMON_STRUCT(temp, 2);
temp.data[0].uint16_data = color_type;
temp.data[1].uint16_data = color;
return_state = ips200pro_write_packet(widgets_id >> 8, IPS200PRO_COMMON_COLOR, (uint8)widgets_id, (ips200pro_header_struct *)&temp, sizeof(temp), NULL, 0);
return return_state;
}
uint8 ips200pro_set_position(uint16 widgets_id, int16 x, int16 y)
{
uint8 return_state;
IPS200PRO_COMMON_STRUCT(temp, 2);
temp.data[0].int16_data = x;
temp.data[1].int16_data = y;
return_state = ips200pro_write_packet(widgets_id >> 8, IPS200PRO_COMMON_POSITION, (uint8)widgets_id, (ips200pro_header_struct *)&temp, sizeof(temp), NULL, 0);
return return_state;
}
uint8 ips200pro_set_hidden(uint16 widgets_id, uint8 state)
{
uint8 return_state;
IPS200PRO_COMMON_STRUCT(temp, 1);
temp.data[0].uint16_data = state;
return_state = ips200pro_write_packet(widgets_id >> 8, IPS200PRO_COMMON_HIDDEN, (uint8)widgets_id, (ips200pro_header_struct *)&temp, sizeof(temp), NULL, 0);
return return_state;
}
uint16 ips200pro_page_create(char *str)
{
uint8 return_state = 1;
if(MAX_ID_PAGE > ips200pro_page_num)
{
return_state = ips200pro_create_widgets(++ips200pro_page_num | (IPS200PRO_WIDGETS_PAGE << 8), 0, 0, 0, 0);
if(1 == return_state)
{
ips200pro_page_num--;
}
else if(NULL != str)
{
return_state = ips200pro_page_set_title_name(ips200pro_page_num, str);
}
}
return return_state == 1 ? 0 : (ips200pro_page_num | (IPS200PRO_WIDGETS_PAGE << 8));
}
uint8 ips200pro_page_switch(uint16 page_id, ips200pro_page_animations_enum anim_en)
{
uint8 return_state;
IPS200PRO_COMMON_STRUCT(temp, 1);
temp.data[0].uint16_data = anim_en;
return_state = ips200pro_write_packet(IPS200PRO_WIDGETS_PAGE, IPS200PRO_PAGE_SWITCH, (uint8)page_id, (ips200pro_header_struct *)&temp, sizeof(temp), NULL, 0);
return return_state;
}
uint8 ips200pro_page_hidden(uint16 page_id, uint8 state)
{
uint8 return_state;
if(0 == page_id)
{
page_id = 0 | (IPS200PRO_WIDGETS_PAGE << 8);
}
return_state = ips200pro_set_hidden(page_id, state);
return return_state;
}
uint8 ips200pro_page_set_title_name(uint16 page_id, char *str)
{
uint8 return_state;
ips200pro_header_struct temp;
return_state = ips200pro_write_packet(IPS200PRO_WIDGETS_PAGE, IPS200PRO_COMMON_VALUE, (uint8)page_id, (ips200pro_header_struct *)&temp, sizeof(temp), str, strlen(str));
return return_state;
}
uint8 ips200pro_page_set_title_position_width(ips200pro_title_position_enum title_position, uint8 title_width)
{
uint8 return_state;
IPS200PRO_COMMON_STRUCT(temp, 2);
temp.data[0].uint16_data = title_position;
temp.data[1].uint16_data = title_width;
return_state = ips200pro_write_packet(IPS200PRO_WIDGETS_PAGE, IPS200PRO_PAGE_TITLE, 1, (ips200pro_header_struct *)&temp, sizeof(temp), NULL, 0);
return return_state;
}
uint16 ips200pro_label_create(int16 x, int16 y, uint16 width, uint16 height)
{
uint8 return_state = 1;
static uint8 lebel_num = 0;
if(MAX_ID_LABEL > lebel_num)
{
return_state = ips200pro_create_widgets(++lebel_num | (IPS200PRO_WIDGETS_LABEL << 8), x, y, width, height);
if(1 == return_state)
{
lebel_num--;
}
}
return return_state == 1 ? 0 : (lebel_num | (IPS200PRO_WIDGETS_LABEL << 8));
}
uint8 ips200pro_label_printf(uint16 label_id, const char *format, ...)
{
int32 str_length;
va_list arg;
va_start(arg, format);
uint8 return_state = 1;
ips200pro_header_struct temp;
str_length = vsnprintf(ips200pro_printf_buffer, sizeof(ips200pro_printf_buffer) - 1, format, arg);
if(0 <= str_length)
{
temp.length = (uint32)str_length;
return_state = ips200pro_write_packet(IPS200PRO_WIDGETS_LABEL, IPS200PRO_COMMON_VALUE, (uint8)label_id, (ips200pro_header_struct *)&temp, sizeof(temp), ips200pro_printf_buffer, temp.length);
}
va_end(arg);
return return_state;
}
uint8 ips200pro_label_show_string(uint16 label_id, const char *str)
{
uint8 return_state;
ips200pro_header_struct temp;
temp.length = strlen(str);
return_state = ips200pro_write_packet(IPS200PRO_WIDGETS_LABEL, IPS200PRO_COMMON_VALUE, (uint8)label_id, (ips200pro_header_struct *)&temp, sizeof(temp), str, temp.length);
return return_state;
}
uint8 ips200pro_label_mode(uint16 label_id, ips200pro_label_mode_enum mode)
{
uint8 return_state;
IPS200PRO_COMMON_STRUCT(temp, 1);
temp.data[0].uint16_data = mode;
return_state = ips200pro_write_packet(IPS200PRO_WIDGETS_LABEL, IPS200PRO_LABEL_LONG_MODE, (uint8)label_id, (ips200pro_header_struct *)&temp, sizeof(temp), NULL, 0);
return return_state;
}
uint16 ips200pro_table_create(int16 x, int16 y, uint16 row_num, uint16 col_num)
{
uint8 return_state = 1;
static uint8 table_num = 0;
if(MAX_ID_TABLE > table_num)
{
return_state = ips200pro_create_widgets(++table_num | (IPS200PRO_WIDGETS_TABLE << 8), x, y, row_num, col_num);
if(1 == return_state)
{
table_num--;
}
}
return return_state == 1 ? 0 : (table_num | (IPS200PRO_WIDGETS_TABLE << 8));
}
uint8 ips200pro_table_cell_printf(uint16 table_id, uint8 row, uint8 col, char *format, ...)
{
int32 str_length;
va_list arg;
va_start(arg, format);
uint8 return_state = 1;
IPS200PRO_COMMON_STRUCT(temp, 2);
str_length = vsnprintf(ips200pro_printf_buffer, sizeof(ips200pro_printf_buffer) - 1, format, arg);
if(0 <= str_length)
{
temp.length = (uint32)str_length;
temp.data[0].uint16_data = row;
temp.data[1].uint16_data = col;
return_state = ips200pro_write_packet(IPS200PRO_WIDGETS_TABLE, IPS200PRO_COMMON_VALUE, (uint8)table_id, (ips200pro_header_struct *)&temp, sizeof(temp), ips200pro_printf_buffer, temp.length);
}
va_end(arg);
return return_state;
}
uint8 ips200pro_table_set_col_width(uint16 table_id, uint8 col, uint16 width)
{
uint8 return_state;
IPS200PRO_COMMON_STRUCT(temp, 2);
temp.data[0].uint16_data = width;
temp.data[1].uint16_data = col;
return_state = ips200pro_write_packet(IPS200PRO_WIDGETS_TABLE, IPS200PRO_TABLE_COL_WIDTH, (uint8)table_id, (ips200pro_header_struct *)&temp, sizeof(temp), NULL, 0);
return return_state;
}
uint8 ips200pro_table_select(uint16 table_id, uint8 row, uint8 col)
{
uint8 return_state;
IPS200PRO_COMMON_STRUCT(temp, 2);
temp.data[0].uint16_data = row;
temp.data[1].uint16_data = col;
return_state = ips200pro_write_packet(IPS200PRO_WIDGETS_TABLE, IPS200PRO_TABLE_SELECT, (uint8)table_id, (ips200pro_header_struct *)&temp, sizeof(temp), NULL, 0);
return return_state;
}
uint16 ips200pro_meter_create(int16 x, int16 y, uint16 size, ips200pro_meter_style_enum style)
{
uint8 return_state = 1;
static uint8 meter_num = 0;
if(MAX_ID_METER > meter_num)
{
return_state = ips200pro_create_widgets(++meter_num | (IPS200PRO_WIDGETS_METER << 8), x, y, size, style);
if(1 == return_state)
{
meter_num--;
}
}
return return_state == 1 ? 0 : (meter_num | (IPS200PRO_WIDGETS_METER << 8));
}
uint8 ips200pro_meter_set_value(uint16 meter_id, int16 value)
{
uint8 return_state;
IPS200PRO_COMMON_STRUCT(temp, 1);
temp.data[0].int16_data = value;
return_state = ips200pro_write_packet(IPS200PRO_WIDGETS_METER, IPS200PRO_COMMON_VALUE, (uint8)meter_id, (ips200pro_header_struct *)&temp, sizeof(temp), NULL, 0);
return return_state;
}
uint16 ips200pro_clock_create(int16 x, int16 y, uint16 clock_size, ips200pro_clock_style_enum clock_type)
{
uint8 return_state = 1;
static uint8 clock_num = 0;
if(MAX_ID_CLOCK > clock_num)
{
return_state = ips200pro_create_widgets(++clock_num | (IPS200PRO_WIDGETS_CLOCK << 8), x, y, clock_size, clock_type);
if(1 == return_state)
{
clock_num--;
}
}
return return_state == 1 ? 0 : (clock_num | (IPS200PRO_WIDGETS_CLOCK << 8));
}
uint16 ips200pro_progress_bar_create(int16 x, int16 y, uint16 width, uint16 height)
{
uint8 return_state = 1;
static uint8 progress_bar_num = 0;
if(MAX_ID_PROGRESS_BAR > progress_bar_num)
{
return_state = ips200pro_create_widgets(++progress_bar_num | (IPS200PRO_WIDGETS_BAR << 8), x, y, width, height);
if(1 == return_state)
{
progress_bar_num--;
}
}
return return_state == 1 ? 0 : (progress_bar_num | (IPS200PRO_WIDGETS_BAR << 8));
}
uint8 ips200pro_progress_bar_set_value(uint16 progress_bar_id, uint8 start_value, uint8 end_value)
{
uint8 return_state;
IPS200PRO_COMMON_STRUCT(temp, 2);
temp.data[0].uint16_data = start_value;
temp.data[1].uint16_data = end_value;
return_state = ips200pro_write_packet(IPS200PRO_WIDGETS_BAR, IPS200PRO_COMMON_VALUE, (uint8)progress_bar_id, (ips200pro_header_struct *)&temp, sizeof(temp), NULL, 0);
return return_state;
}
uint16 ips200pro_calendar_create(int16 x, int16 y, uint16 width, uint16 height)
{
uint8 return_state;
// 只能创建一个日历控件
return_state = ips200pro_create_widgets(1 | (IPS200PRO_WIDGETS_CALENDAR << 8), x, y, width, height);
return return_state == 1 ? 0 : (1 | (IPS200PRO_WIDGETS_CALENDAR << 8));
}
uint8 ips200pro_calendar_display(uint16 year, uint8 month, ips200pro_calendar_mode_enum mode)
{
uint8 return_state;
IPS200PRO_COMMON_STRUCT(temp, 2);
temp.data[0].uint16_data = year;
temp.data[1].uint8_data[0] = month;
temp.data[1].uint8_data[1] = mode;
return_state = ips200pro_write_packet(IPS200PRO_WIDGETS_CALENDAR, IPS200PRO_COMMON_VALUE, 1, (ips200pro_header_struct *)&temp, sizeof(temp), NULL, 0);
return return_state;
}
uint16 ips200pro_waveform_create(int16 x, int16 y, uint16 width, uint16 height)
{
uint8 return_state = 1;
static uint8 waveform_num = 0;
if(MAX_ID_WAVEFORM > waveform_num)
{
return_state = ips200pro_create_widgets(++waveform_num | (IPS200PRO_WIDGETS_WAVEFORM << 8), x, y, width, height);
if(1 == return_state)
{
waveform_num--;
}
}
return return_state == 1 ? 0 : (waveform_num | (IPS200PRO_WIDGETS_WAVEFORM << 8));
}
uint8 ips200pro_waveform_add_value(uint16 waveform_id, uint8 line_id, const uint16 *data, uint16 length, uint16 color)
{
uint8 return_state;
IPS200PRO_COMMON_STRUCT(temp, 2);
temp.data[0].uint16_data = line_id;
temp.data[1].uint16_data = color;
return_state = ips200pro_write_packet(IPS200PRO_WIDGETS_WAVEFORM, IPS200PRO_COMMON_VALUE, (uint8)waveform_id, (ips200pro_header_struct *)&temp, sizeof(temp), data, length * 2);
return return_state;
}
uint8 ips200pro_waveform_line_state(uint16 waveform_id, uint16 line_id, uint16 line_state)
{
uint8 return_state;
IPS200PRO_COMMON_STRUCT(temp, 2);
temp.data[0].uint16_data = line_id;
temp.data[1].uint16_data = line_state;
return_state = ips200pro_write_packet(IPS200PRO_WIDGETS_WAVEFORM, IPS200PRO_WAVEFORM_LINE_STATE, (uint8)waveform_id, (ips200pro_header_struct *)&temp, sizeof(temp), NULL, 0);
return return_state;
}
uint8 ips200pro_waveform_line_type(uint16 waveform_id, uint8 line_type)
{
uint8 return_state;
IPS200PRO_COMMON_STRUCT(temp, 1);
temp.data[0].uint16_data = line_type;
return_state = ips200pro_write_packet(IPS200PRO_WIDGETS_WAVEFORM, IPS200PRO_WAVEFORM_LINE_TYPE, (uint8)waveform_id, (ips200pro_header_struct *)&temp, sizeof(temp), NULL, 0);
return return_state;
}
uint8 ips200pro_waveform_clear(uint16 waveform_id)
{
uint8 return_state;
ips200pro_header_struct temp;
return_state = ips200pro_write_packet(IPS200PRO_WIDGETS_WAVEFORM, IPS200PRO_WAVEFORM_CLEAR, (uint8)waveform_id, (ips200pro_header_struct *)&temp, sizeof(temp), NULL, 0);
return return_state;
}
uint16 ips200pro_image_create(int16 x, int16 y, uint16 width, uint16 height)
{
uint8 return_state = 1;
static uint8 image_num = 0;
if(MAX_ID_IMAGE > image_num)
{
return_state = ips200pro_create_widgets(++image_num | (IPS200PRO_WIDGETS_IMAGE << 8), x, y, width, height);
if(1 == return_state)
{
image_num--;
}
}
return return_state == 1 ? 0 : (image_num | (IPS200PRO_WIDGETS_IMAGE << 8));
}
uint8 ips200pro_image_display(uint16 image_id, const void *image, uint16 width, uint16 height, ips200pro_image_type_enum image_type, uint8 threshold)
{
uint8 return_state = 0;
uint16 send_length;
uint32 image_size;
uint8 const *image_data;
IPS200PRO_COMMON_STRUCT(temp, 4);
image_data = (uint8 *)image;
image_size = width * height * (IMAGE_RGB565 == image_type ? 2 : 1);
// 任意条件满足,则表示不需要发送图像数据,仅通知屏幕更新边线或矩形
if((NULL == image) || (!width) || (!height) || (IMAGE_NULL == image_type))
{
temp.data[0].uint16_data = 0;
temp.data[1].uint16_data = 0;
temp.data[2].uint8_data[1] = IMAGE_NULL;
}
else
{
temp.data[0].uint16_data = width;
temp.data[1].uint16_data = height;
temp.data[2].uint8_data[1] = image_type;
}
temp.data[2].uint8_data[0] = 1; // 图像开始传输标志位
temp.data[3].uint16_data = threshold;
do
{
// 计算本次传输字节数
send_length = image_size > (IPS200PRO_SPI_LENGTH - sizeof(temp)) ? (IPS200PRO_SPI_LENGTH - sizeof(temp)) : (uint16)image_size;
return_state += ips200pro_write_packet(IPS200PRO_WIDGETS_IMAGE, IPS200PRO_COMMON_VALUE, (uint8)image_id, (ips200pro_header_struct *)&temp, sizeof(temp), image_data, send_length);
image_data += send_length;
image_size -= send_length;
temp.data[2].uint8_data[0] = 0;
}while(image_size);
return return_state;
}
uint8 ips200pro_image_draw_line(uint16 image_id, uint8 line_id, void *line_data, uint16 line_length, ips200pro_image_line_type_enum data_type, uint16 color)
{
uint8 return_state = 1;
IPS200PRO_COMMON_STRUCT(temp, 2);
if(MAX_ID_IMAGE_LINE >= line_id)
{
temp.length = data_type * line_length * 2 + sizeof(temp);
temp.data[0].uint8_data[0] = line_id;
temp.data[0].uint8_data[1] = data_type;
temp.data[1].uint16_data = color;
return_state = ips200pro_write_packet(IPS200PRO_WIDGETS_IMAGE, IPS200PRO_IMAGE_DRAW_LINE, (uint8)image_id, (ips200pro_header_struct *)&temp, sizeof(temp), line_data, data_type * line_length * 2);
}
return return_state;
}
uint8 ips200pro_image_draw_rectangle(uint16 image_id, uint8 rectangle_id, int16 x, int16 y, uint16 rectangle_width, uint16 rectangle_height, uint16 color)
{
uint8 return_state = 1;
IPS200PRO_COMMON_STRUCT(temp, 6);
if(MAX_ID_IMAGE_RECTANGLE >= rectangle_id)
{
temp.data[0].uint16_data = rectangle_id;
temp.data[1].int16_data = x;
temp.data[2].int16_data = y;
temp.data[3].uint16_data = rectangle_width;
temp.data[4].uint16_data = rectangle_height;
temp.data[5].uint16_data = color;
return_state = ips200pro_write_packet(IPS200PRO_WIDGETS_IMAGE, IPS200PRO_IMAGE_DRAW_RECTANGLE, (uint8)image_id, (ips200pro_header_struct *)&temp, sizeof(temp), NULL, 0);
}
return return_state;
}
uint16 ips200pro_container_create(int16 x, int16 y, uint16 width, uint16 height)
{
uint8 return_state = 1;
static uint8 container_num = 0;
if(MAX_ID_IMAGE_RECTANGLE > container_num)
{
return_state = ips200pro_create_widgets(++container_num | (IPS200PRO_WIDGETS_CONTAINER << 8), x, y, width, height);
if(1 == return_state)
{
container_num--;
}
}
return return_state == 1 ? 0 : (container_num | (IPS200PRO_WIDGETS_CONTAINER << 8));
}
uint8 ips200pro_container_radius(uint16 container_id, uint16 border_width, uint16 radius)
{
uint8 return_state;
IPS200PRO_COMMON_STRUCT(temp, 2);
temp.data[0].uint16_data = border_width;
temp.data[1].uint16_data = radius;
return_state = ips200pro_write_packet(IPS200PRO_WIDGETS_CONTAINER, IPS200PRO_COMMON_VALUE, (uint8)container_id, (ips200pro_header_struct *)&temp, sizeof(temp), NULL, 0);
return return_state;
}
uint16 ips200pro_init(char *str, ips200pro_title_position_enum title_position, uint8 title_size)
{
uint16 page_id = 0;
spi_init(IPS200PRO_SPI_INDEX, SPI_MODE0, IPS200PRO_SPI_SPEED, IPS200PRO_CLK_PIN, IPS200PRO_MOSI_PIN, IPS200PRO_MISO_PIN, SPI_CS_NULL);
gpio_init(IPS200PRO_RST_PIN, GPO, GPIO_HIGH, GPO_PUSH_PULL);
gpio_init(IPS200PRO_CS_PIN, GPO, GPIO_HIGH, GPO_PUSH_PULL);
// 将屏幕应答引脚修改为上拉,这样即使屏幕在使用过程中被拔掉也不会导致程序卡主
gpio_init(IPS200PRO_INT_PIN, GPI, GPIO_HIGH, GPI_PULL_UP);
gpio_set_level(IPS200PRO_RST_PIN, 0);
system_delay_ms(5);
gpio_set_level(IPS200PRO_RST_PIN, 1);
system_delay_ms(20);
// 某一些主板屏幕接口由于没有MISO引脚,所以无法读取屏幕信息
// ips200pro_get_information(&ips200pro_information);
// ips200pro_get_time(&ips200pro_time);
// 设置时间会立即生效,因此并不建议在初始化中调用时间设置函数,如果在初始化中调用就会导致每次上电之后时间都会还原
// ips200pro_set_time(15, 54, 30);
// 特别注意、特别注意、特别注意
// 设置页面标题显示位置以及标题宽度,需要注意仅在创建页面之前调用才能生效
// 特别注意、特别注意、特别注意
ips200pro_page_set_title_position_width(title_position, title_size);
ips200pro_set_format(IPS200PRO_DEFAULT_FORMAT);
ips200pro_set_default_font(IPS200PRO_DEFAULT_FONT_SIZE);
ips200pro_set_optimize(IPS200PRO_DEFAULT_OPTIMIZE);
// 设置默认参数并创建一个页面
if(NULL != str)
{
page_id = ips200pro_page_create(str); // 创建一个页面
}
#if(1 == IPS200PRO_CRC_ENABLE)
ips200pro_set_crc_state(1); // 使能CRC模式增强抗干扰能力,但是需要消耗主控一部分算力做CRC计算
#endif
return page_id;
}
+772
View File
@@ -0,0 +1,772 @@
/*********************************************************************************************************************
* MSPM0G3507 Opensource Library 即(MSPM0G3507 开源库)是一个基于官方 SDK 接口的第三方开源库
* Copyright (c) 2022 SEEKFREE 逐飞科技
*
* 本文件是 MSPM0G3507 开源库的一部分
*
* MSPM0G3507 开源库 是免费软件
* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款
* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它
*
* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证
* 甚至没有隐含的适销性或适合特定用途的保证
* 更多细节请参见 GPL
*
* 您应该在收到本开源库的同时收到一份 GPL 的副本
* 如果没有,请参阅<https://www.gnu.org/licenses/>
*
* 额外注明:
* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本
* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中
* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件
* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明)
*
* 文件名称 zf_device_ips200pro
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 MDK 5.37
* 适用平台 MSPM0G3507
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2025-06-1 SeekFree first version
********************************************************************************************************************/
#ifndef _zf_device_ips200pro_h_
#define _zf_device_ips200pro_h_
#include "zf_common_typedef.h"
#define IPS200PRO_SPI_SPEED ( 30*1000*1000 ) // 硬件 SPI 速率
#define IPS200PRO_SPI_INDEX ( SPI_0 ) // 硬件 SPI 号
#define IPS200PRO_CLK_PIN ( SPI0_SCK_A12 ) // 硬件 SPI SCK 引脚
#define IPS200PRO_MOSI_PIN ( SPI0_MOSI_A9 ) // 硬件 SPI MOSI 引脚
#define IPS200PRO_MISO_PIN ( SPI0_MISO_A13 ) // 硬件 SPI MISO 引脚 TFT没有MISO引脚,但是这里任然需要定义,在spi的初始化时需要使用
#define IPS200PRO_RST_PIN ( A7 ) // 液晶复位引脚定义
#define IPS200PRO_INT_PIN ( A15 ) // 液晶命令位引脚定义
#define IPS200PRO_CS_PIN ( A8 ) // CS 片选引脚
#define IPS200PRO_WAIT_TIME ( 900 ) // 通讯等待时长,内部是软件延时,因此这里没有时间单位
#define IPS200PRO_CRC_ENABLE ( 0 ) // 0:关闭CRC模式(通常关闭即可) 1:使能CRC模式,在传输的数据包中加入CRC校验,能提高屏幕的抗干扰的能力
#define IPS200PRO_DEFAULT_FORMAT (IPS200PRO_FORMAT_UTF8) // 默认编码格式,会在初始化屏幕的时候进行设置
#define IPS200PRO_DEFAULT_FONT_SIZE ( FONT_SIZE_16 ) // 默认指定大小,会在初始化屏幕的时候进行设置
#define IPS200PRO_DEFAULT_OPTIMIZE ( 1 ) // 0:关闭优化 1:开启优化,默认开启优化,会在初始化屏幕的时候进行设置
// RGB888转RGB565宏定义
#define IPS200PRO_RGB888_TO_RGB565(r8, g8, b8) ((((r8 >> 3) & 0x1FU) << 11) | (((g8 >> 2) & 0x3FU) << 5) | ((b8 >> 3) & 0x1FU))
typedef enum
{
// 仅16、20、24号字体支持中文显示,其余字体仅支持英文显示
FONT_SIZE_12,
FONT_SIZE_14,
FONT_SIZE_16, // 16字体支持中文显示
FONT_SIZE_18,
FONT_SIZE_20, // 20字体支持中文显示
FONT_SIZE_22,
FONT_SIZE_24, // 24字体支持中文显示
FONT_SIZE_26,
FONT_SIZE_28,
FONT_SIZE_30,
FONT_SIZE_32,
FONT_SIZE_34,
FONT_SIZE_36,
FONT_SIZE_40,
}ips200pro_font_size_enum;
typedef enum
{
COLOR_FOREGROUND, // 前景色
COLOR_BACKGROUND, // 背景色 除IMAGE组件不支持其他都支持
COLOR_BORDER, // 组件边线颜色 支持组件有LABEL TABLE METER CLOCK CALENDAR CONTAINER
// 专用指令
COLOR_PAGE_SELECTED_TEXT, // 选中页面后的标题文字颜色
COLOR_PAGE_SELECTED_BG, // 选中页面后的标题背景颜色
COLOR_TABLE_SELECTED_BG, // 表格选中后的颜色
COLOR_MRTER_INDICATOR, // 仪表组件的指针颜色
COLOR_MRTER_TICKS, // 仪表组件刻度颜色
COLOR_CLOCK_HOUR, // 圆形时钟时针颜色
COLOR_CLOCK_MINUTE, // 圆形时钟分针颜色
COLOR_CLOCK_SECOND, // 圆形时钟秒针颜色
COLOR_CLOCK_TICKS, // 圆形时钟组件刻度颜色
COLOR_CALENDAR_YEAR, // 年份颜色
COLOR_CALENDAR_WEEK, // 星期颜色
COLOR_CALENDAR_TODAY, // 今日颜色
}ips200pro_widgets_color_type_enum;
typedef enum
{
PAGE_ANIM_OFF, // 页面切换时关闭动画效果
PAGE_ANIM_ON, // 页面切换时开启动画效果
}ips200pro_page_animations_enum;
typedef enum
{
LABEL_AUTO, // 当宽度无法显示全部内容时,会自动换行显示
LABEL_DOT, // 当无法全部显示的时候,末尾右下角显示...
LABEL_SCROLL, // 当宽度无法显示全部内容时水平滚动显示,当高度无法显示全部内容时垂直滚动显示,只按照一个方向左右或者上下滚动显示,水平滚动优先
LABEL_SCROLL_CIRCULAR, // 当宽度无法显示全部内容时水平滚动显示,当高度无法显示全部内容时垂直滚动显示,只按照一个方向循环滚动显示,水平滚动优先
LABEL_CLIP, // 将无法显示的内容裁剪掉
}ips200pro_label_mode_enum;
typedef enum
{
IPS200PRO_PORTRAIT = 0x01, // 竖屏模式
IPS200PRO_PORTRAIT_180 = 0x02, // 竖屏模式 旋转180
IPS200PRO_CROSSWISE = 0x03, // 横屏模式
IPS200PRO_CROSSWISE_180 = 0x04, // 横屏模式 旋转180
}ips200pro_display_direction_enum;
typedef enum
{
IPS200PRO_TITLE_LEFT = 0x00, // 页面标题显示在左侧 如果不需要显示标题,则将标题高度设置为0即可
IPS200PRO_TITLE_RIGHT = 0x01, // 页面标题显示在右侧
IPS200PRO_TITLE_TOP = 0x02, // 页面标题显示在上侧
IPS200PRO_TITLE_BOTTOM = 0x03, // 页面标题显示在底侧
}ips200pro_title_position_enum;
typedef enum
{
IPS200PRO_CALENDAR_CHINESE = 0x01, // 日历使用中文显示 仅16、20、24号字体支持中文显示
IPS200PRO_CALENDAR_ENGLISH = 0x02, // 日历使用英文显示
}ips200pro_calendar_mode_enum;
typedef enum
{
IMAGE_NULL = 0x00, // 图像为空,用于纯边线显示
IMAGE_GRAYSCALE = 0x03, // 灰度 总钻风、小钻风解压后的图像使用此枚举定义
IMAGE_RGB565, // RGB565彩色 凌瞳使用此枚举定义
}ips200pro_image_type_enum;
typedef enum
{
IMAGE_LINE_TYPE_UINT8 = 0x01, // 线条数据是8位类型
IMAGE_LINE_TYPE_UINT16 = 0x02, // 线条数据是16位类型
}ips200pro_image_line_type_enum;
typedef enum
{
IPS200PRO_FORMAT_GBK = 0x01, // GBK编码,开源库默认的文件都是GBK编码
IPS200PRO_FORMAT_UTF8 = 0x02, // UTF-8编码
}ips200pro_format_enum;
typedef enum
{
METER_ANGLE = 0x01, // 角度指示仪表,可设置字体、背景、边线、刻度、指针的颜色
METER_SPEED, // 速度指示仪表,可设置字体、背景、边线、刻度、指针的颜色
}ips200pro_meter_style_enum;
typedef enum
{
CLOCK_DIGITAL = 0x01, // 数字时钟,可设置字体、背景、边线的颜色
CLOCK_ANALOG, // 指针时钟,可设置字体、背景、边线、刻度、指针的颜色
}ips200pro_clock_style_enum;
// 图像叠加线条 uint8类型的线条结构体
typedef struct
{
uint8 x; // 点的横坐标
uint8 y; // 点的纵坐标
}ips200pro_image_line_uint8_struct;
// 图像叠加线条 uint16类型的线条结构体
typedef struct
{
uint16 x; // 点的横坐标
uint16 y; // 点的纵坐标
}ips200pro_image_line_uint16_struct;
typedef struct
{
uint16 id; // 屏幕ID编号
uint16 width; // 屏幕最大显示宽度
uint16 height; // 屏幕最大显示高度
uint8 version_major; // 固件版本-主版本
uint8 version_middle; // 固件版本-中版本
uint8 version_micro; // 固件版本-微版本
}ips200pro_information_struct;
typedef struct
{
uint16 year; // 年
uint8 month; // 月
uint8 day; // 日
uint8 hour; // 时
uint8 minute; // 分
uint8 second; // 秒
uint8 week; // 星期
}ips200pro_time_struct;
extern ips200pro_information_struct ips200pro_information;
extern ips200pro_time_struct ips200pro_time;
//------------------------------------功能函数一览表-------------------------------------------
//------------------------------------系统功能函数-------------------------------------------
// uint8 ips200pro_set_date (uint16 year, uint8 month, uint8 day); // 设置系统日期
// uint8 ips200pro_set_time (uint8 hour, uint8 minute, uint8 second); // 设置系统时间
// uint8 ips200pro_set_parent (uint16 child_id, uint16 parent_id); // 设置组件父对象
// uint8 ips200pro_set_format (ips200pro_format_enum format); // 设置汉字编码格式
// uint8 ips200pro_set_backlight (uint8 backlight); // 设置屏幕背光亮度
// uint8 ips200pro_set_direction (ips200pro_display_direction_enum dir); // 设置屏幕显示方向
// uint8 ips200pro_set_default_font (ips200pro_font_size_enum font); // 设置默认字体大小
// uint8 ips200pro_set_optimize (uint8 state) // 设置优化(默认是开启的)
//
// uint8 ips200pro_get_date (ips200pro_time_struct *time); // 获取系统日期
// uint8 ips200pro_get_time (ips200pro_time_struct *time); // 获取系统时间
// uint8 ips200pro_get_information (ips200pro_information_struct *information); // 获取系统信息
// uint8 ips200pro_get_free_stack_size (uint32 *stack_size); // 获取系统空闲栈大小
//-----------------------------------通用函数接口-------------------------------------------
// uint8 ips200pro_delete_widgets (uint16 widgets_id); // 删除组件
// uint8 ips200pro_set_font (uint16 widgets_id, ips200pro_font_size_enum font_size); // 设置组件的字体
// uint8 ips200pro_set_color (uint16 widgets_id, ips200pro_widgets_color_type_enum color_type, uint16 color); // 设置组件颜色
// uint8 ips200pro_set_position (uint16 widgets_id, int16 x, int16 y); // 设置组件位置
// uint8 ips200pro_set_hidden (uint16 widgets_id, uint8 state); // 设置组件隐藏
//-----------------------------------PAGE页面操作接口-------------------------------------------
// uint16 ips200pro_page_create (char *str); // 页面创建
// uint8 ips200pro_page_switch (uint16 page_id, ips200pro_page_animations_enum anim_en); // 页面切换
// uint8 ips200pro_page_hidden (uint16 page_id, uint8 state) // 页面隐藏
// uint8 ips200pro_page_set_title_name (uint16 page_id, char *str); // 页面标题设置
//-----------------------------------文本标签操作接口-------------------------------------------
// uint16 ips200pro_label_create (int16 x, int16 y, uint16 width, uint16 height); // 文本标签创建
// uint8 ips200pro_label_printf (uint16 label_id, const char *format, ...); // 文本标签内容设置
// uint8 ips200pro_label_show_string (uint16 label_id, const char *str) // 文本标签字符串显示
// uint8 ips200pro_label_mode (uint16 label_id, ips200pro_label_mode_enum mode); // 文本标签模式设置
//-----------------------------------表格TABLE操作接口-------------------------------------------
// uint16 ips200pro_table_create (int16 x, int16 y, uint16 row_num, uint16 col_num); // 表格创建
// uint8 ips200pro_table_cell_printf (uint16 table_id, uint8 row, uint8 col, char *format, ...); // 表格单元格内容设置
// uint8 ips200pro_table_set_col_width (uint16 table_id, uint8 col, uint16 width); // 表格列宽度设置
// uint8 ips200pro_table_select (uint16 table_id, uint8 row, uint8 col); // 单元格选中
//-----------------------------------仪表指示器操作接口-------------------------------------------
// uint16 ips200pro_meter_create (int16 x, int16 y, uint16 size, ips200pro_meter_style_enum style); // 仪表创建
// uint8 ips200pro_meter_set_value (uint16 meter_id, int16 value); // 仪表数值设置
//-----------------------------------时钟操作接口-------------------------------------------
// uint16 ips200pro_clock_create (int16 x, int16 y, uint16 clock_size, ips200pro_clock_style_enum clock_type) // 时钟创建
//-----------------------------------进度条操作接口-------------------------------------------
// uint16 ips200pro_progress_bar_create (int16 x, int16 y, uint16 width, uint16 height); // 进度条创建
// uint8 ips200pro_progress_bar_set_value (uint16 progress_bar_id, uint8 start_value, uint8 end_value); // 进度条数值设置
//-----------------------------------日历操作接口-------------------------------------------
// uint16 ips200pro_calendar_create (int16 x, int16 y, uint16 width, uint16 height); // 日历创建
// uint8 ips200pro_calendar_display (uint16 year, uint8 month, uint8 ips200pro_calendar_mode_enum); // 日历显示设置
//-----------------------------------波形图操作接口-------------------------------------------
// uint16 ips200pro_waveform_create (int16 x, int16 y, uint16 width, uint16 height); // 波形图创建
// uint8 ips200pro_waveform_add_value (uint16 waveform_id, uint8 line_id, const uint16 *data, uint16 length, uint16 color); // 波形图添加数据
// uint8 ips200pro_waveform_line_state (uint16 waveform_id, uint16 line_id, uint16 line_state); // 波形图线条状态设置
// uint8 ips200pro_waveform_line_type (uint16 waveform_id, uint8 line_type); // 波形图线条类型设置
// uint8 ips200pro_waveform_clear (uint16 waveform_id); // 波形图数据清空
//-----------------------------------图像操作接口-------------------------------------------
// uint16 ips200pro_image_create (int16 x, int16 y, uint16 width, uint16 height); // 图像组件创建
// uint8 ips200pro_image_display (image_id, *image, width, height, image_type, threshold); // 图像数据更新
// uint8 ips200pro_image_draw_line (image_id, line_id, *line_data, line_length, data_type, color); // 图像上画线 先发送ips200pro_image_draw_line再发送ips200pro_image_display
// uint8 ips200pro_image_draw_rectangle (image_id, rectangle_id, x, y, rectangle_width, rectangle_height, color); // 图像上画框 先发送ips200pro_image_draw_rectangle再发送ips200pro_image_display
//-----------------------------------容器操作接口-------------------------------------------
// uint16 ips200pro_container_create (int16 x, int16 y, uint16 width, uint16 height); // 容器组件创建
// uint8 ips200pro_container_radius (uint16 container_id, uint16 border_width, uint16 radius); // 设置容器的边线宽度与圆角半径
//-----------------------------------屏幕初始化-------------------------------------------
// uint16 ips200pro_init (char *str, ips200pro_title_position_enum title_position, uint8 title_size); // 屏幕初始化
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 设置系统日期
// 参数说明 year 年
// 参数说明 month 月
// 参数说明 day 日
// 返回参数 uint8 状态 0:设置成功 1:设置失败
// 使用示例 ips200pro_set_date(2024, 10, 31); // 2024年10月31日
//-------------------------------------------------------------------------------------------------------------------
uint8 ips200pro_set_date (uint16 year, uint8 month, uint8 day);
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 设置系统时间
// 参数说明 hour 时 24小时制(仅支持24小时制)
// 参数说明 minute 分
// 参数说明 second 秒
// 返回参数 uint8 状态 0:设置成功 1:设置失败
// 使用示例 ips200pro_set_time(13, 19, 15); // 13点19分15秒
//-------------------------------------------------------------------------------------------------------------------
uint8 ips200pro_set_time (uint8 hour, uint8 minute, uint8 second);
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 设置组件父对象
// 参数说明 child_id 子组件ID
// 参数说明 parent_id 父组件ID
// 返回参数 uint8 状态 0:设置成功 1:设置失败
// 使用示例 ips200pro_set_parent(1, label_id, container_id); // 将label显示到容器上 设置后label的坐标原点为容器的左上角,不再是屏幕的左上角,并且超出容器范围的内容不会进行显示
//-------------------------------------------------------------------------------------------------------------------
uint8 ips200pro_set_parent (uint16 child_id, uint16 parent_id);
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 设置中文编码格式
// 参数说明 format 中文编码格式
// 返回参数 uint8 状态 0:设置成功 1:设置失败
// 使用示例 ips200pro_set_format(IPS200PRO_FORMAT_GBK); // 将ID为1的表格显示在ID为2的页面上
//-------------------------------------------------------------------------------------------------------------------
uint8 ips200pro_set_format (ips200pro_format_enum format);
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 设置背光亮度
// 参数说明 backlight 亮度1-255
// 返回参数 uint8 状态 0:设置成功 1:设置失败
// 使用示例 ips200pro_set_backlight(100); // 背光亮度设置为100
//-------------------------------------------------------------------------------------------------------------------
uint8 ips200pro_set_backlight (uint8 backlight);
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 设置屏幕显示方向
// 参数说明 dir 亮度1-255
// 返回参数 uint8 状态 0:设置成功 1:设置失败
// 使用示例 ips200pro_set_backlight(100); // 背光亮度设置为100
//-------------------------------------------------------------------------------------------------------------------
uint8 ips200pro_set_direction (ips200pro_display_direction_enum dir);
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 设置默认字体大小
// 参数说明 font 默认字体大小
// 返回参数 uint8 状态 0:设置成功 1:设置失败
// 使用示例 ips200pro_set_default_font(FONT_SIZE_20); // 将默认字体设置为20号
//-------------------------------------------------------------------------------------------------------------------
uint8 ips200pro_set_default_font (ips200pro_font_size_enum font);
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 设置优化(默认为开启状态)
// 参数说明 font 默认字体大小
// 返回参数 uint8 状态 0:关闭优化 1:开启优化
// 使用示例 ips200pro_set_optimize(1); // 开启优化
// 备注说明 目前仅针对图像进行优化,当开启优化时,发送图像给屏幕进行显示,如果屏幕正在显示上次的图像,则本次图像直接丢弃,这样避免用户等待指令响应完成,从而尽量避免用户程序等待的问题
// 如果关闭优化,则等待上次图像显示完成之后,再处理新的图像
//-------------------------------------------------------------------------------------------------------------------
uint8 ips200pro_set_optimize (uint8 state);
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 获取系统日期
// 参数说明 *time 保存时间的指针
// 返回参数 uint8 状态 0:设置成功 1:设置失败
// 使用示例 ips200pro_get_date(&ips200pro_time); //
//-------------------------------------------------------------------------------------------------------------------
uint8 ips200pro_get_date (ips200pro_time_struct *time);
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 获取系统时间
// 参数说明 *time 保存时间的指针
// 返回参数 uint8 状态 0:设置成功 1:设置失败
// 使用示例 ips200pro_get_time(&ips200pro_time); //
//-------------------------------------------------------------------------------------------------------------------
uint8 ips200pro_get_time (ips200pro_time_struct *time);
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 获取空闲栈大小
// 参数说明 *information 保存系统信息的指针
// 返回参数 uint8 状态 0:设置成功 1:设置失败
// 使用示例 ips200pro_get_information(&ips200pro_information); //
//-------------------------------------------------------------------------------------------------------------------
uint8 ips200pro_get_information (ips200pro_information_struct *information);
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 获取系统信息
// 参数说明 *stack_size 保存空闲栈大小的指针
// 返回参数 uint8 状态 0:设置成功 1:设置失败
// 使用示例 ips200pro_get_free_stack_size(&stack_size); //
//-------------------------------------------------------------------------------------------------------------------
uint8 ips200pro_get_free_stack_size (uint32 *stack_size);
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 删除组件
// 参数说明 widgets_id 组件的编号
// 返回参数 uint8 状态 0:设置成功 1:设置失败
// 使用示例 ips200pro_delete_widgets(widgets_id); // 将选中的组件删除
//-------------------------------------------------------------------------------------------------------------------
uint8 ips200pro_delete_widgets (uint16 widgets_id);
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 设置组件字体大小
// 参数说明 widgets_id 组件的编号
// 参数说明 font_size 字体大小(仅16 20 24号字体支持中文显示)
// 返回参数 uint8 状态 0:设置成功 1:设置失败
// 使用示例 ips200pro_set_font(widgets_id, FONT_SIZE_20); // 将选中的组件字体大小设置为20号
//-------------------------------------------------------------------------------------------------------------------
uint8 ips200pro_set_font (uint16 widgets_id, ips200pro_font_size_enum font_size);
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 组件颜色设置
// 参数说明 widgets_id 组件的编号
// 参数说明 color_type 颜色类型
// 参数说明 color RGB565数值
// 返回参数 uint8 状态 0:设置成功 1:设置失败
// 使用示例 ips200pro_set_color(widgets_id, COLOR_BORDER, RGB565_RED); // 将选中的组件边线颜色设置为红色
//-------------------------------------------------------------------------------------------------------------------
uint8 ips200pro_set_color (uint16 widgets_id, ips200pro_widgets_color_type_enum color_type, uint16 color);
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 组件位置设置
// 参数说明 widgets_id 组件的编号
// 参数说明 x 左上角横轴坐标(以像素为单位)
// 参数说明 y 左上角纵轴坐标(以像素为单位)
// 返回参数 uint8 状态 0:设置成功 1:设置失败
// 使用示例 ips200pro_set_position(widgets_id, 10, 10); // 将选中的组件起始坐标设置为10,10
//-------------------------------------------------------------------------------------------------------------------
uint8 ips200pro_set_position (uint16 widgets_id, int16 x, int16 y);
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 组件隐藏设置
// 参数说明 widgets_id 组件的编号
// 参数说明 state 0:取消隐藏 1:将组件隐藏
// 返回参数 uint8 状态 0:设置成功 1:设置失败
// 使用示例 ips200pro_set_hidden(widgets_id, 1); // 将选中的组件隐藏显示
//-------------------------------------------------------------------------------------------------------------------
uint8 ips200pro_set_hidden (uint16 widgets_id, uint8 state);
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 创建页面
// 参数说明 *str 页面名称 不需要名称可以直接填写 ""
// 返回参数 uint16 状态 0:创建失败 其他:创建成功,同时返回的数值表示此PAGE的ID
// 使用示例 uint16 page1_id = ips200pro_page_create("Test"); // 创建一个名称为Test的页面
//-------------------------------------------------------------------------------------------------------------------
uint16 ips200pro_page_create (char *str);
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 切换页面
// 参数说明 page_id 页面ID
// 参数说明 anim_en 动画使能
// 返回参数 uint8 状态 0:设置成功 1:设置失败
// 使用示例 ips200pro_page_switch(page_id, PAGE_ANIM_ON); // 切换到选中的页面进行显示 开启动画效果
//-------------------------------------------------------------------------------------------------------------------
uint8 ips200pro_page_switch (uint16 page_id, ips200pro_page_animations_enum anim_en);
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 隐藏页面
// 参数说明 page_id 页面ID
// 参数说明 state 隐藏状态 1:将页面隐藏 0:取消隐藏
// 返回参数 uint8 状态 0:设置成功 1:设置失败
// 使用示例 ips200pro_page_hidden(page_id, 1); // 将选中的页面隐藏
// 注意事项 ID设置为0,则表示对所有的页面同时进行设置
//-------------------------------------------------------------------------------------------------------------------
uint8 ips200pro_page_hidden (uint16 page_id, uint8 state);
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 设置页面名称
// 参数说明 page_id 页面ID
// 参数说明 *str 页面名称
// 返回参数 uint8 状态 0:设置成功 1:设置失败
// 使用示例 ips200pro_page_set_title_name(page_id, "Test"); // 将选中的页面,名称设置为Test
//-------------------------------------------------------------------------------------------------------------------
uint8 ips200pro_page_set_title_name (uint16 page_id, char *str);
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 创建文本标签
// 参数说明 x 左上角横轴坐标(以像素为单位)
// 参数说明 y 左上角纵轴坐标(以像素为单位)
// 参数说明 width 组件的宽度
// 参数说明 height 组件的高度
// 返回参数 uint16 状态 0:创建失败 其他:创建成功,同时返回的数值表示此PAGE的ID
// 使用示例 uint16 label_id = ips200pro_label_create(0, 0, 50, 20); // 创建一个文本标签 左上角坐标0,0 宽度50 高度20
//-------------------------------------------------------------------------------------------------------------------
uint16 ips200pro_label_create (int16 x, int16 y, uint16 width, uint16 height);
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 文本标签格式化并显示
// 参数说明 label_id 文本标签ID
// 参数说明 *format 字符串
// 参数说明 ... 可变参数列表,方法与printf相同
// 返回参数 uint8 状态 0:成功 1:失败
// 使用示例 ips200pro_label_printf(label_id, "tset=%d", test);
//-------------------------------------------------------------------------------------------------------------------
uint8 ips200pro_label_printf (uint16 label_id, const char *format, ...);
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 文本标签字符串显示
// 参数说明 label_id 文本标签ID
// 参数说明 *str 字符串首地址
// 返回参数 uint8 状态 0:成功 1:失败
// 使用示例 ips200pro_label_show_string(label_id, “This is a test”);
//-------------------------------------------------------------------------------------------------------------------
uint8 ips200pro_label_show_string(uint16 label_id, const char *str);
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 设置文本标签长文本模式
// 参数说明 label_id 文本标签ID
// 参数说明 mode 长文本模式,当文本超过组件可显示范围时的处理方式
// 返回参数 uint8 状态 0:成功 1:失败
// 使用示例 ips200pro_label_mode(label_id, "tset=%d", test);
//-------------------------------------------------------------------------------------------------------------------
uint8 ips200pro_label_mode (uint16 label_id, ips200pro_label_mode_enum mode);
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 创建表格标签
// 参数说明 x 左上角横轴坐标(以像素为单位)
// 参数说明 y 左上角纵轴坐标(以像素为单位)
// 参数说明 row_num 表格行数量
// 参数说明 col_num 表格列数量
// 返回参数 uint16 状态 0:创建失败 其他:创建成功,同时返回的数值表示此PAGE的ID
// 使用示例 uint16 table2_id = ips200pro_table_create(0, 0, 5, 4); // 创建5行4列表格 左上角坐标0,0,如需调整宽度使用ips200pro_table_set_col_width函数单独调整
//-------------------------------------------------------------------------------------------------------------------
uint16 ips200pro_table_create (int16 x, int16 y, uint16 row_num, uint16 col_num);
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 单元格格式化并显示
// 参数说明 table_id 表格ID
// 参数说明 row 单元格所在行 行号从1开始
// 参数说明 col 单元格所在列 列号从1开始
// 参数说明 *format 字符串
// 参数说明 ... 可变参数列表,方法与printf相同
// 返回参数 uint8 状态 0:成功 1:失败
// 使用示例 ips200pro_label_printf(table_id, 1, 1, "tset=%d", test); // 格式化字符串,并显示在表格的第一行 第一列(即左上角的单元格)
//-------------------------------------------------------------------------------------------------------------------
uint8 ips200pro_table_cell_printf (uint16 table_id, uint8 row, uint8 col, char *format, ...);
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 设置表格列宽度
// 参数说明 table_id 表格ID
// 参数说明 col 需要调整的列号 列号从1开始
// 参数说明 width 列宽度(以像素为单位)
// 返回参数 uint8 状态 0:成功 1:失败
// 使用示例 ips200pro_table_set_col_width(table_id, 1, 20); // 将选中的表格 的第一列(即最左侧的一列)宽度设置为20
//-------------------------------------------------------------------------------------------------------------------
uint8 ips200pro_table_set_col_width (uint16 table_id, uint8 col, uint16 width);
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 表格选中
// 参数说明 table_id 表格ID
// 参数说明 row 需要选中的行号 行号从1开始
// 参数说明 col 需要选中的列号 列号从1开始
// 返回参数 uint8 状态 0:成功 1:失败
// 使用示例 ips200pro_table_select(table_id, 1, 2); // 将选中的表格 的第一行、第一列(即最左上角)选中
// 备注说明 选中整列:指定col row设置为0x00 选中整行:指定row col设置为0x00 取消选中row col都设置为0x00
//-------------------------------------------------------------------------------------------------------------------
uint8 ips200pro_table_select (uint16 table_id, uint8 row, uint8 col);
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 创建仪表指示器
// 参数说明 x 左上角横轴坐标(以像素为单位)
// 参数说明 y 左上角纵轴坐标(以像素为单位)
// 参数说明 size 仪表直径(以像素为单位)
// 参数说明 style 仪表样式
// 返回参数 uint16 状态 0:创建失败 其他:创建成功,同时返回的数值表示此PAGE的ID
// 使用示例 uint16 table2_id = ips200pro_meter_create(0, 0, 60, 1); // 1:角度指示器 2:速度指示器
//-------------------------------------------------------------------------------------------------------------------
uint16 ips200pro_meter_create (int16 x, int16 y, uint16 size, ips200pro_meter_style_enum style);
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 仪表指示器数值设置
// 参数说明 meter_id 仪表ID
// 参数说明 value 数值 角度类型数值范围0-360 速度类型设置范围0-100
// 返回参数 uint8 状态 0:成功 1:失败
// 使用示例 ips200pro_meter_set_value(meter_id, 50); // 将选中的仪表数值设置为50
//-------------------------------------------------------------------------------------------------------------------
uint8 ips200pro_meter_set_value (uint16 meter_id, int16 value);
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 创建时钟
// 参数说明 x 左上角横轴坐标(以像素为单位)
// 参数说明 y 左上角纵轴坐标(以像素为单位)
// 参数说明 clock_size 时钟大小,数字时钟时:表示字体大小,可设置范围查看ips200pro_font_size_enum枚举体
// 指针时钟:表示时钟的直径,最小设置为80,最大240
// 参数说明 clock_type 时钟类型查看ips200pro_clock_style_enum枚举定义
// 返回参数 uint16 状态 0:创建失败 其他:创建成功,同时返回的数值表示此PAGE的ID
// 使用示例 uint16 clock2_id = ips200pro_clock_create(0, 0, 150, CLOCK_ANALOG); //
// 备注说明 当宽度与高度一致时,时钟为圆形指针时钟,否则为数字时钟
// 备注说明 如果需要修改时间,使用ips200pro_set_time函数修改
//-------------------------------------------------------------------------------------------------------------------
uint16 ips200pro_clock_create (int16 x, int16 y, uint16 clock_size, ips200pro_clock_style_enum clock_type);
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 创建进度条
// 参数说明 x 左上角横轴坐标(以像素为单位)
// 参数说明 y 左上角纵轴坐标(以像素为单位)
// 参数说明 width 组件的宽度
// 参数说明 height 组件的高度
// 返回参数 uint16 状态 0:创建失败 其他:创建成功,同时返回的数值表示此PAGE的ID
// 使用示例 uint16 bar2_id = ips200pro_progress_bar_create(0, 0, 60, 10); //
// 备注说明 当宽度与高度一致时,为圆形进度条,否为长条形进度条
//-------------------------------------------------------------------------------------------------------------------
uint16 ips200pro_progress_bar_create (int16 x, int16 y, uint16 width, uint16 height);
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 进度条数值设置
// 参数说明 progress_bar_id 进度条ID
// 参数说明 start_value 开始数值
// 参数说明 end_value 结束数值
// 返回参数 uint8 状态 0:成功 1:失败
// 使用示例 ips200pro_progress_bar_set_value(progress_bar_id, 10, 60); //
//-------------------------------------------------------------------------------------------------------------------
uint8 ips200pro_progress_bar_set_value (uint16 progress_bar_id, uint8 start_value, uint8 end_value);
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 创建日历
// 参数说明 x 左上角横轴坐标(以像素为单位)
// 参数说明 y 左上角纵轴坐标(以像素为单位)
// 参数说明 width 组件的宽度
// 参数说明 height 组件的高度
// 返回参数 uint16 状态 0:创建失败 其他:创建成功,同时返回的数值表示此PAGE的ID
// 使用示例 uint16 test_id = ips200pro_calendar_create(0, 0, 200, 200); //
//-------------------------------------------------------------------------------------------------------------------
uint16 ips200pro_calendar_create (int16 x, int16 y, uint16 width, uint16 height);
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 日历显示设置
// 参数说明 year 需要显示的年份 如果填写0则显示当前日期的月份
// 参数说明 month 需要显示的月份 如果填写0则显示当前日期的月份
// 参数说明 mode 显示模式 中文显示(仅16、20、24号字体支持中文显示)
// 返回参数 uint8 状态 0:成功 1:失败
// 使用示例 ips200pro_calendar_display(2036, 1, IPS200PRO_CALENDAR_CHINESE); // 日历显示2036年1月份 中文显示
//-------------------------------------------------------------------------------------------------------------------
uint8 ips200pro_calendar_display (uint16 year, uint8 month, ips200pro_calendar_mode_enum mode);
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 创建波形图
// 参数说明 x 左上角横轴坐标(以像素为单位)
// 参数说明 y 左上角纵轴坐标(以像素为单位)
// 参数说明 width 组件的宽度
// 参数说明 height 组件的高度
// 返回参数 uint16 状态 0:创建失败 其他:创建成功,同时返回的数值表示此PAGE的ID
// 使用示例 uint16 test_id = ips200pro_waveform_create(0, 0, 200, 200); //
//-------------------------------------------------------------------------------------------------------------------
uint16 ips200pro_waveform_create (int16 x, int16 y, uint16 width, uint16 height);
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 波形图添加点
// 参数说明 waveform_id 波形图组件ID
// 参数说明 line_id 线条ID ID从1开始
// 参数说明 *data 增加的点数据地址
// 参数说明 length 增加的点数量
// 参数说明 color 点颜色
// 返回参数 uint8 状态 0:成功 1:失败
// 使用示例 ips200pro_waveform_add_value(1, 1, &point[0], 10, RGB565_RED); //
// 备注说明 波形图显示的点数量上限为组件宽度,当收到的点数量超过组件宽度时优先显示最近收到的点数据
//-------------------------------------------------------------------------------------------------------------------
uint8 ips200pro_waveform_add_value (uint16 waveform_id, uint8 line_id, const uint16 *data, uint16 length, uint16 color);
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 设置波形图线条状态
// 参数说明 waveform_id 波形图组件ID
// 参数说明 line_id 线条ID 从1开始 最多支持叠加5条线条
// 参数说明 line_state 0:隐藏线条 1:显示线条
// 返回参数 uint8 状态 0:成功 1:失败
// 使用示例 ips200pro_waveform_line_state(waveform_id, 1, 0); //
//-------------------------------------------------------------------------------------------------------------------
uint8 ips200pro_waveform_line_state (uint16 waveform_id, uint16 line_id, uint16 line_state);
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 设置波形图线条类型
// 参数说明 waveform_id 波形图组件ID
// 参数说明 line_type 线条类型 0:散点图(点与点之间没有连线) 1:(所有的点连成一条线)
// 返回参数 uint8 状态 0:成功 1:失败
// 使用示例 ips200pro_waveform_line_type(waveform_id, 0); //
//-------------------------------------------------------------------------------------------------------------------
uint8 ips200pro_waveform_line_type (uint16 waveform_id, uint8 line_type);
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 波形图清除数据(即清空显示)
// 参数说明 waveform_id 波形图组件ID
// 返回参数 uint8 状态 0:成功 1:失败
// 使用示例 ips200pro_waveform_clear(waveform_id); //
//-------------------------------------------------------------------------------------------------------------------
uint8 ips200pro_waveform_clear (uint16 waveform_id);
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 创建图像组件
// 参数说明 x 左上角横轴坐标(以像素为单位)
// 参数说明 y 左上角纵轴坐标(以像素为单位)
// 参数说明 width 组件的宽度
// 参数说明 height 组件的高度
// 返回参数 uint16 状态 0:创建失败 其他:创建成功,同时返回的数值表示此PAGE的ID
// 使用示例 uint16 test_id = ips200pro_image_create(0, 0, 188, 120); //
//-------------------------------------------------------------------------------------------------------------------
uint16 ips200pro_image_create (int16 x, int16 y, uint16 width, uint16 height);
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 图像显示
// 参数说明 image_id 图像组件ID
// 参数说明 *image 图像地址 NULL则不发送图像,仅通知屏幕更新边线或矩形
// 参数说明 width 图像宽度 0则不发送图像数据,仅通知屏幕更新边线或矩形
// 参数说明 height 图像高度 0则不发送图像数据,仅通知屏幕更新边线或矩形
// 参数说明 image_type 图像类型 总钻风:IMAGE_GRAYSCALE 凌瞳:IMAGE_RGB565 小钻风:需要自行解压后选择IMAGE_GRAYSCALE IMAGE_NULL:不发送图像数据,仅通知屏幕更新边线或矩形
// 参数说明 threshold 二值化阈值 仅在IMAGE_GRAYSCALE(灰度)模式下有效 0:不启用二值化 其他:启用二值化
// 返回参数 uint8 状态 0:成功 1:失败
// 使用示例 ips200pro_image_display(image_id, mt9v03x_image[0], 188, 120, IMAGE_GRAYSCALE, 0); //
// 备注说明 如果图像宽度、高度与组件的宽度、高度不一致,则会自动缩放,但是缩放会导致屏幕性能下降,从而可能导致显示帧率下降
//-------------------------------------------------------------------------------------------------------------------
uint8 ips200pro_image_display (uint16 image_id, const void *image, uint16 width, uint16 height, ips200pro_image_type_enum image_type, uint8 threshold);
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 图像叠加线条
// 参数说明 image_id 图像组件ID
// 参数说明 line_id 线条ID 从1开始 最多支持叠加10条线条
// 参数说明 *line_data 线条数据地址 只能使用ips200pro_image_line_uint8_struct或者ips200pro_image_line_uint16_struct类型
// 参数说明 line_length 线条长度
// 参数说明 data_type 线条的数据类型 8为类型与16为类型
// 参数说明 color 线条颜色
// 返回参数 uint8 状态 0:成功 1:失败
// 使用示例 ips200pro_image_draw_line(image_id, 1, line, 120, IMAGE_LINE_TYPE_UINT8, RGB565_RED); //
// 备注说明 务必在ips200pro_image_display调用函数之前 调用本函数才能实现线条叠加显示
//-------------------------------------------------------------------------------------------------------------------
uint8 ips200pro_image_draw_line (uint16 image_id, uint8 line_id, void *line_data, uint16 line_length, ips200pro_image_line_type_enum data_type, uint16 color);
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 图像叠加矩形框
// 参数说明 image_id 图像组件ID
// 参数说明 rectangle_id 矩形框ID 从1开始 最多支持叠加5个矩形框
// 参数说明 x 矩形框左上角横坐标
// 参数说明 y 矩形框左上角纵坐标
// 参数说明 rectangle_width 矩形宽度
// 参数说明 rectangle_height 矩形高度
// 参数说明 color 线条颜色
// 返回参数 uint8 状态 0:成功 1:失败
// 使用示例 ips200pro_image_draw_rectangle(image_id, 1, 10, 10, 20, 30, RGB565_RED); //
// 备注说明 务必在ips200pro_image_display调用函数之前 调用本函数才能实现矩形框叠加显示
//-------------------------------------------------------------------------------------------------------------------
uint8 ips200pro_image_draw_rectangle (uint16 image_id, uint8 rectangle_id, int16 x, int16 y, uint16 rectangle_width, uint16 rectangle_height, uint16 color);
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 创建容器组件
// 参数说明 x 左上角横轴坐标(以像素为单位)
// 参数说明 y 左上角纵轴坐标(以像素为单位)
// 参数说明 width 组件的宽度
// 参数说明 height 组件的高度
// 返回参数 uint16 状态 0:创建失败 其他:创建成功,同时返回的数值表示此PAGE的ID
// 使用示例 uint16 test_id = ips200pro_container_create(0, 0, 60, 60); //
//-------------------------------------------------------------------------------------------------------------------
uint16 ips200pro_container_create (int16 x, int16 y, uint16 width, uint16 height);
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 设置容器圆角半径
// 参数说明 container_id 容器的ID
// 参数说明 border_width 容器周围边线宽度
// 参数说明 radius 容器圆角半径
// 返回参数 uint8 状态 0:创建失败 其他:创建成功,同时返回的数值表示此PAGE的ID
// 使用示例 ips200pro_container_radius(container_id, 1, 10); // 将选择的容器 线条宽度设置为1,圆角半径设置为10
// 注意事项 如果容器为宽度高度相同,圆角半径是高度的一半,则最终容易为圆形
//-------------------------------------------------------------------------------------------------------------------
uint8 ips200pro_container_radius (uint16 container_id, uint16 border_width, uint16 radius);
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 屏幕初始化
// 参数说明 str 页面标题名称 NULL:不创建页面 不为空:则创建一个页面,并将此字符串设置为页面名称
// 参数说明 title_position 标题显示的位置
// 参数说明 title_size 标题大小 如果不需要标题设置为0即可
// 返回参数 uint16 页面ID
// 使用示例 ips200pro_init("测试", IPS200PRO_TITLE_BOTTOM, 30); // 初始化屏幕并创建一个标题为测试的页面、标题显示在底部、标题宽度为30
//-------------------------------------------------------------------------------------------------------------------
uint16 ips200pro_init (char *str, ips200pro_title_position_enum title_position, uint8 title_size);
#endif
+148
View File
@@ -0,0 +1,148 @@
/*********************************************************************************************************************
* MSPM0G3507 Opensource Library 即(MSPM0G3507 开源库)是一个基于官方 SDK 接口的第三方开源库
* Copyright (c) 2022 SEEKFREE 逐飞科技
*
* 本文件是 MSPM0G3507 开源库的一部分
*
* MSPM0G3507 开源库 是免费软件
* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款
* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它
*
* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证
* 甚至没有隐含的适销性或适合特定用途的保证
* 更多细节请参见 GPL
*
* 您应该在收到本开源库的同时收到一份 GPL 的副本
* 如果没有,请参阅<https://www.gnu.org/licenses/>
*
* 额外注明:
* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本
* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中
* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件
* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明)
*
* 文件名称 zf_device_key
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件版本说明
* 开发环境 MDK 5.37
* 适用平台 MSPM0G3507
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2025-06-1 SeekFree first version
********************************************************************************************************************/
/*********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* // 一般是主板按键对应的引脚
* KEY1/S1 查看 zf_device_key.h 中 KEY_LIST[0]
* KEY2/S2 查看 zf_device_key.h 中 KEY_LIST[1]
* KEY3/S3 查看 zf_device_key.h 中 KEY_LIST[2]
* KEY4/S4 查看 zf_device_key.h 中 KEY_LIST[3]
* ------------------------------------
********************************************************************************************************************/
#include "zf_common_debug.h"
#include "zf_device_key.h"
static uint32 scanner_period = 0; // 按键的扫描周期
static uint32 key_press_time[KEY_NUMBER]; // 按键信号持续时长
static key_state_enum key_state[KEY_NUMBER]; // 按键状态
static const gpio_pin_enum key_index[KEY_NUMBER] = KEY_LIST;
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 按键状态扫描
// 参数说明 void
// 返回参数 void
// 使用示例 key_scanner();
// 备注信息 这个函数放在主循环或者 PIT 中断中
//-------------------------------------------------------------------------------------------------------------------
void key_scanner (void)
{
uint8 i = 0;
for(i = 0; KEY_NUMBER > i; i ++)
{
if(KEY_RELEASE_LEVEL != gpio_get_level(key_index[i])) // 按键按下
{
key_press_time[i] += scanner_period;
if(KEY_LONG_PRESS_PERIOD <= key_press_time[i])
{
key_state[i] = KEY_LONG_PRESS;
}
}
else // 按键释放
{
if((KEY_LONG_PRESS != key_state[i]) && (KEY_MAX_SHOCK_PERIOD <= key_press_time[i]) && (KEY_LONG_PRESS_PERIOD > key_press_time[i]))
{
key_state[i] = KEY_SHORT_PRESS;
}
else
{
key_state[i] = KEY_RELEASE;
}
key_press_time[i] = 0;
}
}
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 获取按键状态
// 参数说明 key_n 按键索引
// 返回参数 key_state_enum 按键状态
// 使用示例 key_get_state(KEY_1);
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
key_state_enum key_get_state (key_index_enum key_n)
{
return key_state[key_n];
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 清除对应按键状态
// 参数说明 key_n 按键索引
// 返回参数 void 无
// 使用示例 key_clear_state(KEY_1);
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
void key_clear_state (key_index_enum key_n)
{
key_state[key_n] = KEY_RELEASE;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 清除所有按键状态
// 参数说明 void 无
// 返回参数 void 无
// 使用示例 key_clear_all_state();
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
void key_clear_all_state (void)
{
key_state[0] = KEY_RELEASE;
key_state[1] = KEY_RELEASE;
key_state[2] = KEY_RELEASE;
key_state[3] = KEY_RELEASE;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 按键初始化
// 参数说明 period 按键扫描周期 以毫秒为单位
// 返回参数 void
// 使用示例 key_init(10);
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
void key_init (uint32 period)
{
zf_assert(0 < period);
uint8 loop_temp = 0;
for(loop_temp = 0; KEY_NUMBER > loop_temp; loop_temp ++)
{
gpio_init(key_index[loop_temp], GPI, GPIO_HIGH, GPI_PULL_UP);
key_state[loop_temp] = KEY_RELEASE;
}
scanner_period = period;
}
+85
View File
@@ -0,0 +1,85 @@
/*********************************************************************************************************************
* MSPM0G3507 Opensource Library 即(MSPM0G3507 开源库)是一个基于官方 SDK 接口的第三方开源库
* Copyright (c) 2022 SEEKFREE 逐飞科技
*
* 本文件是 MSPM0G3507 开源库的一部分
*
* MSPM0G3507 开源库 是免费软件
* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款
* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它
*
* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证
* 甚至没有隐含的适销性或适合特定用途的保证
* 更多细节请参见 GPL
*
* 您应该在收到本开源库的同时收到一份 GPL 的副本
* 如果没有,请参阅<https://www.gnu.org/licenses/>
*
* 额外注明:
* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本
* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中
* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件
* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明)
*
* 文件名称 zf_device_key
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件版本说明
* 开发环境 MDK 5.37
* 适用平台 MSPM0G3507
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2025-06-1 SeekFree first version
********************************************************************************************************************/
/*********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* // 一般是主板按键对应的引脚
* KEY1/S1 查看 zf_device_key.h 中 KEY_LIST[0]
* KEY2/S2 查看 zf_device_key.h 中 KEY_LIST[1]
* KEY3/S3 查看 zf_device_key.h 中 KEY_LIST[2]
* KEY4/S4 查看 zf_device_key.h 中 KEY_LIST[3]
* ------------------------------------
********************************************************************************************************************/
#ifndef _zf_device_key_h_
#define _zf_device_key_h_
#include "zf_common_debug.h"
#include "zf_driver_gpio.h"
// 定义按键引脚 用户可以新增可以修改 默认定义四个按键
// 定义按键顺序对应下方 key_index_enum 枚举体中定义的顺序
// 如果用户可以新增按键 那么需要同步在下方 key_index_enum 枚举体中新增按键
#define KEY_LIST { A30 , A31 , B0 , B1 }
#define KEY_RELEASE_LEVEL (GPIO_HIGH) // 按键的默认状态 也就是按键释放状态的电平
#define KEY_MAX_SHOCK_PERIOD (10 ) // 按键消抖检测时长 单位毫秒 低于这个时长的信号会被认为是杂波抖动
#define KEY_LONG_PRESS_PERIOD (1000 ) // 最小长按时长 单位毫秒 高于这个时长的信号会被认为是长按动作
typedef enum
{
KEY_1,
KEY_2,
KEY_3,
KEY_4,
KEY_NUMBER,
}key_index_enum; // 按键索引 对应上方定义的按键引脚个数 默认定义四个按键
typedef enum
{
KEY_RELEASE, // 按键释放状态
KEY_SHORT_PRESS, // 按键短按状态
KEY_LONG_PRESS, // 按键长按状态
}key_state_enum;
void key_scanner (void);
key_state_enum key_get_state (key_index_enum key_n);
void key_clear_state (key_index_enum key_n);
void key_clear_all_state (void);
void key_init (uint32 period);
#endif
+763
View File
@@ -0,0 +1,763 @@
/*********************************************************************************************************************
* TC264 Opensourec Library 即(TC264 开源库)是一个基于官方 SDK 接口的第三方开源库
* Copyright (c) 2022 SEEKFREE 逐飞科技
*
* 本文件是 TC264 开源库的一部分
*
* TC264 开源库 是免费软件
* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款
* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它
*
* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证
* 甚至没有隐含的适销性或适合特定用途的保证
* 更多细节请参见 GPL
*
* 您应该在收到本开源库的同时收到一份 GPL 的副本
* 如果没有,请参阅<https://www.gnu.org/licenses/>
*
* 额外注明:
* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本
* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中
* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件
* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明)
*
* 文件名称 zf_device_oled
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 ADS v1.10.2
* 适用平台 TC264D
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2022-09-15 pudding first version
* 2023-04-28 pudding 增加中文注释说明
********************************************************************************************************************/
/*********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* D0 查看 zf_device_oled.h 中 OLED_D0_PIN 宏定义
* D1 查看 zf_device_oled.h 中 OLED_D1_PIN 宏定义
* RES 查看 zf_device_oled.h 中 OLED_RES_PIN 宏定义
* DC 查看 zf_device_oled.h 中 OLED_DC_PIN 宏定义
* CS 查看 zf_device_oled.h 中 OLED_CS_PIN 宏定义
* VCC 3.3V电源
* GND 电源地
* ------------------------------------
********************************************************************************************************************/
#include "zf_common_debug.h"
#include "zf_common_font.h"
#include "zf_common_function.h"
#include "zf_driver_delay.h"
#include "zf_driver_spi.h"
#include "zf_device_oled.h"
#if OLED_USE_SOFT_SPI
static soft_spi_info_struct oled_spi;
#define oled_spi_write_8bit(data) (soft_spi_write_8bit(&oled_spi, (data)))
#else
#define oled_spi_write_8bit(data) (spi_write_8bit(OLED_SPI, (data)))
#endif
static oled_dir_enum oled_display_dir = OLED_DEFAULT_DISPLAY_DIR; // 显示方向
static oled_font_size_enum oled_display_font = OLED_DEFAULT_DISPLAY_FONT; // 显示字体类型
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 写8位数据
// 参数说明 data 数据
// 返回参数 void
// 使用示例 oled_write_data(color);
// 备注信息 内部调用 用户无需关心
//-------------------------------------------------------------------------------------------------------------------
static void oled_write_data (const uint8 data)
{
OLED_DC(1);
oled_spi_write_8bit(data);
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 写命令
// 参数说明 cmd 命令
// 返回参数 void
// 使用示例 oled_write_command(0xb0 + y);
// 备注信息 内部调用 用户无需关心
//-------------------------------------------------------------------------------------------------------------------
static void oled_write_command (const uint8 command)
{
OLED_DC(0);
oled_spi_write_8bit(command);
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 OLED显示坐标设置
// 参数说明 x x轴坐标设置0-127
// 参数说明 y y轴坐标设置0-7
// 返回参数 void
// 使用示例 oled_set_coordinate(x, y);
// 备注信息 内部使用用户无需关心
//-------------------------------------------------------------------------------------------------------------------
static void oled_set_coordinate (uint8 x, uint8 y)
{
// 如果程序在输出了断言信息 并且提示出错位置在这里
// 那么一般是屏幕显示的时候超过屏幕分辨率范围了
// 检查一下你的显示调用的函数 自己计算一下哪里超过了屏幕显示范围
zf_assert(128 > x);
zf_assert(8 > y);
oled_write_command(0xb0 + y);
oled_write_command(((x & 0xf0) >> 4) | 0x10);
oled_write_command((x & 0x0f) | 0x00);
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 OLED显示DEBUG信息初始化
// 参数说明 void
// 返回参数 void
// 使用示例 oled_debug_init();
// 备注信息 内部使用用户无需关心
//-------------------------------------------------------------------------------------------------------------------
static void oled_debug_init (void)
{
debug_output_struct info;
debug_output_struct_init(&info);
info.type_index = 1;
info.display_x_max = OLED_X_MAX;
info.display_y_max = OLED_Y_MAX;
switch(oled_display_font)
{
case OLED_6X8_FONT:
{
info.font_x_size = 6;
info.font_y_size = 1;
}break;
case OLED_8X16_FONT:
{
info.font_x_size = 8;
info.font_y_size = 2;
}break;
case OLED_16X16_FONT:
{
// 暂不支持
}break;
}
info.output_screen = oled_show_string;
info.output_screen_clear = oled_clear;
debug_output_init(&info);
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 OLED 清屏函数
// 参数说明 void
// 返回参数 void
// 使用示例 oled_clear();
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
void oled_clear (void)
{
uint8 y = 0, x = 0;
OLED_CS(0);
for(y = 0; 8 > y; y ++)
{
oled_write_command(0xb0 + y);
oled_write_command(0x01);
oled_write_command(0x10);
for(x = 0; OLED_X_MAX > x; x ++)
{
oled_write_data(0x00);
}
}
OLED_CS(1);
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 OLED 屏幕填充函数
// 参数说明 color 填充颜色选着(0x00 or 0xff)
// 返回参数 void
// 使用示例 oled_full(0x00);
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
void oled_full (const uint8 color)
{
uint8 y = 0, x = 0;
OLED_CS(0);
for(y = 0; 8 > y; y ++)
{
oled_write_command(0xb0 + y);
oled_write_command(0x01);
oled_write_command(0x10);
for(x = 0; OLED_X_MAX > x; x ++)
{
oled_write_data(color);
}
}
OLED_CS(1);
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 设置显示方向
// 参数说明 dir 显示方向 参照 zf_device_oled.h 内 oled_dir_enum 枚举体定义
// 返回参数 void
// 使用示例 oled_set_dir(OLED_CROSSWISE);
// 备注信息 这个函数只有在初始化屏幕之前调用才生效
//-------------------------------------------------------------------------------------------------------------------
void oled_set_dir (oled_dir_enum dir)
{
oled_display_dir = dir;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 设置显示字体
// 参数说明 dir 显示方向 参照 zf_device_oled.h 内 oled_font_size_enum 枚举体定义
// 返回参数 void
// 使用示例 oled_set_font(OLED_8x16_FONT);
// 备注信息 字体可以随时自由设置 设置后生效 后续显示就是新的字体大小
//-------------------------------------------------------------------------------------------------------------------
void oled_set_font (oled_font_size_enum font)
{
oled_display_font = font;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 画点函数
// 参数说明 x x 轴坐标设置 0-127
// 参数说明 y y 轴坐标设置 0-7
// 参数说明 color 8 个点数据
// 返回参数 void
// 使用示例 oled_draw_point(0, 0, 1);
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
void oled_draw_point (uint16 x, uint16 y, const uint8 color)
{
// 如果程序在输出了断言信息 并且提示出错位置在这里
// 那么一般是屏幕显示的时候超过屏幕分辨率范围了
// 检查一下你的显示调用的函数 自己计算一下哪里超过了屏幕显示范围
zf_assert(x < 128);
zf_assert(y < 8);
OLED_CS(0);
oled_set_coordinate((uint8)x, (uint8)y);
oled_write_command(0xb0 + y);
oled_write_command(((x & 0xf0) >> 4) | 0x10);
oled_write_command((x & 0x0f) | 0x00);
oled_write_data(color);
OLED_CS(1);
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 OLED 显示字符串
// 参数说明 x x 轴坐标设置 0-127
// 参数说明 y y 轴坐标设置 0-7
// 参数说明 ch[] 字符串
// 返回参数 void
// 使用示例 oled_show_string(0, 0, "SEEKFREE");
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
void oled_show_string (uint16 x, uint16 y, const char ch[])
{
// 如果程序在输出了断言信息 并且提示出错位置在这里
// 那么一般是屏幕显示的时候超过屏幕分辨率范围了
// 检查一下你的显示调用的函数 自己计算一下哪里超过了屏幕显示范围
zf_assert(128 > x);
zf_assert(8 > y);
OLED_CS(0);
uint8 c = 0, i = 0, j = 0;
while ('\0' != ch[j])
{
switch(oled_display_font)
{
case OLED_6X8_FONT:
{
c = ch[j] - 32;
if(x > 126)
{
x = 0;
y ++;
}
oled_set_coordinate((uint8)x, (uint8)y);
for(i = 0; 6 > i; i ++)
{
oled_write_data(ascii_font_6x8[c][i]);
}
x += 6;
j ++;
}break;
case OLED_8X16_FONT:
{
c = ch[j] - 32;
if(x > 120)
{
x = 0;
y ++;
}
oled_set_coordinate((uint8)x, (uint8)y);
for(i = 0; 8 > i; i ++)
{
oled_write_data(ascii_font_8x16[c][i]);
}
oled_set_coordinate((uint8)x, (uint8)(y + 1));
for(i = 0; 8 > i; i ++)
{
oled_write_data(ascii_font_8x16[c][i + 8]);
}
x += 8;
j ++;
}break;
case OLED_16X16_FONT:
{
// 暂不支持
}break;
}
}
OLED_CS(1);
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 OLED 显示32位有符号 (去除整数部分无效的0)
// 参数说明 x x轴坐标设置 0-127
// 参数说明 y y轴坐标设置 0-7
// 参数说明 dat 需要显示的变量 数据类型 int32
// 参数说明 num 需要显示的位数 最高10位 不包含正负号
// 返回参数 void
// 使用示例 oled_show_int(0, 0, x, 3); // x 可以为 int32 int16 int8 类型
// 备注信息 负数会显示一个 ‘-’号 正数显示一个空格
//-------------------------------------------------------------------------------------------------------------------
void oled_show_int (uint16 x, uint16 y, const int32 dat, uint8 num)
{
// 如果程序在输出了断言信息 并且提示出错位置在这里
// 那么一般是屏幕显示的时候超过屏幕分辨率范围了
// 检查一下你的显示调用的函数 自己计算一下哪里超过了屏幕显示范围
zf_assert(128 > x);
zf_assert(8 > y);
zf_assert(0 < num);
zf_assert(10 >= num);
int32 dat_temp = dat;
int32 offset = 1;
char data_buffer[12];
memset(data_buffer, 0, 12);
memset(data_buffer, ' ', num + 1);
// 用来计算余数显示 123 显示 2 位则应该显示 23
if(10 > num)
{
for(; 0 < num; num --)
{
offset *= 10;
}
dat_temp %= offset;
}
func_int_to_str(data_buffer, dat_temp);
oled_show_string(x, y, (const char *)&data_buffer);
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 OLED 显示32位无符号 (去除整数部分无效的0)
// 参数说明 x x 轴坐标设置 0-127
// 参数说明 y y 轴坐标设置 0-7
// 参数说明 dat 需要显示的变量 数据类型 uint32
// 参数说明 num 需要显示的位数 最高10位 不包含正负号
// 返回参数 void
// 使用示例 oled_show_uint(0, 0, x, 3); // x 可以为 uint32 uint16 uint8 类型
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
void oled_show_uint (uint16 x,uint16 y,const uint32 dat,uint8 num)
{
// 如果程序在输出了断言信息 并且提示出错位置在这里
// 那么一般是屏幕显示的时候超过屏幕分辨率范围了
// 检查一下你的显示调用的函数 自己计算一下哪里超过了屏幕显示范围
zf_assert(128 > x);
zf_assert(8 > y);
zf_assert(0 < num);
zf_assert(10 >= num);
uint32 dat_temp = dat;
int32 offset = 1;
char data_buffer[12];
memset(data_buffer, 0, 12);
memset(data_buffer, ' ', num);
// 用来计算余数显示 123 显示 2 位则应该显示 23
if(10 > num)
{
for(; 0 < num; num --)
{
offset *= 10;
}
dat_temp %= offset;
}
func_uint_to_str(data_buffer, dat_temp);
oled_show_string(x, y, (const char *)&data_buffer);
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 OLED 显示浮点数 (去除整数部分无效的0)
// 参数说明 x x 轴坐标设置 0-127
// 参数说明 y y 轴坐标设置 0-7
// 参数说明 dat 需要显示的变量 数据类型 double
// 参数说明 num 整数位显示长度 最高8位
// 参数说明 pointnum 小数位显示长度 最高6位
// 返回参数 void
// 使用示例 oled_show_float(0, 0, x, 2, 3); // 显示浮点数 整数显示2位 小数显示三位
// 备注信息 特别注意当发现小数部分显示的值与你写入的值不一样的时候,
// 可能是由于浮点数精度丢失问题导致的,这并不是显示函数的问题,
// 有关问题的详情,请自行百度学习 浮点数精度丢失问题。
// 负数会显示一个 ‘-’号 正数显示一个空格
//-------------------------------------------------------------------------------------------------------------------
void oled_show_float (uint16 x,uint16 y,const double dat,uint8 num,uint8 pointnum)
{
// 如果程序在输出了断言信息 并且提示出错位置在这里
// 那么一般是屏幕显示的时候超过屏幕分辨率范围了
// 检查一下你的显示调用的函数 自己计算一下哪里超过了屏幕显示范围
zf_assert(128 > x);
zf_assert(8 > y);
zf_assert(0 < num);
zf_assert(8 >= num);
zf_assert(0 < pointnum);
zf_assert(6 >= pointnum);
double dat_temp = dat;
double offset = 1.0;
char data_buffer[17];
memset(data_buffer, 0, 17);
memset(data_buffer, ' ', num + pointnum + 2);
// 用来计算余数显示 123 显示 2 位则应该显示 23
for(; 0 < num; num --)
{
offset *= 10;
}
dat_temp = dat_temp - ((int)dat_temp / (int)offset) * offset;
func_double_to_str(data_buffer, dat_temp, pointnum);
oled_show_string(x, y, data_buffer);
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 OLED 显示二值图像 数据每八个点组成一个字节数据
// 参数说明 x x 轴坐标设置 0-127
// 参数说明 y y 轴坐标设置 0-7
// 参数说明 *image 图像数组指针
// 参数说明 width 图像实际宽度
// 参数说明 height 图像实际高度
// 参数说明 dis_width 图像显示宽度 参数范围 [0, 128]
// 参数说明 dis_height 图像显示高度 参数范围 [0, 64]
// 返回参数 void
// 使用示例 oled_show_binary_image(0, 0, ov7725_image_binary[0], OV7725_W, OV7725_H, OV7725_W, OV7725_H);
// 备注信息 用于显示小钻风的未解压的压缩二值化图像
// 这个函数不可以用来直接显示总钻风的未压缩的二值化图像
// 这个函数不可以用来直接显示总钻风的未压缩的二值化图像
// 这个函数不可以用来直接显示总钻风的未压缩的二值化图像
//-------------------------------------------------------------------------------------------------------------------
void oled_show_binary_image (uint16 x, uint16 y, const uint8 *image, uint16 width, uint16 height, uint16 dis_width, uint16 dis_height)
{
// 如果程序在输出了断言信息 并且提示出错位置在这里
// 那么一般是屏幕显示的时候超过屏幕分辨率范围了
// 检查一下你的显示调用的函数 自己计算一下哪里超过了屏幕显示范围
zf_assert(128 > x);
zf_assert(8 > y);
zf_assert(NULL != image);
uint32 i = 0, j = 0, z = 0;
uint8 dat = 0;
uint32 width_index = 0, height_index = 0;
OLED_CS(0);
dis_height = dis_height - dis_height % 8;
dis_width = dis_width - dis_width % 8;
for(j = 0; j < dis_height; j += 8)
{
oled_set_coordinate(x + 0, (uint16)(y + j / 8));
height_index = j * height / dis_height;
for(i = 0; i < dis_width; i += 8)
{
width_index = i * width / dis_width / 8;
for(z = 0; 8 > z; z ++)
{
dat = 0;
if(*(image + height_index * width / 8 + width_index + width / 8 * 0) & (0x80 >> z))
{
dat |= 0x01;
}
if(*(image + height_index * width / 8 + width_index + width / 8 * 1) & (0x80 >> z))
{
dat |= 0x02;
}
if(*(image + height_index * width / 8 + width_index + width / 8 * 2) & (0x80 >> z))
{
dat |= 0x04;
}
if(*(image + height_index * width / 8 + width_index + width / 8 * 3) & (0x80 >> z))
{
dat |= 0x08;
}
if(*(image + height_index * width / 8 + width_index + width / 8 * 4) & (0x80 >> z))
{
dat |= 0x10;
}
if(*(image + height_index * width / 8 + width_index + width / 8 * 5) & (0x80 >> z))
{
dat |= 0x20;
}
if(*(image + height_index * width / 8 + width_index + width / 8 * 6) & (0x80 >> z))
{
dat |= 0x40;
}
if(*(image + height_index * width / 8 + width_index + width / 8 * 7) & (0x80 >> z))
{
dat |= 0x80;
}
oled_write_data(dat);
}
}
}
OLED_CS(1);
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 OLED 显示 8bit 灰度图像 带二值化阈值
// 参数说明 x x 轴坐标设置 0-127
// 参数说明 y y 轴坐标设置 0-7
// 参数说明 *image 图像数组指针
// 参数说明 width 图像实际宽度
// 参数说明 height 图像实际高度
// 参数说明 dis_width 图像显示宽度 参数范围 [0, 128]
// 参数说明 dis_height 图像显示高度 参数范围 [0, 64]
// 参数说明 threshold 二值化显示阈值 0-不开启二值化
// 返回参数 void
// 使用示例 oled_show_gray_image(0, 0, mt9v03x_image[0], width, height, 128, 64, x);
// 备注信息 用于显示总钻风的图像
// 如果要显示二值化图像 直接修改最后一个参数为需要的二值化阈值即可
// 如果要显示二值化图像 直接修改最后一个参数为需要的二值化阈值即可
// 如果要显示二值化图像 直接修改最后一个参数为需要的二值化阈值即可
//-------------------------------------------------------------------------------------------------------------------
void oled_show_gray_image (uint16 x, uint16 y, const uint8 *image, uint16 width, uint16 height, uint16 dis_width, uint16 dis_height, uint8 threshold)
{
// 如果程序在输出了断言信息 并且提示出错位置在这里
// 那么一般是屏幕显示的时候超过屏幕分辨率范围了
// 检查一下你的显示调用的函数 自己计算一下哪里超过了屏幕显示范围
zf_assert(128 > x);
zf_assert(8 > y);
zf_assert(NULL != image);
int16 i = 0, j = 0;
uint8 dat = 0;
uint32 width_index = 0, height_index = 0;
OLED_CS(0);
dis_height = dis_height - dis_height % 8;
for(j = 0; j < dis_height; j += 8)
{
oled_set_coordinate(x + 0, y + j / 8);
height_index = j * height / dis_height;
for(i = 0; i < dis_width; i ++)
{
width_index = i * width / dis_width;
dat = 0;
if(*(image + height_index * width + width_index + width * 0) > threshold)
{
dat |= 0x01;
}
if(*(image + height_index * width + width_index + width * 1) > threshold)
{
dat |= 0x02;
}
if(*(image + height_index * width + width_index + width * 2) > threshold)
{
dat |= 0x04;
}
if(*(image + height_index * width + width_index + width * 3) > threshold)
{
dat |= 0x08;
}
if(*(image + height_index * width + width_index + width * 4) > threshold)
{
dat |= 0x10;
}
if(*(image + height_index * width + width_index + width * 5) > threshold)
{
dat |= 0x20;
}
if(*(image + height_index * width + width_index + width * 6) > threshold)
{
dat |= 0x40;
}
if(*(image + height_index * width + width_index + width * 7) > threshold)
{
dat |= 0x80;
}
oled_write_data(dat);
}
}
OLED_CS(1);
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 OLED 显示波形
// 参数说明 x x 轴坐标设置 0-127
// 参数说明 y y 轴坐标设置 0-7
// 参数说明 *wave 波形数组指针
// 参数说明 width 波形实际宽度
// 参数说明 value_max 波形实际最大值
// 参数说明 dis_width 波形显示宽度 参数范围 [0, 128]
// 参数说明 dis_value_max 波形显示最大值 参数范围 [0, 64]
// 返回参数 void
// 使用示例 oled_show_wave(0, 0, data, 128, 64, 128, 64);
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
void oled_show_wave (uint16 x, uint16 y, const uint16 *wave, uint16 width, uint16 value_max, uint16 dis_width, uint16 dis_value_max)
{
// 如果程序在输出了断言信息 并且提示出错位置在这里
// 那么一般是屏幕显示的时候超过屏幕分辨率范围了
// 检查一下你的显示调用的函数 自己计算一下哪里超过了屏幕显示范围
zf_assert(128 > x);
zf_assert(8 > y);
zf_assert(NULL != wave);
uint32 i = 0;
uint32 width_index = 0, value_max_index = 0;
uint8 dis_h = 0;
uint32 x_temp = 0;
uint32 y_temp = 0;
OLED_CS(0);
for(y_temp = 0; y_temp < dis_value_max; y_temp += 8)
{
oled_set_coordinate(x + 0, (uint16)(y + y_temp / 8));
for(x_temp = 0; x_temp < dis_width; x_temp ++)
{
oled_write_data(0x00);
}
}
for(i = 0; i < dis_width; i ++)
{
width_index = i * width / dis_width;
value_max_index = *(wave + width_index) * (dis_value_max - 1) / value_max;
dis_h = (uint8)((dis_value_max - 1) - value_max_index);
oled_set_coordinate((uint16)(i + x), dis_h / 8 + y);
dis_h = (0x01 << dis_h % 8);
oled_write_data(dis_h);
}
OLED_CS(1);
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 汉字显示
// 参数说明 x 横坐标 0-127
// 参数说明 y 纵坐标 0-7
// 参数说明 size 取模的时候设置的汉字字体大小,也就是一个汉字占用的点阵长宽为多少个点,取模的时候需要长宽是一样的。
// 参数说明 *chinese_buffer 需要显示的汉字数组
// 参数说明 number 需要显示多少位
// 返回参数 void
// 使用示例 oled_show_chinese(0, 6, 16, (const uint8 *)oled_16x16_chinese, 4);
// 备注信息 使用PCtoLCD2002软件取模 阴码、逐行式、顺向 16*16
//-------------------------------------------------------------------------------------------------------------------
void oled_show_chinese (uint16 x, uint16 y, uint8 size, const uint8 *chinese_buffer, uint8 number)
{
// 如果程序在输出了断言信息 并且提示出错位置在这里
// 那么一般是屏幕显示的时候超过屏幕分辨率范围了
// 检查一下你的显示调用的函数 自己计算一下哪里超过了屏幕显示范围
zf_assert(128 > x);
zf_assert(8 > y);
zf_assert(NULL != chinese_buffer);
int16 i = 0, j = 0, k = 0;
OLED_CS(0);
for(i = 0; i < number; i ++)
{
for(j = 0; j < (size / 8); j ++)
{
oled_set_coordinate(x + i * size, y + j);
for(k = 0; 16 > k; k ++)
{
oled_write_data(*chinese_buffer);
chinese_buffer ++;
}
}
}
OLED_CS(1);
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 OLED初始化函数
// 参数说明 void
// 返回参数 void
// 使用示例 oled_init();
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
void oled_init (void)
{
#if OLED_USE_SOFT_SPI
soft_spi_init(&oled_spi, 0, OLED_SOFT_SPI_DELAY, OLED_D0_PIN, OLED_D1_PIN, SOFT_SPI_PIN_NULL, SOFT_SPI_PIN_NULL);
#else
spi_init(OLED_SPI, SPI_MODE0, OLED_SPI_SPEED, OLED_D0_PIN, OLED_D1_PIN, OLED_D1_PIN_IN, SPI_CS_NULL);
#endif
gpio_init(OLED_RES_PIN, GPO, GPIO_HIGH, GPO_PUSH_PULL);
gpio_init(OLED_DC_PIN , GPO, GPIO_HIGH, GPO_PUSH_PULL);
gpio_init(OLED_CS_PIN , GPO, GPIO_HIGH, GPO_PUSH_PULL);
oled_set_dir(oled_display_dir);
OLED_CS(0);
OLED_RES(0);
system_delay_ms(50);
OLED_RES(1);
oled_write_command(0xae); // 关闭oled面板
oled_write_command(0x00); // 设置低列地址
oled_write_command(0x10); // 设置高列地址
oled_write_command(0x40); // --set start line address Set Mapping RAM Display Start Line (0x00~0x3F)
oled_write_command(0x81); // 设置对比度控制寄存器
oled_write_command(OLED_BRIGHTNESS); // 设置SEG输出电流亮度
if(OLED_PORTAIT == oled_display_dir)
{
oled_write_command(0xa1); // 设置 SEG/列 映射 0xa0左右反置 0xa1正常
oled_write_command(0xc8); // 设置 COM/行扫描方向 0xc0上下反置 0xc8正常
}
else
{
oled_write_command(0xa0); // 设置 SEG/列 映射 0xa0左右反置 0xa1正常
oled_write_command(0xc0); // 设置 COM/行扫描方向 0xc0上下反置 0xc8正常
}
oled_write_command(0xa6); // 设置正常显示
oled_write_command(0xa8); // 设置复用比(1 ~ 64)
oled_write_command(0x3f); // 1/64 占比
oled_write_command(0xd3); // 设置显示偏移移位映射RAM计数器(0x00~0x3F)
oled_write_command(0x00); // 不偏移
oled_write_command(0xd5); // 设置显示时钟分频比/振荡器频率
oled_write_command(0x80); // 设置分割比率,设置时钟为100帧/秒
oled_write_command(0xd9); // 设定预充期
oled_write_command(0xf1); // 设置预充为15个时钟,放电为1个时钟
oled_write_command(0xda); // 设置com引脚硬件配置
oled_write_command(0x12);
oled_write_command(0xdb); // 设置 vcomh
oled_write_command(0x40); // 设置VCOM取消选择级别
oled_write_command(0x20); // 设置页面寻址模式(0x00/0x01/0x02)
oled_write_command(0x02); //
oled_write_command(0x8d); // 设置充电泵启用/禁用
oled_write_command(0x14); // 设置(0 x10)禁用
oled_write_command(0xa4); // 禁用整个显示打开(0xa4/0xa5)
oled_write_command(0xa6); // 禁用反向显示(0xa6/a7)
oled_write_command(0xaf); // 打开oled面板
OLED_CS(1);
oled_clear(); // 初始清屏
oled_set_coordinate(0, 0); // OLED显示坐标设置
oled_debug_init(); // OLED显示DEBUG信息初始化
}
+148
View File
@@ -0,0 +1,148 @@
/*********************************************************************************************************************
* TC264 Opensourec Library 即(TC264 开源库)是一个基于官方 SDK 接口的第三方开源库
* Copyright (c) 2022 SEEKFREE 逐飞科技
*
* 本文件是 TC264 开源库的一部分
*
* TC264 开源库 是免费软件
* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款
* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它
*
* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证
* 甚至没有隐含的适销性或适合特定用途的保证
* 更多细节请参见 GPL
*
* 您应该在收到本开源库的同时收到一份 GPL 的副本
* 如果没有,请参阅<https://www.gnu.org/licenses/>
*
* 额外注明:
* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本
* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中
* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件
* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明)
*
* 文件名称 zf_device_oled
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 ADS v1.10.2
* 适用平台 TC264D
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2022-09-15 pudding first version
* 2023-04-28 pudding 增加中文注释说明
********************************************************************************************************************/
/*********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* D0 查看 zf_device_oled.h 中 OLED_D0_PIN 宏定义
* D1 查看 zf_device_oled.h 中 OLED_D1_PIN 宏定义
* RES 查看 zf_device_oled.h 中 OLED_RES_PIN 宏定义
* DC 查看 zf_device_oled.h 中 OLED_DC_PIN 宏定义
* CS 查看 zf_device_oled.h 中 OLED_CS_PIN 宏定义
* VCC 3.3V电源
* GND 电源地
* ------------------------------------
********************************************************************************************************************/
#ifndef _zf_device_oled_h_
#define _zf_device_oled_h_
#include "zf_common_typedef.h"
//===================================================定义 OLED 基本配置=================================================
#define OLED_USE_SOFT_SPI (0 ) // 默认使用硬件 SPI 方式驱动 建议使用硬件 SPI 方式驱动
#if OLED_USE_SOFT_SPI // 这两段 颜色正常的才是正确的 颜色灰的就是没有用的
//====================================================软件 SPI 驱动====================================================
#define OLED_SOFT_SPI_DELAY ( 1 ) // 软件 SPI 的时钟延时周期 数值越小 SPI 通信速率越快
#define OLED_D0_PIN ( A12 ) // 软件 SPI SCK 引脚
#define OLED_D1_PIN ( A9 ) // 软件 SPI MOSI 引脚
//====================================================软件 SPI 驱动====================================================
#else
//====================================================硬件 SPI 驱动====================================================
#define OLED_SPI_SPEED ( 30 * 1000 * 1000 ) // 硬件 SPI 速率
#define OLED_SPI ( SPI_0 ) // 硬件 SPI 号
#define OLED_D0_PIN ( SPI0_SCK_A12 ) // 硬件 SPI SCK 引脚
#define OLED_D1_PIN ( SPI0_MOSI_A9 ) // 硬件 SPI MOSI 引脚
#define OLED_D1_PIN_IN (SPI_MISO_NULL ) // 硬件 SPI MISO 引脚 OLED没有MISO引脚,但是这里任然需要定义,在spi的初始化时需要使用
//====================================================硬件 SPI 驱动====================================================
#endif
#define OLED_RES_PIN (A7) // 液晶复位引脚定义
#define OLED_DC_PIN (A15 ) // 液晶命令位引脚定义
#define OLED_CS_PIN (A8 ) // CS 片选引脚
#define OLED_BRIGHTNESS (0x7f) // 设置OLED亮度 越大越亮 范围0-0XFF
#define OLED_DEFAULT_DISPLAY_DIR (OLED_PORTAIT ) // 默认的显示方向
#define OLED_DEFAULT_DISPLAY_FONT (OLED_6X8_FONT ) // 默认的字体模式
#define OLED_X_MAX (128) // 屏幕X轴像素最大值
#define OLED_Y_MAX (64 ) // 屏幕Y轴像素最大值
#define OLED_RES(x) ((x) ? (gpio_high(OLED_RES_PIN)) : (gpio_low(OLED_RES_PIN)))
#define OLED_DC(x) ((x) ? (gpio_high(OLED_DC_PIN)) : (gpio_low(OLED_DC_PIN)))
#define OLED_CS(x) ((x) ? (gpio_high(OLED_CS_PIN)) : (gpio_low(OLED_CS_PIN)))
//===================================================定义 OLED 基本配置=================================================
//===================================================定义 OLED 参数结构体=================================================
typedef enum
{
OLED_PORTAIT = 0, // 竖屏模式
OLED_PORTAIT_180 = 1, // 竖屏模式 旋转180
}oled_dir_enum;
typedef enum
{
OLED_6X8_FONT = 0, // 6x8 字体
OLED_8X16_FONT = 1, // 8x16 字体
OLED_16X16_FONT = 2, // 16x16 字体 目前不支持
}oled_font_size_enum;
//===================================================定义 OLED 基本配置=================================================
//===================================================声明 OLED 基本函数=================================================
void oled_clear (void); // OLED 清屏函数
void oled_full (const uint8 color); // OLED 屏幕填充函数
void oled_set_dir (oled_dir_enum dir); // OLED 设置显示方向
void oled_set_font (oled_font_size_enum font); // OLED 设置显示字体
void oled_draw_point (uint16 x, uint16 y, const uint8 color); // OLED 画点函数
void oled_show_string (uint16 x, uint16 y, const char ch[]); // OLED 显示字符串
void oled_show_int (uint16 x, uint16 y, const int32 dat, uint8 num); // OLED 显示32位有符号 (去除整数部分无效的0)
void oled_show_uint (uint16 x, uint16 y, const uint32 dat, uint8 num); // OLED 显示32位无符号 (去除整数部分无效的0)
void oled_show_float (uint16 x, uint16 y, const double dat, uint8 num, uint8 pointnum);
void oled_show_binary_image (uint16 x, uint16 y, const uint8 *image, uint16 width, uint16 height, uint16 dis_width, uint16 dis_height); // OLED 显示二值图像 数据每八个点组成一个字节数据
void oled_show_gray_image (uint16 x, uint16 y, const uint8 *image, uint16 width, uint16 height, uint16 dis_width, uint16 dis_height, uint8 threshold); // OLED 显示 8bit 灰度图像 带二值化阈值
void oled_show_wave (uint16 x, uint16 y, const uint16 *image, uint16 width, uint16 value_max, uint16 dis_width, uint16 dis_value_max); // OLED 显示波形
void oled_show_chinese (uint16 x, uint16 y, uint8 size, const uint8 *chinese_buffer, uint8 number); // OLED 汉字显示
void oled_init (void); // OLED 初始化函数
//===================================================定义 OLED 基本函数=================================================
//===================================================定义 OLED 扩展配置=================================================
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 OLED 128*64 显示小钻风图像
// 参数说明 p 图像数组
// 返回参数 void
// 使用示例 oled_displayimage7725(ov7725_image_binary[0]);
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
#define oled_displayimage7725(p) (oled_show_binary_image(0, 0, (p), OV7725_W, OV7725_H, 128, 64))
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 OLED 128*64 显示总钻风图像 带二值化
// 参数说明 p 图像数组
// 参数说明 x 二值化显示阈值
// 返回参数 void
// 使用示例 oled_displayimage03x(mt9v03x_image[0], 127);
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
#define oled_displayimage03x(p,x) (oled_show_gray_image(0, 0, (p), MT9V03X_W, MT9V03X_H, 128, 64, (x)))
//===================================================定义 OLED 扩展配置=================================================
#endif
File diff suppressed because it is too large Load Diff
+159
View File
@@ -0,0 +1,159 @@
/*********************************************************************************************************************
* MSPM0G3507 Opensource Library 即(MSPM0G3507 开源库)是一个基于官方 SDK 接口的第三方开源库
* Copyright (c) 2022 SEEKFREE 逐飞科技
*
* 本文件是 MSPM0G3507 开源库的一部分
*
* MSPM0G3507 开源库 是免费软件
* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款
* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它
*
* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证
* 甚至没有隐含的适销性或适合特定用途的保证
* 更多细节请参见 GPL
*
* 您应该在收到本开源库的同时收到一份 GPL 的副本
* 如果没有,请参阅<https://www.gnu.org/licenses/>
*
* 额外注明:
* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本
* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中
* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件
* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明)
*
* 文件名称 zf_device_tft180
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件版本说明
* 开发环境 MDK 5.37
* 适用平台 MSPM0G3507
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2025-06-1 SeekFree first version
********************************************************************************************************************/
/*********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* SCL 查看 zf_device_tft180.h 中 TFT180_SCL_PIN 宏定义
* SDA 查看 zf_device_tft180.h 中 TFT180_SDA_PIN 宏定义
* RES 查看 zf_device_tft180.h 中 TFT180_RES_PIN 宏定义
* DC 查看 zf_device_tft180.h 中 TFT180_DC_PIN 宏定义
* CS 查看 zf_device_tft180.h 中 TFT180_CS_PIN 宏定义
* BL 查看 zf_device_tft180.h 中 TFT180_BL_PIN 宏定义
* VCC 3.3V电源
* GND 电源地
* 最大分辨率160*128
* ------------------------------------
********************************************************************************************************************/
#ifndef _zf_device_tft180_h_
#define _zf_device_tft180_h_
#include "zf_common_typedef.h"
#define TFT180_USE_SOFT_SPI ( 0 ) //只能使用硬件SPI // 默认使用硬件 SPI 方式驱动 建议使用硬件 SPI 方式驱动
#if TFT180_USE_SOFT_SPI // 这两段 颜色正常的才是正确的 颜色灰的就是没有用的
//====================================================软件 SPI 驱动====================================================
#define TFT180_SOFT_SPI_DELAY ( 100 ) // 软件 SPI 的时钟延时周期 数值越小 SPI 通信速率越快
#define TFT180_SCL_PIN ( A12 ) // 软件 SPI SCK 引脚
#define TFT180_SDA_PIN ( A9 ) // 软件 SPI MOSI 引脚
//====================================================软件 SPI 驱动====================================================
#else
//====================================================硬件 SPI 驱动====================================================
#define TFT180_SPI_SPEED ( 30 * 1000 * 1000 ) // 硬件 SPI 速率
#define TFT180_SPI ( SPI_0 ) // 硬件 SPI 号
#define TFT180_SCL_PIN ( SPI0_SCK_A12 ) // 硬件 SPI SCK 引脚
#define TFT180_SDA_PIN ( SPI0_MOSI_A9 ) // 硬件 SPI MOSI 引脚
//====================================================硬件 SPI 驱动====================================================
#endif
#define TFT180_RES_PIN ( A7 ) // 液晶复位引脚定义
#define TFT180_DC_PIN ( A15 ) // 液晶命令位引脚定义
#define TFT180_CS_PIN ( A8 ) // CS 片选引脚
#define TFT180_BL_PIN ( A13 ) // 液晶背光引脚定义
#define TFT180_DEFAULT_DISPLAY_DIR ( TFT180_PORTAIT ) // 默认的显示方向
#define TFT180_DEFAULT_PENCOLOR ( RGB565_RED ) // 默认的画笔颜色
#define TFT180_DEFAULT_BGCOLOR ( RGB565_WHITE ) // 默认的背景颜色
#define TFT180_DEFAULT_DISPLAY_FONT ( TFT180_8X16_FONT ) // 默认的字体模式
#define TFT180_DC(x) ((x) ? (gpio_high(TFT180_DC_PIN)) : (gpio_low(TFT180_DC_PIN)))
#define TFT180_RST(x) ((x) ? (gpio_high(TFT180_RES_PIN)) : (gpio_low(TFT180_RES_PIN)))
#define TFT180_CS(x) ((x) ? (gpio_high(TFT180_CS_PIN)) : (gpio_low(TFT180_CS_PIN)))
#define TFT180_BLK(x) ((x) ? (gpio_high(TFT180_BL_PIN)) : (gpio_low(TFT180_BL_PIN)))
typedef enum
{
TFT180_PORTAIT = 0, // 竖屏模式
TFT180_PORTAIT_180 = 1, // 竖屏模式 旋转180
TFT180_CROSSWISE = 2, // 横屏模式
TFT180_CROSSWISE_180 = 3, // 横屏模式 旋转180
}tft180_dir_enum;
typedef enum
{
TFT180_6X8_FONT = 0, // 6x8 字体
TFT180_8X16_FONT = 1, // 8x16 字体
TFT180_16X16_FONT = 2, // 16x16 字体 目前不支持
}tft180_font_size_enum;
void tft180_clear (void);
void tft180_full (const uint16 color);
void tft180_set_dir (tft180_dir_enum dir);
void tft180_set_font (tft180_font_size_enum font);
void tft180_set_color (const uint16 pen, const uint16 bgcolor);
void tft180_draw_point (uint16 x, uint16 y, const uint16 color);
void tft180_draw_line (uint16 x_start, uint16 y_start, uint16 x_end, uint16 y_end, const uint16 color);
void tft180_show_char (uint16 x, uint16 y, const char dat);
void tft180_show_string (uint16 x, uint16 y, const char dat[]);
void tft180_show_int (uint16 x, uint16 y, const int32 dat, uint8 num);
void tft180_show_uint (uint16 x, uint16 y, const uint32 dat, uint8 num);
void tft180_show_float (uint16 x, uint16 y, const double dat, uint8 num, uint8 pointnum);
void tft180_show_binary_image (uint16 x, uint16 y, const uint8 *image, uint16 width, uint16 height, uint16 dis_width, uint16 dis_height);
void tft180_show_gray_image (uint16 x, uint16 y, const uint8 *image, uint16 width, uint16 height, uint16 dis_width, uint16 dis_height, uint8 threshold);
void tft180_show_rgb565_image (uint16 x, uint16 y, const uint16 *image, uint16 width, uint16 height, uint16 dis_width, uint16 dis_height, uint8 color_mode);
void tft180_show_wave (uint16 x, uint16 y, const uint16 *wave, uint16 width, uint16 value_max, uint16 dis_width, uint16 dis_value_max);
void tft180_show_chinese (uint16 x, uint16 y, uint8 size, const uint8 *chinese_buffer, uint8 number, const uint16 color);
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 TFT180 显示小钻风图像
// 参数说明 p 图像数组
// 参数说明 width 显示宽度
// 参数说明 height 显示高度
// 返回参数 void
// 使用示例 tft180_displayimage7725(ov7725_image_binary[0], 80, 60);
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
#define tft180_displayimage7725(p, width, height) (tft180_show_binary_image(0, 0, (p), OV7725_W, OV7725_H, (width), (height)))
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 TFT180 显示总钻风图像 不带二值化 显示灰度图像
// 参数说明 p 图像数组
// 参数说明 width 显示宽度
// 参数说明 height 显示高度
// 返回参数 void
// 使用示例 tft180_displayimage03x(mt9v03x_image[0], 94, 60);
// 备注信息 如果要显示二值化图像就去调用 tft180_show_gray_image 函数
//-------------------------------------------------------------------------------------------------------------------
#define tft180_displayimage03x(p, width, height) (tft180_show_gray_image(0, 0, (p), MT9V03X_W, MT9V03X_H, (width), (height), 0))
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 TFT180 显示凌瞳图像
// 参数说明 p 图像数组
// 参数说明 width 显示宽度
// 参数说明 height 显示高度
// 返回参数 void
// 使用示例 tft180_displayimage8660(scc8660_image[0], 80, 60);
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
#define tft180_displayimage8660(p, width, height) (tft180_show_rgb565_image(0, 0, (p), SCC8660_W, SCC8660_H, (width), (height), 1))
void tft180_init (void);
#endif
+141
View File
@@ -0,0 +1,141 @@
/*********************************************************************************************************************
* MSPM0G3507 Opensource Library 即(MSPM0G3507 开源库)是一个基于官方 SDK 接口的第三方开源库
* Copyright (c) 2022 SEEKFREE 逐飞科技
*
* 本文件是 MSPM0G3507 开源库的一部分
*
* MSPM0G3507 开源库 是免费软件
* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款
* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它
*
* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证
* 甚至没有隐含的适销性或适合特定用途的保证
* 更多细节请参见 GPL
*
* 您应该在收到本开源库的同时收到一份 GPL 的副本
* 如果没有,请参阅<https://www.gnu.org/licenses/>
*
* 额外注明:
* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本
* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中
* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件
* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明)
*
* 文件名称 zf_device_tsl1401
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件版本说明
* 开发环境 MDK 5.37
* 适用平台 MSPM0G3507
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2025-06-1 SeekFree first version
********************************************************************************************************************/
/*********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* CLK 查看 zf_device_tsl1401.h 中 TSL1401_CLK_PIN 宏定义
* SI 查看 zf_device_tsl1401.h 中 TSL1401_SI_PIN 宏定义
* AO[x] 查看 zf_device_tsl1401.h 中 TSL1401_AO_PIN_LIST 宏定义
* VCC 3.3V电源
* GND 电源地
* ------------------------------------
********************************************************************************************************************/
#include "zf_common_debug.h"
#include "zf_driver_adc.h"
#include "zf_driver_delay.h"
#include "zf_driver_gpio.h"
#include "zf_driver_pit.h"
#include "zf_device_tsl1401.h"
adc_pin_enum tsl1401_ao_list[TSL1401_AO_PIN_MAX] = TSL1401_AO_PIN_LIST;
uint16 tsl1401_data[TSL1401_AO_PIN_MAX][TSL1401_DATA_LEN]; // TSL1401 数据存放数组
static uint8 tsl1401_init_state = 0; // TSL1401 初始化标志位
vuint8 tsl1401_finish_flag; // TSL1401 数据准备就绪标志位
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 TSL1401 线阵 CCD 数据采集
// 参数说明 void
// 返回参数 void
// 使用示例 tsl1401_collect_pit_handler(NULL,NULL);
// 备注信息 该函数在 isr.c 中对应 TSL1401_PIT_INDEX 的中断服务函数调用
//-------------------------------------------------------------------------------------------------------------------
void tsl1401_collect_pit_handler (uint32 event, void *ptr)
{
// *((uint8 *)ptr) = 1;
if(!tsl1401_init_state) return;
uint8 i = 0,j = 0;
TSL1401_CLK(1);
TSL1401_SI (0);
TSL1401_CLK(0);
TSL1401_SI (1);
TSL1401_CLK(1);
TSL1401_SI (0);
for(i = 0; i < TSL1401_DATA_LEN; i ++)
{
TSL1401_CLK(0);
for(j = 0; j < TSL1401_AO_PIN_MAX; j++)
{
tsl1401_data[j][i] = adc_convert(tsl1401_ao_list[j]);
}
TSL1401_CLK(1);
}
tsl1401_finish_flag = 1; // 采集完成标志位置1
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 TSL1401 线阵 CCD 图像发送至上位机查看图像
// 参数说明 uart_n 串口号
// 参数说明 index 对应接入的哪个 TSL1401 [0-1]
// 返回参数 void
// 使用示例 tsl1401_send_data(DEBUG_UART_INDEX, 1);
// 备注信息 调用该函数前请先初始化串口
//-------------------------------------------------------------------------------------------------------------------
void tsl1401_send_data (uart_index_enum uart_n, uint8 index)
{
uint8 i;
uart_write_byte(uart_n, 0x00);
uart_write_byte(uart_n, 0xff);
uart_write_byte(uart_n, 0x01);
uart_write_byte(uart_n, 0x00);
for(i=0; i<TSL1401_DATA_LEN; i++)
{
switch(TSL1401_AD_RESOLUTION)
{
case ADC_8BIT: uart_write_byte(uart_n, (uint8)(tsl1401_data[index][i])); break;
case ADC_10BIT: uart_write_byte(uart_n, (uint8)(tsl1401_data[index][i] >> 2)); break;
case ADC_12BIT: uart_write_byte(uart_n, (uint8)(tsl1401_data[index][i] >> 4)); break;
}
}
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 TSL1401 线阵 CCD 初始化
// 参数说明 void
// 返回参数 void
// 使用示例 tsl1401_init(0); //代表初始化CCD1
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
void tsl1401_init (uint8 index)
{
adc_init (tsl1401_ao_list[index], TSL1401_AD_RESOLUTION);
gpio_init(TSL1401_CLK_PIN, GPO, GPIO_LOW, GPO_PUSH_PULL);
gpio_init(TSL1401_SI_PIN, GPO, GPIO_LOW, GPO_PUSH_PULL);
pit_ms_init(TSL1401_PIT_INDEX, TSL1401_EXPOSURE_TIME,tsl1401_collect_pit_handler,NULL);
tsl1401_init_state = 1;
}
+84
View File
@@ -0,0 +1,84 @@
/*********************************************************************************************************************
* MSPM0G3507 Opensource Library 即(MSPM0G3507 开源库)是一个基于官方 SDK 接口的第三方开源库
* Copyright (c) 2022 SEEKFREE 逐飞科技
*
* 本文件是 MSPM0G3507 开源库的一部分
*
* MSPM0G3507 开源库 是免费软件
* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款
* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它
*
* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证
* 甚至没有隐含的适销性或适合特定用途的保证
* 更多细节请参见 GPL
*
* 您应该在收到本开源库的同时收到一份 GPL 的副本
* 如果没有,请参阅<https://www.gnu.org/licenses/>
*
* 额外注明:
* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本
* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中
* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件
* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明)
*
* 文件名称 zf_device_tsl1401
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件版本说明
* 开发环境 MDK 5.37
* 适用平台 MSPM0G3507
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2025-06-1 SeekFree first version
********************************************************************************************************************/
/*********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* CLK 查看 zf_device_tsl1401.h 中 TSL1401_CLK_PIN 宏定义
* SI 查看 zf_device_tsl1401.h 中 TSL1401_SI_PIN 宏定义
* AO[x] 查看 zf_device_tsl1401.h 中 TSL1401_AO_PIN_BUFFER 宏定义
* VCC 3.3V电源
* GND 电源地
* ------------------------------------
********************************************************************************************************************/
#ifndef _zf_device_tsl1401_h_
#define _zf_device_tsl1401_h_
#include "zf_driver_uart.h"
#include "zf_device_type.h"
//=================================================定义 TSL1401 基本配置================================================
// TSL1401 的控制引脚定义 多个 TSL1401 建议将控制引脚直接并联
#define TSL1401_CLK_PIN (A28) // TSL1401 的 CLK 引脚定义
#define TSL1401_SI_PIN (A29) // TSL1401 的 SI 引脚定义
#define TSL1401_CLK(x) ((x) ? (gpio_high(TSL1401_CLK_PIN)) : (gpio_low(TSL1401_CLK_PIN)))
#define TSL1401_SI(x) ((x) ? (gpio_high(TSL1401_SI_PIN)) : (gpio_low(TSL1401_SI_PIN)))
#define TSL1401_AO_PIN_MAX ( 4 )
#define TSL1401_AO_PIN_LIST { ADC0_CH2_A25, ADC0_CH3_A24, ADC0_CH4_B25, ADC0_CH5_B24 } //CCD ADC引脚
// TSL1401 的周期采集部分定义
#define TSL1401_EXPOSURE_TIME (10 ) // 定义 TSL1401 曝光时间 单位 MS
#define TSL1401_PIT_INDEX (PIT_TIM_G8) // 使用周期中断
#define TSL1401_AD_RESOLUTION (ADC_8BIT) // ADC 精度 8bit
#define TSL1401_DATA_LEN (128 ) // TSL1401 数据长度
//=================================================定义 TSL1401 基本配置================================================
//=================================================声明 TSL1401 全局变量=================================================
extern uint16 tsl1401_data[TSL1401_AO_PIN_MAX][TSL1401_DATA_LEN]; // TSL1401 数据存放数组
extern vuint8 tsl1401_finish_flag; // TSL1401 数据采集完成标志
//=================================================声明 TSL1401 全局变量=================================================
//=================================================声明 TSL1401 基础函数=================================================
void tsl1401_collect_pit_handler (uint32 event, void *ptr); // TSL1401 线阵 CCD 数据采集
void tsl1401_send_data (uart_index_enum uart_n, uint8 index); // TSL1401 线阵 CCD 图像发送至上位机查看图像
void tsl1401_init (uint8 index); // TSL1401 线阵 CCD 初始化
//=================================================声明 TSL1401 基础函数=================================================
#endif
+115
View File
@@ -0,0 +1,115 @@
/*********************************************************************************************************************
* MSPM0G3507 Opensource Library 即(MSPM0G3507 开源库)是一个基于官方 SDK 接口的第三方开源库
* Copyright (c) 2022 SEEKFREE 逐飞科技
*
* 本文件是 MSPM0G3507 开源库的一部分
*
* MSPM0G3507 开源库 是免费软件
* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款
* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它
*
* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证
* 甚至没有隐含的适销性或适合特定用途的保证
* 更多细节请参见 GPL
*
* 您应该在收到本开源库的同时收到一份 GPL 的副本
* 如果没有,请参阅<https://www.gnu.org/licenses/>
*
* 额外注明:
* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本
* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中
* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件
* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明)
*
* 文件名称 zf_device_types
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件版本说明
* 开发环境 MDK 5.37
* 适用平台 MSPM0G3507
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2025-06-1 SeekFree first version
********************************************************************************************************************/
#include "zf_device_type.h"
static void type_default_callback (void);
camera_type_enum camera_type = NO_CAMERE; // 摄像头类型变量
callback_function camera_uart_handler = type_default_callback; // 串口通讯中断函数指针,根据初始化时设置的函数进行跳转
callback_function camera_vsync_handler = type_default_callback; // 场中断函数指针,根据初始化时设置的函数进行跳转
callback_function camera_dma_handler = type_default_callback; // DMA完成中断函数指针,根据初始化时设置的函数进行跳转
wireless_type_enum wireless_type = NO_WIRELESS;
callback_function wireless_module_uart_handler = type_default_callback; // 无线串口接收中断函数指针,根据初始化时设置的函数进行跳转
callback_function wireless_module_spi_handler = type_default_callback; // WIFI SPI GPIO中断函数指针,根据初始化时设置的函数进行跳转
tof_type_enum tof_type = NO_TOF;
callback_function tof_module_exti_handler = type_default_callback; // ToF 模块 INT 更新中断
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 默认回调函数
// 参数说明 void
// 返回参数 void
// 使用示例
// 备注信息 保护性冗余设计 防止在没有初始化设备的时候跑飞
//-------------------------------------------------------------------------------------------------------------------
static void type_default_callback (void)
{
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 设置摄像头类型
// 参数说明 type_set 选定的摄像头类型
// 参数说明 vsync_callback 设备的场中断回调函数
// 参数说明 dma_callback 设备的 DMA 完成中断回调函数
// 参数说明 uart_callback 设备的串口回调函数
// 返回参数 void
// 使用示例 set_camera_type(CAMERA_GRAYSCALE);
// 备注信息 一般由各摄像头初始化内部调用
//-------------------------------------------------------------------------------------------------------------------
void set_camera_type (camera_type_enum type_set, callback_function vsync_callback, callback_function dma_callback, callback_function uart_callback)
{
camera_type = type_set;
camera_uart_handler = ((uart_callback == NULL) ? (type_default_callback) : (uart_callback));
camera_vsync_handler = ((vsync_callback == NULL) ? (type_default_callback) : (vsync_callback));
camera_dma_handler = ((dma_callback == NULL) ? (type_default_callback) : (dma_callback));
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 设置无线模块类型
// 参数说明 type_set 选定的无线模块类型
// 参数说明 uart_callback 设备的串口回调函数
// 返回参数 void
// 使用示例 set_wireless_type(WIRELESS_UART, uart_callback);
// 备注信息 一般由各摄像头初始化内部调用
//-------------------------------------------------------------------------------------------------------------------
void set_wireless_type (wireless_type_enum type_set, callback_function wireless_callback)
{
wireless_type = type_set;
if(WIFI_SPI == wireless_type)
{
wireless_module_spi_handler = ((wireless_callback == NULL) ? (type_default_callback) : (wireless_callback));
}
else
{
wireless_module_uart_handler = ((wireless_callback == NULL) ? (type_default_callback) : (wireless_callback));
}
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 设置 ToF 模块类型
// 参数说明 type_set 选定的 ToF 模块类型
// 参数说明 exti_callback 设备的外部中断回调函数
// 返回参数 void
// 使用示例 set_tof_type(TOF_DL1A, dl1a_int_handler);
// 备注信息 一般由各摄像头初始化内部调用
//-------------------------------------------------------------------------------------------------------------------
void set_tof_type (tof_type_enum type_set, callback_function exti_callback)
{
tof_type = type_set;
tof_module_exti_handler = ((exti_callback == NULL) ? (type_default_callback) : (exti_callback));
}
+92
View File
@@ -0,0 +1,92 @@
/*********************************************************************************************************************
* MSPM0G3507 Opensource Library 即(MSPM0G3507 开源库)是一个基于官方 SDK 接口的第三方开源库
* Copyright (c) 2022 SEEKFREE 逐飞科技
*
* 本文件是 MSPM0G3507 开源库的一部分
*
* MSPM0G3507 开源库 是免费软件
* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款
* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它
*
* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证
* 甚至没有隐含的适销性或适合特定用途的保证
* 更多细节请参见 GPL
*
* 您应该在收到本开源库的同时收到一份 GPL 的副本
* 如果没有,请参阅<https://www.gnu.org/licenses/>
*
* 额外注明:
* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本
* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中
* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件
* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明)
*
* 文件名称 zf_device_types
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件版本说明
* 开发环境 MDK 5.37
* 适用平台 MSPM0G3507
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2025-06-1 SeekFree first version
********************************************************************************************************************/
#ifndef _zf_device_type_h_
#define _zf_device_type_h_
#include "zf_common_typedef.h"
//==============================================定义 外设 参数结构体==================================================
typedef enum
{
NO_CAMERE = 0, // 无摄像头
CAMERA_BIN_IIC, // 小钻风 IIC 版本
CAMERA_BIN_UART, // 小钻风 UART 版本
CAMERA_GRAYSCALE, // 总钻风
CAMERA_COLOR, // 凌瞳
}camera_type_enum;
typedef enum
{
NO_WIRELESS = 0, // 无设备
WIRELESS_UART, // 无线串口
BLUETOOTH_CH9141, // 蓝牙 CH9141
WIFI_UART, // 串口 WiFi
WIFI_SPI // SPI WiFi
}wireless_type_enum;
typedef enum
{
NO_TOF = 0, // 无设备
TOF_DL1A, // DL1A
TOF_DL1B, // DL1B
}tof_type_enum;
//==============================================定义 外设 参数结构体==================================================
//===========================================声明 回调函数指针及外设 类型==============================================
typedef void (*callback_function)(void);
extern wireless_type_enum wireless_type;
extern callback_function wireless_module_uart_handler; // 无线串口接收中断函数指针,根据初始化时设置的函数进行跳转
extern callback_function wireless_module_spi_handler; // WIFI SPI GPIO中断函数指针,根据初始化时设置的函数进行跳转
extern camera_type_enum camera_type;
extern callback_function camera_dma_handler; // 串口通讯中断函数指针,根据初始化时设置的函数进行跳转
extern callback_function camera_vsync_handler; // 串口通讯中断函数指针,根据初始化时设置的函数进行跳转
extern callback_function camera_uart_handler; // 串口通讯中断函数指针,根据初始化时设置的函数进行跳转
extern tof_type_enum tof_type; // ToF 模块 类型
extern callback_function tof_module_exti_handler; // ToF 模块 INT 更新中断
//===========================================声明 回调函数指针及外设 类型==============================================
//=============================================声明 中断回调 基础函数================================================
void set_camera_type (camera_type_enum type_set, callback_function vsync_callback, callback_function dma_callback, callback_function uart_callback);
void set_wireless_type (wireless_type_enum type_set, callback_function wireless_callback);
void set_tof_type (tof_type_enum type_set, callback_function exti_callback);
//=============================================声明 中断回调 基础函数================================================
#endif
+672
View File
@@ -0,0 +1,672 @@
/*********************************************************************************************************************
* MSPM0G3507 Opensource Library 即(MSPM0G3507 开源库)是一个基于官方 SDK 接口的第三方开源库
* Copyright (c) 2022 SEEKFREE 逐飞科技
*
* 本文件是 MSPM0G3507 开源库的一部分
*
* MSPM0G3507 开源库 是免费软件
* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款
* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它
*
* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证
* 甚至没有隐含的适销性或适合特定用途的保证
* 更多细节请参见 GPL
*
* 您应该在收到本开源库的同时收到一份 GPL 的副本
* 如果没有,请参阅<https://www.gnu.org/licenses/>
*
* 额外注明:
* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本
* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中
* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件
* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明)
*
* 文件名称 zf_device_wifi_spi
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件版本说明
* 开发环境 MDK 5.37
* 适用平台 MSPM0G3507
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2025-06-1 SeekFree first version
********************************************************************************************************************/
/*********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* RST 查看 zf_device_wifi_spi.h 中 WIFI_SPI_RST_PIN 宏定义
* INT 查看 zf_device_wifi_spi.h 中 WIFI_SPI_INT_PIN 宏定义
* CS 查看 zf_device_wifi_spi.h 中 WIFI_SPI_CS_PIN 宏定义
* MISO 查看 zf_device_wifi_spi.h 中 WIFI_SPI_MISO_PIN 宏定义
* SCK 查看 zf_device_wifi_spi.h 中 WIFI_SPI_SCK_PIN 宏定义
* MOSI 查看 zf_device_wifi_spi.h 中 WIFI_SPI_MOSI_PIN 宏定义
* 5V 5V 电源
* GND 电源地
* 其余引脚悬空
* ------------------------------------
*********************************************************************************************************************/
#include "stdio.h"
#include "zf_common_clock.h"
#include "zf_common_debug.h"
#include "zf_common_fifo.h"
#include "zf_driver_delay.h"
#include "zf_driver_gpio.h"
#include "zf_driver_spi.h"
#include "zf_device_type.h"
#include "zf_device_wifi_spi.h"
#define WIFI_CONNECT_TIME_OUT 10000 // 单位毫秒
#define SOCKET_CONNECT_TIME_OUT 50000 // 单位毫秒
#define OTHER_TIME_OUT 1000 // 单位毫秒
char wifi_spi_version[12]; // 保存模块固件版本信息
char wifi_spi_mac_addr[20]; // 保存模块MAC地址信息
char wifi_spi_ip_addr_port[25]; // 保存模块IP地址与端口信息
static fifo_struct wifi_spi_fifo;
static uint8 wifi_spi_buffer[WIFI_SPI_RECVIVE_FIFO_SIZE];
static volatile wifi_spi_state_enum wifi_spi_mutex;
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 等待WIFI SPI就绪
// 参数说明 wait_time 最大等待时间 单位毫秒
// 返回参数 uint8 状态 0-成功 1-错误
// 使用示例 内部使用,用户无需关心
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
static uint8 wifi_spi_wait_idle (uint32 wait_time)
{
uint32 time = 0;
wait_time = wait_time*100;
while(0 == gpio_get_level(WIFI_SPI_INT_PIN))
{
system_delay_us(10);
time++;
if(wait_time <= time)
{
break;
}
}
return (wait_time <= time);
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 写入数据到WIFI SPI
// 参数说明 *buffer1 第一组需要发送的数据缓冲区地址
// 参数说明 length1 第一组数据长度
// 参数说明 *buffer2 第二组需要发送的数据缓冲区地址
// 参数说明 length2 第二组数据长度
// 返回参数 void
// 使用示例 内部使用,用户无需关心
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
static void wifi_spi_write (const uint8 *buffer1, uint16 length1, const uint8 *buffer2, uint16 length2)
{
gpio_low(WIFI_SPI_CS_PIN);
if(NULL != buffer1)
{
spi_write_8bit_array(WIFI_SPI_INDEX, buffer1, length1);
}
if(NULL != buffer2)
{
spi_write_8bit_array(WIFI_SPI_INDEX, buffer2, length2);
}
gpio_high(WIFI_SPI_CS_PIN);
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 WIFI SPI 发送与接收同时进行(命令收发)
// 参数说明 *packets 发送与接收的地址
// 参数说明 length 需要接收的长度
// 返回参数 void
// 使用示例 内部使用,用户无需关心
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
static void wifi_spi_transfer_command (wifi_spi_packets_struct *packets, uint16 length)
{
gpio_low(WIFI_SPI_CS_PIN);
spi_transfer_8bit(WIFI_SPI_INDEX, (uint8 *)&(packets->head), (uint8 *)&(packets->head), sizeof(wifi_spi_head_struct));
if(length)
{
spi_transfer_8bit(WIFI_SPI_INDEX, (const uint8 *)(packets->buffer), packets->buffer, length);
}
gpio_high(WIFI_SPI_CS_PIN);
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 WIFI SPI 发送与接收同时进行(数据收发)
// 参数说明 *write_data 发送的数据缓冲区地址
// 参数说明 *read_data 接收到的数据的存储地址
// 参数说明 length 需要接收的长度
// 返回参数 void
// 使用示例 内部使用,用户无需关心
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
static void wifi_spi_transfer_data (const uint8 *write_data, wifi_spi_packets_struct *read_data, uint16 length)
{
gpio_low(WIFI_SPI_CS_PIN);
read_data->head.command = WIFI_SPI_DATA;
read_data->head.length = length;
spi_transfer_8bit(WIFI_SPI_INDEX, (uint8 *)&(read_data->head), (uint8 *)&(read_data->head), sizeof(wifi_spi_head_struct));
if(WIFI_SPI_RECVIVE_SIZE < length)
{
spi_transfer_8bit(WIFI_SPI_INDEX, write_data, read_data->buffer, WIFI_SPI_RECVIVE_SIZE);
spi_write_8bit_array(WIFI_SPI_INDEX, &write_data[WIFI_SPI_RECVIVE_SIZE], length - WIFI_SPI_RECVIVE_SIZE);
}
else
{
// 将需要发送的数据拷贝到读取缓冲区,避免出现write_data越界访问
memcpy(read_data->buffer, write_data, length);
spi_transfer_8bit(WIFI_SPI_INDEX, read_data->buffer, read_data->buffer, WIFI_SPI_RECVIVE_SIZE);
}
gpio_high(WIFI_SPI_CS_PIN);
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 WIFI SPI 参数设置
// 参数说明 command 命令类型
// 参数说明 *buffer 参数地址
// 参数说明 length 参数长度
// 参数说明 wait_time 最大等待时间 单位100微妙
// 返回参数 uint8 状态 0-成功 1-错误
// 使用示例 内部使用,用户无需关心
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
static uint8 wifi_spi_set_parameter (wifi_spi_packets_command_enum command, uint8 *buffer, uint16 length, uint32 wait_time)
{
uint8 return_state;
wifi_spi_head_struct head;
return_state = 1;
do
{
head.command = command;
head.length = length;
// 等待从机准备就绪
if(wifi_spi_wait_idle(wait_time))
{
break;
}
wifi_spi_write(&head.command, sizeof(wifi_spi_head_struct), buffer, length);
if(wifi_spi_wait_idle(wait_time))
{
break;
}
// 接收应答信号
head.command = WIFI_SPI_DATA;
head.length = 0;
wifi_spi_transfer_command((wifi_spi_packets_struct *)&head, head.length);
system_delay_us(20);
if(WIFI_SPI_REPLY_OK == head.command)
{
return_state = 0;
}
}while(0);
return return_state;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 WIFI SPI 模块信息获取
// 参数说明 command 命令类型
// 参数说明 *read_data 保存接收到的参数地址
// 参数说明 wait_time 最大等待时间 单位100微妙
// 返回参数 uint8 状态 0-成功 1-错误
// 使用示例 内部使用,用户无需关心
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
static uint8 wifi_spi_get_parameter (wifi_spi_packets_command_enum command, wifi_spi_packets_struct *read_data, uint32 wait_time)
{
uint8 return_state;
return_state = 1;
do
{
// 等待从机准备就绪
if(wifi_spi_wait_idle(wait_time))
{
break;
}
read_data->head.command = command;
wifi_spi_write(&(read_data->head.command), WIFI_SPI_RECVIVE_SIZE, NULL, 0);
if(wifi_spi_wait_idle(wait_time))
{
break;
}
read_data->head.command = WIFI_SPI_DATA;
read_data->head.length = 0;
wifi_spi_transfer_command(read_data, WIFI_SPI_RECVIVE_SIZE);
return_state = 0;
}while(0);
return return_state;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 WIFI SPI 固件版本获取
// 参数说明 void 端口号
// 返回参数 uint8 状态 0-成功 1-错误
// 使用示例
// 备注信息 调用函数之后,固件版本信息以字符串形式保存在wifi_spi_version数组中
//-------------------------------------------------------------------------------------------------------------------
static uint8 wifi_spi_get_version (void)
{
uint8 return_state;
wifi_spi_packets_struct temp_packets;
return_state = wifi_spi_get_parameter(WIFI_SPI_GET_VERSION, &temp_packets, OTHER_TIME_OUT);
if((0 == return_state) && (WIFI_SPI_REPLY_VERSION == temp_packets.head.command))
{
memcpy(wifi_spi_version, temp_packets.buffer, temp_packets.head.length);
}
return_state = (return_state == 0) ? (WIFI_SPI_REPLY_VERSION != temp_packets.head.command) : 1;
return return_state;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 WIFI SPI MAC地址获取
// 参数说明 void 端口号
// 返回参数 uint8 状态 0-成功 1-错误
// 使用示例
// 备注信息 调用函数之后,MAC地址信息以字符串形式保存在wifi_spi_mac_addr数组中
//-------------------------------------------------------------------------------------------------------------------
static uint8 wifi_spi_get_mac_addr (void)
{
uint8 return_state;
wifi_spi_packets_struct temp_packets;
return_state = wifi_spi_get_parameter(WIFI_SPI_GET_MAC_ADDR, &temp_packets, OTHER_TIME_OUT);
if((0 == return_state) && (WIFI_SPI_REPLY_MAC_ADDR == temp_packets.head.command))
{
memcpy(wifi_spi_mac_addr, temp_packets.buffer, temp_packets.head.length);
}
return_state = (return_state == 0) ? (WIFI_SPI_REPLY_MAC_ADDR != temp_packets.head.command) : 1;
return return_state;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 WIFI SPI IP地址与端口号获取
// 参数说明 void 端口号
// 返回参数 uint8 状态 0-成功 1-错误
// 使用示例
// 备注信息 调用函数之后,IP地址与端口号信息以字符串形式保存在wifi_spi_ip_addr_port数组中
// 需要在连接Socket之后调用此函数才能正常获取信息
//-------------------------------------------------------------------------------------------------------------------
static uint8 wifi_spi_get_ip_addr_port (void)
{
uint8 return_state;
wifi_spi_packets_struct temp_packets;
return_state = wifi_spi_get_parameter(WIFI_SPI_GET_IP_ADDR, &temp_packets, OTHER_TIME_OUT);
if((0 == return_state) && (WIFI_SPI_REPLY_IP_ADDR == temp_packets.head.command))
{
memcpy(wifi_spi_ip_addr_port, temp_packets.buffer, temp_packets.head.length);
}
return_state = (return_state == 0) ? (WIFI_SPI_REPLY_IP_ADDR != temp_packets.head.command) : 1;
return return_state;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 WIFI SPI 设置连接的WiFi信息并尝试连接WiFi
// 参数说明 *wifi_ssid WIFI名称
// 参数说明 *pass_word WIFI密码
// 返回参数 uint8 状态 0-成功 1-错误
// 使用示例 wifi_spi_wifi_connect("SEEKFREE", "SEEKFREE123");
// 备注信息 wifi_spi_wifi_connect("SEEKFREE", NULL); // 连接没有密码的WIFI热点
//-------------------------------------------------------------------------------------------------------------------
uint8 wifi_spi_wifi_connect (char *wifi_ssid, char *pass_word)
{
uint8 return_state;
uint8 temp_buffer[64];
uint16 length;
if(NULL != pass_word)
{
// WIFI热点有密码发送热点名称与密码
length = (uint16)sprintf((char *)temp_buffer, "%s\r\n%s\r\n", wifi_ssid, pass_word);
}
else
{
// WIFI热点没有密码只需要发送热点名称
length = (uint16)sprintf((char *)temp_buffer, "%s\r\n", wifi_ssid);
}
return_state = wifi_spi_set_parameter(WIFI_SPI_SET_WIFI_INFORMATION, temp_buffer, length, WIFI_CONNECT_TIME_OUT);
// 本机IP地址与端口号信息以字符串形式保存在wifi_spi_ip_addr_port数组中
wifi_spi_get_ip_addr_port();
return return_state;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 WIFI SPI 设置连接的Socket信息并尝试连接Socket
// 参数说明 *transport_type 传输类型
// 参数说明 *ip_addr IP地址
// 参数说明 *port 目标端口号
// 参数说明 *local_port 本机端口号
// 返回参数 uint8 状态 0-成功 1-错误
// 使用示例 wifi_spi_socket_connect("TCP", "192.168.2.5", "8080", "6060");
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
uint8 wifi_spi_socket_connect (char *transport_type, char *ip_addr, char *port, char *local_port)
{
uint8 return_state;
uint8 temp_buffer[41];
uint16 length;
length = (uint16)sprintf((char *)temp_buffer, "%s\r\n%s\r\n%s\r\n%s\r\n", transport_type, ip_addr, port, local_port);
return_state = wifi_spi_set_parameter(WIFI_SPI_SET_SOCKET_INFORMATION, temp_buffer, length, SOCKET_CONNECT_TIME_OUT);
// 本机IP地址与端口号信息以字符串形式保存在wifi_spi_ip_addr_port数组中
wifi_spi_get_ip_addr_port();
return return_state;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 WIFI SPI 断开Socket连接
// 参数说明 void
// 返回参数 uint8 状态 0-成功 1-错误
// 使用示例 wifi_spi_socket_disconnect();
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
uint8 wifi_spi_socket_disconnect (void)
{
wifi_spi_packets_struct temp_packets;
return wifi_spi_get_parameter(WIFI_SPI_CLOSE_SOCKET, &temp_packets, OTHER_TIME_OUT);
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 WIFI SPI 软复位
// 参数说明 void
// 返回参数 uint8 状态 0-成功 1-错误
// 使用示例
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
uint8 wifi_spi_reset (void)
{
uint8 return_state;
wifi_spi_head_struct head;
return_state = 1;
do
{
head.command = WIFI_SPI_RESET;
head.length = 0xA5A5;
return_state = wifi_spi_wait_idle(OTHER_TIME_OUT);
if(return_state)
{
break;
}
wifi_spi_write(&head.command, sizeof(wifi_spi_head_struct), NULL, 0);
}while(0);
return return_state;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 WIFI SPI UDP模式时立即发送函数
// 参数说明 void
// 返回参数 uint8 状态 0-成功 1-错误
// 使用示例
// 备注信息 在UDP模式下模块收到数据后会等待2毫秒,2毫秒后未收到数据则将数据通过socket发送到网络,如果希望立即发送则在数据传输完毕后调用此函数
//-------------------------------------------------------------------------------------------------------------------
uint8 wifi_spi_udp_send_now (void)
{
uint8 return_state = 1;
wifi_spi_packets_struct temp_packets;
if(WIFI_SPI_IDLE == wifi_spi_mutex)
{
// 将通讯状态设置为忙
wifi_spi_mutex = WIFI_SPI_BUSY;
do
{
if(wifi_spi_wait_idle(OTHER_TIME_OUT))
{
break;
}
// 立即开始socket发送
temp_packets.head.command = WIFI_SPI_UDP_SEND;
temp_packets.head.length = 0;
wifi_spi_transfer_command(&temp_packets, WIFI_SPI_RECVIVE_SIZE);
// 检查收到的包中是否有数据
if((WIFI_SPI_REPLY_DATA_START == temp_packets.head.command) || (WIFI_SPI_REPLY_DATA_END == temp_packets.head.command))
{
// 保存接收到的数据
if(temp_packets.head.length)
{
fifo_write_buffer(&wifi_spi_fifo, temp_packets.buffer, temp_packets.head.length);
}
}
// 等待应答信号
if(wifi_spi_wait_idle(OTHER_TIME_OUT))
{
break;
}
// 接收应答信号
temp_packets.head.command = WIFI_SPI_DATA;
temp_packets.head.length = 0;
wifi_spi_transfer_command(&temp_packets, temp_packets.head.length);
if(WIFI_SPI_REPLY_OK == temp_packets.head.command)
{
return_state = 0;
}
}while(0);
// 将通讯状态设置为空闲
wifi_spi_mutex = WIFI_SPI_IDLE;
}
return return_state;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 WIFI SPI 数据块发送函数并同步接收数据
// 参数说明 *buffer 需要发送的数据地址
// 参数说明 length 发送长度
// 返回参数 uint32 剩余未发送的长度
// 使用示例 wifi_spi_send_buffer(buffer, 100);
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
uint32 wifi_spi_send_buffer (const uint8 *buffer, uint32 length)
{
uint16 send_length;
wifi_spi_packets_struct temp_packets;
// 检查WIFI SPI状态,如果在其他中断或者线程中已经发起了通讯,则本次不能发送数据
if(WIFI_SPI_IDLE == wifi_spi_mutex)
{
// 将通讯状态设置为忙
wifi_spi_mutex = WIFI_SPI_BUSY;
while(length)
{
send_length = length > WIFI_SPI_TRANSFER_SIZE ? (uint16)WIFI_SPI_TRANSFER_SIZE : (uint16)length;
if(wifi_spi_wait_idle(OTHER_TIME_OUT))
{
break;
}
wifi_spi_transfer_data(buffer, &temp_packets, send_length);
// 检查收到的包中是否有数据
if((WIFI_SPI_REPLY_DATA_START == temp_packets.head.command) || (WIFI_SPI_REPLY_DATA_END == temp_packets.head.command))
{
// 保存接收到的数据
if(temp_packets.head.length)
{
fifo_write_buffer(&wifi_spi_fifo, temp_packets.buffer, temp_packets.head.length);
}
}
length -= send_length;
buffer += send_length;
}
// 检查最后一次的接收是否将所有的数据都接收完毕
while(WIFI_SPI_REPLY_DATA_START == temp_packets.head.command)
{
if(wifi_spi_wait_idle(OTHER_TIME_OUT))
{
break;
}
// 继续读取模块剩余数据
temp_packets.head.command = WIFI_SPI_DATA;
temp_packets.head.length = 0;
wifi_spi_transfer_command(&temp_packets, WIFI_SPI_RECVIVE_SIZE);
// 检查收到的包中是否有数据
if((WIFI_SPI_REPLY_DATA_START == temp_packets.head.command) || (WIFI_SPI_REPLY_DATA_END == temp_packets.head.command))
{
// 保存接收到的数据
if(temp_packets.head.length)
{
fifo_write_buffer(&wifi_spi_fifo, temp_packets.buffer, temp_packets.head.length);
}
}
}
wifi_spi_mutex = WIFI_SPI_IDLE;
}
return length;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 WIFI SPI 读取缓冲区
// 参数说明 *buffer 接收缓冲区
// 参数说明 length 读取数据长度
// 返回参数 uint32 实际读取数据长度
// 使用示例 wifi_spi_read_buffer(buffer, 100);
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
uint32 wifi_spi_read_buffer (uint8 *buffer, uint32 length)
{
zf_assert(NULL != buffer);
uint32 data_len = length;
#if(1 == WIFI_SPI_READ_TRANSFER)
wifi_spi_packets_struct temp_packets;
// 检查WIFI SPI状态,如果在其他中断或者线程中已经发起了通讯,则本次不能发送数据
if(WIFI_SPI_IDLE == wifi_spi_mutex)
{
// 将通讯状态设置为忙
wifi_spi_mutex = WIFI_SPI_BUSY;
// 发起通讯查看模块内是否有数据未读取
do
{
if(wifi_spi_wait_idle(OTHER_TIME_OUT))
{
break;
}
temp_packets.head.command = WIFI_SPI_DATA;
temp_packets.head.length = 0;
wifi_spi_transfer_command(&temp_packets, WIFI_SPI_RECVIVE_SIZE);
// 检查收到的包中是否有数据
if((WIFI_SPI_REPLY_DATA_START == temp_packets.head.command) || (WIFI_SPI_REPLY_DATA_END == temp_packets.head.command))
{
// 保存接收到的数据
if(temp_packets.head.length)
{
fifo_write_buffer(&wifi_spi_fifo, temp_packets.buffer, temp_packets.head.length);
}
}
}while(WIFI_SPI_REPLY_DATA_START == temp_packets.head.command);
wifi_spi_mutex = WIFI_SPI_IDLE;
}
#endif
fifo_read_buffer(&wifi_spi_fifo, buffer, &data_len, FIFO_READ_AND_CLEAN);
return data_len;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 WiFi 模块初始化
// 参数说明 *wifi_ssid 目标连接的 WiFi 的名称 字符串形式
// 参数说明 *pass_word 目标连接的 WiFi 的密码 字符串形式
// 返回参数 uint8 模块初始化状态 0-成功 1-错误
// 使用示例 wifi_spi_init("SEEKFREE", "SEEKFREE123");
// 备注信息 wifi_spi_init("SEEKFREE", NULL); // 连接没有密码的WIFI热点
//-------------------------------------------------------------------------------------------------------------------
uint8 wifi_spi_init (char *wifi_ssid, char *pass_word)
{
uint8 return_state = 0;
fifo_init(&wifi_spi_fifo, FIFO_DATA_8BIT, wifi_spi_buffer, WIFI_SPI_RECVIVE_FIFO_SIZE);
spi_init(WIFI_SPI_INDEX, SPI_MODE0, WIFI_SPI_SPEED, WIFI_SPI_SCK_PIN, WIFI_SPI_MOSI_PIN, WIFI_SPI_MISO_PIN, SPI_CS_NULL);//硬件SPI初始化
gpio_init(WIFI_SPI_CS_PIN, GPO, 1, GPO_PUSH_PULL);
gpio_init(WIFI_SPI_RST_PIN, GPO, 1, GPO_PUSH_PULL);
gpio_init(WIFI_SPI_INT_PIN, GPI, 0, GPI_PULL_DOWN);
// 复位
gpio_set_level(WIFI_SPI_RST_PIN, 0);
system_delay_ms(10);
gpio_set_level(WIFI_SPI_RST_PIN, 1);
// 等待模块初始化
system_delay_ms(100);
wifi_spi_mutex = WIFI_SPI_IDLE;
do
{
// 固件版本信息以字符串形式保存在wifi_spi_version数组中
return_state = wifi_spi_get_version();
if(return_state)
{
break;
}
// MAC地址信息以字符串形式保存在wifi_spi_mac_addr数组中
wifi_spi_get_mac_addr();
return_state = wifi_spi_wifi_connect(wifi_ssid, pass_word);
if(return_state)
{
break;
}
#if(1 == WIFI_SPI_AUTO_CONNECT)
return_state = wifi_spi_socket_connect("TCP", WIFI_SPI_TARGET_IP, WIFI_SPI_TARGET_PORT, WIFI_SPI_LOCAL_PORT);
if(return_state)
{
break;
}
#endif
#if(2 == WIFI_SPI_AUTO_CONNECT)
return_state = wifi_spi_socket_connect("UDP", WIFI_SPI_TARGET_IP, WIFI_SPI_TARGET_PORT, WIFI_SPI_LOCAL_PORT);
if(return_state)
{
break;
}
#endif
}while(0);
return return_state;
}
+153
View File
@@ -0,0 +1,153 @@
/*********************************************************************************************************************
* MSPM0G3507 Opensource Library 即(MSPM0G3507 开源库)是一个基于官方 SDK 接口的第三方开源库
* Copyright (c) 2022 SEEKFREE 逐飞科技
*
* 本文件是 MSPM0G3507 开源库的一部分
*
* MSPM0G3507 开源库 是免费软件
* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款
* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它
*
* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证
* 甚至没有隐含的适销性或适合特定用途的保证
* 更多细节请参见 GPL
*
* 您应该在收到本开源库的同时收到一份 GPL 的副本
* 如果没有,请参阅<https://www.gnu.org/licenses/>
*
* 额外注明:
* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本
* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中
* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件
* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明)
*
* 文件名称 zf_device_wifi_spi
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件版本说明
* 开发环境 MDK 5.37
* 适用平台 MSPM0G3507
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2025-06-1 SeekFree first version
********************************************************************************************************************/
/*********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* RST 查看 zf_device_wifi_spi.h 中 WIFI_SPI_RST_PIN 宏定义
* INT 查看 zf_device_wifi_spi.h 中 WIFI_SPI_INT_PIN 宏定义
* CS 查看 zf_device_wifi_spi.h 中 WIFI_SPI_CS_PIN 宏定义
* MISO 查看 zf_device_wifi_spi.h 中 WIFI_SPI_MISO_PIN 宏定义
* SCK 查看 zf_device_wifi_spi.h 中 WIFI_SPI_SCK_PIN 宏定义
* MOSI 查看 zf_device_wifi_spi.h 中 WIFI_SPI_MOSI_PIN 宏定义
* 5V 5V 电源
* GND 电源地
* 其余引脚悬空
* ------------------------------------
*********************************************************************************************************************/
#ifndef _zf_device_wifi_spi_h
#define _zf_device_wifi_spi_h
#include "zf_common_typedef.h"
#define WIFI_SPI_INDEX (SPI_0) // 定义使用的SPI号
#define WIFI_SPI_SPEED (30 * 1000 * 1000) // 硬件 SPI 速率
#define WIFI_SPI_SCK_PIN (SPI0_SCK_A12) // 定义SPI_SCK引脚
#define WIFI_SPI_MOSI_PIN (SPI0_MOSI_A9) // 定义SPI_MOSI引脚
#define WIFI_SPI_MISO_PIN (SPI0_MISO_A13) // 定义SPI_MISO引脚 IPS没有MISO引脚,但是这里任然需要定义,在spi的初始化时需要使用
#define WIFI_SPI_CS_PIN (B20) // 定义SPI_CS引脚 采用软件CS引脚
#define WIFI_SPI_INT_PIN (A17) // 定义中断引脚
#define WIFI_SPI_RST_PIN (A16) // 定义复位引脚
#define WIFI_SPI_RECVIVE_FIFO_SIZE (1024) // 接收FIFO大小
#define WIFI_SPI_READ_TRANSFER (1) // 在调用wifi_spi_read_buffer 是否尝试发起SPI通讯来检测模块内是否有数据需要读取 1:发起SPI通讯 0:不发起SPI通讯,仅读取FIFO
// 如果应用程序中没有任何的地方调用发送函数,则WIFI_SPI_READ_TRANSFER必须设置为1
#define WIFI_SPI_AUTO_CONNECT (0) // 定义是否初始化时建立TCP或者UDP连接 0-不自动连接 1-自动连接TCP服务器 2-自动连接UDP
#if (WIFI_SPI_AUTO_CONNECT > 2)
#error "WIFI_SPI_AUTO_CONNECT 的值只能为 [0,1,2]"
#else
#define WIFI_SPI_TARGET_IP "192.168.137.1" // 连接目标的 IP
#define WIFI_SPI_TARGET_PORT "8000" // 连接目标的端口
#define WIFI_SPI_LOCAL_PORT "8086" // 本机的端口 0:随机 可设置范围2048-65535 默认 6666
#endif
#define WIFI_SPI_RECVIVE_SIZE (32) // 每次SPI传输接收的字节数 不允许修改
#define WIFI_SPI_TRANSFER_SIZE (4088) // 最大SPI传输接收的字节数 不允许修改
typedef enum
{
// 主机发送的命令
WIFI_SPI_INVALID1 = 0x00, // 无效数据包
WIFI_SPI_RESET = 0x01, // 复位命令
WIFI_SPI_DATA = 0x02, // 透传数据包
WIFI_SPI_UDP_SEND = 0x03, // UDP下立即发送命令,默认SPI接收数据后2MS未收到数据自动发送数据
WIFI_SPI_CLOSE_SOCKET = 0x04, // 断开连接
WIFI_SPI_SET_WIFI_INFORMATION = 0x10, // 设置WIFI信息命令
WIFI_SPI_SET_SOCKET_INFORMATION = 0x11, // 设置SOCKET信息命令
WIFI_SPI_GET_VERSION = 0x20, // 获取模块版本
WIFI_SPI_GET_MAC_ADDR = 0x21, // 获取模块MAC地址
WIFI_SPI_GET_IP_ADDR = 0x22, // 获取模块IP地址
// 从机回传的命令
WIFI_SPI_REPLY_OK = 0x80, // 从机应答的正确命令
WIFI_SPI_REPLY_ERROR = 0x81, // 从机应答的错误命令
WIFI_SPI_REPLY_DATA_START = 0x90, // 从机回传的数据包,并且还有数据需要主机读取
WIFI_SPI_REPLY_DATA_END = 0x91, // 从机回传的数据包,数据已读取完毕
WIFI_SPI_REPLY_VERSION = 0xA0, // 从机回复固件版本
WIFI_SPI_REPLY_MAC_ADDR = 0xA1, // 从机回复本机MAC地址等信息
WIFI_SPI_REPLY_IP_ADDR = 0xA2, // 从机回复本机IP地址、端口号
WIFI_SPI_INVALID2 = 0xFF // 无效数据包
}wifi_spi_packets_command_enum;
typedef enum
{
WIFI_SPI_IDLE, // 模块空闲,可以进行SPI通讯
WIFI_SPI_BUSY, // 模块正忙,不可进行SPI通讯
}wifi_spi_state_enum;
typedef struct
{
uint8 command; // 命令字
uint8 reserve; // 保留
uint16 length; // 包有效长度
}wifi_spi_head_struct;
typedef struct
{
wifi_spi_head_struct head; // 帧头
uint8 buffer[WIFI_SPI_RECVIVE_SIZE]; // 缓冲区
}wifi_spi_packets_struct;
extern char wifi_spi_version[12]; // 固件版本 字符串
extern char wifi_spi_mac_addr[20]; // 模块MAC地址 字符串
extern char wifi_spi_ip_addr_port[25]; // IP地址与端口号 字符串
uint8 wifi_spi_wifi_connect (char *wifi_ssid, char *pass_word);
uint8 wifi_spi_socket_connect (char *transport_type, char *ip_addr, char *port, char *local_port);
uint8 wifi_spi_socket_disconnect (void);
uint8 wifi_spi_udp_send_now (void);
uint32 wifi_spi_send_buffer (const uint8 *buff, uint32 length);
void wifi_spi_send_string (const char *string);
uint32 wifi_spi_read_buffer (uint8 *buffer, uint32 length);
uint8 wifi_spi_init (char *wifi_ssid, char *pass_word);
#endif
File diff suppressed because it is too large Load Diff
+148
View File
@@ -0,0 +1,148 @@
/*********************************************************************************************************************
* MSPM0G3507 Opensource Library 即(MSPM0G3507 开源库)是一个基于官方 SDK 接口的第三方开源库
* Copyright (c) 2022 SEEKFREE 逐飞科技
*
* 本文件是 MSPM0G3507 开源库的一部分
*
* MSPM0G3507 开源库 是免费软件
* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款
* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它
*
* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证
* 甚至没有隐含的适销性或适合特定用途的保证
* 更多细节请参见 GPL
*
* 您应该在收到本开源库的同时收到一份 GPL 的副本
* 如果没有,请参阅<https://www.gnu.org/licenses/>
*
* 额外注明:
* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本
* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中
* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件
* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明)
*
* 文件名称 zf_device_wifi_uart
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件版本说明
* 开发环境 MDK 5.37
* 适用平台 MSPM0G3507
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2025-06-1 SeekFree first version
********************************************************************************************************************/
/*********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* RX 查看 zf_device_wifi_uart.h 中 WIFI_UART_RX_PIN 宏定义
* TX 查看 zf_device_wifi_uart.h 中 WIFI_UART_TX_PIN 宏定义
* RTS 查看 zf_device_wifi_uart.h 中 WIFI_UART_RTS_PIN 宏定义
* RST 查看 zf_device_wifi_uart.h 中 WIFI_UART_RST_PIN 宏定义
* VCC 5V 电源
* GND 电源地
* 其余引脚悬空
* ------------------------------------
*********************************************************************************************************************/
#ifndef _zf_device_wifi_uart_h_
#define _zf_device_wifi_uart_h_
#include "zf_common_typedef.h"
#define WIFI_UART_INDEX ( UART_1 ) // WIFI 模块 所使用到的串口
#define WIFI_UART_RX_PIN ( UART1_TX_B6 ) // 连接 WIFI 模块 RX
#define WIFI_UART_TX_PIN ( UART1_RX_B7 ) // 连接 WIFI 模块 TX
#define WIFI_UART_BAUD ( 115200 ) // 模块工作波特率
#define WIFI_UART_RTS_PIN ( B2 ) // 定义流控位引脚 指示当前模块是否可以接受数据 0-可以继续接收 1-不可以继续接收
#define WIFI_UART_HARDWARE_RST ( 1 ) // 定义是否使用硬件复位引脚 0-使用软件复位 1-使用硬件 RST
#if WIFI_UART_HARDWARE_RST // 建议使用硬件复位引脚 否则容易出现单片机复位后无法正常初始化模块
#define WIFI_UART_RST_PIN ( B3 ) // 定义硬件复位引脚
#endif
#define WIFI_UART_BUFFER_SIZE (256) // 定义接收缓存区大小
#define WIFI_UART_AUTO_CONNECT (0) // 定义是否初始化时建立TCP或者UDP连接 0-不连接 1-自动连接TCP服务器 2-自动连接UDP服务器 3:自动建立TCP服务器
#if (WIFI_UART_AUTO_CONNECT > 3)
#error "WIFI_UART_AUTO_CONNECT 的值只能为 [0,1,2,3]"
#else
#define WIFI_UART_TARGET_IP "192.168.2.16" // 连接目标的 IP
#define WIFI_UART_TARGET_PORT "8086" // 连接目标的端口
#define WIFI_UART_LOCAL_PORT "5555" // 本机端口
#endif
typedef enum
{
WIFI_UART_STATION, // 设备模式
WIFI_UART_SOFTAP, // AP模式
}wifi_uart_mode_enum;
typedef enum
{
WIFI_UART_COMMAND, // 使用命令的方式发送数据
WIFI_UART_SERIANET, // 使用透传的方式发送数据
}wifi_uart_transfer_mode_enum;
typedef enum
{
WIFI_UART_TCP_CLIENT, // 模块连接TCP服务器
WIFI_UART_TCP_SERVER, // 模块作为TCP服务器
WIFI_UART_UDP_CLIENT, // 模块启用UDP连接
}wifi_uart_connect_mode_enum;
typedef enum
{
WIFI_UART_SERVER_OFF, // 模块未连接服务器
WIFI_UART_SERVER_ON, // 模块已经连接服务器
}wifi_uart_connect_state_enum;
typedef enum
{
WIFI_UART_LINK_0, // 模块当前链接 0
WIFI_UART_LINK_1, // 模块当前链接 1
WIFI_UART_LINK_2, // 模块当前链接 2
WIFI_UART_LINK_3, // 模块当前链接 3
WIFI_UART_LINK_4, // 模块当前链接 4
}wifi_uart_link_id_enum;
typedef struct
{
uint8 wifi_uart_version[12]; // 固件版本 字符串形式
uint8 wifi_uart_mac[20]; // 本机 MAC 地址 字符串形式
uint8 wifi_uart_local_ip[17]; // 本机 IP 地址 字符串形式
uint8 wifi_uart_local_port[10]; // 本机端口号 字符串形式
uint8 wifi_uart_remote_ip[5][17]; // 远端 IP 地址 字符串形式
wifi_uart_mode_enum wifi_uart_mode; // WIFI 模式
wifi_uart_transfer_mode_enum wifi_uart_transfer_mode; // 当前传输模式
wifi_uart_connect_mode_enum wifi_uart_connect_mode; // 网络连接模式
wifi_uart_connect_state_enum wifi_uart_connect_state; // 服务器连接情况
}wifi_uart_information_struct;
extern wifi_uart_information_struct wifi_uart_information;
uint8 wifi_uart_get_gmt_time (char* gmt_time);
uint8 wifi_uart_disconnected_wifi (void); // 断开 WIFI 连接
uint8 wifi_uart_entry_serianet (void); // 打开透传模式
uint8 wifi_uart_exit_serianet (void); // 关闭透传模式
uint8 wifi_uart_connect_tcp_servers (char *ip, char *port, wifi_uart_transfer_mode_enum mode); // 建立 TCP 连接
uint8 wifi_uart_connect_udp_client (char *ip, char *port, char *local_port, wifi_uart_transfer_mode_enum mode); // 建立 UDP 传输
uint8 wifi_uart_disconnect_link (void); // 断开连接 TCP Server 使用本接口将会断开所有连接
uint8 wifi_uart_disconnect_link_with_id (wifi_uart_link_id_enum link_id); // TCP Server 断开指定连接 TCP/UDP Client 将不会有反应
uint8 wifi_uart_entry_tcp_servers (char *port); // 建立 TCP 服务器
uint8 wifi_uart_exit_tcp_servers (void); // 关闭 TCP 服务器
uint8 wifi_uart_tcp_servers_check_link (void); // TCP Server 模式下检查当前链接数量 并获取 IP
uint32 wifi_uart_send_buffer (const uint8 *buff, uint32 len); // WIFI 模块数据发送函数
uint32 wifi_uart_tcp_servers_send_buffer (const uint8 *buff, uint32 len, wifi_uart_link_id_enum id); // WIFI 模块作为 TCP Server 指定目标设备发送函数
uint32 wifi_uart_read_buffer (uint8 *buff, uint32 len); // WIFI 模块数据接收函数
void wifi_uart_callback (void); // WIFI 模块串口回调函数
uint8 wifi_uart_init (char *wifi_ssid, char *pass_word, wifi_uart_mode_enum wifi_mode); // WIFI 模块初始化函数
#endif
@@ -0,0 +1,281 @@
/*********************************************************************************************************************
* MSPM0G3507 Opensource Library 即(MSPM0G3507 开源库)是一个基于官方 SDK 接口的第三方开源库
* Copyright (c) 2022 SEEKFREE 逐飞科技
*
* 本文件是 MSPM0G3507 开源库的一部分
*
* MSPM0G3507 开源库 是免费软件
* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款
* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它
*
* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证
* 甚至没有隐含的适销性或适合特定用途的保证
* 更多细节请参见 GPL
*
* 您应该在收到本开源库的同时收到一份 GPL 的副本
* 如果没有,请参阅<https://www.gnu.org/licenses/>
*
* 额外注明:
* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本
* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中
* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件
* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明)
*
* 文件名称 zf_device_wireless_uart
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件版本说明
* 开发环境 MDK 5.37
* 适用平台 MSPM0G3507
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2025-06-1 SeekFree first version
********************************************************************************************************************/
/*********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* RX 查看 zf_device_wireless_uart.h 中 WIRELESS_UART_RX_PINx 宏定义
* TX 查看 zf_device_wireless_uart.h 中 WIRELESS_UART_TX_PINx 宏定义
* RTS 查看 zf_device_wireless_uart.h 中 WIRELESS_UART_RTS_PINx 宏定义
* VCC 3.3V电源
* GND 电源地
* 其余引脚悬空
* ------------------------------------
********************************************************************************************************************/
#include "zf_common_debug.h"
#include "zf_common_fifo.h"
#include "zf_driver_delay.h"
#include "zf_driver_gpio.h"
#include "zf_driver_uart.h"
#include "zf_device_type.h"
#include "zf_device_wireless_uart.h"
static fifo_struct wireless_uart_fifo;
static uint8 wireless_uart_buffer[WIRELESS_UART_BUFFER_SIZE];
static uint8 wireless_uart_data = 0;
#if (1 == WIRELESS_UART_AUTO_BAUD_RATE)
static volatile wireless_uart_auto_baudrate_state_enum wireless_auto_baud_flag = WIRELESS_UART_AUTO_BAUD_RATE_INIT;
static volatile uint8 wireless_auto_baud_data[3] = {0x00, 0x01, 0x03};
#endif
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 无线转串口模块 发送数据
// 参数说明 data 8bit 数据
// 返回参数 uint32 剩余发送长度 0-发送完毕 1-未发送完成
// 使用示例 wireless_uart_send_byte(data);
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
uint32 wireless_uart_send_byte (const uint8 data)
{
uint16 time_count = WIRELESS_UART_TIMEOUT_COUNT;
while(time_count)
{
if(!gpio_get_level(WIRELESS_UART_RTS_PIN))
{
uart_write_byte(WIRELESS_UART_INDEX, data); // 发送数据
break;
}
time_count --;
system_delay_ms(1);
}
return (0 == time_count);
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 无线转串口模块 发送数据块
// 参数说明 *buff 发送缓冲区
// 参数说明 len 发送数据长度
// 返回参数 uint32 剩余发送长度
// 使用示例 wireless_uart_send_buffer(buff, 64);
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
uint32 wireless_uart_send_buffer (const uint8 *buff, uint32 len)
{
zf_assert(NULL != buff);
uint16 time_count = 0;
while(0 != len)
{
if(!gpio_get_level(WIRELESS_UART_RTS_PIN)) // 如果RTS为低电平 则继续发送数据
{
if(30 <= len) // 数据分 30byte 每包发送
{
uart_write_buffer(WIRELESS_UART_INDEX, buff, 30); // 发送数据
buff += 30; // 地址偏移
len -= 30; // 数量
time_count = 0;
}
else // 不足 30byte 的数据一次性发送完毕
{
uart_write_buffer(WIRELESS_UART_INDEX, buff, len); // 发送数据
len = 0;
break;
}
}
else // 如果RTS为高电平 则模块忙
{
if(WIRELESS_UART_TIMEOUT_COUNT <= (++ time_count)) // 超出了最大等待时间
{
break; // 退出发送
}
system_delay_ms(1);
}
}
return len;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 无线转串口模块 发送字符串
// 参数说明 *str 要发送的字符串地址
// 返回参数 uint32 剩余发送长度
// 使用示例 wireless_uart_send_string("Believe in yourself.");
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
uint32 wireless_uart_send_string (const char *str)
{
zf_assert(NULL != str);
uint16 time_count = 0;
uint32 len = strlen(str);
while(0 != len)
{
if(!gpio_get_level(WIRELESS_UART_RTS_PIN)) // 如果RTS为低电平 则继续发送数据
{
if(30 <= len) // 数据分 30byte 每包发送
{
uart_write_buffer(WIRELESS_UART_INDEX, (const uint8 *)str, 30); // 发送数据
str += 30; // 地址偏移
len -= 30; // 数量
time_count = 0;
}
else // 不足 30byte 的数据一次性发送完毕
{
uart_write_buffer(WIRELESS_UART_INDEX, (const uint8 *)str, len);// 发送数据
len = 0;
break;
}
}
else // 如果RTS为高电平 则模块忙
{
if(WIRELESS_UART_TIMEOUT_COUNT <= (++ time_count)) // 超出了最大等待时间
{
break; // 退出发送
}
system_delay_ms(1);
}
}
return len;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 无线转串口模块 读取缓冲
// 参数说明 *buff 接收缓冲区
// 参数说明 len 读取数据长度
// 返回参数 uint32 实际读取数据长度
// 使用示例 wireless_uart_read_buffer(buff, 32);
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
uint32 wireless_uart_read_buffer (uint8 *buff, uint32 len)
{
zf_assert(NULL != buff);
uint32 data_len = len;
fifo_read_buffer(&wireless_uart_fifo, buff, &data_len, FIFO_READ_AND_CLEAN);
return data_len;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 无线转串口模块 串口中断回调函数
// 参数说明 void
// 返回参数 void
// 使用示例 wireless_uart_callback();
// 备注信息 该函数在 ISR 文件 串口中断程序被调用
// 由串口中断服务函数调用 wireless_module_uart_handler() 函数
// 再由 wireless_module_uart_handler() 函数调用本函数
//-------------------------------------------------------------------------------------------------------------------
void wireless_uart_callback (void)
{
if(uart_query_byte(WIRELESS_UART_INDEX, &wireless_uart_data))
{
fifo_write_buffer(&wireless_uart_fifo, &wireless_uart_data, 1);
}
#if WIRELESS_UART_AUTO_BAUD_RATE // 开启自动波特率
if(WIRELESS_UART_AUTO_BAUD_RATE_START == wireless_auto_baud_flag && 3 == fifo_used(&wireless_uart_fifo))
{
uint32 wireless_auto_baud_count = 3;
wireless_auto_baud_flag = WIRELESS_UART_AUTO_BAUD_RATE_GET_ACK;
fifo_read_buffer(&wireless_uart_fifo, (uint8 *)wireless_auto_baud_data, (uint32 *)&wireless_auto_baud_count, FIFO_READ_AND_CLEAN);
}
#endif
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 无线转串口模块 初始化
// 参数说明 void
// 返回参数 void
// 使用示例 wireless_uart_init();
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
uint8 wireless_uart_init (void)
{
uint8 return_state = 0;
set_wireless_type(WIRELESS_UART, wireless_uart_callback);
fifo_init(&wireless_uart_fifo, FIFO_DATA_8BIT, wireless_uart_buffer, WIRELESS_UART_BUFFER_SIZE);
gpio_init(WIRELESS_UART_RTS_PIN, GPI, GPIO_HIGH, GPI_PULL_UP);
#if(0 == WIRELESS_UART_AUTO_BAUD_RATE) // 关闭自动波特率
// 本函数使用的波特率为115200 为无线转串口模块的默认波特率 如需其他波特率请自行配置模块并修改串口的波特率
uart_init (WIRELESS_UART_INDEX, WIRELESS_UART_BUAD_RATE, WIRELESS_UART_RX_PIN, WIRELESS_UART_TX_PIN); // 初始化串口
// uart_rx_interrupt(WIRELESS_UART_INDEX, 1);
uart_set_interrupt_config(WIRELESS_UART_INDEX,UART_INTERRUPT_CONFIG_RX_ENABLE);
#elif(1 == WIRELESS_UART_AUTO_BAUD_RATE) // 开启自动波特率
uint8 rts_init_status = 0;
wireless_auto_baud_flag = WIRELESS_UART_AUTO_BAUD_RATE_INIT;
wireless_auto_baud_data[0] = 0;
wireless_auto_baud_data[1] = 1;
wireless_auto_baud_data[2] = 3;
rts_init_status = gpio_get_level(WIRELESS_UART_RTS_PIN);
gpio_init(WIRELESS_UART_RTS_PIN, GPO, rts_init_status, GPO_PUSH_PULL); // 初始化流控引脚
uart_init (WIRELESS_UART_INDEX, WIRELESS_UART_BUAD_RATE, WIRELESS_UART_RX_PIN, WIRELESS_UART_TX_PIN); // 初始化串口
uart_rx_interrupt(WIRELESS_UART_INDEX, 1);
system_delay_ms(5); // 模块上电之后需要延时等待
gpio_set_level(WIRELESS_UART_RTS_PIN, !rts_init_status); // RTS引脚拉高,进入自动波特率模式
system_delay_ms(100); // RTS拉高之后必须延时20ms
gpio_toggle_level(WIRELESS_UART_RTS_PIN); // RTS引脚取反
do
{
wireless_auto_baud_flag = WIRELESS_UART_AUTO_BAUD_RATE_START;
uart_write_byte(WIRELESS_UART_INDEX, wireless_auto_baud_data[0]); // 发送特定数据 用于模块自动判断波特率
uart_write_byte(WIRELESS_UART_INDEX, wireless_auto_baud_data[1]); // 发送特定数据 用于模块自动判断波特率
uart_write_byte(WIRELESS_UART_INDEX, wireless_auto_baud_data[2]); // 发送特定数据 用于模块自动判断波特率
system_delay_ms(20);
if(WIRELESS_UART_AUTO_BAUD_RATE_GET_ACK != wireless_auto_baud_flag) // 检验自动波特率是否完成
{
return_state = 1; // 如果程序进入到此语句内 说明自动波特率失败了
break;
}
if( 0xa5 != wireless_auto_baud_data[0] && // 检验自动波特率是否正确
0xff != wireless_auto_baud_data[1] && // 检验自动波特率是否正确
0xff != wireless_auto_baud_data[2] ) // 检验自动波特率是否正确
{
return_state = 1; // 如果程序进入到此语句内 说明自动波特率失败了
break;
}
wireless_auto_baud_flag = WIRELESS_UART_AUTO_BAUD_RATE_SUCCESS;
gpio_init(WIRELESS_UART_RTS_PIN, GPI, 0, GPI_PULL_UP); // 初始化流控引脚
system_delay_ms(10); // 延时等待 模块准备就绪
}while(0);
#endif
return return_state;
}
@@ -0,0 +1,101 @@
/*********************************************************************************************************************
* MSPM0G3507 Opensource Library 即(MSPM0G3507 开源库)是一个基于官方 SDK 接口的第三方开源库
* Copyright (c) 2022 SEEKFREE 逐飞科技
*
* 本文件是 MSPM0G3507 开源库的一部分
*
* MSPM0G3507 开源库 是免费软件
* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款
* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它
*
* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证
* 甚至没有隐含的适销性或适合特定用途的保证
* 更多细节请参见 GPL
*
* 您应该在收到本开源库的同时收到一份 GPL 的副本
* 如果没有,请参阅<https://www.gnu.org/licenses/>
*
* 额外注明:
* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本
* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中
* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件
* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明)
*
* 文件名称 zf_device_wireless_uart
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件版本说明
* 开发环境 MDK 5.37
* 适用平台 MSPM0G3507
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2025-06-1 SeekFree first version
********************************************************************************************************************/
/*********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* RX 查看 zf_device_wireless_uart.h 中 WIRELESS_UART_RX_PINx 宏定义
* TX 查看 zf_device_wireless_uart.h 中 WIRELESS_UART_TX_PINx 宏定义
* RTS 查看 zf_device_wireless_uart.h 中 WIRELESS_UART_RTS_PINx 宏定义
* VCC 3.3V电源
* GND 电源地
* 其余引脚悬空
* ------------------------------------
********************************************************************************************************************/
#ifndef _zf_device_wireless_uart_h_
#define _zf_device_wireless_uart_h_
#include "zf_common_typedef.h"
//================================================定义 无线串口 基本配置===================================================
#define WIRELESS_UART_INDEX (UART_1 ) // 无线串口对应使用的串口号
#define WIRELESS_UART_BUAD_RATE (115200 ) // 无线串口对应使用的串口波特率
#define WIRELESS_UART_TX_PIN (UART1_RX_B7 ) // 无线串口对应模块的 TX 要接到单片机的 RX
#define WIRELESS_UART_RX_PIN (UART1_TX_B6 ) // 无线串口对应模块的 RX 要接到单片机的 TX
#define WIRELESS_UART_RTS_PIN (B2 ) // 无线串口对应模块的 RTS 引脚
//====================================================自动波特率====================================================
// 注意事项1:无线转串口模块版本是V2.0以下的是无法开启自动波特率的。
// 注意事项2:开启自动波特率务必连接RTS引脚 否则会开启失败。
// 注意事项3:模块自动波特率失败的话 可以尝试断电重启
// 开启自动波特率务必阅读上面两条 注意事项
// 开启自动波特率务必阅读上面两条 注意事项
// 开启自动波特率务必阅读上面两条 注意事项
// 0:关闭自动波特率
// 1:开启自动波特率 自动波特率的作用是修改 WIRELESS_UART_BAUD 之后不需要对模块进行配置 模块会自动设置为对应的波特率
#define WIRELESS_UART_AUTO_BAUD_RATE ( 0 )
//====================================================自动波特率====================================================
#if (1 == WIRELESS_UART_AUTO_BAUD_RATE)
typedef enum
{
WIRELESS_UART_AUTO_BAUD_RATE_SUCCESS,
WIRELESS_UART_AUTO_BAUD_RATE_INIT,
WIRELESS_UART_AUTO_BAUD_RATE_START,
WIRELESS_UART_AUTO_BAUD_RATE_GET_ACK,
}wireless_uart_auto_baudrate_state_enum;
#endif
#define WIRELESS_UART_BUFFER_SIZE ( 64 )
#define WIRELESS_UART_TIMEOUT_COUNT ( 0x64 )
//================================================定义 无线串口 基本配置===================================================
//================================================声明 无线串口 基础函数===================================================
uint32 wireless_uart_send_byte (const uint8 data);
uint32 wireless_uart_send_buffer (const uint8 *buff, uint32 len);
uint32 wireless_uart_send_string (const char *str);
uint32 wireless_uart_read_buffer (uint8 *buff, uint32 len);
void wireless_uart_callback (void);
uint8 wireless_uart_init (void);
//================================================声明 无线串口 基础函数===================================================
#endif