Initial commit: TC264 smart car project with IPS200 menu system

- IPS200 display menu with real-time status and parameter settings
- Camera image processing and line tracking
- IMU attitude solution and PID control
- WiFi SPI oscilloscope data transmission
This commit is contained in:
32343 committed 2026-05-10 21:38:49 +08:00
commit 843447835d
660 files changed
+443632

No files matched your search

@@ -0,0 +1,230 @@
/*********************************************************************************************************************
* 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_absolute_encoder
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 ADS v1.10.2
* 适用平台 TC264D
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2022-09-15 pudding first version
* 2023-04-25 pudding 增加中文注释说明
********************************************************************************************************************/
/*********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* 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_debug.h"
#include "zf_common_function.h"
#include "zf_driver_delay.h"
#include "zf_driver_soft_spi.h"
#include "zf_driver_spi.h"
#include "zf_device_absolute_encoder.h"
static int16 now_location = 0; // 当前位置定义 static:静态声明,仅此文件可用此变量
static int16 last_location = 0; // 上次位置定义 static:静态声明,仅此文件可用此变量
#if ABSOLUTE_ENCODER_USE_SOFT_SPI
static soft_spi_info_struct absolute_encoder_spi; // 定义角度编码器软件SPI结构体
#define absolute_encoder_read() (soft_spi_read_8bit(&absolute_encoder_spi)) // 定义数据读取函数
#define absolute_encoder_write(data) (soft_spi_write_8bit(&absolute_encoder_spi, (data))) // 定义数据写入函数
#else
#define absolute_encoder_read() (spi_read_8bit(ABSOLUTE_ENCODER_SPI)) // 定义数据读取函数
#define absolute_encoder_write(data) (spi_write_8bit(ABSOLUTE_ENCODER_SPI, (data))) // 定义数据写入函数
#endif
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 绝对值编码器写寄存器
// 参数说明 reg 寄存器地址
// 参数说明 data 数据
// 返回参数 void
// 使用示例 absolute_encoder_write_register(i + 1, dat[i]);
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
static void absolute_encoder_write_register(uint8 reg, uint8 data)
{
ABSOLUTE_ENCODER_CSN(0); // 片选拉低选中
absolute_encoder_write(reg | ABSOLUTE_ENCODER_SPI_W); // 寄存器
absolute_encoder_write(data); // 数据
ABSOLUTE_ENCODER_CSN(1); // 片选拉高释放
system_delay_us(1); // 必要操作
ABSOLUTE_ENCODER_CSN(0); // 片选拉低选中
absolute_encoder_read(); // 这里会返回写入是否成功 但不作判断
absolute_encoder_read(); // 必要操作
ABSOLUTE_ENCODER_CSN(1); // 片选拉高释放
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 绝对值编码器读寄存器 内部调用
// 参数说明 reg 寄存器地址
// 返回参数 uint8 数据
// 使用示例 absolute_encoder_read_register(6);
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
static uint8 absolute_encoder_read_register(uint8 reg)
{
uint8 data = 0;
ABSOLUTE_ENCODER_CSN(0); // 片选拉低选中
absolute_encoder_write(reg | ABSOLUTE_ENCODER_SPI_R); // 寄存器
absolute_encoder_write(0x00); // 占位
ABSOLUTE_ENCODER_CSN(1); // 片选拉高释放
system_delay_us(1); // 必要操作
ABSOLUTE_ENCODER_CSN(0); // 片选拉低选中
data = absolute_encoder_read(); // 获取读取的数据
absolute_encoder_read(); // 必要操作
ABSOLUTE_ENCODER_CSN(1); // 片选拉高释放
return data;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 绝对值编码器读位置 内部调用
// 参数说明 void
// 返回参数 uint16 位置值
// 使用示例 absolute_encoder_read_data();
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
static uint16 absolute_encoder_read_data (void)
{
uint16 data = 0;
ABSOLUTE_ENCODER_CSN(0); // 片选拉低选中
data = absolute_encoder_read(); // 获取高八位数据
data = (data & 0x00FF) << 8; // 数据位移
data |= absolute_encoder_read(); // 获取低八位数据
ABSOLUTE_ENCODER_CSN(1); // 片选拉高释放
return data;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 绝对值编码器自检 内部调用
// 参数说明 void
// 返回参数 uint8 自检状态
// 使用示例 absolute_encoder_self_check();
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
static uint8 absolute_encoder_self_check (void)
{
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(6)) // 获取状态寄存器
{
for(i = 0; 6 > i; i ++)
{
absolute_encoder_write_register(i + 1, dat[i]); // 写入默认配置参数
system_delay_ms(1);
}
if(ABSOLUTE_ENCODER_TIMEOUT_COUNT < time_count ++) // 等待超时
{
return_state = 1;
break;
}
}
return return_state;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 绝对值编码器获取当前角度值
// 参数说明 void
// 返回参数 int16 角度值
// 使用示例 absolute_encoder_get_location();
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
int16 absolute_encoder_get_location (void)
{
last_location = now_location; // 更新数据前保存上一次的位置
now_location = absolute_encoder_read_data() >> 4; // 读取当前位置
return now_location;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 绝对值编码器获取相较上次位置的偏移值
// 参数说明 void
// 返回参数 int16 偏移值
// 使用示例 absolute_encoder_get_offset();
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
int16 absolute_encoder_get_offset (void)
{
int16 result_data = 0;
if(2048 < func_abs(now_location - last_location))
{
result_data = (2048 < now_location ? (now_location - 4096 - last_location) : (now_location + 4096 - last_location));
}
else
{
result_data = (now_location - last_location);
}
return result_data;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 绝对值编码器初始化
// 参数说明 void
// 返回参数 uint8 初始化状态 0-成功 1-失败
// 使用示例 absolute_encoder_init();
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
uint8 absolute_encoder_init (void)
{
uint8 return_state = 0;
uint16 zero_position = ABSOLUTE_ENCODER_DEFAULT_ZERO;
#if ABSOLUTE_ENCODER_USE_SOFT_SPI
soft_spi_init(&absolute_encoder_spi, 0, ABSOLUTE_ENCODER_SOFT_SPI_DELAY, ABSOLUTE_ENCODER_SCLK_PIN, ABSOLUTE_ENCODER_MOSI_PIN, ABSOLUTE_ENCODER_MISO_PIN, SOFT_SPI_PIN_NULL);
#else
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);
#endif
gpio_init(ABSOLUTE_ENCODER_CS_PIN, GPO, GPIO_LOW, GPO_PUSH_PULL);
do
{
if(absolute_encoder_self_check())
{
// 如果程序在输出了断言信息 并且提示出错位置在这里
// 那么就是绝对值编码器自检出错并超时退出了
// 检查一下接线有没有问题 如果没问题可能就是坏了
return_state = 1;
zf_log(0, "absolute encoder init errror.");
break;
}
absolute_encoder_write_register(ABSOLUTE_ENCODER_DIR_REG, 0x00); // 设置旋转方向 正转数值变小:0x00 反转数值变大:0x80
zero_position = (uint16)(4096 - zero_position);
zero_position = zero_position << 4;
absolute_encoder_write_register(ABSOLUTE_ENCODER_ZERO_L_REG, (uint8)zero_position); // 设置零位
absolute_encoder_write_register(ABSOLUTE_ENCODER_ZERO_H_REG, zero_position >> 8);
}while(0);
return return_state;
}
@@ -0,0 +1,94 @@
/*********************************************************************************************************************
* 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_absolute_encoder
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 ADS v1.10.2
* 适用平台 TC264D
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2022-09-15 pudding first version
* 2023-04-25 pudding 增加中文注释说明
********************************************************************************************************************/
/*********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* 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"
//=================================================定义 角度传感器 基本配置================================================
#define ABSOLUTE_ENCODER_USE_SOFT_SPI (0) // 默认使用硬件 SPI 方式驱动
#if ABSOLUTE_ENCODER_USE_SOFT_SPI // 这两段 颜色正常的才是正确的 颜色灰的就是没有用的
//====================================================软件 SPI 驱动====================================================
#define ABSOLUTE_ENCODER_SOFT_SPI_DELAY (1) // 软件 SPI 的时钟延时周期 数值越小 SPI 通信速率越快
#define ABSOLUTE_ENCODER_SCLK_PIN (P20_11) // 软件 SPI SCK 引脚
#define ABSOLUTE_ENCODER_MOSI_PIN (P20_14) // 软件 SPI MOSI 引脚
#define ABSOLUTE_ENCODER_MISO_PIN (P20_12) // 软件 SPI MISO 引脚
//====================================================软件 SPI 驱动====================================================
#else
//====================================================硬件 SPI 驱动====================================================
#define ABSOLUTE_ENCODER_SPI_SPEED (10*1000*1000) // 硬件 SPI 速率
#define ABSOLUTE_ENCODER_SPI (SPI_0) // 硬件 SPI 号
#define ABSOLUTE_ENCODER_SCLK_PIN (SPI0_SCLK_P20_11) // 硬件 SPI SCK 引脚
#define ABSOLUTE_ENCODER_MOSI_PIN (SPI0_MOSI_P20_14) // 硬件 SPI MOSI 引脚
#define ABSOLUTE_ENCODER_MISO_PIN (SPI0_MISO_P20_12) // 硬件 SPI MISO 引脚
//====================================================硬件 SPI 驱动====================================================
#endif
#define ABSOLUTE_ENCODER_CS_PIN (P20_13) // CS引脚定义
#define ABSOLUTE_ENCODER_CSN(x) ((x) ? (gpio_high(ABSOLUTE_ENCODER_CS_PIN)): (gpio_low(ABSOLUTE_ENCODER_CS_PIN)))
#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)
//=================================================定义 角度传感器 基本配置================================================
//=================================================声明 角度传感器 基础函数================================================
int16 absolute_encoder_get_location (void); // 绝对值编码器获取当前角度值
int16 absolute_encoder_get_offset (void); // 绝对值编码器获取相较上次位置的偏移值
uint8 absolute_encoder_init (void); // 绝对值编码器初始化
//=================================================声明 角度传感器 基础函数================================================
#endif
+299
View File
@@ -0,0 +1,299 @@
/*********************************************************************************************************************
* 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_ble6a20
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 ADS v1.10.2
* 适用平台 TC264D
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2024-07-02 pudding first version
********************************************************************************************************************/
/*********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* RX 查看 zf_device_ble6a20.h 中 BLE6A20_RX_PIN 宏定义
* TX 查看 zf_device_ble6a20.h 中 BLE6A20_TX_PIN 宏定义
* RTS 查看 zf_device_ble6a20.h 中 BLE6A20_RTS_PIN 宏定义
* VCC 3.3V电源
* GND 电源地
* 其余引脚悬空
* ------------------------------------
*********************************************************************************************************************/
#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_uart.h"
#include "zf_device_type.h"
#include "zf_device_ble6a20.h"
static fifo_struct ble6a20_fifo;
static uint8 ble6a20_buffer[BLE6A20_BUFFER_SIZE];
static uint8 ble6a20_data = 0;
#if (1 == BLE6A20_AUTO_BAUD_RATE)
static volatile ble6a20_auto_baudrate_state_enum ble6a20_auto_baud_flag = BLE6A20_AUTO_BAUD_RATE_INIT;
static volatile uint8 ble6a20_auto_baud_data[3] = {0x00, 0x01, 0x03};
#endif
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 蓝牙转串口模块 发送数据
// 参数说明 data 8bit 数据
// 返回参数 uint32 剩余发送长度 0-发送完毕 1-未发送完成
// 使用示例 ble6a20_send_byte(data);
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
uint32 ble6a20_send_byte (const uint8 data)
{
uint16 time_count = BLE6A20_TIMEOUT_COUNT;
while(time_count)
{
if(!gpio_get_level(BLE6A20_RTS_PIN))
{
uart_write_byte(BLE6A20_INDEX, data); // 发送数据
break;
}
time_count --;
system_delay_ms(1);
}
return (0 == time_count);
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 蓝牙转串口模块 发送数据块
// 参数说明 *buff 发送缓冲区
// 参数说明 len 发送数据长度
// 返回参数 uint32 剩余发送长度
// 使用示例 ble6a20_send_buffer(buff, 64);
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
uint32 ble6a20_send_buffer (const uint8 *buff, uint32 len)
{
zf_assert(NULL != buff);
uint16 time_count = 0;
while(0 != len)
{
if(!gpio_get_level(BLE6A20_RTS_PIN)) // 如果RTS为低电平 则继续发送数据
{
if(30 <= len) // 数据分 30byte 每包发送
{
uart_write_buffer(BLE6A20_INDEX, buff, 30); // 发送数据
buff += 30; // 地址偏移
len -= 30; // 数量
time_count = 0;
}
else // 不足 30byte 的数据一次性发送完毕
{
uart_write_buffer(BLE6A20_INDEX, buff, len); // 发送数据
len = 0;
break;
}
}
else // 如果RTS为高电平 则模块忙
{
if(BLE6A20_TIMEOUT_COUNT <= (++ time_count)) // 超出了最大等待时间
{
break; // 退出发送
}
system_delay_ms(1);
}
}
return len;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 蓝牙转串口模块 发送字符串
// 参数说明 *str 要发送的字符串地址
// 返回参数 uint32 剩余发送长度
// 使用示例 ble6a20_send_string("Believe in yourself.");
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
uint32 ble6a20_send_string (const char *str)
{
zf_assert(NULL != str);
uint16 time_count = 0;
uint32 len = strlen(str);
while(0 != len)
{
if(!gpio_get_level(BLE6A20_RTS_PIN)) // 如果RTS为低电平 则继续发送数据
{
if(128 <= len) // 数据分 128byte 每包发送
{
uart_write_buffer(BLE6A20_INDEX, (const uint8 *)str, 128); // 发送数据
str += 128; // 地址偏移
len -= 128; // 数量
time_count = 0;
}
else // 不足 128byte 的数据一次性发送完毕
{
uart_write_buffer(BLE6A20_INDEX, (const uint8 *)str, len);// 发送数据
len = 0;
break;
}
}
else // 如果RTS为高电平 则模块忙
{
if(BLE6A20_TIMEOUT_COUNT <= (++ time_count)) // 超出了最大等待时间
{
break; // 退出发送
}
system_delay_ms(1);
}
}
return len;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 蓝牙转串口模块 发送摄像头图像至上位机查看图像
// 参数说明 *image_addr 需要发送的图像地址
// 参数说明 image_size 图像的大小
// 返回参数 void
// 使用示例 ble6a20_send_image(&mt9v03x_image[0][0], MT9V03X_IMAGE_SIZE);
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
void ble6a20_send_image (const uint8 *image_addr, uint32 image_size)
{
zf_assert(NULL != image_addr);
extern uint8 camera_send_image_frame_header[4];
ble6a20_send_buffer(camera_send_image_frame_header, 4);
ble6a20_send_buffer((uint8 *)image_addr, image_size);
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 蓝牙转串口模块 读取缓冲区数据
// 参数说明 *buff 接收缓冲区
// 参数说明 len 读取数据长度
// 返回参数 uint32 实际读取数据长度
// 使用示例 ble6a20_read_buffer(buff, 32);
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
uint32 ble6a20_read_buffer (uint8 *buff, uint32 len)
{
zf_assert(NULL != buff);
uint32 data_len = len;
fifo_read_buffer(&ble6a20_fifo, buff, &data_len, FIFO_READ_AND_CLEAN);
return data_len;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 蓝牙转串口模块 串口中断回调函数
// 参数说明 void
// 返回参数 void
// 使用示例 ble6a20_callback();
// 备注信息 该函数在 ISR 文件 串口中断程序被调用
// 由串口中断服务函数调用 wireless_module_uart_handler() 函数
// 再由 wireless_module_uart_handler() 函数调用本函数
//-------------------------------------------------------------------------------------------------------------------
void ble6a20_callback (void)
{
if(uart_query_byte(BLE6A20_INDEX, &ble6a20_data))
{
fifo_write_buffer(&ble6a20_fifo, &ble6a20_data, 1);
#if BLE6A20_AUTO_BAUD_RATE // 开启自动波特率
if(BLE6A20_AUTO_BAUD_RATE_START == ble6a20_auto_baud_flag && 3 == fifo_used(&ble6a20_fifo))
{
uint32 ble6a20_auto_baud_count = 3;
ble6a20_auto_baud_flag = BLE6A20_AUTO_BAUD_RATE_GET_ACK;
fifo_read_buffer(&ble6a20_fifo, (uint8 *)ble6a20_auto_baud_data, (uint32 *)&ble6a20_auto_baud_count, FIFO_READ_AND_CLEAN);
}
#endif
}
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 蓝牙转串口模块 初始化
// 参数说明 void
// 返回参数 void
// 使用示例 ble6a20_init();
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
uint8 ble6a20_init (void)
{
uint8 return_state = 0;
// 等待模块初始化
system_delay_ms(50);
set_wireless_type(BLE6A20, ble6a20_callback);
fifo_init(&ble6a20_fifo, FIFO_DATA_8BIT, ble6a20_buffer, BLE6A20_BUFFER_SIZE);
gpio_init(BLE6A20_RTS_PIN, GPI, GPIO_HIGH, GPI_PULL_UP);
#if(0 == BLE6A20_AUTO_BAUD_RATE) // 关闭自动波特率
// 本函数使用的波特率为115200 为蓝牙转串口模块的默认波特率 如需其他波特率请自行配置模块并修改串口的波特率
uart_init (BLE6A20_INDEX, BLE6A20_BUAD_RATE, BLE6A20_RX_PIN, BLE6A20_TX_PIN); // 初始化串口
uart_rx_interrupt(BLE6A20_INDEX, 1);
#elif(1 == BLE6A20_AUTO_BAUD_RATE) // 开启自动波特率
uint8 rts_init_status = 0;
ble6a20_auto_baud_flag = BLE6A20_AUTO_BAUD_RATE_INIT;
ble6a20_auto_baud_data[0] = 0;
ble6a20_auto_baud_data[1] = 1;
ble6a20_auto_baud_data[2] = 3;
rts_init_status = gpio_get_level(BLE6A20_RTS_PIN);
gpio_init(BLE6A20_RTS_PIN, GPO, rts_init_status, GPO_PUSH_PULL); // 初始化流控引脚
uart_init (BLE6A20_INDEX, BLE6A20_BUAD_RATE, BLE6A20_RX_PIN, BLE6A20_TX_PIN); // 初始化串口
uart_rx_interrupt(BLE6A20_INDEX, 1);
system_delay_ms(5); // 模块上电之后需要延时等待
gpio_set_level(BLE6A20_RTS_PIN, !rts_init_status); // RTS引脚拉高,进入自动波特率模式
system_delay_ms(100); // RTS拉高之后必须延时20ms
gpio_toggle_level(BLE6A20_RTS_PIN); // RTS引脚取反
do
{
ble6a20_auto_baud_flag = BLE6A20_AUTO_BAUD_RATE_START;
uart_write_byte(BLE6A20_INDEX, ble6a20_auto_baud_data[0]); // 发送特定数据 用于模块自动判断波特率
uart_write_byte(BLE6A20_INDEX, ble6a20_auto_baud_data[1]); // 发送特定数据 用于模块自动判断波特率
uart_write_byte(BLE6A20_INDEX, ble6a20_auto_baud_data[2]); // 发送特定数据 用于模块自动判断波特率
system_delay_ms(20);
if(BLE6A20_AUTO_BAUD_RATE_GET_ACK != ble6a20_auto_baud_flag) // 检验自动波特率是否完成
{
return_state = 1; // 如果程序进入到此语句内 说明自动波特率失败了
break;
}
if( 0xa5 != ble6a20_auto_baud_data[0] && // 检验自动波特率是否正确
0xff != ble6a20_auto_baud_data[1] && // 检验自动波特率是否正确
0xff != ble6a20_auto_baud_data[2] ) // 检验自动波特率是否正确
{
return_state = 1; // 如果程序进入到此语句内 说明自动波特率失败了
break;
}
ble6a20_auto_baud_flag = BLE6A20_AUTO_BAUD_RATE_SUCCESS;
gpio_init(BLE6A20_RTS_PIN, GPI, 0, GPI_PULL_UP); // 初始化流控引脚
system_delay_ms(10); // 延时等待 模块准备就绪
}while(0);
#endif
return return_state;
}
+108
View File
@@ -0,0 +1,108 @@
/*********************************************************************************************************************
* 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_ble6a20.h
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 ADS v1.10.2
* 适用平台 TC264D
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2024-07-02 pudding first version
********************************************************************************************************************/
/*********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* RX 查看 zf_device_ble6a20.h 中 BLE6A20_RX_PIN 宏定义
* TX 查看 zf_device_ble6a20.h 中 BLE6A20_TX_PIN 宏定义
* RTS 查看 zf_device_ble6a20.h 中 BLE6A20_RTS_PIN 宏定义
* VCC 3.3V电源
* GND 电源地
* 其余引脚悬空
* ------------------------------------
*********************************************************************************************************************/
#ifndef _zf_device_ble6a20_h_
#define _zf_device_ble6a20_h_
#include "zf_common_typedef.h"
//=================================================定义 蓝牙串口 基本配置================================================
#define BLE6A20_INDEX (UART_2) // 蓝牙串口对应使用的串口号
#define BLE6A20_BUAD_RATE (115200) // 蓝牙串口对应使用的串口波特率
// 波特率仅支持 9600 57600 115200 230400 460800 921600 1500000 2000000
#define BLE6A20_TX_PIN (UART2_RX_P10_6) // 蓝牙串口对应模块的 TX 要接到单片机的 RX
#define BLE6A20_RX_PIN (UART2_TX_P10_5) // 蓝牙串口对应模块的 RX 要接到单片机的 TX
#define BLE6A20_RTS_PIN (P10_2) // 蓝牙串口对应模块的 RTS 引脚
#define BLE6A20_BUFFER_SIZE ( 64 ) // 蓝牙串口缓冲区大小
#define BLE6A20_TIMEOUT_COUNT ( 0x64 ) // 蓝牙串口通讯超时范围
// ------------------------------------ 自动波特率 ------------------------------------
// 注意事项1:开启自动波特率务必连接RTS引脚 否则会开启失败。
// 注意事项2:模块自动波特率失败的话 可以尝试断电重启
// 开启自动波特率务必阅读上面两条 注意事项
// 开启自动波特率务必阅读上面两条 注意事项
// 开启自动波特率务必阅读上面两条 注意事项
// 0:关闭自动波特率
// 1:开启自动波特率 自动波特率的作用是修改 BLE6A20_BAUD 之后不需要对模块进行配置 模块会自动设置为对应的波特率
// 自动波特率仅支持 9600 57600 115200 230400 460800 921600 1500000 2000000
#define BLE6A20_AUTO_BAUD_RATE ( 0 )
#if (1 == BLE6A20_AUTO_BAUD_RATE)
typedef enum
{
BLE6A20_AUTO_BAUD_RATE_SUCCESS,
BLE6A20_AUTO_BAUD_RATE_INIT,
BLE6A20_AUTO_BAUD_RATE_START,
BLE6A20_AUTO_BAUD_RATE_GET_ACK,
}ble6a20_auto_baudrate_state_enum;
#endif
// ------------------------------------ 自动波特率 ------------------------------------
//=================================================定义 蓝牙串口 基本配置================================================
//=================================================声明 蓝牙串口 基础函数================================================
uint32 ble6a20_send_byte (const uint8 data); // 蓝牙转串口模块 发送数据
uint32 ble6a20_send_buffer (const uint8 *buff, uint32 len); // 蓝牙转串口模块 发送数据块
uint32 ble6a20_send_string (const char *str); // 蓝牙转串口模块 发送字符串
void ble6a20_send_image (const uint8 *image_addr, uint32 image_size); // 蓝牙转串口模块 发送摄像头图像至上位机查看图像
uint32 ble6a20_read_buffer (uint8 *buff, uint32 len); // 蓝牙转串口模块 读取缓冲区数据
void ble6a20_callback (void); // 蓝牙转串口模块 串口中断回调函数
uint8 ble6a20_init (void); // 蓝牙转串口模块 初始化
//=================================================声明 蓝牙串口 基础函数================================================
#endif
@@ -0,0 +1,235 @@
/*********************************************************************************************************************
* 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_bluetooth_ch9141
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 ADS v1.10.2
* 适用平台 TC264D
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2022-09-15 pudding first version
* 2023-04-25 pudding 增加中文注释说明
********************************************************************************************************************/
/*********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 蓝牙转串口 单片机
* RX 查看zf_device_bluetooth_ch9141.h文件中的BLUETOOTH_CH9141_TX_PIN宏定义
* TX 查看zf_device_bluetooth_ch9141.h文件中的BLUETOOTH_CH9141_RX_PIN宏定义
* RTS 查看zf_device_bluetooth_ch9141.h文件中的BLUETOOTH_CH9141_RTS_PIN宏定义
* CTS 悬空
* CMD 悬空或者上拉
* ------------------------------------
*********************************************************************************************************************/
#include "zf_common_debug.h"
#include "zf_common_fifo.h"
#include "zf_driver_gpio.h"
#include "zf_driver_uart.h"
#include "zf_driver_delay.h"
#include "zf_device_type.h"
#include "zf_device_camera.h"
#include "zf_device_bluetooth_ch9141.h"
static fifo_struct bluetooth_ch9141_fifo; // fifo缓冲区结构体定义
static uint8 bluetooth_ch9141_buffer[BLUETOOTH_CH9141_BUFFER_SIZE]; // 数据存放数组
static uint8 bluetooth_ch9141_data = 0; // 数据临时存放变量
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 蓝牙转串口模块 发送数据
// 参数说明 data 8bit 数据
// 返回参数 uint32 剩余发送长度
// 使用示例 bluetooth_ch9141_send_byte(0x5A);
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
uint32 bluetooth_ch9141_send_byte (const uint8 data)
{
uint16 time_count = BLUETOOTH_CH9141_TIMEOUT_COUNT;
while(time_count)
{
if(!gpio_get_level(BLUETOOTH_CH9141_RTS_PIN))
{
uart_write_byte(BLUETOOTH_CH9141_INDEX, data); // 发送数据
break;
}
time_count --;
system_delay_ms(1);
}
return (0 < time_count);
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 蓝牙转串口模块 发送数组
// 参数说明 buff 需要发送的数据地址
// 返回参数 len 发送长度
// 使用示例 uint32 剩余未发送的字节数
// 使用示例 bluetooth_ch9141_send_buff(buff, 16);
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
uint32 bluetooth_ch9141_send_buffer (const uint8 *buff, uint32 len)
{
zf_assert(NULL != buff);
uint16 time_count = 0;
while(0 != len)
{
if(!gpio_get_level(BLUETOOTH_CH9141_RTS_PIN)) // 如果RTS为低电平 则继续发送数据
{
if(30 <= len) // 数据分 30byte 每包发送
{
uart_write_buffer(BLUETOOTH_CH9141_INDEX, buff, 30); // 发送数据
buff += 30; // 地址偏移
len -= 30; // 数量
time_count = 0;
}
else // 不足 30byte 的数据一次性发送完毕
{
uart_write_buffer(BLUETOOTH_CH9141_INDEX, buff, len); // 发送数据
len = 0;
break;
}
}
else // 如果RTS为高电平 则模块忙
{
if(BLUETOOTH_CH9141_TIMEOUT_COUNT <= (++ time_count)) // 超出了最大等待时间
{
break; // 退出发送
}
system_delay_ms(1);
}
}
return len;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 蓝牙转串口模块 发送字符串
// 参数说明 *str 要发送的字符串地址
// 返回参数 uint32 剩余发送长度
// 使用示例 bluetooth_ch9141_send_string("Trust yourself.");
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
uint32 bluetooth_ch9141_send_string (const char *str)
{
zf_assert(NULL != str);
uint16 time_count = 0;
uint32 len = strlen(str);
while(0 != len)
{
if(!gpio_get_level(BLUETOOTH_CH9141_RTS_PIN)) // 如果RTS为低电平 则继续发送数据
{
if(30 <= len) // 数据分 30byte 每包发送
{
uart_write_buffer(BLUETOOTH_CH9141_INDEX, (const uint8 *)str, 30); // 发送数据
str += 30; // 地址偏移
len -= 30; // 数量
time_count = 0;
}
else // 不足 30byte 的数据一次性发送完毕
{
uart_write_buffer(BLUETOOTH_CH9141_INDEX, (const uint8 *)str, len); // 发送数据
len = 0;
break;
}
}
else // 如果RTS为高电平 则模块忙
{
if(BLUETOOTH_CH9141_TIMEOUT_COUNT <= (++ time_count)) // 超出了最大等待时间
{
break; // 退出发送
}
system_delay_ms(1);
}
}
return len;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 蓝牙转串口模块 发送摄像头图像至上位机查看图像
// 参数说明 *image_addr 需要发送的图像地址
// 参数说明 image_size 图像的大小
// 返回参数 void
// 使用示例 bluetooth_ch9141_send_image(&mt9v03x_image[0][0], MT9V03X_IMAGE_SIZE);
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
void bluetooth_ch9141_send_image (const uint8 *image_addr, uint32 image_size)
{
zf_assert(NULL != image_addr);
bluetooth_ch9141_send_buffer(camera_send_image_frame_header, 4);
bluetooth_ch9141_send_buffer((uint8 *)image_addr, image_size);
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 蓝牙转串口模块 读取函数
// 参数说明 buff 存储的数据地址
// 参数说明 len 长度
// 返回参数 uint32 实际读取字节数
// 使用示例 bluetooth_ch9141_read_buffer(buff, 16);
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
uint32 bluetooth_ch9141_read_buffer (uint8 *buff, uint32 len)
{
zf_assert(NULL != buff);
uint32 data_len = len;
fifo_read_buffer(&bluetooth_ch9141_fifo, buff, &data_len, FIFO_READ_AND_CLEAN);
return data_len;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 蓝牙转串口模块 串口中断回调函数
// 参数说明 void
// 返回参数 void
// 使用示例
// 备注信息 该函数在 ISR 文件的串口中断程序被调用
// 由串口中断服务函数调用 wireless_module_uart_handler() 函数
// 再由 wireless_module_uart_handler() 函数调用本函数
//-------------------------------------------------------------------------------------------------------------------
void bluetooth_ch9141_uart_callback (void)
{
uart_query_byte(BLUETOOTH_CH9141_INDEX, &bluetooth_ch9141_data); // 读取串口数据
fifo_write_buffer(&bluetooth_ch9141_fifo, &bluetooth_ch9141_data, 1); // 存入 FIFO
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 蓝牙转串口模块 初始化
// 参数说明 void
// 返回参数 uint8 初始化状态 0-成功 1-失败
// 使用示例 bluetooth_ch9141_init();
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
uint8 bluetooth_ch9141_init (void)
{
uint8 return_state = 0;
set_wireless_type(BLUETOOTH_CH9141, bluetooth_ch9141_uart_callback);
fifo_init(&bluetooth_ch9141_fifo, FIFO_DATA_8BIT, bluetooth_ch9141_buffer, BLUETOOTH_CH9141_BUFFER_SIZE);
// 本函数使用的波特率为115200 为蓝牙转串口模块的默认波特率 如需其他波特率请使用上位机修改模块参数
gpio_init(BLUETOOTH_CH9141_RTS_PIN, GPI, 1, GPI_PULL_UP); // 初始化流控引脚
uart_init(BLUETOOTH_CH9141_INDEX, BLUETOOTH_CH9141_BUAD_RATE, BLUETOOTH_CH9141_RX_PIN, BLUETOOTH_CH9141_TX_PIN);
uart_rx_interrupt(BLUETOOTH_CH9141_INDEX, 1);
return return_state;
}
@@ -0,0 +1,75 @@
/*********************************************************************************************************************
* 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 文件
* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明)
*
* 文件名称 main
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 ADS v1.10.2
* 适用平台 TC264D
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2022-09-15 pudding first version
* 2023-04-25 pudding 增加中文注释说明
********************************************************************************************************************/
/*********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 蓝牙转串口 单片机
* RX 查看zf_device_bluetooth_ch9141.h文件中的BLUETOOTH_CH9141_TX_PIN宏定义
* TX 查看zf_device_bluetooth_ch9141.h文件中的BLUETOOTH_CH9141_RX_PIN宏定义
* RTS 查看zf_device_bluetooth_ch9141.h文件中的BLUETOOTH_CH9141_RTS_PIN宏定义
* CTS 悬空
* CMD 悬空或者上拉
* ------------------------------------
*********************************************************************************************************************/
#ifndef _zf_device_bluetooth_ch9141_h_
#define _zf_device_bluetooth_ch9141_h_
#include "zf_common_typedef.h"
//=================================================定义 9141蓝牙 基本配置================================================
#define BLUETOOTH_CH9141_INDEX (UART_2) // 蓝牙模块对应使用的串口号
#define BLUETOOTH_CH9141_BUAD_RATE (115200) // 蓝牙模块对应使用的串口波特率
#define BLUETOOTH_CH9141_TX_PIN (UART2_RX_P10_6) // 蓝牙模块对应模块的 TX 要接到单片机的 RX
#define BLUETOOTH_CH9141_RX_PIN (UART2_TX_P10_5) // 蓝牙模块对应模块的 RX 要接到单片机的 TX
#define BLUETOOTH_CH9141_RTS_PIN (P10_2) // 蓝牙模块对应模块的 RTS 引脚(流控位)
#define BLUETOOTH_CH9141_BUFFER_SIZE (64) // 接收数据的缓冲区大小
#define BLUETOOTH_CH9141_TIMEOUT_COUNT (500) // 执行操作的超时时间
//=================================================定义 9141蓝牙 基本配置================================================
//=================================================声明 9141蓝牙 基础函数================================================
uint32 bluetooth_ch9141_send_byte (const uint8 data); // 蓝牙转串口模块 发送数据
uint32 bluetooth_ch9141_send_buffer (const uint8 *buff, uint32 len); // 蓝牙转串口模块 发送数组
uint32 bluetooth_ch9141_send_string (const char *str); // 蓝牙转串口模块 发送字符串
void bluetooth_ch9141_send_image (const uint8 *image_addr, uint32 image_size); // 蓝牙转串口模块 发送摄像头图像至上位机查看图像
uint32 bluetooth_ch9141_read_buffer (uint8 *buff, uint32 len); // 蓝牙转串口模块 读取函数
void bluetooth_ch9141_uart_callback (void); // 蓝牙转串口模块 串口中断回调函数
uint8 bluetooth_ch9141_init (void); // 蓝牙转串口模块 初始化
//=================================================声明 9141蓝牙 基础函数================================================
#endif
+187
View File
@@ -0,0 +1,187 @@
/*********************************************************************************************************************
* 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_camera
* ��˾���� �ɶ���ɿƼ����޹�˾
* �汾��Ϣ �鿴 libraries/doc �ļ����� version �ļ� �汾˵��
* �������� ADS v1.10.2
* ����ƽ̨ TC264D
* �������� https://seekfree.taobao.com/
*
* �޸ļ�¼
* ���� ���� ��ע
* 2022-09-15 pudding first version
* 2023-04-25 pudding ��������ע��˵��
********************************************************************************************************************/
#include "zf_common_debug.h"
#include "zf_common_interrupt.h"
#include "zf_driver_gpio.h"
#include "zf_driver_dma.h"
#include "zf_driver_exti.h"
#include "zf_device_mt9v03x_double.h"
#include "zf_device_ov7725.h"
#include "zf_device_scc8660.h"
#include "isr_config.h"
#include "zf_device_camera.h"
fifo_struct camera_receiver_fifo; // ��������ͷ��������fifo�ṹ��
uint8 camera_receiver_buffer[CAMERA_RECEIVER_BUFFER_SIZE]; // ��������ͷ�������ݻ�����
uint8 camera_send_image_frame_header[4] = {0x00, 0xFF, 0x01, 0x01}; // ��������ͷ���ݷ��͵���λ����֡ͷ
//-------------------------------------------------------------------------------------------------------------------
// ������� ����ͷ������ͼ�����ݽ�ѹΪʮ�����ư�λ���� С�����
// ����˵�� *data1 ����ͷͼ������
// ����˵�� *data2 ��Ž�ѹ���ݵĵ�ַ
// ����˵�� image_size ͼ��Ĵ�С
// @return void
// Sample usage: camera_binary_image_decompression(&ov7725_image_binary[0][0], &data_buffer[0][0], OV7725_SIZE);
//-------------------------------------------------------------------------------------------------------------------
void camera_binary_image_decompression (const uint8 *data1, uint8 *data2, uint32 image_size)
{
zf_assert(NULL != data1);
zf_assert(NULL != data2);
uint8 i = 8;
while(image_size --)
{
i = 8;
while(i --)
{
*data2 ++ = (((*data1 >> i) & 0x01) ? 255 : 0);
}
data1 ++;
}
}
//-------------------------------------------------------------------------------------------------------------------
// ������� ����ͷͼ��������λ���鿴ͼ��
// ����˵�� uartn ʹ�õĴ��ں�
// ����˵�� *image_addr ��Ҫ���͵�ͼ���ַ
// ����˵�� image_size ͼ��Ĵ�С
// @return void
// Sample usage: camera_send_image(DEBUG_UART_INDEX, &mt9v03x_image[0][0], MT9V03X_IMAGE_SIZE);
//-------------------------------------------------------------------------------------------------------------------
void camera_send_image (uart_index_enum uartn, const uint8 *image_addr, uint32 image_size)
{
zf_assert(NULL != image_addr);
// ��������
uart_write_buffer(uartn, camera_send_image_frame_header, 4);
// ����ͼ��
uart_write_buffer(uartn, (uint8 *)image_addr, image_size);
}
//-------------------------------------------------------------------------------------------------------------------
// ������� ����ͷ���� FIFO ��ʼ��
// ����˵�� void
// ���ز��� void
// ʹ��ʾ�� camera_fifo_init();
// ��ע��Ϣ
//-------------------------------------------------------------------------------------------------------------------
void camera_fifo_init (void)
{
fifo_init(&camera_receiver_fifo, FIFO_DATA_8BIT, camera_receiver_buffer, CAMERA_RECEIVER_BUFFER_SIZE);
}
//-------------------------------------------------------------------------------------------------------------------
// ������� ����ͷ�ɼ���ʼ��
// ����˵�� source_addr ������Դ�����ַ
// ����˵�� destination_addr ͼ�񻺳�����ַ
// ����˵�� image_size ͼ��Ĵ�С
// ���ز��� uint8 DMA ��������
// @return void
// Sample usage: camera_init();
//-------------------------------------------------------------------------------------------------------------------
uint8 camera_init (uint8 *source_addr, uint8 *destination_addr, uint32 image_size)
{
uint8 num;
uint8 link_list_num;
switch(camera_type)
{
case CAMERA_BIN_IIC: // IIC ���
case CAMERA_BIN_UART: // UART ���
for(num = 0; num < 8; num ++)
{
gpio_init((gpio_pin_enum)(OV7725_DATA_PIN + num), GPI, GPIO_LOW, GPI_FLOATING_IN);
}
link_list_num = dma_init(OV7725_DMA_CH,
source_addr,
destination_addr,
OV7725_PCLK_PIN,
EXTI_TRIGGER_FALLING,
image_size);
exti_init(OV7725_VSYNC_PIN, EXTI_TRIGGER_FALLING); //��ʼ�����жϣ�������Ϊ�½��ش����ж�
break;
case CAMERA_GRAYSCALE_1: // ����� 1
for(num = 0; num < 8; num ++)
{
gpio_init((gpio_pin_enum)(MT9V03X_1_DATA_PIN + num), GPI, GPIO_LOW, GPI_FLOATING_IN);
}
link_list_num = dma_init(MT9V03X_1_DMA_CH,
source_addr,
destination_addr,
MT9V03X_1_PCLK_PIN,
EXTI_TRIGGER_FALLING,
image_size); // 主频在300M 用于倍频时采集改为FALLING
exti_init(MT9V03X_1_VSYNC_PIN, EXTI_TRIGGER_BOTH); // ��ʼ�����жϣ�������Ϊ�½��ش����ж�
break;
case CAMERA_GRAYSCALE_2: // ����� 2
for(num = 0; num < 8; num ++)
{
gpio_init((gpio_pin_enum)(MT9V03X_2_DATA_PIN + num), GPI, GPIO_LOW, GPI_FLOATING_IN);
}
link_list_num = dma_init_2(MT9V03X_2_DMA_CH,
source_addr,
destination_addr,
MT9V03X_2_PCLK_PIN,
EXTI_TRIGGER_FALLING,
image_size); // 主频在300M 用于倍频时采集改为FALLING
exti_init(MT9V03X_2_VSYNC_PIN, EXTI_TRIGGER_BOTH); // ��ʼ�����жϣ�������Ϊ�½��ش����ж�
break;
case CAMERA_COLOR: // ��ͫ
for(num=0; num<8; num++)
{
gpio_init((gpio_pin_enum)(SCC8660_DATA_PIN + num), GPI, GPIO_LOW, GPI_FLOATING_IN);
}
link_list_num = dma_init(SCC8660_DMA_CH,
source_addr,
destination_addr,
SCC8660_PCLK_PIN,
EXTI_TRIGGER_RISING,
image_size); // �����Ƶ��300M �����ڶ�������������ΪFALLING
exti_init(SCC8660_VSYNC_PIN, EXTI_TRIGGER_FALLING); // ��ʼ�����жϣ�������Ϊ�½��ش����ж�
break;
default:
break;
}
return link_list_num;
}
+58
View File
@@ -0,0 +1,58 @@
/*********************************************************************************************************************
* 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_camera
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 ADS v1.10.2
* 适用平台 TC264D
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2022-09-15 pudding first version
* 2023-04-25 pudding 增加中文注释说明
********************************************************************************************************************/
#ifndef _zf_device_camera_h_
#define _zf_device_camera_h_
#include "zf_common_fifo.h"
#include "zf_common_typedef.h"
#include "zf_driver_uart.h"
#include "zf_device_type.h"
//=================================================摄像头公共库 基本配置================================================
#define CAMERA_RECEIVER_BUFFER_SIZE (8) // 定义摄像头接收数据缓冲区大小
extern fifo_struct camera_receiver_fifo; // 声明摄像头接收数据fifo结构体
extern uint8 camera_send_image_frame_header[4]; // 声明摄像头数据发送到上位机的帧头
//=================================================摄像头公共库 基本配置================================================
//=================================================摄像头公共库 基础函数================================================
void camera_binary_image_decompression (const uint8 *data1, uint8 *data2, uint32 image_size); // 摄像头二进制图像数据解压为十六进制八位数据 小钻风用
void camera_send_image (uart_index_enum uartn, const uint8 *image_addr, uint32 image_size); // 摄像头图像发送至上位机查看图像
void camera_fifo_init (void); // 摄像头串口 FIFO 初始化
uint8 camera_init (uint8 *source_addr, uint8 *destination_addr, uint32 image_size); // 摄像头采集初始化
//=================================================摄像头公共库 基础函数================================================
#endif
Binary file not shown.
+58
View File
@@ -0,0 +1,58 @@
/*********************************************************************************************************************
* 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_config
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 ADS v1.10.2
* 适用平台 TC264D
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2022-09-15 pudding first version
* 2024-02-02 pudding 新增凌瞳静态库函数
********************************************************************************************************************/
#ifndef _zf_device_config_h_
#define _zf_device_config_h_
extern const unsigned char imu660ra_config_file[8192];
extern const unsigned char dl1b_config_file[135];
void mt9v03x_sccb_check_id_1 (void *soft_iic_obj);
unsigned char mt9v03x_set_config_sccb_1 (void *soft_iic_obj, short int buff[10][2]);
unsigned char mt9v03x_set_exposure_time_sccb_1 (unsigned short int light);
unsigned char mt9v03x_set_reg_sccb_1 (unsigned char addr, unsigned short int data);
void mt9v03x_sccb_check_id_2 (void *soft_iic_obj);
unsigned char mt9v03x_set_config_sccb_2 (void *soft_iic_obj, short int buff[10][2]);
unsigned char mt9v03x_set_exposure_time_sccb_2 (unsigned short int light);
unsigned char mt9v03x_set_reg_sccb_2 (unsigned char addr, unsigned short int data);
unsigned char scc8660_set_config_sccb (void *soft_iic_obj, short int buff[10][2]);
unsigned char scc8660_set_brightness_sccb (unsigned short int brightness);
unsigned char scc8660_set_manual_wb_sccb (unsigned short int manual_wb);
unsigned char scc8660_set_reg_sccb (unsigned char reg, unsigned short int data);
#endif
+771
View File
@@ -0,0 +1,771 @@
/*********************************************************************************************************************
* 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_dl1a
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 ADS v1.10.2
* 适用平台 TC264D
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2022-09-15 pudding first version
* 2023-04-28 pudding 增加中文注释说明
********************************************************************************************************************/
/*********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* 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.99);
uint8 data_buffer[3];
uint16 limit_mcps_16bit = (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;
}
+215
View File
@@ -0,0 +1,215 @@
/*********************************************************************************************************************
* 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_dl1a
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 ADS v1.10.2
* 适用平台 TC264D
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2022-09-15 pudding first version
* 2023-04-28 pudding 增加中文注释说明
********************************************************************************************************************/
/*********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* 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 (100) // 软件 IIC 的时钟延时周期 数值越小 IIC 通信速率越快
#define DL1A_SCL_PIN (P33_4) // 软件 IIC SCL 引脚 连接 VL53L0X 的 SCL 引脚
#define DL1A_SDA_PIN (P33_5) // 软件 IIC SDA 引脚 连接 VL53L0X 的 SDA 引脚
//====================================================软件 IIC 驱动====================================================
#else
#error "暂不支持硬件IIC通讯"
#endif
#define DL1A_XS_PIN (P20_2)
#define DL1A_INT_ENABLE ( 1 ) // 是否启用 INT 引脚 启用则会自动更新数据
#if DL1A_INT_ENABLE
#define DL1A_INT_PIN (ERU_CH1_REQ10_P14_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 @@
/*********************************************************************************************************************
* 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_dl1b
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 ADS v1.10.2
* 适用平台 TC264D
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2022-09-15 pudding 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"
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
#error "暂不支持硬件IIC通讯"
#endif
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 返回以毫米为单位的范围读数
// 参数说明 void
// 返回参数 void
// 使用示例 dl1b_get_distance();
// 备注信息 在开始单次射程测量后也调用此函数
//-------------------------------------------------------------------------------------------------------------------
void dl1b_get_distance (void)
{
if(dl1b_init_flag)
{
uint8 data_buffer[3] = {0};
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;
}while(0);
#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);
return return_state;
}
+99
View File
@@ -0,0 +1,99 @@
/*********************************************************************************************************************
* 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_dl1b
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 ADS v1.10.2
* 适用平台 TC264D
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2022-09-15 pudding 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 ( P33_4 ) // 软件 IIC SCL 引脚 连接 DL1B 的 SCL 引脚
#define DL1B_SDA_PIN ( P33_5 ) // 软件 IIC SDA 引脚 连接 DL1B 的 SDA 引脚
//====================================================软件 IIC 驱动====================================================
#else
#error "暂不支持硬件IIC通讯"
#endif
#define DL1B_XS_PIN ( P20_2 )
#define DL1B_INT_ENABLE ( 0 ) // 是否启用 INT 引脚 启用则会自动更新数据
#if DL1B_INT_ENABLE
#define DL1B_INT_PIN ( ERU_CH1_REQ10_P14_3 )
#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
+621
View File
@@ -0,0 +1,621 @@
/*********************************************************************************************************************
* 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_gnss
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 ADS v1.10.2
* 适用平台 TC264D
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2023-12-28 pudding first version
* 2024-01-30 pudding 新增RTK "D" 报头协议
********************************************************************************************************************/
/*********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* RX 查看 zf_device_gnss.h 中 GNSS_RX 宏定义
* TX 查看 zf_device_gnss.h 中 GNSS_TX 宏定义
* VCC 3.3V电源
* GND 电源地
* ------------------------------------
********************************************************************************************************************/
#include "math.h"
#include "zf_common_function.h"
#include "zf_common_fifo.h"
#include "zf_driver_delay.h"
#include "zf_driver_uart.h"
#include "zf_device_gnss.h"
#define GNSS_BUFFER_SIZE ( 128 )
uint8 gnss_flag = 0; // 1:采集完成等待处理数据 0:没有采集完成
gnss_info_struct gnss; // GPS解析之后的数据
static uint8 gnss_state = 0; // 1:GPS初始化完成
static fifo_struct gnss_receiver_fifo; //
static uint8 gnss_receiver_buffer[GNSS_BUFFER_SIZE]; // 数据存放数组
static gps_state_enum gnss_gga_state = GPS_STATE_RECEIVING; // gga 语句状态
static gps_state_enum gnss_rmc_state = GPS_STATE_RECEIVING; // rmc 语句状态
static gps_state_enum gnss_ths_state = GPS_STATE_RECEIVING; // rmc 语句状态
static uint8 gps_gga_buffer[GNSS_BUFFER_SIZE];
static uint8 gps_rmc_buffer[GNSS_BUFFER_SIZE];
static uint8 gps_ths_buffer[GNSS_BUFFER_SIZE];
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 获取指定 ',' 后面的索引
// 参数说明 num 第几个逗号
// 参数说明 *str 字符串
// 返回参数 uint8 返回索引
// 使用示例 get_parameter_index(1, s);
// 备注信息 内部使用
//-------------------------------------------------------------------------------------------------------------------
static uint8 get_parameter_index (uint8 num, char *str)
{
uint8 i = 0, j = 0;
char *temp = strchr(str, '\n');
uint8 len = 0, len1 = 0;
if(NULL != temp)
{
len = (uint8)((uint32)temp - (uint32)str + 1);
}
for(i = 0; i < len; i ++)
{
if(',' == str[i])
{
j ++;
}
if(j == num)
{
len1 = i + 1;
break;
}
}
return len1;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 给定字符串第一个 ',' 之前的数据转换为int
// 参数说明 *s 字符串
// 返回参数 float 返回数值
// 使用示例 get_int_number(&buf[get_parameter_index(7, buf)]);
// 备注信息 内部使用
//-------------------------------------------------------------------------------------------------------------------
static int get_int_number (char *s)
{
char buf[10];
uint8 i = 0;
int return_value = 0;
i = get_parameter_index(1, s);
i = i - 1;
strncpy(buf, s, i);
buf[i] = 0;
return_value = func_str_to_int(buf);
return return_value;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 给定字符串第一个 ',' 之前的数据转换为float
// 参数说明 *s 字符串
// 返回参数 float 返回数值
// 使用示例 get_float_number(&buf[get_parameter_index(8, buf)]);
// 备注信息 内部使用
//-------------------------------------------------------------------------------------------------------------------
static float get_float_number (char *s)
{
uint8 i = 0;
char buf[15];
float return_value = 0;
i = get_parameter_index(1, s);
i = i - 1;
strncpy(buf, s, i);
buf[i] = 0;
return_value = (float)func_str_to_double(buf);
return return_value;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 给定字符串第一个 ',' 之前的数据转换为double
// 参数说明 *s 字符串
// 返回参数 double 返回数值
// 使用示例 get_double_number(&buf[get_parameter_index(3, buf)]);
// 备注信息 内部使用
//-------------------------------------------------------------------------------------------------------------------
static double get_double_number (char *s)
{
uint8 i = 0;
char buf[15];
double return_value = 0;
i = get_parameter_index(1, s);
i = i - 1;
strncpy(buf, s, i);
buf[i] = 0;
return_value = func_str_to_double(buf);
return return_value;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 世界时间转换为北京时间
// 参数说明 *time 保存的时间
// 返回参数 void
// 使用示例 utc_to_btc(&gnss->time);
// 备注信息 内部使用
//-------------------------------------------------------------------------------------------------------------------
static void utc_to_btc (gps_time_struct *time)
{
uint8 day_num = 0;
time->hour = time->hour + 8;
if(23 < time->hour)
{
time->hour -= 24;
time->day += 1;
if(2 == time->month)
{
day_num = 28;
if((0 == time->year % 4 && 0 != time->year % 100) || 0 == time->year % 400) // 判断是否为闰年
{
day_num ++; // 闰月 2月为29天
}
}
else
{
day_num = 31; // 1 3 5 7 8 10 12这些月份为31天
if(4 == time->month || 6 == time->month || 9 == time->month || 11 == time->month )
{
day_num = 30;
}
}
if(time->day > day_num)
{
time->day = 1;
time->month ++;
if(12 < time->month)
{
time->month -= 12;
time->year ++;
}
}
}
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 RMC语句解析
// 参数说明 *line 接收到的语句信息
// 参数说明 *gnss 保存解析后的数据
// 返回参数 uint8 1:解析成功 0:数据有问题不能解析
// 使用示例 gps_gnrmc_parse((char *)data_buffer, &gnss);
// 备注信息 内部使用
//-------------------------------------------------------------------------------------------------------------------
static uint8 gps_gnrmc_parse (char *line, gnss_info_struct *gnss)
{
uint8 state = 0, temp = 0;
double latitude = 0; // 纬度
double longitude = 0; // 经度
double lati_cent_tmp = 0, lati_second_tmp = 0;
double long_cent_tmp = 0, long_second_tmp = 0;
float speed_tmp = 0;
char *buf = line;
uint8 return_state = 0;
state = buf[get_parameter_index(2, buf)];
if('A' == state || 'D' == state) // 如果数据有效 则解析数据
{
return_state = 1;
gnss->state = 1;
gnss -> ns = buf[get_parameter_index(4, buf)];
gnss -> ew = buf[get_parameter_index(6, buf)];
latitude = get_double_number(&buf[get_parameter_index(3, buf)]);
longitude = get_double_number(&buf[get_parameter_index(5, buf)]);
gnss->latitude_degree = (int)latitude / 100; // 纬度转换为度分秒
lati_cent_tmp = (latitude - gnss->latitude_degree * 100);
gnss->latitude_cent = (int)lati_cent_tmp;
lati_second_tmp = (lati_cent_tmp - gnss->latitude_cent) * 6000;
gnss->latitude_second = (int)lati_second_tmp;
gnss->longitude_degree = (int)longitude / 100; // 经度转换为度分秒
long_cent_tmp = (longitude - gnss->longitude_degree * 100);
gnss->longitude_cent = (int)long_cent_tmp;
long_second_tmp = (long_cent_tmp - gnss->longitude_cent) * 6000;
gnss->longitude_second = (int)long_second_tmp;
gnss->latitude = gnss->latitude_degree + lati_cent_tmp / 60;
gnss->longitude = gnss->longitude_degree + long_cent_tmp / 60;
speed_tmp = get_float_number(&buf[get_parameter_index(7, buf)]); // 速度(海里/小时)
gnss->speed = speed_tmp * 1.85f; // 转换为公里/小时
gnss->direction = get_float_number(&buf[get_parameter_index(8, buf)]); // 角度
}
else
{
gnss->state = 0;
}
// 在定位没有生效前也是有时间数据的,可以直接解析
gnss->time.hour = (buf[7] - '0') * 10 + (buf[8] - '0'); // 时间
gnss->time.minute = (buf[9] - '0') * 10 + (buf[10] - '0');
gnss->time.second = (buf[11] - '0') * 10 + (buf[12] - '0');
temp = get_parameter_index(9, buf);
gnss->time.day = (buf[temp + 0] - '0') * 10 + (buf[temp + 1] - '0'); // 日期
gnss->time.month = (buf[temp + 2] - '0') * 10 + (buf[temp + 3] - '0');
gnss->time.year = (buf[temp + 4] - '0') * 10 + (buf[temp + 5] - '0') + 2000;
utc_to_btc(&gnss->time);
return return_state;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 GGA语句解析
// 参数说明 *line 接收到的语句信息
// 参数说明 *gnss 保存解析后的数据
// 返回参数 uint8 1:解析成功 0:数据有问题不能解析
// 使用示例 gps_gngga_parse((char *)data_buffer, &gnss);
// 备注信息 内部使用
//-------------------------------------------------------------------------------------------------------------------
static uint8 gps_gngga_parse (char *line, gnss_info_struct *gnss)
{
uint8 state = 0;
char *buf = line;
uint8 return_state = 0;
state = buf[get_parameter_index(2, buf)];
if(',' != state)
{
gnss->satellite_used = (uint8)get_int_number(&buf[get_parameter_index(7, buf)]);
gnss->height = get_float_number(&buf[get_parameter_index(9, buf)]) + get_float_number(&buf[get_parameter_index(11, buf)]); // 高度 = 海拔高度 + 地球椭球面相对大地水准面的高度
return_state = 1;
}
return return_state;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 THS语句解析
// 参数说明 *line 接收到的语句信息
// 参数说明 *gnss 保存解析后的数据
// 返回参数 uint8 1:解析成功 0:数据有问题不能解析
// 使用示例 gps_gnths_parse((char *)data_buffer, &gnss);
// 备注信息 内部使用
//-------------------------------------------------------------------------------------------------------------------
static uint8 gps_gnths_parse (char *line, gnss_info_struct *gnss)
{
uint8 state = 0;
char *buf = line;
uint8 return_state = 0;
state = buf[get_parameter_index(2, buf)];
if('A' == state)
{
gnss->antenna_direction_state = 1;
gnss->antenna_direction = get_float_number(&buf[get_parameter_index(1, buf)]);
return_state = 1;
}
else
{
gnss->antenna_direction_state = 0;
}
return return_state;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 计算从第一个点到第二个点的距离
// 参数说明 latitude1 第一个点的纬度
// 参数说明 longitude1 第一个点的经度
// 参数说明 latitude2 第二个点的纬度
// 参数说明 longitude2 第二个点的经度
// 返回参数 double 返回两点距离
// 使用示例 get_two_points_distance(latitude1_1, longitude1, latitude2, longitude2);
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
double get_two_points_distance (double latitude1, double longitude1, double latitude2, double longitude2)
{
const double EARTH_RADIUS = 6378137; // 地球半径(单位:m)
double rad_latitude1 = 0;
double rad_latitude2 = 0;
double rad_longitude1 = 0;
double rad_longitude2 = 0;
double distance = 0;
double a = 0;
double b = 0;
rad_latitude1 = ANGLE_TO_RAD(latitude1); // 根据角度计算弧度
rad_latitude2 = ANGLE_TO_RAD(latitude2);
rad_longitude1 = ANGLE_TO_RAD(longitude1);
rad_longitude2 = ANGLE_TO_RAD(longitude2);
a = rad_latitude1 - rad_latitude2;
b = rad_longitude1 - rad_longitude2;
distance = 2 * asin(sqrt(pow(sin(a / 2), 2) + cos(rad_latitude1) * cos(rad_latitude2) * pow(sin(b / 2), 2))); // google maps 里面实现的算法
distance = distance * EARTH_RADIUS;
return distance;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 计算从第一个点到第二个点的方位角
// 参数说明 latitude1 第一个点的纬度
// 参数说明 longitude1 第一个点的经度
// 参数说明 latitude2 第二个点的纬度
// 参数说明 longitude2 第二个点的经度
// 返回参数 double 返回方位角(0至360)
// 使用示例 get_two_points_azimuth(latitude1_1, longitude1, latitude2, longitude2);
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
double get_two_points_azimuth (double latitude1, double longitude1, double latitude2, double longitude2)
{
latitude1 = ANGLE_TO_RAD(latitude1);
latitude2 = ANGLE_TO_RAD(latitude2);
longitude1 = ANGLE_TO_RAD(longitude1);
longitude2 = ANGLE_TO_RAD(longitude2);
double x = sin(longitude2 - longitude1) * cos(latitude2);
double y = cos(latitude1) * sin(latitude2) - sin(latitude1) * cos(latitude2) * cos(longitude2 - longitude1);
double angle = RAD_TO_ANGLE(atan2(x, y));
return ((0 < angle) ? angle : (angle + 360));
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 解析GPS数据
// 参数说明 void
// 返回参数 uint8 0-解析成功 1-解析失败 可能数据包错误
// 使用示例 gps_data_parse();
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
uint8 gnss_data_parse (void)
{
uint8 return_state = 0;
uint8 check_buffer[5] = {'0', 'x', 0x00, 0x00, 0x00};
uint8 bbc_xor_origin = 0;
uint8 bbc_xor_calculation = 0;
uint32 data_len = 0;
do
{
if(GPS_STATE_RECEIVED == gnss_rmc_state)
{
gnss_rmc_state = GPS_STATE_PARSING;
strncpy((char *)&check_buffer[2], strchr((const char *)gps_rmc_buffer, '*') + 1, 2);
bbc_xor_origin = (uint8)func_str_to_hex((char *)check_buffer);
for(bbc_xor_calculation = gps_rmc_buffer[1], data_len = 2; '*' != gps_rmc_buffer[data_len]; data_len ++)
{
bbc_xor_calculation ^= gps_rmc_buffer[data_len];
}
if(bbc_xor_calculation != bbc_xor_origin)
{
// 数据校验失败
return_state = 1;
break;
}
gps_gnrmc_parse((char *)gps_rmc_buffer, &gnss);
}
gnss_rmc_state = GPS_STATE_RECEIVING;
if(GPS_STATE_RECEIVED == gnss_gga_state)
{
gnss_gga_state = GPS_STATE_PARSING;
strncpy((char *)&check_buffer[2], strchr((const char *)gps_gga_buffer, '*') + 1, 2);
bbc_xor_origin = (uint8)func_str_to_hex((char *)check_buffer);
for(bbc_xor_calculation = gps_gga_buffer[1], data_len = 2; '*' != gps_gga_buffer[data_len]; data_len ++)
{
bbc_xor_calculation ^= gps_gga_buffer[data_len];
}
if(bbc_xor_calculation != bbc_xor_origin)
{
// 数据校验失败
return_state = 1;
break;
}
gps_gngga_parse((char *)gps_gga_buffer, &gnss);
}
gnss_gga_state = GPS_STATE_RECEIVING;
if(GPS_STATE_RECEIVED == gnss_ths_state)
{
gnss_ths_state = GPS_STATE_PARSING;
strncpy((char *)&check_buffer[2], strchr((const char *)gps_ths_buffer, '*') + 1, 2);
bbc_xor_origin = (uint8)func_str_to_hex((char *)check_buffer);
for(bbc_xor_calculation = gps_ths_buffer[1], data_len = 2; '*' != gps_ths_buffer[data_len]; data_len ++)
{
bbc_xor_calculation ^= gps_ths_buffer[data_len];
}
if(bbc_xor_calculation != bbc_xor_origin)
{
// 数据校验失败
return_state = 1;
break;
}
gps_gnths_parse((char *)gps_ths_buffer, &gnss);
}
gnss_ths_state = GPS_STATE_RECEIVING;
}while(0);
return return_state;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 GPS串口回调函数
// 参数说明 void
// 返回参数 void
// 使用示例 gps_uart_callback();
// 备注信息 此函数需要在串口接收中断内进行调用
//-------------------------------------------------------------------------------------------------------------------
void gnss_uart_callback (void)
{
uint8 temp_gps[6];
uint32 temp_length = 0;
if(gnss_state)
{
uint8 dat;
while(uart_query_byte(GNSS_UART, &dat))
{
fifo_write_buffer(&gnss_receiver_fifo, &dat, 1);
}
if('\n' == dat)
{
// 读取前6个数据 用于判断语句类型
temp_length = 6;
fifo_read_buffer(&gnss_receiver_fifo, temp_gps, &temp_length, FIFO_READ_ONLY);
// 根据不同类型将数据拷贝到不同的缓冲区
if(0 == strncmp((char *)&temp_gps[3], "RMC", 3))
{
// 如果没有在解析数据则更新缓冲区的数据
if(GPS_STATE_PARSING != gnss_rmc_state)
{
gnss_rmc_state = GPS_STATE_RECEIVED;
temp_length = fifo_used(&gnss_receiver_fifo);
fifo_read_buffer(&gnss_receiver_fifo, gps_rmc_buffer, &temp_length, FIFO_READ_AND_CLEAN);
}
}
else if(0 == strncmp((char *)&temp_gps[3], "GGA", 3))
{
// 如果没有在解析数据则更新缓冲区的数据
if(GPS_STATE_PARSING != gnss_gga_state)
{
gnss_gga_state = GPS_STATE_RECEIVED;
temp_length = fifo_used(&gnss_receiver_fifo);
fifo_read_buffer(&gnss_receiver_fifo, gps_gga_buffer, &temp_length, FIFO_READ_AND_CLEAN);
}
}
else if(0 == strncmp((char *)&temp_gps[3], "THS", 3))
{
// 如果没有在解析数据则更新缓冲区的数据
if(GPS_STATE_PARSING != gnss_ths_state)
{
gnss_ths_state = GPS_STATE_RECEIVED;
temp_length = fifo_used(&gnss_receiver_fifo);
fifo_read_buffer(&gnss_receiver_fifo, gps_ths_buffer, &temp_length, FIFO_READ_AND_CLEAN);
}
}
// 统一将FIFO清空
fifo_clear(&gnss_receiver_fifo);
gnss_flag = 1;
}
}
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 GPS初始化
// 参数说明 void
// 返回参数 void
// 使用示例 gps_init();
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
void gnss_init (gps_device_enum gps_device)
{
const uint8 set_rate[] = {0xF1, 0xD9, 0x06, 0x42, 0x14, 0x00, 0x00, 0x0A, 0x05, 0x00, 0x64, 0x00, 0x00, 0x00, 0x60, 0xEA, 0x00, 0x00, 0xD0, 0x07, 0x00, 0x00, 0xC8, 0x00, 0x00, 0x00, 0xB8, 0xED};
const uint8 open_gga[] = {0xF1, 0xD9, 0x06, 0x01, 0x03, 0x00, 0xF0, 0x00, 0x01, 0xFB, 0x10};
const uint8 open_rmc[] = {0xF1, 0xD9, 0x06, 0x01, 0x03, 0x00, 0xF0, 0x05, 0x01, 0x00, 0x1A};
const uint8 close_gll[] = {0xF1, 0xD9, 0x06, 0x01, 0x03, 0x00, 0xF0, 0x01, 0x00, 0xFB, 0x11};
const uint8 close_gsa[] = {0xF1, 0xD9, 0x06, 0x01, 0x03, 0x00, 0xF0, 0x02, 0x00, 0xFC, 0x13};
const uint8 close_grs[] = {0xF1, 0xD9, 0x06, 0x01, 0x03, 0x00, 0xF0, 0x03, 0x00, 0xFD, 0x15};
const uint8 close_gsv[] = {0xF1, 0xD9, 0x06, 0x01, 0x03, 0x00, 0xF0, 0x04, 0x00, 0xFE, 0x17};
const uint8 close_vtg[] = {0xF1, 0xD9, 0x06, 0x01, 0x03, 0x00, 0xF0, 0x06, 0x00, 0x00, 0x1B};
const uint8 close_zda[] = {0xF1, 0xD9, 0x06, 0x01, 0x03, 0x00, 0xF0, 0x07, 0x00, 0x01, 0x1D};
const uint8 close_gst[] = {0xF1, 0xD9, 0x06, 0x01, 0x03, 0x00, 0xF0, 0x08, 0x00, 0x02, 0x1F};
const uint8 close_txt[] = {0xF1, 0xD9, 0x06, 0x01, 0x03, 0x00, 0xF0, 0x40, 0x00, 0x3A, 0x8F};
const uint8 close_txt_ant[] = {0xF1, 0xD9, 0x06, 0x01, 0x03, 0x00, 0xF0, 0x20, 0x00, 0x1A, 0x4F};
if((TAU1201 == gps_device) || (GN42A == gps_device))
{
fifo_init(&gnss_receiver_fifo, FIFO_DATA_8BIT, gnss_receiver_buffer, GNSS_BUFFER_SIZE);
system_delay_ms(500); // 等待GPS启动后开始初始化
uart_init(GNSS_UART, 115200, GNSS_RX, GNSS_TX);
uart_write_buffer(GNSS_UART, (uint8 *)set_rate, sizeof(set_rate)); // 设置GPS更新速率为10hz 如果不调用此语句则默认为1hz
system_delay_ms(200);
uart_write_buffer(GNSS_UART, (uint8 *)open_rmc, sizeof(open_rmc)); // 开启rmc语句
system_delay_ms(50);
uart_write_buffer(GNSS_UART, (uint8 *)open_gga, sizeof(open_gga)); // 开启gga语句
system_delay_ms(50);
uart_write_buffer(GNSS_UART, (uint8 *)close_gll, sizeof(close_gll));
system_delay_ms(50);
uart_write_buffer(GNSS_UART, (uint8 *)close_gsa, sizeof(close_gsa));
system_delay_ms(50);
uart_write_buffer(GNSS_UART, (uint8 *)close_grs, sizeof(close_grs));
system_delay_ms(50);
uart_write_buffer(GNSS_UART, (uint8 *)close_gsv, sizeof(close_gsv));
system_delay_ms(50);
uart_write_buffer(GNSS_UART, (uint8 *)close_vtg, sizeof(close_vtg));
system_delay_ms(50);
uart_write_buffer(GNSS_UART, (uint8 *)close_zda, sizeof(close_zda));
system_delay_ms(50);
uart_write_buffer(GNSS_UART, (uint8 *)close_gst, sizeof(close_gst));
system_delay_ms(50);
uart_write_buffer(GNSS_UART, (uint8 *)close_txt, sizeof(close_txt));
system_delay_ms(50);
uart_write_buffer(GNSS_UART, (uint8 *)close_txt_ant, sizeof(close_txt_ant));
system_delay_ms(50);
gnss_state = 1;
uart_rx_interrupt(GNSS_UART, 1);
}
else if(GN43RFA == gps_device)
{
// GN43RFA RTK模块不需要进行参数设置,如果需要修改参数应该使用专用的上位机修改参数
fifo_init(&gnss_receiver_fifo, FIFO_DATA_8BIT, gnss_receiver_buffer, GNSS_BUFFER_SIZE);
uart_init(GNSS_UART, 115200, GNSS_RX, GNSS_TX);
gnss_state = 1;
uart_rx_interrupt(GNSS_UART, 1);
}
}
+125
View File
@@ -0,0 +1,125 @@
/*********************************************************************************************************************
* 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_gnss
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 ADS v1.10.2
* 适用平台 TC264D
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2023-12-28 pudding first version
********************************************************************************************************************/
/*********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* RX 查看 zf_device_gnss.h 中 GNSS_RX 宏定义
* TX 查看 zf_device_gnss.h 中 GNSS_TX 宏定义
* VCC 3.3V电源
* GND 电源地
* ------------------------------------
********************************************************************************************************************/
#ifndef _zf_device_gnss_h_
#define _zf_device_gnss_h_
#include "zf_common_typedef.h"
//--------------------------------------------------------------------------------------------------
//引脚配置
//--------------------------------------------------------------------------------------------------
#define GNSS_UART (UART_3)
#define GNSS_RX (UART3_TX_P15_6) // GPS RX引脚连接到单片机此
#define GNSS_TX (UART3_RX_P15_7) // GPS TX串口引脚
#define ANGLE_TO_RAD(x) ( (x) * PI / 180.0 ) // 角度转换为弧度
#define RAD_TO_ANGLE(x) ( (x) * 180.0 / PI ) // 弧度转换为角度
#define PI ( 3.1415926535898 )
typedef enum
{
TAU1201 = 1, // 逐飞科技双频GPS模块
GN42A = 1, // 逐飞科技双频GPS模块 与TAU1201是一样的
GN43RFA = 2, // 逐飞科技三频RTK模块
}gps_device_enum;
typedef struct
{
uint16 year;
uint8 month;
uint8 day;
uint8 hour;
uint8 minute;
uint8 second;
}gps_time_struct;
typedef struct
{
gps_time_struct time; // 时间
uint8 state; // 有效状态 1:定位有效 0:定位无效
uint16 latitude_degree; // 度
uint16 latitude_cent; // 分
uint16 latitude_second; // 秒 这里的秒是被放大了100倍的,主要是避免使用浮点数
uint16 longitude_degree; // 度
uint16 longitude_cent; // 分
uint16 longitude_second; // 秒 这里的秒是被放大了100倍的,主要是避免使用浮点数
double latitude; // 纬度
double longitude; // 经度
int8 ns; // 纬度半球 N(北半球)或 S(南半球)
int8 ew; // 经度半球 E(东经)或 W(西经)
float speed; // 速度(公里/每小时)
float direction; // 地面航向(000.0~359.9 度,以真北方为参考基准)+
uint8 antenna_direction_state; // 双天线测向有效状态 1:测向有效 0:测向无效,无效时antenna_direction数据是无效的
float antenna_direction; // 主天线指向从天线与真北构成的夹角(000.0~359.9 度)
// 下面两个个信息从GNGGA语句中获取
uint8 satellite_used; // 用于定位的卫星数量
float height; // 高度
}gnss_info_struct;
typedef enum
{
GPS_STATE_RECEIVING, // 正在接收数据
GPS_STATE_RECEIVED, // 数据接收完成
GPS_STATE_PARSING, // 正在解析
}gps_state_enum;
extern gnss_info_struct gnss;
extern uint8 gnss_flag;
double get_two_points_distance (double lat1, double lng1, double lat2, double lng2);
double get_two_points_azimuth (double lat1, double lon1, double lat2, double lon2);
uint8 gnss_data_parse (void);
void gnss_uart_callback (void);
void gnss_init (gps_device_enum gps_device);
#endif
+347
View File
@@ -0,0 +1,347 @@
/*********************************************************************************************************************
* 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_icm20602
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 ADS v1.10.2
* 适用平台 TC264D
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2022-09-15 pudding first version
* 2023-04-28 pudding 增加中文注释说明
********************************************************************************************************************/
/*********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* // 硬件 SPI 引脚
* SCL/SPC 查看 zf_device_icm20602.h 中 ICM20602_SPC_PIN 宏定义
* SDA/DSI 查看 zf_device_icm20602.h 中 ICM20602_SDI_PIN 宏定义
* SA0/SDO 查看 zf_device_icm20602.h 中 ICM20602_SDO_PIN 宏定义
* CS 查看 zf_device_icm20602.h 中 ICM20602_CS_PIN 宏定义
* VCC 3.3V电源
* GND 电源地
* 其余引脚悬空
*
* // 软件 IIC 引脚
* SCL/SPC 查看 zf_device_icm20602.h 中 ICM20602_SCL_PIN 宏定义
* SDA/DSI 查看 zf_device_icm20602.h 中 ICM20602_SDA_PIN 宏定义
* VCC 3.3V电源
* GND 电源地
* 其余引脚悬空
* ------------------------------------
********************************************************************************************************************/
#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_icm20602.h"
int16 icm20602_gyro_x = 0, icm20602_gyro_y = 0, icm20602_gyro_z = 0; // 三轴陀螺仪数据 gyro (陀螺仪)
int16 icm20602_acc_x = 0, icm20602_acc_y = 0, icm20602_acc_z = 0; // 三轴加速度计数据 acc (accelerometer 加速度计)
float icm20602_transition_factor[2] = {4096, 16.4}; // 转换实际值的比例
#if ICM20602_USE_SOFT_IIC
static soft_iic_info_struct icm20602_iic_struct;
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 ICM20602 写寄存器
// 参数说明 reg 寄存器地址
// 参数说明 data 数据
// 返回参数 void
// 使用示例 icm20602_write_register(ICM20602_PWR_MGMT_1, 0x80);
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
#define icm20602_write_register(reg, data) (soft_iic_write_8bit_register(&icm20602_iic_struct, (reg), (data)))
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 ICM20602 读寄存器
// 参数说明 reg 寄存器地址
// 返回参数 uint8 数据
// 使用示例 icm20602_read_register(ICM20602_WHO_AM_I);
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
#define icm20602_read_register(reg) (soft_iic_read_8bit_register(&icm20602_iic_struct, (reg)))
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 ICM20602 读数据
// 参数说明 reg 寄存器地址
// 参数说明 data 数据缓冲区
// 参数说明 len 数据长度
// 返回参数 void
// 使用示例 icm20602_read_registers(ICM20602_ACCEL_XOUT_H, dat, 6);
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
#define icm20602_read_registers(reg, data, len) (soft_iic_read_8bit_registers(&icm20602_iic_struct, (reg), (data), (len)))
#else
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 ICM20602 写寄存器
// 参数说明 reg 寄存器地址
// 参数说明 data 数据
// 返回参数 void
// 使用示例 icm20602_write_register(ICM20602_PWR_MGMT_1, 0x80);
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
static void icm20602_write_register(uint8 reg, uint8 data)
{
ICM20602_CS(0);
spi_write_8bit_register(ICM20602_SPI, reg | ICM20602_SPI_W, data);
ICM20602_CS(1);
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 ICM20602 读寄存器
// 参数说明 reg 寄存器地址
// 返回参数 uint8 数据
// 使用示例 icm20602_read_register(ICM20602_WHO_AM_I);
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
static uint8 icm20602_read_register(uint8 reg)
{
uint8 data = 0;
ICM20602_CS(0);
data = spi_read_8bit_register(ICM20602_SPI, reg | ICM20602_SPI_R);
ICM20602_CS(1);
return data;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 ICM20602 读数据
// 参数说明 reg 寄存器地址
// 参数说明 data 数据缓冲区
// 参数说明 len 数据长度
// 返回参数 void
// 使用示例 icm20602_read_registers(ICM20602_ACCEL_XOUT_H, dat, 6);
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
static void icm20602_read_registers(uint8 reg, uint8 *data, uint32 len)
{
ICM20602_CS(0);
spi_read_8bit_registers(ICM20602_SPI, reg | ICM20602_SPI_R, data, len);
ICM20602_CS(1);
}
#endif
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 ICM20602 自检
// 参数说明 void
// 返回参数 uint8 1-自检失败 0-自检成功
// 使用示例 icm20602_self_check();
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
static uint8 icm20602_self_check (void)
{
uint8 dat = 0, return_state = 0;
uint16 timeout_count = 0;
while(0x12 != dat) // 判断 ID 是否正确
{
if(ICM20602_TIMEOUT_COUNT < timeout_count ++)
{
return_state = 1;
break;
}
dat = icm20602_read_register(ICM20602_WHO_AM_I);
system_delay_ms(10);
}
return return_state;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 获取 ICM20602 加速度计数据
// 参数说明 void
// 返回参数 void
// 使用示例 icm20602_get_acc(); // 执行该函数后,直接查看对应的变量即可
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
void icm20602_get_acc (void)
{
uint8 dat[6];
icm20602_read_registers(ICM20602_ACCEL_XOUT_H, dat, 6);
icm20602_acc_x = (int16)(((uint16)dat[0] << 8 | dat[1]));
icm20602_acc_y = (int16)(((uint16)dat[2] << 8 | dat[3]));
icm20602_acc_z = (int16)(((uint16)dat[4] << 8 | dat[5]));
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 获取 ICM20602 陀螺仪数据
// 参数说明 void
// 返回参数 void
// 使用示例 icm20602_get_gyro(); // 执行该函数后,直接查看对应的变量即可
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
void icm20602_get_gyro (void)
{
uint8 dat[6];
icm20602_read_registers(ICM20602_GYRO_XOUT_H, dat, 6);
icm20602_gyro_x = (int16)(((uint16)dat[0] << 8 | dat[1]));
icm20602_gyro_y = (int16)(((uint16)dat[2] << 8 | dat[3]));
icm20602_gyro_z = (int16)(((uint16)dat[4] << 8 | dat[5]));
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 初始化 ICM20602
// 参数说明 void
// 返回参数 uint8 1-初始化失败 0-初始化成功
// 使用示例 icm20602_init();
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
uint8 icm20602_init (void)
{
uint8 val = 0x0, return_state = 0;
uint16 timeout_count = 0;
system_delay_ms(10); // 上电延时
#if ICM20602_USE_SOFT_IIC
soft_iic_init(&icm20602_iic_struct, ICM20602_DEV_ADDR, ICM20602_SOFT_IIC_DELAY, ICM20602_SCL_PIN, ICM20602_SDA_PIN);
#else
spi_init(ICM20602_SPI, SPI_MODE0, ICM20602_SPI_SPEED, ICM20602_SPC_PIN, ICM20602_SDI_PIN, ICM20602_SDO_PIN, SPI_CS_NULL);
gpio_init(ICM20602_CS_PIN, GPO, GPIO_HIGH, GPO_PUSH_PULL);
#endif
do
{
if(icm20602_self_check())
{
// 如果程序在输出了断言信息 并且提示出错位置在这里
// 那么就是 ICM20602 自检出错并超时退出了
// 检查一下接线有没有问题 如果没问题可能就是坏了
zf_log(0, "icm20602 self check error.");
return_state = 1;
break;
}
icm20602_write_register(ICM20602_PWR_MGMT_1, 0x80); // 复位设备
system_delay_ms(2);
do
{ // 等待复位成功
val = icm20602_read_register(ICM20602_PWR_MGMT_1);
if(ICM20602_TIMEOUT_COUNT < timeout_count ++)
{
// 如果程序在输出了断言信息 并且提示出错位置在这里
// 那么就是 ICM20602 自检出错并超时退出了
// 检查一下接线有没有问题 如果没问题可能就是坏了
zf_log(0, "icm20602 reset error.");
return_state = 1;
break;
}
}while(0x41 != val);
if(1 == return_state)
{
break;
}
icm20602_write_register(ICM20602_PWR_MGMT_1, 0x01); // 时钟设置
icm20602_write_register(ICM20602_PWR_MGMT_2, 0x00); // 开启陀螺仪和加速度计
icm20602_write_register(ICM20602_CONFIG, 0x01); // 176HZ 1KHZ
icm20602_write_register(ICM20602_SMPLRT_DIV, 0x07); // 采样速率 SAMPLE_RATE = INTERNAL_SAMPLE_RATE / (1 + SMPLRT_DIV)
// ICM20602_ACCEL_CONFIG 寄存器
// 设置为 0x00 加速度计量程为 ±2 g 获取到的加速度计数据除以 16384 可以转化为带物理单位的数据 单位 g(m/s^2)
// 设置为 0x08 加速度计量程为 ±4 g 获取到的加速度计数据除以 8192 可以转化为带物理单位的数据 单位 g(m/s^2)
// 设置为 0x10 加速度计量程为 ±8 g 获取到的加速度计数据除以 4096 可以转化为带物理单位的数据 单位 g(m/s^2)
// 设置为 0x18 加速度计量程为 ±16 g 获取到的加速度计数据除以 2048 可以转化为带物理单位的数据 单位 g(m/s^2)
switch(ICM20602_ACC_SAMPLE_DEFAULT)
{
case ICM20602_ACC_SAMPLE_SGN_2G:
{
icm20602_write_register(ICM20602_ACCEL_CONFIG, 0x00);
icm20602_transition_factor[0] = 16384;
}break;
case ICM20602_ACC_SAMPLE_SGN_4G:
{
icm20602_write_register(ICM20602_ACCEL_CONFIG, 0x08);
icm20602_transition_factor[0] = 8192;
}break;
case ICM20602_ACC_SAMPLE_SGN_8G:
{
icm20602_write_register(ICM20602_ACCEL_CONFIG, 0x10);
icm20602_transition_factor[0] = 4096;
}break;
case ICM20602_ACC_SAMPLE_SGN_16G:
{
icm20602_write_register(ICM20602_ACCEL_CONFIG, 0x18);
icm20602_transition_factor[0] = 2048;
}break;
default:
{
zf_log(0, "ICM20602_ACC_SAMPLE_DEFAULT set error.");
return_state = 1;
}break;
}
if(1 == return_state)
{
break;
}
// ICM20602_GYRO_CONFIG 寄存器
// 设置为 0x00 陀螺仪量程为 ±250 dps 获取到的陀螺仪数据除以 131 可以转化为带物理单位的数据 单位为 °/s
// 设置为 0x08 陀螺仪量程为 ±500 dps 获取到的陀螺仪数据除以 65.5 可以转化为带物理单位的数据 单位为 °/s
// 设置为 0x10 陀螺仪量程为 ±1000 dps 获取到的陀螺仪数据除以 32.8 可以转化为带物理单位的数据 单位为 °/s
// 设置为 0x18 陀螺仪量程为 ±2000 dps 获取到的陀螺仪数据除以 16.4 可以转化为带物理单位的数据 单位为 °/s
switch(ICM20602_GYRO_SAMPLE_DEFAULT)
{
case ICM20602_GYRO_SAMPLE_SGN_250DPS:
{
icm20602_write_register(ICM20602_GYRO_CONFIG, 0x00);
icm20602_transition_factor[1] = 131.0;
}break;
case ICM20602_GYRO_SAMPLE_SGN_500DPS:
{
icm20602_write_register(ICM20602_GYRO_CONFIG, 0x08);
icm20602_transition_factor[1] = 65.5;
}break;
case ICM20602_GYRO_SAMPLE_SGN_1000DPS:
{
icm20602_write_register(ICM20602_GYRO_CONFIG, 0x10);
icm20602_transition_factor[1] = 32.8;
}break;
case ICM20602_GYRO_SAMPLE_SGN_2000DPS:
{
icm20602_write_register(ICM20602_GYRO_CONFIG, 0x18);
icm20602_transition_factor[1] = 16.4;
}break;
default:
{
zf_log(0, "ICM20602_GYRO_SAMPLE_DEFAULT set error.");
return_state = 1;
}break;
}
if(1 == return_state)
{
break;
}
icm20602_write_register(ICM20602_ACCEL_CONFIG_2, 0x03); // Average 4 samples 44.8HZ //0x23 Average 16 samples
}while(0);
return return_state;
}
+227
View File
@@ -0,0 +1,227 @@
/*********************************************************************************************************************
* 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_icm20602
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 ADS v1.10.2
* 适用平台 TC264D
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2022-09-15 pudding first version
* 2023-04-28 pudding 增加中文注释说明
* 2024-01-30 pudding 更正宏转换函数 变量增加括号
********************************************************************************************************************/
/*********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* // 硬件 SPI 引脚
* SCL/SPC 查看 zf_device_icm20602.h 中 ICM20602_SPC_PIN 宏定义
* SDA/DSI 查看 zf_device_icm20602.h 中 ICM20602_SDI_PIN 宏定义
* SA0/SDO 查看 zf_device_icm20602.h 中 ICM20602_SDO_PIN 宏定义
* CS 查看 zf_device_icm20602.h 中 ICM20602_CS_PIN 宏定义
* VCC 3.3V电源
* GND 电源地
* 其余引脚悬空
*
* // 软件 IIC 引脚
* SCL/SPC 查看 zf_device_icm20602.h 中 ICM20602_SCL_PIN 宏定义
* SDA/DSI 查看 zf_device_icm20602.h 中 ICM20602_SDA_PIN 宏定义
* VCC 3.3V电源
* GND 电源地
* 其余引脚悬空
* ------------------------------------
********************************************************************************************************************/
#ifndef _zf_device_icm20602_h_
#define _zf_device_icm20602_h_
#include "zf_common_typedef.h"
//================================================定义 ICM20602 基本配置================================================
// ICM20602_USE_SOFT_IIC定义为0表示使用硬件SPI驱动 定义为1表示使用软件IIC驱动
#define ICM20602_USE_SOFT_IIC (0) // 默认使用硬件 SPI 方式驱动
#if ICM20602_USE_SOFT_IIC // 这两段 颜色正常的才是正确的 颜色灰的就是没有用的
//====================================================软件 IIC 驱动====================================================
#define ICM20602_SOFT_IIC_DELAY (59 ) // 软件 IIC 的时钟延时周期 数值越小 IIC 通信速率越快
#define ICM20602_SCL_PIN (P20_11) // 软件 IIC SCL 引脚 连接 ICM20602 的 SCL 引脚
#define ICM20602_SDA_PIN (P20_14) // 软件 IIC SDA 引脚 连接 ICM20602 的 SDA 引脚
//====================================================软件 IIC 驱动====================================================
#else
//====================================================硬件 SPI 驱动====================================================
#define ICM20602_SPI_SPEED (10 * 1000 * 1000) // 硬件 SPI 速率
#define ICM20602_SPI (SPI_0) // 硬件 SPI 号
#define ICM20602_SPC_PIN (SPI0_SCLK_P20_11) // 硬件 SPI SCK 引脚
#define ICM20602_SDI_PIN (SPI0_MOSI_P20_14) // 硬件 SPI MOSI 引脚
#define ICM20602_SDO_PIN (SPI0_MISO_P20_12) // 硬件 SPI MISO 引脚
//====================================================硬件 SPI 驱动====================================================
#endif
#define ICM20602_CS_PIN (P20_13) // CS 片选引脚
#define ICM20602_CS(x) ((x) ? (gpio_high(ICM20602_CS_PIN)) : (gpio_low(ICM20602_CS_PIN)))
typedef enum
{
ICM20602_ACC_SAMPLE_SGN_2G , // 加速度计量程 ±2G (ACC = Accelerometer 加速度计) (SGN = signum 带符号数 表示正负范围) (G = g 重力加速度 g≈9.80 m/s^2)
ICM20602_ACC_SAMPLE_SGN_4G , // 加速度计量程 ±4G (ACC = Accelerometer 加速度计) (SGN = signum 带符号数 表示正负范围) (G = g 重力加速度 g≈9.80 m/s^2)
ICM20602_ACC_SAMPLE_SGN_8G , // 加速度计量程 ±8G (ACC = Accelerometer 加速度计) (SGN = signum 带符号数 表示正负范围) (G = g 重力加速度 g≈9.80 m/s^2)
ICM20602_ACC_SAMPLE_SGN_16G, // 加速度计量程 ±16G (ACC = Accelerometer 加速度计) (SGN = signum 带符号数 表示正负范围) (G = g 重力加速度 g≈9.80 m/s^2)
}icm20602_acc_sample_config;
typedef enum
{
ICM20602_GYRO_SAMPLE_SGN_250DPS , // 陀螺仪量程 ±250DPS (GYRO = Gyroscope 陀螺仪) (SGN = signum 带符号数 表示正负范围) (DPS = Degree Per Second 角速度单位 °/S)
ICM20602_GYRO_SAMPLE_SGN_500DPS , // 陀螺仪量程 ±500DPS (GYRO = Gyroscope 陀螺仪) (SGN = signum 带符号数 表示正负范围) (DPS = Degree Per Second 角速度单位 °/S)
ICM20602_GYRO_SAMPLE_SGN_1000DPS, // 陀螺仪量程 ±1000DPS (GYRO = Gyroscope 陀螺仪) (SGN = signum 带符号数 表示正负范围) (DPS = Degree Per Second 角速度单位 °/S)
ICM20602_GYRO_SAMPLE_SGN_2000DPS, // 陀螺仪量程 ±2000DPS (GYRO = Gyroscope 陀螺仪) (SGN = signum 带符号数 表示正负范围) (DPS = Degree Per Second 角速度单位 °/S)
}icm20602_gyro_sample_config;
#define ICM20602_ACC_SAMPLE_DEFAULT ( ICM20602_ACC_SAMPLE_SGN_8G ) // 在这设置默认的 加速度计 初始化量程
#define ICM20602_GYRO_SAMPLE_DEFAULT ( ICM20602_GYRO_SAMPLE_SGN_2000DPS ) // 在这设置默认的 陀螺仪 初始化量程
#define ICM20602_TIMEOUT_COUNT (0x00FF) // ICM20602 超时计数
//================================================定义 ICM20602 基本配置================================================
//================================================定义 ICM20602 内部地址================================================
#define ICM20602_DEV_ADDR (0x69) // SA0接地:0x68 SA0上拉:0x69 模块默认上拉
#define ICM20602_SPI_W (0x00)
#define ICM20602_SPI_R (0x80)
#define ICM20602_XG_OFFS_TC_H (0x04)
#define ICM20602_XG_OFFS_TC_L (0x05)
#define ICM20602_YG_OFFS_TC_H (0x07)
#define ICM20602_YG_OFFS_TC_L (0x08)
#define ICM20602_ZG_OFFS_TC_H (0x0A)
#define ICM20602_ZG_OFFS_TC_L (0x0B)
#define ICM20602_SELF_TEST_X_ACCEL (0x0D)
#define ICM20602_SELF_TEST_Y_ACCEL (0x0E)
#define ICM20602_SELF_TEST_Z_ACCEL (0x0F)
#define ICM20602_XG_OFFS_USRH (0x13)
#define ICM20602_XG_OFFS_USRL (0x14)
#define ICM20602_YG_OFFS_USRH (0x15)
#define ICM20602_YG_OFFS_USRL (0x16)
#define ICM20602_ZG_OFFS_USRH (0x17)
#define ICM20602_ZG_OFFS_USRL (0x18)
#define ICM20602_SMPLRT_DIV (0x19)
#define ICM20602_CONFIG (0x1A)
#define ICM20602_GYRO_CONFIG (0x1B)
#define ICM20602_ACCEL_CONFIG (0x1C)
#define ICM20602_ACCEL_CONFIG_2 (0x1D)
#define ICM20602_LP_MODE_CFG (0x1E)
#define ICM20602_ACCEL_WOM_X_THR (0x20)
#define ICM20602_ACCEL_WOM_Y_THR (0x21)
#define ICM20602_ACCEL_WOM_Z_THR (0x22)
#define ICM20602_FIFO_EN (0x23)
#define ICM20602_FSYNC_INT (0x36)
#define ICM20602_INT_PIN_CFG (0x37)
#define ICM20602_INT_ENABLE (0x38)
#define ICM20602_FIFO_WM_INT_STATUS (0x39)
#define ICM20602_INT_STATUS (0x3A)
#define ICM20602_ACCEL_XOUT_H (0x3B)
#define ICM20602_ACCEL_XOUT_L (0x3C)
#define ICM20602_ACCEL_YOUT_H (0x3D)
#define ICM20602_ACCEL_YOUT_L (0x3E)
#define ICM20602_ACCEL_ZOUT_H (0x3F)
#define ICM20602_ACCEL_ZOUT_L (0x40)
#define ICM20602_TEMP_OUT_H (0x41)
#define ICM20602_TEMP_OUT_L (0x42)
#define ICM20602_GYRO_XOUT_H (0x43)
#define ICM20602_GYRO_XOUT_L (0x44)
#define ICM20602_GYRO_YOUT_H (0x45)
#define ICM20602_GYRO_YOUT_L (0x46)
#define ICM20602_GYRO_ZOUT_H (0x47)
#define ICM20602_GYRO_ZOUT_L (0x48)
#define ICM20602_SELF_TEST_X_GYRO (0x50)
#define ICM20602_SELF_TEST_Y_GYRO (0x51)
#define ICM20602_SELF_TEST_Z_GYRO (0x52)
#define ICM20602_FIFO_WM_TH1 (0x60)
#define ICM20602_FIFO_WM_TH2 (0x61)
#define ICM20602_SIGNAL_PATH_RESET (0x68)
#define ICM20602_ACCEL_INTEL_CTRL (0x69)
#define ICM20602_USER_CTRL (0x6A)
#define ICM20602_PWR_MGMT_1 (0x6B)
#define ICM20602_PWR_MGMT_2 (0x6C)
#define ICM20602_I2C_IF (0x70)
#define ICM20602_FIFO_COUNTH (0x72)
#define ICM20602_FIFO_COUNTL (0x73)
#define ICM20602_FIFO_R_W (0x74)
#define ICM20602_WHO_AM_I (0x75)
#define ICM20602_XA_OFFSET_H (0x77)
#define ICM20602_XA_OFFSET_L (0x78)
#define ICM20602_YA_OFFSET_H (0x7A)
#define ICM20602_YA_OFFSET_L (0x7B)
#define ICM20602_ZA_OFFSET_H (0x7D)
#define ICM20602_ZA_OFFSET_L (0x7E)
#define ICM20602_ACC_SAMPLE (0x10) // 加速度计量程
// 设置为:0x00 加速度计量程为:±2g 获取到的加速度计数据 除以16384 可以转化为带物理单位的数据,单位:g(m/s^2)
// 设置为:0x08 加速度计量程为:±4g 获取到的加速度计数据 除以8192 可以转化为带物理单位的数据,单位:g(m/s^2)
// 设置为:0x10 加速度计量程为:±8g 获取到的加速度计数据 除以4096 可以转化为带物理单位的数据,单位:g(m/s^2)
// 设置为:0x18 加速度计量程为:±16g 获取到的加速度计数据 除以2048 可以转化为带物理单位的数据,单位:g(m/s^2)
#define ICM20602_GYR_SAMPLE (0x18) // 陀螺仪量程
// 设置为:0x00 陀螺仪量程为:±250 dps 获取到的陀螺仪数据除以131 可以转化为带物理单位的数据,单位为:°/s
// 设置为:0x08 陀螺仪量程为:±500 dps 获取到的陀螺仪数据除以65.5 可以转化为带物理单位的数据,单位为:°/s
// 设置为:0x10 陀螺仪量程为:±1000dps 获取到的陀螺仪数据除以32.8 可以转化为带物理单位的数据,单位为:°/s
// 设置为:0x18 陀螺仪量程为:±2000dps 获取到的陀螺仪数据除以16.4 可以转化为带物理单位的数据,单位为:°/s
//================================================定义 ICM20602 内部地址================================================
//================================================声明 ICM20602 全局变量================================================
extern int16 icm20602_gyro_x, icm20602_gyro_y, icm20602_gyro_z; // 三轴陀螺仪数据 GYRO (陀螺仪)
extern int16 icm20602_acc_x, icm20602_acc_y, icm20602_acc_z; // 三轴加速度计数据 ACC (accelerometer 加速度计)
extern float icm20602_transition_factor[2]; // 转换实际值的比例
//================================================声明 ICM20602 全局变量================================================
//================================================声明 ICM20602 基础函数================================================
void icm20602_get_acc (void); // 获取 ICM20602 加速度计数据
void icm20602_get_gyro (void); // 获取 ICM20602 陀螺仪数据
uint8 icm20602_init (void); // 初始化 ICM20602
//================================================声明 ICM20602 基础函数================================================
//================================================声明 ICM20602 拓展函数================================================
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 将 ICM20602 加速度计数据转换为实际物理数据
// 参数说明 acc_value 任意轴的加速度计数据
// 返回参数 void
// 使用示例 float data = icm20602_acc_transition(icm20602_acc_x); // 单位为 g(m/s^2)
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
#define icm20602_acc_transition(acc_value) ((float)(acc_value) / icm20602_transition_factor[0])
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 将 ICM20602 陀螺仪数据转换为实际物理数据
// 参数说明 gyro_value 任意轴的陀螺仪数据
// 返回参数 void
// 使用示例 float data = icm20602_gyro_transition(icm20602_gyro_x); // 单位为 °/s
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
#define icm20602_gyro_transition(gyro_value) ((float)(gyro_value) / icm20602_transition_factor[1])
//================================================声明 ICM20602 拓展函数================================================
#endif
+341
View File
@@ -0,0 +1,341 @@
/*********************************************************************************************************************
* 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_imu660ra
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 ADS v1.10.2
* 适用平台 TC264D
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2022-09-15 pudding first version
* 2023-04-28 pudding 增加中文注释说明
********************************************************************************************************************/
/*********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* // 硬件 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_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_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_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
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 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_SOFT_IIC
gpio_init(IMU660RA_CS_PIN, GPO, GPIO_LOW, GPO_PUSH_PULL); // 配置 IMU660RA 的CS端口
soft_iic_init(&imu660ra_iic_struct, IMU660RA_DEV_ADDR, IMU660RA_SOFT_IIC_DELAY, IMU660RA_SCL_PIN, IMU660RA_SDA_PIN); // 配置 IMU660RA 的 IIC 端口
#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;
}
+159
View File
@@ -0,0 +1,159 @@
/*********************************************************************************************************************
* 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_imu660ra
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 ADS v1.10.2
* 适用平台 TC264D
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2022-09-15 pudding first version
* 2023-04-28 pudding 增加中文注释说明
********************************************************************************************************************/
/*********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* // 硬件 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_SOFT_IIC定义为0表示使用硬件SPI驱动 定义为1表示使用软件IIC驱动
// 当更改IMU660RA_USE_SOFT_IIC定义后,需要先编译并下载程序,单片机与模块需要断电重启才能正常通讯
#define IMU660RA_USE_SOFT_IIC (0) // 默认使用硬件 SPI 方式驱动
#if IMU660RA_USE_SOFT_IIC // 这两段 颜色正常的才是正确的 颜色灰的就是没有用的
//====================================================软件 IIC 驱动====================================================
#define IMU660RA_SOFT_IIC_DELAY (59) // 软件 IIC 的时钟延时周期 数值越小 IIC 通信速率越快
#define IMU660RA_SCL_PIN (P20_11) // 软件 IIC SCL 引脚 连接 IMU660RA 的 SCL 引脚
#define IMU660RA_SDA_PIN (P20_14) // 软件 IIC SDA 引脚 连接 IMU660RA 的 SDA 引脚
//====================================================软件 IIC 驱动====================================================
#else
//====================================================硬件 SPI 驱动====================================================
#define IMU660RA_SPI_SPEED (10 * 1000 * 1000) // 硬件 SPI 速率
#define IMU660RA_SPI (SPI_0) // 硬件 SPI 号
#define IMU660RA_SPC_PIN (SPI0_SCLK_P20_11 ) // 硬件 SPI SCK 引脚
#define IMU660RA_SDI_PIN (SPI0_MOSI_P20_14) // 硬件 SPI MOSI 引脚
#define IMU660RA_SDO_PIN (SPI0_MISO_P20_12) // 硬件 SPI MISO 引脚
//====================================================硬件 SPI 驱动====================================================
#endif
#define IMU660RA_CS_PIN (P20_13) // CS 片选引脚
#define IMU660RA_CS(x) ((x) ? (gpio_high(IMU660RA_CS_PIN)) : (gpio_low(IMU660RA_CS_PIN)))
typedef enum
{
IMU660RA_ACC_SAMPLE_SGN_2G , // 加速度计量程 ±2G (ACC = Accelerometer 加速度计) (SGN = signum 带符号数 表示正负范围) (G = g 重力加速度 g≈9.80 m/s^2)
IMU660RA_ACC_SAMPLE_SGN_4G , // 加速度计量程 ±4G (ACC = Accelerometer 加速度计) (SGN = signum 带符号数 表示正负范围) (G = g 重力加速度 g≈9.80 m/s^2)
IMU660RA_ACC_SAMPLE_SGN_8G , // 加速度计量程 ±8G (ACC = Accelerometer 加速度计) (SGN = signum 带符号数 表示正负范围) (G = g 重力加速度 g≈9.80 m/s^2)
IMU660RA_ACC_SAMPLE_SGN_16G, // 加速度计量程 ±16G (ACC = Accelerometer 加速度计) (SGN = signum 带符号数 表示正负范围) (G = g 重力加速度 g≈9.80 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 内部地址================================================
//================================================声明 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];
//================================================声明 IMU660RA 全局变量================================================
//================================================声明 IMU660RA 基础函数================================================
void imu660ra_get_acc (void); // 获取 IMU660RA 加速度计数据
void imu660ra_get_gyro (void); // 获取 IMU660RA 陀螺仪数据
uint8 imu660ra_init (void); // 初始化 IMU660RA
//================================================声明 IMU660RA 基础函数================================================
//================================================声明 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])
#endif
+346
View File
@@ -0,0 +1,346 @@
/*********************************************************************************************************************
* 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_imu660rb
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 ADS v1.10.2
* 适用平台 TC264D
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2022-09-15 pudding first version
* 2023-04-28 pudding 增加中文注释说明
********************************************************************************************************************/
/********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* // 硬件 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_debug.h"
#include "zf_driver_delay.h"
#include "zf_driver_spi.h"
#include "zf_driver_soft_iic.h"
#include "zf_device_imu660rb.h"
int16 imu660rb_gyro_x = 0, imu660rb_gyro_y = 0, imu660rb_gyro_z = 0; // 三轴陀螺仪数据 GYRO (陀螺仪)
int16 imu660rb_acc_x = 0, imu660rb_acc_y = 0, imu660rb_acc_z = 0; // 三轴加速度计数据 ACC (accelerometer 加速度计)
float imu660rb_transition_factor[2] = {4098, 14.3}; // 转换实际值的比例
#if IMU660RB_USE_SOFT_IIC
static soft_iic_info_struct imu660rb_iic_struct;
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IMU660RB 写寄存器
// 参数说明 reg 寄存器地址
// 参数说明 data 数据
// 返回参数 void
// 使用示例 imu660rb_write_acc_gyro_register(IMU660RB_SLV0_CONFIG, 0x00);
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
#define imu660rb_write_acc_gyro_register(reg,data) (soft_iic_write_8bit_register(&imu660rb_iic_struct,reg,data))
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IMU660RB 读寄存器
// 参数说明 reg 寄存器地址
// 返回参数 uint8 数据
// 使用示例 imu660rb_read_acc_gyro_register(IMU660RB_STATUS_MASTER);
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
#define imu660rb_read_acc_gyro_register(reg) (soft_iic_sccb_read_register(&imu660rb_iic_struct,reg))
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IMU660RB 读数据 内部调用
// 参数说明 reg 寄存器地址
// 参数说明 data 数据缓冲区
// 参数说明 len 数据长度
// 返回参数 void
// 使用示例 imu660rb_read_acc_gyro_registers(IMU660RB_OUTX_L_A, dat, 6);
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
#define imu660rb_read_acc_gyro_registers(reg,data,len) (soft_iic_read_8bit_registers(&imu660rb_iic_struct,reg,data,len))
#else
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IMU660RB 写寄存器
// 参数说明 reg 寄存器地址
// 参数说明 data 数据
// 返回参数 void
// 使用示例 imu660rb_write_acc_gyro_register(IMU660RB_SLV0_CONFIG, 0x00);
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
static void imu660rb_write_acc_gyro_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_acc_gyro_register(IMU660RB_STATUS_MASTER);
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
static uint8 imu660rb_read_acc_gyro_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_acc_gyro_registers(IMU660RB_OUTX_L_A, dat, 6);
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
static void imu660rb_read_acc_gyro_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 六轴自检 内部调用
// 参数说明 void
// 返回参数 uint8 1-自检失败 0-自检成功
// 使用示例 imu660rb_acc_gyro_self_check();
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
static uint8 imu660rb_acc_gyro_self_check (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_acc_gyro_register(IMU660RB_WHO_AM_I);
system_delay_ms(10);
}
return return_state;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 获取 IMU660RB 加速度计数据
// 参数说明 void
// 返回参数 void
// 使用示例 imu660rb_get_acc();
// 备注信息 执行该函数后,直接查看对应的变量即可
//-------------------------------------------------------------------------------------------------------------------
void imu660rb_get_acc (void)
{
uint8 dat[6];
imu660rb_read_acc_gyro_registers(IMU660RB_OUTX_L_A, 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 dat[6];
imu660rb_read_acc_gyro_registers(IMU660RB_OUTX_L_G, dat, 6);
imu660rb_gyro_x = (int16)(((uint16)dat[1]<<8 | dat[0]));
imu660rb_gyro_y = (int16)(((uint16)dat[3]<<8 | dat[2]));
imu660rb_gyro_z = (int16)(((uint16)dat[5]<<8 | dat[4]));
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 初始化 IMU660RB
// 参数说明 void
// 返回参数 uint8 1-初始化失败 0-初始化成功
// 使用示例 imu660rb_init();
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
uint8 imu660rb_init (void)
{
uint8 return_state = 0;
system_delay_ms(10); // 上电延时
#if IMU660RB_USE_SOFT_IIC
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
{
imu660rb_write_acc_gyro_register(IMU660RB_FUNC_CFG_ACCESS, 0x00); // 关闭HUB寄存器访问
imu660rb_write_acc_gyro_register(IMU660RB_CTRL3_C, 0x01); // 复位设备
system_delay_ms(2);
imu660rb_write_acc_gyro_register(IMU660RB_FUNC_CFG_ACCESS, 0x00); // 关闭HUB寄存器访问
if(imu660rb_acc_gyro_self_check())
{
zf_log(0, "IMU660RB acc and gyro self check error.");
return_state = 1;
break;
}
imu660rb_write_acc_gyro_register(IMU660RB_INT1_CTRL, 0x03); // 开启陀螺仪 加速度数据就绪中断
// IMU660RB_CTRL1_XL 寄存器
// 设置为 0x30 加速度量程为 ±2 G 获取到的加速度计数据除以 16393 可以转化为带物理单位的数据 单位 g(m/s^2)
// 设置为 0x38 加速度量程为 ±4 G 获取到的加速度计数据除以 8197 可以转化为带物理单位的数据 单位 g(m/s^2)
// 设置为 0x3C 加速度量程为 ±8 G 获取到的加速度计数据除以 4098 可以转化为带物理单位的数据 单位 g(m/s^2)
// 设置为 0x34 加速度量程为 ±16 G 获取到的加速度计数据除以 2049 可以转化为带物理单位的数据 单位 g(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_acc_gyro_register(IMU660RB_CTRL1_XL, 0x30);
imu660rb_transition_factor[0] = 16393;
}break;
case IMU660RB_ACC_SAMPLE_SGN_4G:
{
imu660rb_write_acc_gyro_register(IMU660RB_CTRL1_XL, 0x38);
imu660rb_transition_factor[0] = 8197;
}break;
case IMU660RB_ACC_SAMPLE_SGN_8G:
{
imu660rb_write_acc_gyro_register(IMU660RB_CTRL1_XL, 0x3C);
imu660rb_transition_factor[0] = 4098;
}break;
case IMU660RB_ACC_SAMPLE_SGN_16G:
{
imu660rb_write_acc_gyro_register(IMU660RB_CTRL1_XL, 0x34);
imu660rb_transition_factor[0] = 2049;
}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_acc_gyro_register(IMU660RB_CTRL2_G, 0x52);
imu660rb_transition_factor[1] = 228.6;
}break;
case IMU660RB_GYRO_SAMPLE_SGN_250DPS:
{
imu660rb_write_acc_gyro_register(IMU660RB_CTRL2_G, 0x50);
imu660rb_transition_factor[1] = 114.3;
}break;
case IMU660RB_GYRO_SAMPLE_SGN_500DPS:
{
imu660rb_write_acc_gyro_register(IMU660RB_CTRL2_G, 0x54);
imu660rb_transition_factor[1] = 57.1;
}break;
case IMU660RB_GYRO_SAMPLE_SGN_1000DPS:
{
imu660rb_write_acc_gyro_register(IMU660RB_CTRL2_G, 0x58);
imu660rb_transition_factor[1] = 28.6;
}break;
case IMU660RB_GYRO_SAMPLE_SGN_2000DPS:
{
imu660rb_write_acc_gyro_register(IMU660RB_CTRL2_G, 0x5C);
imu660rb_transition_factor[1] = 14.3;
}break;
case IMU660RB_GYRO_SAMPLE_SGN_4000DPS:
{
imu660rb_write_acc_gyro_register(IMU660RB_CTRL2_G, 0x51);
imu660rb_transition_factor[1] = 7.1;
}break;
}
if(1 == return_state)
{
break;
}
imu660rb_write_acc_gyro_register(IMU660RB_CTRL3_C, 0x44); // 使能陀螺仪数字低通滤波器
imu660rb_write_acc_gyro_register(IMU660RB_CTRL4_C, 0x02); // 使能数字低通滤波器
imu660rb_write_acc_gyro_register(IMU660RB_CTRL5_C, 0x00); // 加速度计与陀螺仪四舍五入
imu660rb_write_acc_gyro_register(IMU660RB_CTRL6_C, 0x00); // 开启加速度计高性能模式 陀螺仪低通滤波 133hz
imu660rb_write_acc_gyro_register(IMU660RB_CTRL7_G, 0x00); // 开启陀螺仪高性能模式 关闭高通滤波
imu660rb_write_acc_gyro_register(IMU660RB_CTRL9_XL, 0x01); // 关闭I3C接口
}while(0);
return return_state;
}
+196
View File
@@ -0,0 +1,196 @@
/*********************************************************************************************************************
* 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_imu660rb
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 ADS v1.10.2
* 适用平台 TC264D
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2022-09-15 pudding first version
* 2023-04-28 pudding 增加中文注释说明
* 2024-01-30 pudding 更正宏转换函数 变量增加括号
********************************************************************************************************************/
/********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* // 硬件 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_
#include "zf_common_typedef.h"
//================================================定义 IMU660RB 基本配置================================================
#define IMU660RB_USE_SOFT_IIC (0) // 默认使用硬件 SPI 方式驱动
#if IMU660RB_USE_SOFT_IIC // 这两段 颜色正常的才是正确的 颜色灰的就是没有用的
//====================================================软件 IIC 驱动====================================================
#define IMU660RB_SOFT_IIC_DELAY (59 ) // 软件 IIC 的时钟延时周期 数值越小 IIC 通信速率越快
#define IMU660RB_SCL_PIN (P20_11) // 软件 IIC SCL 引脚 连接 IMU660RB 的 SCL 引脚
#define IMU660RB_SDA_PIN (P20_14) // 软件 IIC SDA 引脚 连接 IMU660RB 的 SDA 引脚
//====================================================软件 IIC 驱动====================================================
#else
//====================================================硬件 SPI 驱动====================================================
#define IMU660RB_SPI_SPEED (10 * 1000 * 1000) // 硬件 SPI 速率
#define IMU660RB_SPI (SPI_0 ) // 硬件 SPI 号
#define IMU660RB_SPC_PIN (SPI0_SCLK_P20_11) // 硬件 SPI SCK 引脚
#define IMU660RB_SDI_PIN (SPI0_MOSI_P20_14) // 硬件 SPI MOSI 引脚
#define IMU660RB_SDO_PIN (SPI0_MISO_P20_12) // 硬件 SPI MISO 引脚
//====================================================硬件 SPI 驱动====================================================
#endif
#define IMU660RB_CS_PIN (P20_13) // CS 片选引脚
#define IMU660RB_CS(x) (x? (gpio_high(IMU660RB_CS_PIN)): (gpio_low(IMU660RB_CS_PIN)))
typedef enum
{
IMU660RB_ACC_SAMPLE_SGN_2G , // 加速度计量程 ±2G (ACC = Accelerometer 加速度计) (SGN = signum 带符号数 表示正负范围) (G = g 重力加速度 g≈9.80 m/s^2)
IMU660RB_ACC_SAMPLE_SGN_4G , // 加速度计量程 ±4G (ACC = Accelerometer 加速度计) (SGN = signum 带符号数 表示正负范围) (G = g 重力加速度 g≈9.80 m/s^2)
IMU660RB_ACC_SAMPLE_SGN_8G , // 加速度计量程 ±8G (ACC = Accelerometer 加速度计) (SGN = signum 带符号数 表示正负范围) (G = g 重力加速度 g≈9.80 m/s^2)
IMU660RB_ACC_SAMPLE_SGN_16G, // 加速度计量程 ±16G (ACC = Accelerometer 加速度计) (SGN = signum 带符号数 表示正负范围) (G = g 重力加速度 g≈9.80 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;
#define IMU660RB_ACC_SAMPLE_DEFAULT ( IMU660RB_ACC_SAMPLE_SGN_8G ) // 在这设置默认的 加速度计 初始化量程
#define IMU660RB_GYRO_SAMPLE_DEFAULT ( IMU660RB_GYRO_SAMPLE_SGN_2000DPS ) // 在这设置默认的 陀螺仪 初始化量程
#define IMU660RB_TIMEOUT_COUNT (0x00FF) // IMU660RB 超时计数
//================================================定义 IMU660RB 基本配置================================================
//================================================定义 IMU660RB 内部地址================================================
#define IMU660RB_DEV_ADDR (0x6B) // SA0接地:0x6A SA0上拉:0x6B 模块默认上拉
#define IMU660RB_SPI_W (0x00)
#define IMU660RB_SPI_R (0x80)
#define IMU660RB_FUNC_CFG_ACCESS (0x01)
#define IMU660RB_INT1_CTRL (0x0D)
#define IMU660RB_WHO_AM_I (0x0F)
#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_OUTX_L_G (0x22)
#define IMU660RB_OUTX_L_A (0x28)
//集线器功能相关寄存器 需要将FUNC_CFG_ACCESS的SHUB_REG_ACCESS位设置为1才能正确访问
#define IMU660RB_SENSOR_HUB_1 (0x02)
#define IMU660RB_MASTER_CONFIG (0x14)
#define IMU660RB_SLV0_ADD (0x15)
#define IMU660RB_SLV0_SUBADD (0x16)
#define IMU660RB_SLV0_CONFIG (0x17)
#define IMU660RB_DATAWRITE_SLV0 (0x21)
#define IMU660RB_STATUS_MASTER (0x22)
#define IMU660RB_MAG_ADDR (0x0D) // 7位IIC地址
#define IMU660RB_MAG_OUTX_L (0x00)
#define IMU660RB_MAG_CONTROL1 (0x09)
#define IMU660RB_MAG_CONTROL2 (0x0A)
#define IMU660RB_MAG_FBR (0x0B)
#define IMU660RB_MAG_CHIP_ID (0x0D)
#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
//================================================声明 IMU660RB 全局变量================================================
extern int16 imu660rb_acc_x, imu660rb_acc_y, imu660rb_acc_z; // 三轴陀螺仪数据 GYRO (陀螺仪)
extern int16 imu660rb_gyro_x, imu660rb_gyro_y, imu660rb_gyro_z; // 三轴加速度计数据 ACC (accelerometer 加速度计)
extern float imu660rb_transition_factor[2]; // 转换实际值的比例
//================================================声明 IMU660RB 全局变量================================================
//================================================声明 IMU660RB 基础函数================================================
void imu660rb_get_acc (void); // 获取 IMU660RB 加速度计数据
void imu660rb_get_gyro (void); // 获取 IMU660RB 陀螺仪数据
uint8 imu660rb_init (void); // 初始化 IMU660RB
//================================================声明 IMU660RB 基础函数================================================
//================================================声明 IMU660RB 拓展函数================================================
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 将 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_transition_factor[0])
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 将 IMU660RB 陀螺仪数据转换为实际物理数据
// 参数说明 gyro_value 任意轴的陀螺仪数据
// 返回参数 void
// 使用示例 float data = imu660rb_gyro_transition(imu660rb_gyro_x); // 单位为 °/s
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
#define imu660rb_gyro_transition(gyro_value) ((float)(gyro_value) / imu660rb_transition_factor[1])
#endif
+563
View File
@@ -0,0 +1,563 @@
/*********************************************************************************************************************
* 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 文件 版本说明
* 开发环境 ADS v1.10.2
* 适用平台 TC264
* 店铺链接 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(void)
{
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_SOFT_IIC
soft_iic_init(&imu660rc_iic_struct, IMU660RC_DEV_ADDR, IMU660RC_SOFT_IIC_DELAY, IMU660RC_SCL_PIN, IMU660RC_SDA_PIN); // 配置 IMU660RC 的 IIC 端口
#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);
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);
}
}while(0);
return return_state;
}
+211
View File
@@ -0,0 +1,211 @@
/*********************************************************************************************************************
* 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 文件 版本说明
* 开发环境 ADS v1.10.2
* 适用平台 TC264
* 店铺链接 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 方式驱动
#if IMU660RC_USE_SOFT_IIC // 这两段 颜色正常的才是正确的 颜色灰的就是没有用的
//====================================================软件 IIC 驱动====================================================
#define IMU660RC_SOFT_IIC_DELAY ( 0 ) // 软件 IIC 的时钟延时周期 数值越小 IIC 通信速率越快
#define IMU660RC_SCL_PIN ( P20_11 ) // 软件 IIC SCL 引脚 连接 IMU660RC 的 SCL 引脚
#define IMU660RC_SDA_PIN ( P20_14 ) // 软件 IIC SDA 引脚 连接 IMU660RC 的 SDA 引脚
//====================================================软件 IIC 驱动====================================================
#else
//====================================================硬件 SPI 驱动====================================================
#define IMU660RC_SPI_SPEED (10 * 1000 * 1000) // 硬件 SPI 速率
#define IMU660RC_SPI (SPI_0) // 硬件 SPI 号
#define IMU660RC_SPC_PIN (SPI0_SCLK_P20_11 ) // 硬件 SPI SCK 引脚
#define IMU660RC_SDI_PIN (SPI0_MOSI_P20_14) // 硬件 SPI MOSI 引脚
#define IMU660RC_SDO_PIN (SPI0_MISO_P20_12) // 硬件 SPI MISO 引脚
//====================================================硬件 SPI 驱动====================================================
#endif
#define IMU660RC_CS_PIN ( P20_13 ) // CS 片选引脚
#define IMU660RC_CS(x) ( (x) ? (gpio_high(IMU660RC_CS_PIN)) : (gpio_low(IMU660RC_CS_PIN)) )
#define IMU660RC_INT2_PIN ( ERU_CH0_REQ0_P15_4 ) // 中断信号引脚,在读取四元数时需要使用
#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])
void imu660rc_callback (void);
uint8 imu660rc_init (imu660rc_quarternion_rate_config quarternion_rate);
#endif
+499
View File
@@ -0,0 +1,499 @@
/*********************************************************************************************************************
* 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_imu660rx
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 ADS v1.10.2
* 适用平台 TC264D
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2025-03-6 SeekFree first version
********************************************************************************************************************/
/*********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* // 硬件 SPI 引脚
* SCL/SPC 查看 zf_device_imu660rx.h 中 IMU660RX_SPC_PIN 宏定义
* SDA/DSI 查看 zf_device_imu660rx.h 中 IMU660RX_SDI_PIN 宏定义
* SA0/SDO 查看 zf_device_imu660rx.h 中 IMU660RX_SDO_PIN 宏定义
* CS 查看 zf_device_imu660rx.h 中 IMU660RX_CS_PIN 宏定义
* VCC 3.3V电源
* GND 电源地
* 其余引脚悬空
*
* // 软件 IIC 引脚
* SCL/SPC 查看 zf_device_imu660rx.h 中 IMU660RX_SCL_PIN 宏定义
* SDA/DSI 查看 zf_device_imu660rx.h 中 IMU660RX_SDA_PIN 宏定义
* VCC 3.3V电源
* GND 电源地
* 其余引脚悬空
* ------------------------------------
********************************************************************************************************************/
#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_device_imu660ra.h"
#include "zf_device_imu660rb.h"
#include "zf_device_imu660rx.h"
int16 imu660rx_gyro_x = 0, imu660rx_gyro_y = 0, imu660rx_gyro_z = 0; // 三轴陀螺仪数据 gyro (陀螺仪)
int16 imu660rx_acc_x = 0, imu660rx_acc_y = 0, imu660rx_acc_z = 0; // 三轴加速度计数据 acc (accelerometer 加速度计)
float imu660rx_transition_factor[2] = {4096, 16.4};
uint8 imu660rx_self_check_id = 0;
uint8 imu660rx_acc_address = 0, imu660rx_gyro_address = 0;
#if IMU660RX_USE_SOFT_IIC
static soft_iic_info_struct imu660rx_iic_struct;
#define imu660rx_write_register(reg, data) (soft_iic_write_8bit_register (&imu660rx_iic_struct, (reg), (data)))
#define imu660rx_write_registers(reg, data, len) (soft_iic_write_8bit_registers(&imu660rx_iic_struct, (reg), (data), (len)))
#define imu660rx_read_registers(reg, data, len) (soft_iic_read_8bit_registers (&imu660rx_iic_struct, (reg), (data), (len)))
#else
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IMU660RX 写寄存器
// 参数说明 reg 寄存器地址
// 参数说明 data 数据
// 返回参数 void
// 使用示例 imu660rx_write_register(IMU660RB_PWR_CONF, 0x00); // 关闭高级省电模式
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
static void imu660rx_write_register(uint8 reg, uint8 data)
{
IMU660RX_CS(0);
spi_write_8bit_register(IMU660RX_SPI, reg | IMU660RX_SPI_W, data);
IMU660RX_CS(1);
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IMU660RX 写数据
// 参数说明 reg 寄存器地址
// 参数说明 data 数据
// 返回参数 void
// 使用示例 imu660rx_write_registers(IMU660RA_INIT_DATA, imu660ra_config_file, sizeof(imu660ra_config_file));
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
static void imu660rx_write_registers(uint8 reg, const uint8 *data, uint32 len)
{
IMU660RX_CS(0);
spi_write_8bit_registers(IMU660RX_SPI, reg | IMU660RX_SPI_W, data, len);
IMU660RX_CS(1);
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IMU660RX 读数据
// 参数说明 reg 寄存器地址
// 参数说明 data 数据缓冲区
// 参数说明 len 数据长度
// 返回参数 void
// 使用示例 imu660rx_read_registers(IMU660RB_ACC_ADDRESS, dat, 6);
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
static void imu660rx_read_registers(uint8 reg, uint8 *data, uint32 len)
{
uint8 temp_data[8];
IMU660RX_CS(0);
if (imu660rx_self_check_id == IMU660RX_CHIP_IDA)
{
spi_read_8bit_registers(IMU660RX_SPI, reg | IMU660RX_SPI_R, temp_data, len + 1);
IMU660RX_CS(1);
for(int i = 0; i < len; i ++)
{
*(data ++) = temp_data[i + 1];
}
}
else if (imu660rx_self_check_id == IMU660RX_CHIP_IDB)
{
spi_read_8bit_registers(IMU660RX_SPI, reg | IMU660RX_SPI_R, data, len);
IMU660RX_CS(1);
}
}
#endif
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IMU660RX 读寄存器
// 参数说明 reg 寄存器地址
// 参数说明 bit 寄存器位数
// 返回参数 uint8 数据
// 使用示例 imu660rx_read_register(IMU660RA_CHIP_ID1,2);
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
static uint8 imu660rx_read_register(uint8 reg, uint8 bit)
{
uint8 data[2];
#if IMU660RX_USE_SOFT_IIC
return soft_iic_read_8bit_register (&imu660rx_iic_struct, (reg));
#else
IMU660RX_CS(0);
spi_read_8bit_registers(IMU660RX_SPI, reg | IMU660RX_SPI_R, data, bit);
IMU660RX_CS(1);
#endif
return data[bit - 1];
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IMU660RX 自检
// 参数说明 void
// 返回参数 uint8 1-自检失败 0-自检成功
// 使用示例 imu660rx_self_check();
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
static uint8 imu660rx_self_check (void)
{
uint8 dat = 0, return_state = 0;
uint16 timeout_count = 0;
do
{
if(timeout_count ++ > IMU660RX_TIMEOUT_COUNT)
{
return_state = 1;
break;
}
#if IMU660RX_USE_SOFT_IIC
imu660rx_iic_struct.addr = IMU660RA_DEV_ADDR;
#endif
dat = imu660rx_read_register(IMU660RX_CHIP_IDA,2);
system_delay_ms(1);
if(0x24 == dat) // 读取设备ID1是否等于0X24,如果不是0X24则认为没检测到设备
{
imu660rx_self_check_id = IMU660RX_CHIP_IDA; //记录读取到的设备ID
break;
}
#if IMU660RX_USE_SOFT_IIC
imu660rx_iic_struct.addr = IMU660RB_DEV_ADDR;
#endif
dat = imu660rx_read_register(IMU660RX_CHIP_IDB,1);
system_delay_ms(1);
if(0x6B == dat) // 读取设备ID2是否等于0X6B,如果不是0X6B则认为没检测到设备
{
imu660rx_self_check_id = IMU660RX_CHIP_IDB; //记录读取到的设备ID
break;
}
}while(1);
return return_state;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 获取 IMU660RX 加速度计数据
// 参数说明 void
// 返回参数 void
// 使用示例 imu660rx_get_acc(); // 执行该函数后,直接查看对应的变量即可
// 备注信息 使用 SPI 的采集时间为69us
// 使用 IIC 的采集时间为126us 采集加速度计的时间与采集陀螺仪的时间一致的原因是都只是读取寄存器数据
//-------------------------------------------------------------------------------------------------------------------
void imu660rx_get_acc (void)
{
uint8 dat[6];
imu660rx_read_registers(imu660rx_acc_address, dat, 6);
imu660rx_acc_x = (int16)(((uint16)dat[1]<<8 | dat[0]));
imu660rx_acc_y = (int16)(((uint16)dat[3]<<8 | dat[2]));
imu660rx_acc_z = (int16)(((uint16)dat[5]<<8 | dat[4]));
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 获取 IMU660RX 陀螺仪数据
// 参数说明 void
// 返回参数 void
// 使用示例 imu660rx_get_gyro(); // 执行该函数后,直接查看对应的变量即可
// 备注信息 使用 SPI 的采集时间为69us
// 使用 IIC 的采集时间为126us
//-------------------------------------------------------------------------------------------------------------------
void imu660rx_get_gyro (void)
{
uint8 dat[6];
imu660rx_read_registers(imu660rx_gyro_address, dat, 6);
imu660rx_gyro_x = (int16)(((uint16)dat[1]<<8 | dat[0]));
imu660rx_gyro_y = (int16)(((uint16)dat[3]<<8 | dat[2]));
imu660rx_gyro_z = (int16)(((uint16)dat[5]<<8 | dat[4]));
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 初始化 IMU660RX
// 参数说明 void
// 返回参数 uint8 1-初始化失败 0-初始化成功
// 使用示例 imu660rx_init();
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
uint8 imu660rx_init (void)
{
uint8 return_state = 0;
system_delay_ms(20); // 等待设备上电成功
#if IMU660RX_USE_SOFT_IIC
soft_iic_init(&imu660rx_iic_struct, IMU660RX_DEV_ADDR, IMU660RX_SOFT_IIC_DELAY, IMU660RX_SCL_PIN, IMU660RX_SDA_PIN); // 配置 IMU660RX 的 IIC 端口
#else
spi_init(IMU660RX_SPI, SPI_MODE0, IMU660RX_SPI_SPEED, IMU660RX_SPC_PIN, IMU660RX_SDI_PIN, IMU660RX_SDO_PIN, SPI_CS_NULL); // 配置 IMU660RX 的 SPI 端口
gpio_init(IMU660RX_CS_PIN, GPO, GPIO_HIGH, GPO_PUSH_PULL); // 配置 IMU660RX 的 CS 端口
#endif
do{
if(imu660rx_self_check()) // IMU660RX 自检
{
// 如果程序在输出了断言信息 并且提示出错位置在这里
// 那么就是 IMU660RX 自检出错并超时退出了
// 检查一下接线有没有问题 如果没问题可能就是坏了
zf_log(0, "imu660rx self check error.");
return_state = 1;
break;
}
if (imu660rx_self_check_id == IMU660RX_CHIP_IDA)
{
imu660rx_acc_address = IMU660RA_ACC_ADDRESS;
imu660rx_gyro_address = IMU660RA_GYRO_ADDRESS;
imu660rx_write_register(IMU660RA_PWR_CONF, 0x00); // 关闭高级省电模式
system_delay_ms(1);
imu660rx_write_register(IMU660RA_INIT_CTRL, 0x00); // 开始对模块进行初始化配置
imu660rx_write_registers(IMU660RA_INIT_DATA, imu660ra_config_file, sizeof(imu660ra_config_file)); // 输出配置文件
imu660rx_write_register(IMU660RA_INIT_CTRL, 0x01); // 初始化配置结束
system_delay_ms(20);
if(1 != imu660rx_read_register(IMU660RA_INT_STA,2)) // 检查是否配置完成
{
// 如果程序在输出了断言信息 并且提示出错位置在这里
// 那么就是 IMU660RA 配置初始化文件出错了
// 检查一下接线有没有问题 如果没问题可能就是坏了
zf_log(0, "imu660ra init error.");
return_state = 1;
break;
}
imu660rx_write_register(IMU660RA_PWR_CTRL, 0x0E); // 开启性能模式 使能陀螺仪、加速度、温度传感器
imu660rx_write_register(IMU660RA_ACC_CONF, 0xA7); // 加速度采集配置 性能模式 正常采集 50Hz 采样频率
imu660rx_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:
{
imu660rx_write_register(IMU660RA_ACC_RANGE, 0x00);
imu660rx_transition_factor[0] = 16384;
}break;
case IMU660RA_ACC_SAMPLE_SGN_4G:
{
imu660rx_write_register(IMU660RA_ACC_RANGE, 0x01);
imu660rx_transition_factor[0] = 8192;
}break;
case IMU660RA_ACC_SAMPLE_SGN_8G:
{
imu660rx_write_register(IMU660RA_ACC_RANGE, 0x02);
imu660rx_transition_factor[0] = 4096;
}break;
case IMU660RA_ACC_SAMPLE_SGN_16G:
{
imu660rx_write_register(IMU660RA_ACC_RANGE, 0x03);
imu660rx_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:
{
imu660rx_write_register(IMU660RA_GYR_RANGE, 0x04);
imu660rx_transition_factor[1] = 262.4;
}break;
case IMU660RA_GYRO_SAMPLE_SGN_250DPS:
{
imu660rx_write_register(IMU660RA_GYR_RANGE, 0x03);
imu660rx_transition_factor[1] = 131.2;
}break;
case IMU660RA_GYRO_SAMPLE_SGN_500DPS:
{
imu660rx_write_register(IMU660RA_GYR_RANGE, 0x02);
imu660rx_transition_factor[1] = 65.6;
}break;
case IMU660RA_GYRO_SAMPLE_SGN_1000DPS:
{
imu660rx_write_register(IMU660RA_GYR_RANGE, 0x01);
imu660rx_transition_factor[1] = 32.8;
}break;
case IMU660RA_GYRO_SAMPLE_SGN_2000DPS:
{
imu660rx_write_register(IMU660RA_GYR_RANGE, 0x00);
imu660rx_transition_factor[1] = 16.4;
}break;
}
if(1 == return_state)
{
break;
}
}
else if (imu660rx_self_check_id == IMU660RX_CHIP_IDB)
{
imu660rx_acc_address = IMU660RB_OUTX_L_A;
imu660rx_gyro_address = IMU660RB_OUTX_L_G;
imu660rx_write_register(IMU660RB_FUNC_CFG_ACCESS, 0x00); // 关闭HUB寄存器访问
imu660rx_write_register(IMU660RB_CTRL3_C, 0x01); // 复位设备
system_delay_ms(2);
imu660rx_write_register(IMU660RB_FUNC_CFG_ACCESS, 0x00); // 关闭HUB寄存器访问
imu660rx_write_register(IMU660RB_INT1_CTRL, 0x03); // 开启陀螺仪 加速度数据就绪中断
// IMU660RB_CTRL1_XL 寄存器
// 设置为 0x30 加速度量程为 ±2 G 获取到的加速度计数据除以 16393 可以转化为带物理单位的数据 单位 g(m/s^2)
// 设置为 0x38 加速度量程为 ±4 G 获取到的加速度计数据除以 8197 可以转化为带物理单位的数据 单位 g(m/s^2)
// 设置为 0x3C 加速度量程为 ±8 G 获取到的加速度计数据除以 4098 可以转化为带物理单位的数据 单位 g(m/s^2)
// 设置为 0x34 加速度量程为 ±16 G 获取到的加速度计数据除以 2049 可以转化为带物理单位的数据 单位 g(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:
{
imu660rx_write_register(IMU660RB_CTRL1_XL, 0x30);
imu660rx_transition_factor[0] = 16393;
}break;
case IMU660RB_ACC_SAMPLE_SGN_4G:
{
imu660rx_write_register(IMU660RB_CTRL1_XL, 0x38);
imu660rx_transition_factor[0] = 8197;
}break;
case IMU660RB_ACC_SAMPLE_SGN_8G:
{
imu660rx_write_register(IMU660RB_CTRL1_XL, 0x3C);
imu660rx_transition_factor[0] = 4098;
}break;
case IMU660RB_ACC_SAMPLE_SGN_16G:
{
imu660rx_write_register(IMU660RB_CTRL1_XL, 0x34);
imu660rx_transition_factor[0] = 2049;
}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:
{
imu660rx_write_register(IMU660RB_CTRL2_G, 0x52);
imu660rx_transition_factor[1] = 228.6;
}break;
case IMU660RB_GYRO_SAMPLE_SGN_250DPS:
{
imu660rx_write_register(IMU660RB_CTRL2_G, 0x50);
imu660rx_transition_factor[1] = 114.3;
}break;
case IMU660RB_GYRO_SAMPLE_SGN_500DPS:
{
imu660rx_write_register(IMU660RB_CTRL2_G, 0x54);
imu660rx_transition_factor[1] = 57.1;
}break;
case IMU660RB_GYRO_SAMPLE_SGN_1000DPS:
{
imu660rx_write_register(IMU660RB_CTRL2_G, 0x58);
imu660rx_transition_factor[1] = 28.6;
}break;
case IMU660RB_GYRO_SAMPLE_SGN_2000DPS:
{
imu660rx_write_register(IMU660RB_CTRL2_G, 0x5C);
imu660rx_transition_factor[1] = 14.3;
}break;
case IMU660RB_GYRO_SAMPLE_SGN_4000DPS:
{
imu660rx_write_register(IMU660RB_CTRL2_G, 0x51);
imu660rx_transition_factor[1] = 7.1;
}break;
}
if(1 == return_state)
{
break;
}
imu660rx_write_register(IMU660RB_CTRL3_C, 0x44); // 使能陀螺仪数字低通滤波器
imu660rx_write_register(IMU660RB_CTRL4_C, 0x02); // 使能数字低通滤波器
imu660rx_write_register(IMU660RB_CTRL5_C, 0x00); // 加速度计与陀螺仪四舍五入
imu660rx_write_register(IMU660RB_CTRL6_C, 0x00); // 开启加速度计高性能模式 陀螺仪低通滤波 133hz
imu660rx_write_register(IMU660RB_CTRL7_G, 0x00); // 开启陀螺仪高性能模式 关闭高通滤波
imu660rx_write_register(IMU660RB_CTRL9_XL, 0x01); // 关闭I3C接口
}
}while(0);
return return_state;
}
+132
View File
@@ -0,0 +1,132 @@
/*********************************************************************************************************************
* 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_imu660rx
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 ADS v1.10.2
* 适用平台 TC264D
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2025-03-6 SeekFree first version
********************************************************************************************************************/
/*********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* // 硬件 SPI 引脚
* SCL/SPC 查看 zf_device_imu660rx.h 中 IMU660RX_SPC_PIN 宏定义
* SDA/DSI 查看 zf_device_imu660rx.h 中 IMU660RX_SDI_PIN 宏定义
* SA0/SDO 查看 zf_device_imu660rx.h 中 IMU660RX_SDO_PIN 宏定义
* CS 查看 zf_device_imu660rx.h 中 IMU660RX_CS_PIN 宏定义
* VCC 3.3V电源
* GND 电源地
* 其余引脚悬空
*
* // 软件 IIC 引脚
* SCL/SPC 查看 zf_device_imu660rx.h 中 IMU660RX_SCL_PIN 宏定义
* SDA/DSI 查看 zf_device_imu660rx.h 中 IMU660RX_SDA_PIN 宏定义
* VCC 3.3V电源
* GND 电源地
* 其余引脚悬空
* ------------------------------------
********************************************************************************************************************/
#ifndef _zf_device_imu660rx_h_
#define _zf_device_imu660rx_h_
#include "zf_device_imu660rb.h"
#include "zf_device_imu660ra.h"
#include "zf_common_typedef.h"
// IMU660RX_USE_SOFT_IIC定义为0表示使用硬件SPI驱动 定义为1表示使用软件IIC驱动
// 当更改IMU660RX_USE_SOFT_IIC定义后,需要先编译并下载程序,单片机与模块需要断电重启才能正常通讯
#define IMU660RX_USE_SOFT_IIC (0) // 默认使用硬件 SPI 方式驱动
#if IMU660RX_USE_SOFT_IIC // 这两段 颜色正常的才是正确的 颜色灰的就是没有用的
//====================================================软件 IIC 驱动====================================================
#define IMU660RX_SOFT_IIC_DELAY (60) // 软件 IIC 的时钟延时周期 数值越小 IIC 通信速率越快
#define IMU660RX_SCL_PIN (P20_11) // 软件 IIC SCL 引脚 连接 IMU660RX 的 SCL 引脚
#define IMU660RX_SDA_PIN (P20_14) // 软件 IIC SDA 引脚 连接 IMU660RX 的 SDA 引脚
//====================================================软件 IIC 驱动====================================================
#else
//====================================================硬件 SPI 驱动====================================================
#define IMU660RX_SPI_SPEED (10 * 1000 * 1000) // 硬件 SPI 速率
#define IMU660RX_SPI (SPI_0) // 硬件 SPI 号
#define IMU660RX_SPC_PIN (SPI0_SCLK_P20_11 ) // 硬件 SPI SCK 引脚
#define IMU660RX_SDI_PIN (SPI0_MOSI_P20_14) // 硬件 SPI MOSI 引脚
#define IMU660RX_SDO_PIN (SPI0_MISO_P20_12) // 硬件 SPI MISO 引脚
//====================================================硬件 SPI 驱动====================================================
#endif
#define IMU660RX_CS_PIN (P20_13) // CS 片选引脚
#define IMU660RX_CS(x) ((x) ? (gpio_high(IMU660RX_CS_PIN)) : (gpio_low(IMU660RX_CS_PIN)))
#define IMU660RX_TIMEOUT_COUNT (0x0FFF) // IMU660 超时计数
//================================================定义 IMU660RX 内部地址================================================
#define IMU660RX_DEV_ADDR (0x6B) // SA0接地:0x6B SA0上拉:0x69 模块默认上拉
#define IMU660RX_SPI_W (0x00)
#define IMU660RX_SPI_R (0x80)
#define IMU660RX_CHIP_IDA (0x00) //660RAID
#define IMU660RX_CHIP_IDB (0x0F) //660RBID
//================================================声明 IMU660RX 全局变量================================================
extern int16 imu660rx_gyro_x, imu660rx_gyro_y, imu660rx_gyro_z; // 三轴陀螺仪数据 gyro (陀螺仪)
extern int16 imu660rx_acc_x, imu660rx_acc_y, imu660rx_acc_z; // 三轴加速度计数据 acc (accelerometer 加速度计)
extern float imu660rx_transition_factor[2];
//================================================声明 IMU660RX 全局变量================================================
//================================================声明 IMU660RX 基础函数================================================
void imu660rx_get_acc (void); // 获取 IMU660RX 加速度计数据
void imu660rx_get_gyro (void); // 获取 IMU660RX 陀螺仪数据
uint8 imu660rx_init (void); // 初始化 IMU660RX
//================================================声明 IMU660RX 基础函数================================================
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 将 IMU660RX 加速度计数据转换为实际物理数据
// 参数说明 acc_value 任意轴的加速度计数据
// 返回参数 void
// 使用示例 float data = imu660ra_acc_transition(imu660ra_acc_x); // 单位为 g(m/s^2)
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
#define imu660rx_acc_transition(acc_value) ((float)(acc_value) / imu660rx_transition_factor[0])
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 将 IMU660RA 陀螺仪数据转换为实际物理数据
// 参数说明 gyro_value 任意轴的陀螺仪数据
// 返回参数 void
// 使用示例 float data = imu660ra_gyro_transition(imu660ra_gyro_x); // 单位为 °/s
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
#define imu660rx_gyro_transition(gyro_value) ((float)(gyro_value) / imu660rx_transition_factor[1])
#endif
+530
View File
@@ -0,0 +1,530 @@
/*********************************************************************************************************************
* 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_imu963ra
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 ADS v1.10.2
* 适用平台 TC264D
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2022-09-15 pudding first version
* 2023-04-28 pudding 增加中文注释说明
********************************************************************************************************************/
/********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* // 硬件 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_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; // 三轴陀螺仪数据 GYRO (陀螺仪)
int16 imu963ra_acc_x = 0, imu963ra_acc_y = 0, imu963ra_acc_z = 0; // 三轴加速度计数据 ACC (accelerometer 加速度计)
int16 imu963ra_mag_x = 0, imu963ra_mag_y = 0, imu963ra_mag_z = 0; // 三轴磁力计数据 MAG (magnetometer 磁力计)
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
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(m/s^2)
// 设置为 0x38 加速度量程为 ±4 G 获取到的加速度计数据除以 8197 可以转化为带物理单位的数据 单位 g(m/s^2)
// 设置为 0x3C 加速度量程为 ±8 G 获取到的加速度计数据除以 4098 可以转化为带物理单位的数据 单位 g(m/s^2)
// 设置为 0x34 加速度量程为 ±16 G 获取到的加速度计数据除以 2049 可以转化为带物理单位的数据 单位 g(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;
}
+217
View File
@@ -0,0 +1,217 @@
/*********************************************************************************************************************
* 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_imu963ra
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 ADS v1.10.2
* 适用平台 TC264D
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2022-09-15 pudding first version
* 2023-04-28 pudding 增加中文注释说明
* 2024-01-30 pudding 更正宏转换函数 变量增加括号
********************************************************************************************************************/
/********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* // 硬件 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 驱动====================================================
#define IMU963RA_SOFT_IIC_DELAY (59) // 软件 IIC 的时钟延时周期 数值越小 IIC 通信速率越快
#define IMU963RA_SCL_PIN (P20_11) // 软件 IIC SCL 引脚 连接 IMU963RA 的 SCL 引脚
#define IMU963RA_SDA_PIN (P20_14) // 软件 IIC SDA 引脚 连接 IMU963RA 的 SDA 引脚
//====================================================软件 IIC 驱动====================================================
#else
//====================================================硬件 SPI 驱动====================================================
#define IMU963RA_SPI_SPEED (10 * 1000 * 1000) // 硬件 SPI 速率
#define IMU963RA_SPI (SPI_0 ) // 硬件 SPI 号
#define IMU963RA_SPC_PIN (SPI0_SCLK_P20_11) // 硬件 SPI SCK 引脚
#define IMU963RA_SDI_PIN (SPI0_MOSI_P20_14) // 硬件 SPI MOSI 引脚
#define IMU963RA_SDO_PIN (SPI0_MISO_P20_12) // 硬件 SPI MISO 引脚
//====================================================硬件 SPI 驱动====================================================
#endif
#define IMU963RA_CS_PIN (P20_13) // 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 @@
/*********************************************************************************************************************
* 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_ips114
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 ADS v1.10.2
* 适用平台 TC264D
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2022-09-15 pudding first version
* 2023-04-28 pudding 增加中文注释说明
********************************************************************************************************************/
/********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* 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 (0 ) // 软件 SPI 的时钟延时周期 数值越小 SPI 通信速率越快
#define IPS114_SCL_PIN (P15_3) // 软件 SPI SCK 引脚
#define IPS114_SDA_PIN (P15_5) // 软件 SPI MOSI 引脚
//====================================================软件 SPI 驱动==================================================
#else
//====================================================硬件 SPI 驱动==================================================
#define IPS114_SPI_SPEED (60*1000*1000) // 硬件 SPI 速率
#define IPS114_SPI (SPI_2) // 硬件 SPI 号
#define IPS114_SCL_PIN (SPI2_SCLK_P15_3) // 硬件 SPI SCK 引脚
#define IPS114_SDA_PIN (SPI2_MOSI_P15_5) // 硬件 SPI MOSI 引脚
#define IPS114_SDA_IN_PIN (SPI2_MISO_P15_4) // 定义SPI_MISO引脚 IPS没有MISO引脚,但是这里任然需要定义,在spi的初始化时需要使用
//====================================================硬件 SPI 驱动==================================================
#endif
#define IPS114_RST_PIN (P15_1) // 液晶复位引脚定义
#define IPS114_DC_PIN (P15_0 ) // 液晶命令位引脚定义
#define IPS114_CS_PIN (P15_2) // CS 片选引脚
#define IPS114_BLK_PIN (P15_4) // 液晶背光引脚定义
#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_1_W, MT9V03X_1_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
+228
View File
@@ -0,0 +1,228 @@
/*********************************************************************************************************************
* 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_ips200
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 ADS v1.10.2
* 适用平台 TC264D
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2022-09-15 pudding first version
* 2023-04-28 pudding 增加中文注释说明
* 2025-02-08 pudding 修改部分注释 移除“单排排针”“双排排针”命名规范
********************************************************************************************************************/
/********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* // 八位并口 并口两寸屏 硬件引脚
* RD 查看 zf_device_ips200.h 中 IPS200_RD_PIN_PARALLEL8 宏定义
* WR 查看 zf_device_ips200.h 中 IPS200_WR_PIN_PARALLEL8 宏定义
* RS 查看 zf_device_ips200.h 中 IPS200_RS_PIN_PARALLEL8 宏定义
* RST 查看 zf_device_ips200.h 中 IPS200_RST_PIN_PARALLEL8 宏定义
* CS 查看 zf_device_ips200.h 中 IPS200_CS_PIN_PARALLEL8 宏定义
* BL 查看 zf_device_ips200.h 中 IPS200_BL_PIN_PARALLEL8 宏定义
* D0-D7 查看 zf_device_ips200.h 中 IPS200_Dx_PIN_PARALLEL8 宏定义
* VCC 3.3V电源
* GND 电源地
*
* // SPI 串口 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"
//==================================================定义 IPS200 基本配置================================================
#define IPS200_USE_SOFT_SPI (0 ) // 默认使用硬件 SPI 方式驱动 建议使用硬件 SPI 方式驱动
#if IPS200_USE_SOFT_SPI // 这两段 颜色正常的才是正确的 颜色灰的就是没有用的
//====================================================软件 SPI 驱动====================================================
// 如果使用的是SPI 串口的两寸屏幕 SPI 驱动控制引脚 可以修改
#define IPS200_SOFT_SPI_DELAY (0 ) // 软件 SPI 的时钟延时周期 数值越小 SPI 通信速率越快
#define IPS200_SCL_PIN (P15_3) // 软件 SPI SCK 引脚
#define IPS200_SDA_PIN (P15_5) // 软件 SPI MOSI 引脚
//====================================================软件 SPI 驱动====================================================
#else
//====================================================硬件 SPI 驱动====================================================
// 如果使用的是SPI 串口的两寸屏幕 SPI 驱动控制引脚 可以修改
#define IPS200_SPI_SPEED (60*1000*1000) // 硬件 SPI 速率
#define IPS200_SPI (SPI_2 ) // 硬件 SPI 号
#define IPS200_SCL_PIN_SPI (SPI2_SCLK_P15_3 ) // 硬件 SPI SCK 引脚
#define IPS200_SDA_PIN_SPI (SPI2_MOSI_P15_5 ) // 硬件 SPI MOSI 引脚
#define IPS200_SDA_IN_PIN_SPI (SPI2_MISO_P15_4 ) // 硬件 SPI MISO 引脚 IPS没有MISO引脚,但是这里任然需要定义,在spi的初始化时需要使用
//====================================================硬件 SPI 驱动====================================================
#endif
// 如果使用的是SPI 串口的两寸屏幕 SPI 驱动控制引脚 可以修改
#define IPS200_RST_PIN_SPI (P15_1) // (SPI串口)液晶复位引脚定义
#define IPS200_DC_PIN_SPI (P15_0) // (SPI串口)液晶命令位引脚定义
#define IPS200_CS_PIN_SPI (P15_2) // (SPI串口)液晶片选引脚定义
#define IPS200_BLk_PIN_SPI (P15_4) // (SPI串口)液晶背光引脚定义
// 如果使用的是八位并口的两寸屏幕 并口驱动控制引脚 可以修改
#define IPS200_RD_PIN_PARALLEL8 (P15_3) // (八位并口)液晶读取位引脚定义
#define IPS200_WR_PIN_PARALLEL8 (P15_5) // (八位并口)液晶写入位引脚定义
#define IPS200_RST_PIN_PARALLEL8 (P15_0) // (八位并口)液晶复位引脚定义
#define IPS200_RS_PIN_PARALLEL8 (P15_1) // (八位并口)液晶命令位引脚定义
#define IPS200_CS_PIN_PARALLEL8 (P15_2) // (八位并口)液晶片选引脚定义
#define IPS200_BL_PIN_PARALLEL8 (P15_4) // (八位并口)液晶背光引脚定义
//并口驱动数据引脚 可以修改 如果你的屏幕是八位并口 这里的引脚用得到
//D0-D3四个数据引脚必须连续 例如C0-C3,C1-C4等等,
//D4-D7四个数据引脚必须连续 例如B0-B3,B1-B4等等。
//可以连接到不同端口的意思就是屏幕的D0-D3与C1-C4连接,D4-D7与B2-B5连接。
//切换引脚后注意修改IPS200_DATA_PORT1和IPS200_DATA_PORT2宏定义
#define IPS200_D0_PIN_PARALLEL8 (P02_0 ) // (八位并口)液晶数据引脚D0
#define IPS200_D1_PIN_PARALLEL8 (P02_1) // (八位并口)液晶数据引脚D1
#define IPS200_D2_PIN_PARALLEL8 (P02_2) // (八位并口)液晶数据引脚D2
#define IPS200_D3_PIN_PARALLEL8 (P02_3) // (八位并口)液晶数据引脚D3
#define IPS200_D4_PIN_PARALLEL8 (P13_0 ) // (八位并口)液晶数据引脚D4
#define IPS200_D5_PIN_PARALLEL8 (P13_1 ) // (八位并口)液晶数据引脚D5
#define IPS200_D6_PIN_PARALLEL8 (P13_2 ) // (八位并口)液晶数据引脚D6
#define IPS200_D7_PIN_PARALLEL8 (P13_3 ) // (八位并口)液晶数据引脚D7
#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) // 默认的字体模式
//定义数据端口所在PORT,切换引脚后务必根据引脚所在PORT进行更改 这里使用了两组端口进行组合 因此定义了两个引脚起始编号
#define IPS200_DATA_PORT1 (3) //0:P00端口 1:P02端口 2:P10端口 3:P11端口 4:P13端口 5:P14端口 6:P15端口 7:P20端口 8:P21端口 9:P22端口 10:P23端口 11:P32端口 12:P33端口
#define IPS200_DATAPORT1 (get_port_out_addr(IPS200_DATA_PORT1))
#define DATA_START_NUM1 (IPS200_D0_PIN_PARALLEL8&0x1f) // 定义数据引脚的起始编号
#define IPS200_DATA_PORT2 (4) //0:P00端口 1:P02端口 2:P10端口 3:P11端口 4:P13端口 5:P14端口 6:P15端口 7:P20端口 8:P21端口 9:P22端口 10:P23端口 11:P32端口 12:P33端口
#define IPS200_DATAPORT2 (get_port_out_addr(IPS200_DATA_PORT2))
#define DATA_START_NUM2 (IPS200_D4_PIN_PARALLEL8&0x1f) // 定义数据引脚的起始编号
// 控制语句
#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(IPS200_CS_PIN_SPI)) : (gpio_low(IPS200_CS_PIN_SPI)))
//==================================================定义 IPS200 基本配置================================================
//==================================================定义 IPS200 参数结构体===============================================
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;
extern uint16 ips200_width_max;
extern uint16 ips200_height_max;
//==================================================定义 IPS200 参数结构体===============================================
//==================================================声明 IPS200 基础函数================================================
void ips200_clear (void); // IPS200 清屏函数
void ips200_full (const uint16 color); // IPS200 屏幕填充函数
void ips200_set_dir (ips200_dir_enum dir); // IPS200 设置显示方向
void ips200_set_font (ips200_font_size_enum font); // IPS200 设置显示字体
void ips200_set_color (const uint16 pen, const uint16 bgcolor); // IPS200 设置显示颜色
void ips200_draw_point (uint16 x, uint16 y, const uint16 color); // IPS200 画点函数
void ips200_draw_line (uint16 x_start, uint16 y_start, uint16 x_end, uint16 y_end, const uint16 color); // IPS200 画线函数
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); // IPS200 显示二值图像 数据每八个点组成一个字节数据
void ips200_show_gray_image (uint16 x, uint16 y, const uint8 *image, uint16 width, uint16 height, uint16 dis_width, uint16 dis_height, uint8 threshold); // IPS200 显示 8bit 灰度图像 带二值化阈值
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); // IPS200 显示 RGB565 彩色图像
void ips200_show_wave (uint16 x, uint16 y, const uint16 *wave, uint16 width, uint16 value_max, uint16 dis_width, uint16 dis_value_max); // IPS200 显示波形
void ips200_show_chinese (uint16 x, uint16 y, uint8 size, const uint8 *chinese_buffer, uint8 number, const uint16 color); // IPS200 汉字显示
void ips200_init (ips200_type_enum type_select); // 2寸 IPS液晶初始化
//==================================================声明 IPS200 基础函数================================================
//==================================================声明 IPS200 扩展函数================================================
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IPS200 显示小钻风图像
// 参数说明 p 图像数组指针
// 参数说明 width 图像实际宽度
// 参数说明 height 图像实际高度
// 返回参数 void
// 使用示例 ips200_displayimage7725(ov7725_image_binary[0], OV7725_W, OV7725_H);
// 备注信息 拓展的一键显示函数,默认无缩放,从屏幕坐标起始点开始显示
//-------------------------------------------------------------------------------------------------------------------
#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], MT9V03X_W, MT9V03X_H);
// 备注信息 拓展的一键显示函数,默认无缩放,从屏幕坐标起始点开始显示
//-------------------------------------------------------------------------------------------------------------------
#define ips200_displayimage03x(p, width, height) (ips200_show_gray_image(0, 0, (p), MT9V03X_1_W, MT9V03X_1_H, (width), (height), 0))
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IPS200 显示凌瞳图像
// 参数说明 p 图像数组指针
// 参数说明 width 图像实际宽度
// 参数说明 height 图像实际高度
// 返回参数 void
// 使用示例 ips200_displayimage8660(scc8660_image[0], SCC8660_W, SCC8660_H);
// 备注信息 拓展的一键显示函数,默认无缩放,从屏幕坐标起始点开始显示
//-------------------------------------------------------------------------------------------------------------------
#define ips200_displayimage8660(p, width, height) (ips200_show_rgb565_image(0, 0, (p), SCC8660_W, SCC8660_H, (width), (height), 1))
//==================================================声明 IPS200 扩展函数================================================
#endif
+989
View File
@@ -0,0 +1,989 @@
/*********************************************************************************************************************
* 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_ips200pro
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 ADS v1.10.2
* 适用平台 TC264D
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2025-05-15 seekfree first version
********************************************************************************************************************/
/********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* // SPI 串口 SPI 两寸屏 硬件引脚
* SCL 查看 zf_device_ips200pro.h 中 IPS200PRO_SCL_PIN_SPI 宏定义
* SDA 查看 zf_device_ips200pro.h 中 IPS200PRO_SDA_PIN_SPI 宏定义
* RST 查看 zf_device_ips200pro.h 中 IPS200PRO_RST_PIN_SPI 宏定义
* DC 查看 zf_device_ips200pro.h 中 IPS200PRO_DC_PIN_SPI 宏定义
* CS 查看 zf_device_ips200pro.h 中 IPS200PRO_CS_PIN_SPI 宏定义
* BLk 查看 zf_device_ips200pro.h 中 IPS200PRO_BLk_PIN_SPI 宏定义
* VCC 3.3V电源
* GND 电源地
* 最大分辨率 320 * 240
* ------------------------------------
********************************************************************************************************************/
#include "zf_common_debug.h"
#include "zf_common_function.h"
#include "zf_driver_delay.h"
#include "zf_driver_soft_spi.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_WAVEFORM_LINE ( 5 )
#define MAX_ID_IMAGE ( 5 )
#define MAX_ID_IMAGE_LINE ( 10 )
#define MAX_ID_IMAGE_RECTANGLE ( 5 )
#define MAX_ID_CONTAINER ( 20 )
ips200pro_information_struct ips200pro_information;
ips200pro_time_struct ips200pro_time;
static char ips200pro_printf_buffer[51];
static uint8 ips200pro_lebel_num = 0;
static uint8 ips200pro_table_num = 0;
static uint8 ips200pro_meter_num = 0;
static uint8 ips200pro_clock_num = 0;
static uint8 ips200pro_progress_bar_num = 0;
static uint8 ips200pro_waveform_num = 0;
static uint8 ips200pro_image_num = 0;
static uint8 ips200pro_container_num = 0;
static uint8 ips200pro_page_num = 0;
// 系统参数的子命令与屏幕组件的子命令
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_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;
if(MAX_ID_LABEL > ips200pro_lebel_num)
{
return_state = ips200pro_create_widgets(++ips200pro_lebel_num | (IPS200PRO_WIDGETS_LABEL << 8), x, y, width, height);
if(1 == return_state)
{
ips200pro_lebel_num--;
}
}
return return_state == 1 ? 0 : (ips200pro_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;
if(MAX_ID_TABLE > ips200pro_table_num)
{
return_state = ips200pro_create_widgets(++ips200pro_table_num | (IPS200PRO_WIDGETS_TABLE << 8), x, y, row_num, col_num);
if(1 == return_state)
{
ips200pro_table_num--;
}
}
return return_state == 1 ? 0 : (ips200pro_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;
if(MAX_ID_METER > ips200pro_meter_num)
{
return_state = ips200pro_create_widgets(++ips200pro_meter_num | (IPS200PRO_WIDGETS_METER << 8), x, y, size, style);
if(1 == return_state)
{
ips200pro_meter_num--;
}
}
return return_state == 1 ? 0 : (ips200pro_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;
if(MAX_ID_CLOCK > ips200pro_clock_num)
{
return_state = ips200pro_create_widgets(++ips200pro_clock_num | (IPS200PRO_WIDGETS_CLOCK << 8), x, y, clock_size, clock_type);
if(1 == return_state)
{
ips200pro_clock_num--;
}
}
return return_state == 1 ? 0 : (ips200pro_clock_num | (IPS200PRO_WIDGETS_CLOCK << 8));
}
uint16 ips200pro_progress_bar_create(int16 x, int16 y, uint16 width, uint16 height)
{
uint8 return_state = 1;
if(MAX_ID_PROGRESS_BAR > ips200pro_progress_bar_num)
{
return_state = ips200pro_create_widgets(++ips200pro_progress_bar_num | (IPS200PRO_WIDGETS_BAR << 8), x, y, width, height);
if(1 == return_state)
{
ips200pro_progress_bar_num--;
}
}
return return_state == 1 ? 0 : (ips200pro_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;
if(MAX_ID_WAVEFORM > ips200pro_waveform_num)
{
return_state = ips200pro_create_widgets(++ips200pro_waveform_num | (IPS200PRO_WIDGETS_WAVEFORM << 8), x, y, width, height);
if(1 == return_state)
{
ips200pro_waveform_num--;
}
}
return return_state == 1 ? 0 : (ips200pro_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 = 1;
if(MAX_ID_WAVEFORM_LINE > line_id - 1)
{
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 = 1;
if(MAX_ID_WAVEFORM_LINE > line_id - 1)
{
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;
if(MAX_ID_IMAGE > ips200pro_image_num)
{
return_state = ips200pro_create_widgets(++ips200pro_image_num | (IPS200PRO_WIDGETS_IMAGE << 8), x, y, width, height);
if(1 == return_state)
{
ips200pro_image_num--;
}
}
return return_state == 1 ? 0 : (ips200pro_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;
if(MAX_ID_CONTAINER > ips200pro_container_num)
{
return_state = ips200pro_create_widgets(++ips200pro_container_num | (IPS200PRO_WIDGETS_CONTAINER << 8), x, y, width, height);
if(1 == return_state)
{
ips200pro_container_num--;
}
}
return return_state == 1 ? 0 : (ips200pro_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);
ips200pro_lebel_num = 0;
ips200pro_table_num = 0;
ips200pro_meter_num = 0;
ips200pro_clock_num = 0;
ips200pro_progress_bar_num = 0;
ips200pro_waveform_num = 0;
ips200pro_image_num = 0;
ips200pro_container_num = 0;
ips200pro_page_num = 0;
// 某一些主板屏幕接口由于没有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;
}
+796
View File
@@ -0,0 +1,796 @@
/*********************************************************************************************************************
* 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_ips200pro
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 ADS v1.10.2
* 适用平台 TC264D
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2025-05-15 seekfree first version
********************************************************************************************************************/
/********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* // SPI 串口 SPI 两寸屏 硬件引脚
* SCL 查看 zf_device_ips200pro.h 中 IPS200PRO_SCL_PIN_SPI 宏定义
* SDA 查看 zf_device_ips200pro.h 中 IPS200PRO_SDA_PIN_SPI 宏定义
* RST 查看 zf_device_ips200pro.h 中 IPS200PRO_RST_PIN_SPI 宏定义
* DC 查看 zf_device_ips200pro.h 中 IPS200PRO_DC_PIN_SPI 宏定义
* CS 查看 zf_device_ips200pro.h 中 IPS200PRO_CS_PIN_SPI 宏定义
* BLk 查看 zf_device_ips200pro.h 中 IPS200PRO_BLk_PIN_SPI 宏定义
* VCC 3.3V电源
* GND 电源地
* 最大分辨率 320 * 240
* ------------------------------------
********************************************************************************************************************/
#ifndef _zf_device_ips200pro_h_
#define _zf_device_ips200pro_h_
#include "zf_common_typedef.h"
#define IPS200PRO_SPI_SPEED ( 40*1000*1000 ) // 硬件 SPI 速率
#define IPS200PRO_SPI_INDEX ( SPI_2 ) // 硬件 SPI 号
#define IPS200PRO_CLK_PIN ( SPI2_SCLK_P15_3 ) // 硬件 SPI SCK 引脚
#define IPS200PRO_MOSI_PIN ( SPI2_MOSI_P15_5 ) // 硬件 SPI MOSI 引脚
#define IPS200PRO_MISO_PIN ( SPI2_MISO_P15_4 ) // 硬件 SPI MISO 引脚 TFT没有MISO引脚,但是这里任然需要定义,在spi的初始化时需要使用
#define IPS200PRO_RST_PIN ( P15_1 ) // 液晶复位引脚定义
#define IPS200PRO_INT_PIN ( P15_0 ) // 液晶命令位引脚定义
#define IPS200PRO_CS_PIN ( P15_2 ) // CS 片选引脚
#define IPS200PRO_WAIT_TIME ( 900 ) // 通讯等待时长,内部是软件延时,因此这里没有时间单位
#define IPS200PRO_CRC_ENABLE ( 0 ) // 0:关闭CRC模式(通常关闭即可) 1:使能CRC模式,在传输的数据包中加入CRC校验,能提高屏幕的抗干扰的能力
#define IPS200PRO_DEFAULT_FORMAT (IPS200PRO_FORMAT_GBK) // 默认编码格式,会在初始化屏幕的时候进行设置
#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
{
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
{
// 仅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 , // 前景色 除 WAVEFORM CONTAINER 组件不支持其他都支持
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 组件的编号
// 参数说明 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
+149
View File
@@ -0,0 +1,149 @@
/*********************************************************************************************************************
* 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_key
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 ADS v1.10.2
* 适用平台 TC264D
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2022-09-15 pudding first version
* 2023-04-28 pudding 增加中文注释说明
********************************************************************************************************************/
/*********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* // 一般是主板按键对应的引脚
* 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] ++;
if(KEY_LONG_PRESS_PERIOD / scanner_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;
}
+93
View File
@@ -0,0 +1,93 @@
/*********************************************************************************************************************
* 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_key
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 ADS v1.10.2
* 适用平台 TC264D
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2022-09-15 pudding first version
* 2023-04-28 pudding 增加中文注释说明
********************************************************************************************************************/
/*********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* // 一般是主板按键对应的引脚
* 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 {P20_6, P20_7, P11_2, P11_3}
#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
+185
View File
@@ -0,0 +1,185 @@
/*********************************************************************************************************************
* 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_menc15a
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 ADS v1.10.2
* 适用平台 TC264D
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2024-11-19 pudding first version
********************************************************************************************************************/
/*********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* // 硬件 SPI 引脚
* SCL/SPC 查看 zf_device_menc15a.h 中 MENC15A_SPC_PIN 宏定义
* SDA/DSI 查看 zf_device_menc15a.h 中 MENC15A_SDI_PIN 宏定义
* SA0/SDO 查看 zf_device_menc15a.h 中 MENC15A_SDO_PIN 宏定义
* CS 查看 zf_device_menc15a.h 中 MENC15A_CS_PIN 宏定义
* VCC 3.3V电源
* GND 电源地
* 其余引脚悬空
* ------------------------------------
********************************************************************************************************************/
#include "zf_common_debug.h"
#include "zf_common_function.h"
#include "zf_device_config.h"
#include "zf_driver_delay.h"
#include "zf_driver_gpio.h"
#include "zf_driver_spi.h"
#include "zf_device_menc15a.h"
uint16 menc15a_absolute_data[2] = {0};
int16 menc15a_absolute_offset_data[2] = {0};
int16 menc15a_speed_data[2] = {0};
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 计算编码器旋转偏差
// 参数说明 encoder_max 编码器精度 填写十进制数据
// 参数说明 now_location 当前位置信息
// 参数说明 last_location 上一次的位置信息
// 返回参数 int32 计算的偏差值
// 使用示例 magnetic_encoder_get_offset();
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
static int32 magnetic_encoder_get_offset (int32 encoder_max, int32 now_location, int32 last_location)
{
int32 result_data = 0;
if((encoder_max / 2) < func_abs(now_location - last_location))
{
result_data = ((encoder_max / 2) < now_location ? (now_location - encoder_max - last_location) : (now_location + encoder_max - last_location));
}
else
{
result_data = (now_location - last_location);
}
return result_data;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 获取 MENC15A 磁编码器 的 绝对值 角度数据
// 参数说明 menc15a_module 磁编码器 模块号
// 返回参数 uint16 绝对值 角度数据
// 使用示例 menc15a_1_get_absolute_data();
// 备注信息 执行该函数后,可直接使用返回值 也可以通过查询对应变量获取结果
//-------------------------------------------------------------------------------------------------------------------
uint16 menc15a_get_absolute_data(menc15a_module_enum menc15a_module)
{
uint16 read_data = 0;
uint16 data_last = menc15a_absolute_data[menc15a_module];
if(menc15a_module == menc15a_1_module)
{
MENC15A_1_CS(0);
read_data = spi_read_16bit_register(MENC15A_1_SPI, 0x8021);
MENC15A_1_CS(1);
}
else
{
MENC15A_2_CS(0);
read_data = spi_read_16bit_register(MENC15A_2_SPI, 0x8021);
MENC15A_2_CS(1);
}
menc15a_absolute_data[menc15a_module] = (read_data & 0x7fff);
menc15a_absolute_offset_data[menc15a_module] = (int16)magnetic_encoder_get_offset(32768, menc15a_absolute_data[menc15a_module], data_last);
return menc15a_absolute_data[menc15a_module];
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 获取 MENC15A 磁编码器 的 转速数据
// 参数说明 menc15a_module 磁编码器 模块号
// 返回参数 int16 转速数据(每秒旋转弧度 rad/s)
// 使用示例 menc15a_1_get_speed_data();
// 备注信息 执行该函数后,可直接使用返回值 也可以通过查询对应变量获取结果
//-------------------------------------------------------------------------------------------------------------------
int16 menc15a_get_speed_data(menc15a_module_enum menc15a_module)
{
int16 read_data = 0;
if(menc15a_module == menc15a_1_module)
{
MENC15A_1_CS(0);
read_data = spi_read_16bit_register(MENC15A_1_SPI, 0x8032);
MENC15A_1_CS(1);
}
else
{
MENC15A_2_CS(0);
read_data = spi_read_16bit_register(MENC15A_2_SPI, 0x8032);
MENC15A_2_CS(1);
}
read_data = (read_data & 0x7fff);
if(read_data > 16384)
{
read_data = read_data - 32768;
}
menc15a_speed_data[menc15a_module] = (int16)((float)read_data * 1.917476f);
return menc15a_speed_data[menc15a_module];
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 初始化 MENC15A
// 参数说明 void
// 返回参数 uint8 1-初始化失败 0-初始化成功
// 使用示例 menc15a_init();
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
uint8 menc15a_init(void)
{
spi_init(MENC15A_1_SPI, SPI_MODE1, MENC15A_1_SPI_SPEED, MENC15A_1_CLK_PIN, MENC15A_1_MOSI_PIN, MENC15A_1_MISO_PIN, SPI_CS_NULL); // 配置 MENC15A-1 的 SPI端口
gpio_init(MENC15A_1_CS_PIN, GPO, GPIO_HIGH, GPO_PUSH_PULL); // 配置 MENC15A-1 的 CS端口
spi_init(MENC15A_2_SPI, SPI_MODE1, MENC15A_2_SPI_SPEED, MENC15A_2_CLK_PIN, MENC15A_2_MOSI_PIN, MENC15A_2_MISO_PIN, SPI_CS_NULL); // 配置 MENC15A-2 的 SPI端口
gpio_init(MENC15A_2_CS_PIN, GPO, GPIO_HIGH, GPO_PUSH_PULL); // 配置 MENC15A-2 的 CS端口
return 0;
}
+102
View File
@@ -0,0 +1,102 @@
/*********************************************************************************************************************
* 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_menc15a
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 ADS v1.10.2
* 适用平台 TC264D
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2024-11-19 pudding first version
********************************************************************************************************************/
/*********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* // 硬件 SPI 引脚
* CLK 查看 zf_device_menc15a.h 中 MENC15A_CLK_PIN 宏定义
* MOSI 查看 zf_device_menc15a.h 中 MENC15A_MOSI_PIN 宏定义
* MISO 查看 zf_device_menc15a.h 中 MENC15A_MISO_PIN 宏定义
* CS 查看 zf_device_menc15a.h 中 MENC15A_CS_PIN 宏定义
* VCC 3.3V电源
* GND 电源地
* 其余引脚悬空
* ------------------------------------
********************************************************************************************************************/
#ifndef _zf_device_menc15a_h_
#define _zf_device_menc15a_h_
#include "zf_common_typedef.h"
//================================================定义 MENC15A 基本配置================================================
//====================================================硬件 SPI 驱动====================================================
#define MENC15A_1_SPI_SPEED (20 * 1000 * 1000) // 磁编码器1 硬件 SPI 速率
#define MENC15A_1_SPI (SPI_0 ) // 磁编码器1 硬件 SPI 号
#define MENC15A_1_CLK_PIN (SPI0_SCLK_P20_11) // 磁编码器1 硬件 SPI SCK 引脚
#define MENC15A_1_MOSI_PIN (SPI0_MOSI_P20_14) // 磁编码器1 硬件 SPI MOSI 引脚
#define MENC15A_1_MISO_PIN (SPI0_MISO_P20_12) // 磁编码器1 硬件 SPI MISO 引脚
#define MENC15A_1_CS_PIN (P20_13) // 磁编码器1 CS 片选引脚
#define MENC15A_1_CS(x) ((x) ? (gpio_high(MENC15A_1_CS_PIN)) : (gpio_low(MENC15A_1_CS_PIN)))
#define MENC15A_2_SPI_SPEED (20 * 1000 * 1000) // 磁编码器2 硬件 SPI 速率
#define MENC15A_2_SPI (SPI_0 ) // 磁编码器2 硬件 SPI 号
#define MENC15A_2_CLK_PIN (SPI0_SCLK_P20_11 ) // 磁编码器2 硬件 SPI SCK 引脚
#define MENC15A_2_MOSI_PIN (SPI0_MOSI_P20_14 ) // 磁编码器2 硬件 SPI MOSI 引脚
#define MENC15A_2_MISO_PIN (SPI0_MISO_P20_12 ) // 磁编码器2 硬件 SPI MISO 引脚
#define MENC15A_2_CS_PIN (P20_15) // 磁编码器2 CS 片选引脚
#define MENC15A_2_CS(x) ((x) ? (gpio_high(MENC15A_2_CS_PIN)) : (gpio_low(MENC15A_2_CS_PIN)))
//====================================================硬件 SPI 驱动====================================================
// 枚举磁编码模块
typedef enum
{
menc15a_1_module,
menc15a_2_module,
}menc15a_module_enum;
//================================================定义 MENC15A 基本配置================================================
extern uint16 menc15a_absolute_data[2];
extern int16 menc15a_absolute_offset_data[2];
extern int16 menc15a_speed_data[2];
uint16 menc15a_get_absolute_data(menc15a_module_enum menc15a_module);
int16 menc15a_get_speed_data(menc15a_module_enum menc15a_module);
uint8 menc15a_init(void);
#endif
+227
View File
@@ -0,0 +1,227 @@
/*********************************************************************************************************************
* 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_mpu6050
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 ADS v1.10.2
* 适用平台 TC264D
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2022-09-15 pudding first version
* 2023-04-28 pudding 增加中文注释说明
********************************************************************************************************************/
/*********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* 软件 IIC 通信引脚对应关系
* SCL 查看 zf_device_mpu6050.h 中 MPU6050_SOFT_IIC_SCL 宏定义
* SDA 查看 zf_device_mpu6050.h 中 MPU6050_SOFT_IIC_SDA 宏定义
* VCC 3.3V电源
* GND 电源地
* 其余引脚悬空
*
* 硬件 IIC 通信引脚应关系
* SCL 查看 zf_device_mpu6050.h 中 MPU6050_IIC_SCL 宏定义
* SDA 查看 zf_device_mpu6050.h 中 MPU6050_IIC_SDA 宏定义
* VCC 3.3V电源
* GND 电源地
* 其余引脚悬空
* ------------------------------------
********************************************************************************************************************/
#include "zf_common_debug.h"
#include "zf_driver_delay.h"
#include "zf_driver_soft_iic.h"
#include "zf_device_mpu6050.h"
int16 mpu6050_gyro_x = 0, mpu6050_gyro_y = 0, mpu6050_gyro_z = 0; // 三轴陀螺仪数据 GYRO (陀螺仪)
int16 mpu6050_acc_x = 0, mpu6050_acc_y = 0, mpu6050_acc_z = 0; // 三轴加速度计数据 ACC (accelerometer 加速度计)
#if MPU6050_USE_SOFT_IIC
static soft_iic_info_struct mpu6050_iic_struct; // 定义 mpu6050 IIC通讯结构体
#define mpu6050_write_register(reg, data) (soft_iic_write_8bit_register(&mpu6050_iic_struct, (reg), (data)))
#define mpu6050_read_register(reg) (soft_iic_read_8bit_register(&mpu6050_iic_struct, (reg)))
#define mpu6050_read_registers(reg, data, len) (soft_iic_read_8bit_registers(&mpu6050_iic_struct, (reg), (data), (len)))
#else
#error "暂不支持硬件IIC通讯"
#endif
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 MPU6050 自检
// 参数说明 void
// 返回参数 uint8 1-自检失败 0-自检成功
// 使用示例 if(mpu6050_self1_check())
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
static uint8 mpu6050_self1_check (void)
{
uint8 dat = 0, return_state = 0;
uint16 timeout_count = 0;
mpu6050_write_register(MPU6050_PWR_MGMT_1, 0x00); // 解除休眠状态
mpu6050_write_register(MPU6050_SMPLRT_DIV, 0x07); // 125HZ采样率
while(0x07 != dat)
{
if(MPU6050_TIMEOUT_COUNT < timeout_count ++)
{
return_state = 1;
break;
}
dat = mpu6050_read_register(MPU6050_SMPLRT_DIV);
system_delay_ms(10);
}
return return_state;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 获取 MPU6050 加速度计数据
// 参数说明 void
// 返回参数 void
// 使用示例 mpu6050_get_acc(); // 执行该函数后,直接查看对应的变量即可
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
void mpu6050_get_acc (void)
{
uint8 dat[6];
mpu6050_read_registers(MPU6050_ACCEL_XOUT_H, dat, 6);
mpu6050_acc_x = (int16)(((uint16)dat[0] << 8 | dat[1]));
mpu6050_acc_y = (int16)(((uint16)dat[2] << 8 | dat[3]));
mpu6050_acc_z = (int16)(((uint16)dat[4] << 8 | dat[5]));
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 获取 MPU6050 陀螺仪数据
// 参数说明 void
// 返回参数 void
// 使用示例 mpu6050_get_gyro(); // 执行该函数后,直接查看对应的变量即可
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
void mpu6050_get_gyro (void)
{
uint8 dat[6];
mpu6050_read_registers(MPU6050_GYRO_XOUT_H, dat, 6);
mpu6050_gyro_x = (int16)(((uint16)dat[0] << 8 | dat[1]));
mpu6050_gyro_y = (int16)(((uint16)dat[2] << 8 | dat[3]));
mpu6050_gyro_z = (int16)(((uint16)dat[4] << 8 | dat[5]));
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 将 MPU6050 加速度计数据转换为实际物理数据
// 参数说明 gyro_value // 任意轴的加速度计数据
// 返回参数 void
// 使用示例 float data = mpu6050_acc_transition(imu660ra_acc_x); //单位为 g(m/s^2)
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
float mpu6050_acc_transition (int16 acc_value)
{
float acc_data = 0;
switch(MPU6050_ACC_SAMPLE)
{
case 0x00: acc_data = (float)acc_value / 16384; break; // 0x00 加速度计量程为:±2g 获取到的加速度计数据 除以16384 可以转化为带物理单位的数据,单位:g(m/s^2)
case 0x08: acc_data = (float)acc_value / 8192; break; // 0x08 加速度计量程为:±4g 获取到的加速度计数据 除以8192 可以转化为带物理单位的数据,单位:g(m/s^2)
case 0x10: acc_data = (float)acc_value / 4096; break; // 0x10 加速度计量程为:±8g 获取到的加速度计数据 除以4096 可以转化为带物理单位的数据,单位:g(m/s^2)
case 0x18: acc_data = (float)acc_value / 2048; break; // 0x18 加速度计量程为:±16g 获取到的加速度计数据 除以2048 可以转化为带物理单位的数据,单位:g(m/s^2)
default: break;
}
return acc_data;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 将 MPU6050 陀螺仪数据转换为实际物理数据
// 参数说明 gyro_value // 任意轴的陀螺仪数据
// 返回参数 void
// 使用示例 float data = mpu6050_gyro_transition(imu660ra_gyro_x); // 单位为°/s
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
float mpu6050_gyro_transition (int16 gyro_value)
{
float gyro_data = 0;
switch(MPU6050_GYR_SAMPLE)
{
case 0x00: gyro_data = (float)gyro_value / 131.0f; break; // 0x00 陀螺仪量程为:±250 dps 获取到的陀螺仪数据除以 131 可以转化为带物理单位的数据,单位为:°/s
case 0x08: gyro_data = (float)gyro_value / 65.5f; break; // 0x08 陀螺仪量程为:±500 dps 获取到的陀螺仪数据除以 65.5 可以转化为带物理单位的数据,单位为:°/s
case 0x10: gyro_data = (float)gyro_value / 32.8f; break; // 0x10 陀螺仪量程为:±1000dps 获取到的陀螺仪数据除以32.8 可以转化为带物理单位的数据,单位为:°/s
case 0x18: gyro_data = (float)gyro_value / 16.4f; break; // 0x18 陀螺仪量程为:±2000dps 获取到的陀螺仪数据除以16.4 可以转化为带物理单位的数据,单位为:°/s
default: break;
}
return gyro_data;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 初始化 MPU6050
// 参数说明 void
// 返回参数 uint8 1-初始化失败 0-初始化成功
// 使用示例 mpu6050_init();
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
uint8 mpu6050_init (void)
{
uint8 return_state = 0;
#if MPU6050_USE_SOFT_IIC
soft_iic_init(&mpu6050_iic_struct, MPU6050_DEV_ADDR, MPU6050_SOFT_IIC_DELAY, MPU6050_SCL_PIN, MPU6050_SDA_PIN);
#else
iic_init(MPU6050_IIC, MPU6050_DEV_ADDR, MPU6050_IIC_SPEED, MPU6050_SCL_PIN, MPU6050_SDA_PIN);
#endif
system_delay_ms(100); // 上电延时
do
{
if(mpu6050_self1_check())
{
// 如果程序在输出了断言信息 并且提示出错位置在这里
// 那么就是 MPU6050 自检出错并超时退出了
// 检查一下接线有没有问题 如果没问题可能就是坏了
zf_log(0, "MPU6050 self check error.");
return_state = 1;
break;
}
mpu6050_write_register(MPU6050_PWR_MGMT_1, 0x00); // 解除休眠状态
mpu6050_write_register(MPU6050_SMPLRT_DIV, 0x07); // 125HZ采样率
mpu6050_write_register(MPU6050_CONFIG, 0x04);
mpu6050_write_register(MPU6050_GYRO_CONFIG, MPU6050_GYR_SAMPLE); // 2000
// GYRO_CONFIG寄存器
// 设置为:0x00 陀螺仪量程为:±250 dps 获取到的陀螺仪数据除以131.2 可以转化为带物理单位的数据,单位为:°/s
// 设置为:0x08 陀螺仪量程为:±500 dps 获取到的陀螺仪数据除以65.6 可以转化为带物理单位的数据,单位为:°/s
// 设置为:0x10 陀螺仪量程为:±1000dps 获取到的陀螺仪数据除以32.8 可以转化为带物理单位的数据,单位为:°/s
// 设置为:0x18 陀螺仪量程为:±2000dps 获取到的陀螺仪数据除以16.4 可以转化为带物理单位的数据,单位为:°/s
mpu6050_write_register(MPU6050_ACCEL_CONFIG, MPU6050_ACC_SAMPLE); // 8g
// ACCEL_CONFIG寄存器
// 设置为:0x00 加速度计量程为:±2g 获取到的加速度计数据 除以16384 可以转化为带物理单位的数据,单位:g(m/s^2)
// 设置为:0x08 加速度计量程为:±4g 获取到的加速度计数据 除以8192 可以转化为带物理单位的数据,单位:g(m/s^2)
// 设置为:0x10 加速度计量程为:±8g 获取到的加速度计数据 除以4096 可以转化为带物理单位的数据,单位:g(m/s^2)
// 设置为:0x18 加速度计量程为:±16g 获取到的加速度计数据 除以2048 可以转化为带物理单位的数据,单位:g(m/s^2)
mpu6050_write_register(MPU6050_USER_CONTROL, 0x00);
mpu6050_write_register(MPU6050_INT_PIN_CFG, 0x02);
}while(0);
return return_state;
}
+120
View File
@@ -0,0 +1,120 @@
/*********************************************************************************************************************
* 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_mpu6050
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 ADS v1.10.2
* 适用平台 TC264D
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2022-09-15 pudding first version
* 2023-04-28 pudding 增加中文注释说明
********************************************************************************************************************/
/*********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* 软件 IIC 通信引脚对应关系
* SCL 查看 zf_device_mpu6050.h 中 MPU6050_SOFT_IIC_SCL 宏定义
* SDA 查看 zf_device_mpu6050.h 中 MPU6050_SOFT_IIC_SDA 宏定义
* VCC 3.3V电源
* GND 电源地
* 其余引脚悬空
*
* 硬件 IIC 通信引脚应关系
* SCL 查看 zf_device_mpu6050.h 中 MPU6050_IIC_SCL 宏定义
* SDA 查看 zf_device_mpu6050.h 中 MPU6050_IIC_SDA 宏定义
* VCC 3.3V电源
* GND 电源地
* 其余引脚悬空
* ------------------------------------
********************************************************************************************************************/
#ifndef _zf_device_mpu6050_h_
#define _zf_device_mpu6050_h_
#include "zf_common_typedef.h"
//================================================定义 MPU6050 基本配置================================================
#define MPU6050_USE_SOFT_IIC (1) // 默认使用软件 IIC 方式驱动 建议使用软件 IIC 方式
#if MPU6050_USE_SOFT_IIC // 这两段 颜色正常的才是正确的 颜色灰的就是没有用的
//====================================================软件 IIC 驱动====================================================
#define MPU6050_SOFT_IIC_DELAY (59 ) // 软件 IIC 的时钟延时周期 数值越小 IIC 通信速率越快
#define MPU6050_SCL_PIN (P20_11) // 软件 IIC SCL 引脚 连接 MPU6050 的 SCL 引脚
#define MPU6050_SDA_PIN (P20_14) // 软件 IIC SDA 引脚 连接 MPU6050 的 SDA 引脚
//====================================================软件 IIC 驱动====================================================
#else
#error "暂不支持硬件IIC通讯"
#endif
#define MPU6050_TIMEOUT_COUNT (0x00FF) // MPU6050 超时计数
//================================================定义 MPU6050 基本配置================================================
//================================================定义 MPU6050 内部地址================================================
#define MPU6050_DEV_ADDR (0xD0>>1) // IIC写入时的地址字节数据,+1为读取
#define MPU6050_SMPLRT_DIV (0x19) // 陀螺仪采样率,典型值:0x07(125Hz)
#define MPU6050_CONFIG (0x1A) // 低通滤波频率,典型值:0x06(5Hz)
#define MPU6050_GYRO_CONFIG (0x1B) // 陀螺仪自检及测量范围,典型值:0x18(不自检,2000deg/s)
#define MPU6050_ACCEL_CONFIG (0x1C) // 加速计自检、测量范围及高通滤波频率,典型值:0x01(不自检,2G,5Hz)
#define MPU6050_INT_PIN_CFG (0x37) // 设置6050辅助I2C为直通模式寄存器
#define MPU6050_ACCEL_XOUT_H (0x3B)
#define MPU6050_GYRO_XOUT_H (0x43)
#define MPU6050_USER_CONTROL (0x6A) // 关闭6050对辅助I2C设备的控制
#define MPU6050_PWR_MGMT_1 (0x6B) // 电源管理,典型值:0x00(正常启用)
#define MPU6050_WHO_AM_I (0x75) // IIC地址寄存器(默认数值0x68,只读)
#define MPU6050_ACC_SAMPLE (0x10) // 加速度计量程
// 设置为:0x00 陀螺仪量程为:±250 dps 获取到的陀螺仪数据除以131.2 可以转化为带物理单位的数据,单位为:°/s
// 设置为:0x08 陀螺仪量程为:±500 dps 获取到的陀螺仪数据除以65.6 可以转化为带物理单位的数据,单位为:°/s
// 设置为:0x10 陀螺仪量程为:±1000dps 获取到的陀螺仪数据除以32.8 可以转化为带物理单位的数据,单位为:°/s
// 设置为:0x18 陀螺仪量程为:±2000dps 获取到的陀螺仪数据除以16.4 可以转化为带物理单位的数据,单位为:°/s
#define MPU6050_GYR_SAMPLE (0x18) // 陀螺仪量程
// 设置为:0x00 陀螺仪量程为:±250 dps 获取到的陀螺仪数据除以131.2 可以转化为带物理单位的数据,单位为:°/s
// 设置为:0x08 陀螺仪量程为:±500 dps 获取到的陀螺仪数据除以65.6 可以转化为带物理单位的数据,单位为:°/s
// 设置为:0x10 陀螺仪量程为:±1000dps 获取到的陀螺仪数据除以32.8 可以转化为带物理单位的数据,单位为:°/s
// 设置为:0x18 陀螺仪量程为:±2000dps 获取到的陀螺仪数据除以16.4 可以转化为带物理单位的数据,单位为:°/s
//================================================定义 MPU6050 内部地址================================================
//================================================声明 MPU6050 全局变量================================================
extern int16 mpu6050_gyro_x, mpu6050_gyro_y, mpu6050_gyro_z; // 三轴陀螺仪数据 gyro (陀螺仪)
extern int16 mpu6050_acc_x, mpu6050_acc_y, mpu6050_acc_z; // 三轴加速度计数据 acc (accelerometer 加速度计)
//================================================声明 MPU6050 全局变量================================================
//================================================声明 MPU6050 基础函数================================================
void mpu6050_get_acc (void); // 获取 MPU6050 加速度计数据
void mpu6050_get_gyro (void); // 获取 MPU6050 陀螺仪数据
float mpu6050_acc_transition (int16 acc_value); // 将 MPU6050 加速度计数据转换为实际物理数据
float mpu6050_gyro_transition (int16 gyro_value); // 将 MPU6050 陀螺仪数据转换为实际物理数据
uint8 mpu6050_init (void); // 初始化 MPU6050
//================================================声明 MPU6050 基础函数================================================
#endif
@@ -0,0 +1,489 @@
/*********************************************************************************************************************
* 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_mt9v03x_double
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 ADS v1.10.2
* 适用平台 TC264D
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2022-09-15 pudding first version
* 2023-04-28 pudding 增加中文注释说明
********************************************************************************************************************/
/*********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* SCL 查看 zf_device_mt9v03x_double.h 中 MT9V03X_COF_IIC_SCL 宏定义
* SDA 查看 zf_device_mt9v03x_double.h 中 MT9V03X_COF_IIC_SDA 宏定义
* PCLK 查看 zf_device_mt9v03x_double.h 中 MT9V03X_PCLK_PIN 宏定义
* VSY 查看 zf_device_mt9v03x_double.h 中 MT9V03X_VSYNC_PIN 宏定义
* D0-D7 查看 zf_device_mt9v03x_double.h 中 MT9V03X_DATA_PIN 宏定义 从该定义开始的连续八个引脚
* VCC 3.3V电源
* GND 电源地
* 其余引脚悬空
* ------------------------------------
********************************************************************************************************************/
#include "IfxStm.h"
#include "zf_common_interrupt.h"
#include "zf_common_debug.h"
#include "zf_driver_soft_iic.h"
#include "zf_driver_delay.h"
#include "zf_driver_dma.h"
#include "zf_driver_exti.h"
#include "zf_driver_gpio.h"
#include "zf_driver_timer.h"
#include "zf_device_camera.h"
#include "zf_device_config.h"
#include "zf_device_mt9v03x_double.h"
#pragma section all "cpu0_dsram"
vuint8 mt9v03x_finish_flag_1 = 0; // 总钻风摄像头1 单幅图像采集完成标志位
vuint8 mt9v03x_finish_flag_2 = 0; // 总钻风摄像头2 单幅图像采集完成标志位
IFX_ALIGN(4) uint8 mt9v03x_image_1[MT9V03X_1_H][MT9V03X_1_W]; // 总钻风摄像头1 图像数据存储数组
IFX_ALIGN(4) uint8 mt9v03x_image_2[MT9V03X_2_H][MT9V03X_2_W]; // 总钻风摄像头2 图像数据存储数组
uint32 mt9v03x_fps[2]; // 总钻风摄像头实际采集帧率
int16 time_out_1 = MT9V03X_1_INIT_TIMEOUT; // 定义超时溢出时长
int16 time_out_2 = MT9V03X_2_INIT_TIMEOUT; // 定义超时溢出时长
uint8 mt9v03x_link_list_num_1 = 0; // 当前DMA链表数量
uint8 mt9v03x_link_list_num_2 = 0; // 当前DMA链表数量
m9v03x_double_init_type_enum camera_work_type = mt9v03x_1; // 当前摄像头工作类型
soft_iic_info_struct mt9v03x_iic_struct_1;
soft_iic_info_struct mt9v03x_iic_struct_2;
uint8 mt9v03x_dma_state[2] = {0, 0};
uint8 mt9v03x_gather_flag = 0;
uint32 mt9v03x_time[2] = {0, 0};
// 需要配置到摄像头的数据 不允许在这修改参数
int16 mt9v03x_set_confing_buffer_1[MT9V03X_DOUBLE_CONFIG_FINISH][2]=
{
{MT9V03X_DOUBLE_INIT, 0}, // 摄像头开始初始化
{MT9V03X_DOUBLE_AUTO_EXP, MT9V03X_1_AUTO_EXP_DEF}, // 自动曝光设置 范围1-63 0为关闭 如果自动曝光开启 EXP_TIME命令设置的数据将会变为最大曝光时间,也就是自动曝光时间的上限
{MT9V03X_DOUBLE_EXP_TIME, MT9V03X_1_EXP_TIME_DEF}, // 曝光时间 摄像头收到后会自动计算出最大曝光时间,如果设置过大则设置为计算出来的最大曝光值
{MT9V03X_DOUBLE_FPS, MT9V03X_1_FPS_DEF}, // 图像帧率 摄像头收到后会自动计算出最大FPS,如果过大则设置为计算出来的最大FPS
{MT9V03X_DOUBLE_SET_COL, MT9V03X_1_W}, // 图像列数量 范围1-752
{MT9V03X_DOUBLE_SET_ROW, MT9V03X_1_H}, // 图像行数量 范围1-480
{MT9V03X_DOUBLE_LR_OFFSET, MT9V03X_1_LR_OFFSET_DEF}, // 图像左右偏移量 正值 右偏移 负值 左偏移 列为188 376 752时无法设置偏移 摄像头收偏移数据后会自动计算最大偏移,如果超出则设置计算出来的最大偏移
{MT9V03X_DOUBLE_UD_OFFSET, MT9V03X_1_UD_OFFSET_DEF}, // 图像上下偏移量 正值 上偏移 负值 下偏移 行为120 240 480时无法设置偏移 摄像头收偏移数据后会自动计算最大偏移,如果超出则设置计算出来的最大偏移
{MT9V03X_DOUBLE_GAIN, MT9V03X_1_GAIN_DEF}, // 图像增益 范围16-64 增益可以在曝光时间固定的情况下改变图像亮暗程度
{MT9V03X_DOUBLE_PCLK_MODE, MT9V03X_1_PCLK_MODE_DEF}, // 像素时钟模式 仅总钻风MT9V034 V2.0以及以上版本支持该命令
};
int16 mt9v03x_set_confing_buffer_2[MT9V03X_DOUBLE_CONFIG_FINISH][2]=
{
{MT9V03X_DOUBLE_INIT, 0}, // 摄像头开始初始化
{MT9V03X_DOUBLE_AUTO_EXP, MT9V03X_2_AUTO_EXP_DEF}, // 自动曝光设置 范围1-63 0为关闭 如果自动曝光开启 EXP_TIME命令设置的数据将会变为最大曝光时间,也就是自动曝光时间的上限
{MT9V03X_DOUBLE_EXP_TIME, MT9V03X_2_EXP_TIME_DEF}, // 曝光时间 摄像头收到后会自动计算出最大曝光时间,如果设置过大则设置为计算出来的最大曝光值
{MT9V03X_DOUBLE_FPS, MT9V03X_2_FPS_DEF}, // 图像帧率 摄像头收到后会自动计算出最大FPS,如果过大则设置为计算出来的最大FPS
{MT9V03X_DOUBLE_SET_COL, MT9V03X_2_W}, // 图像列数量 范围1-752
{MT9V03X_DOUBLE_SET_ROW, MT9V03X_2_H}, // 图像行数量 范围1-480
{MT9V03X_DOUBLE_LR_OFFSET, MT9V03X_2_LR_OFFSET_DEF}, // 图像左右偏移量 正值 右偏移 负值 左偏移 列为188 376 752时无法设置偏移 摄像头收偏移数据后会自动计算最大偏移,如果超出则设置计算出来的最大偏移
{MT9V03X_DOUBLE_UD_OFFSET, MT9V03X_2_UD_OFFSET_DEF}, // 图像上下偏移量 正值 上偏移 负值 下偏移 行为120 240 480时无法设置偏移 摄像头收偏移数据后会自动计算最大偏移,如果超出则设置计算出来的最大偏移
{MT9V03X_DOUBLE_GAIN, MT9V03X_2_GAIN_DEF}, // 图像增益 范围16-64 增益可以在曝光时间固定的情况下改变图像亮暗程度
{MT9V03X_DOUBLE_PCLK_MODE, MT9V03X_2_PCLK_MODE_DEF}, // 像素时钟模式 仅总钻风MT9V034 V2.0以及以上版本支持该命令
};
#pragma section all restore
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 MT9V03X 摄像头1 DMA 重置
// 参数说明 void
// 返回参数 void
// 使用示例 mt9v03x_dma_restart_1();
//-------------------------------------------------------------------------------------------------------------------
static void mt9v03x_dma_restart_1(void)
{
dma_disable(MT9V03X_1_DMA_CH);
exti_disable(MT9V03X_1_PCLK_PIN);
IfxDma_resetChannel(&MODULE_DMA, MT9V03X_1_DMA_CH);
dma_init(MT9V03X_1_DMA_CH,
MT9V03X_1_DATA_ADD,
mt9v03x_image_1[0],
MT9V03X_1_PCLK_PIN,
EXTI_TRIGGER_FALLING,
MT9V03X_1_IMAGE_SIZE);
dma_enable(MT9V03X_1_DMA_CH);
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 MT9V03X 摄像头2 DMA 重置
// 参数说明 void
// 返回参数 void
// 使用示例 mt9v03x_dma_restart_1();
//-------------------------------------------------------------------------------------------------------------------
static void mt9v03x_dma_restart_2(void)
{
dma_disable(MT9V03X_2_DMA_CH);
exti_disable(MT9V03X_2_PCLK_PIN);
IfxDma_resetChannel(&MODULE_DMA, MT9V03X_2_DMA_CH);
dma_init_2(MT9V03X_2_DMA_CH,
MT9V03X_2_DATA_ADD,
mt9v03x_image_2[0],
MT9V03X_2_PCLK_PIN,
EXTI_TRIGGER_FALLING,
MT9V03X_2_IMAGE_SIZE);
dma_enable(MT9V03X_2_DMA_CH);
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 MT9V03X摄像头场中断
// 参数说明 void
// 返回参数 void
// 使用示例 mt9v03x_vsync_handler();
//-------------------------------------------------------------------------------------------------------------------
static void mt9v03x_vsync_handler_1(void)
{
Ifx_STM *module_num;
uint32 temp_time = 0;
static uint32 mt9v03x_fps_count = 0;
if(gpio_get_level(P33_7))
{
if(camera_work_type == mt9v03x_double && mt9v03x_dma_state[0] && gpio_get_level(P10_3) == 0)
{
mt9v03x_dma_state[0] = 0;
mt9v03x_dma_restart_2();
mt9v03x_gather_flag = 2;
}
else if(mt9v03x_gather_flag == 0)
{
mt9v03x_dma_restart_1();
mt9v03x_gather_flag = 1;
}
}
else
{
if(mt9v03x_gather_flag == 1)
{
// 采集完成
// 一副图像从采集开始到采集结束耗时与当前分辨率和帧率有关
dma_disable(MT9V03X_1_DMA_CH);
if(camera_work_type == mt9v03x_double)
{
if(gpio_get_level(P10_3))
{
mt9v03x_dma_state[0] = 1;
}
else
{
mt9v03x_dma_restart_2();
mt9v03x_gather_flag = 2;
}
}
else
{
mt9v03x_dma_restart_1();
}
module_num = IfxStm_getAddress((IfxStm_Index)(IfxCpu_getCoreId()));
if(mt9v03x_time[0] == 0)
{
mt9v03x_time[0] = IfxStm_getLower(module_num);
}
else
{
temp_time = (uint32)((uint64)(IfxStm_getLower(module_num) - mt9v03x_time[0]) * 1000 / IfxStm_getFrequency(module_num));
if(temp_time >= 1000)
{
mt9v03x_time[0] = IfxStm_getLower(module_num);
mt9v03x_fps[0] = mt9v03x_fps_count - 1;
mt9v03x_fps_count = 0;
}
}
mt9v03x_fps_count ++;
mt9v03x_finish_flag_1 = 1;
}
}
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 MT9V03X摄像头场中断
// 参数说明 void
// 返回参数 void
// 使用示例 mt9v03x_vsync_handler();
//-------------------------------------------------------------------------------------------------------------------
static void mt9v03x_vsync_handler_2(void)
{
Ifx_STM *module_num;
uint32 temp_time = 0;
static uint32 mt9v03x_fps_count = 0;
if(gpio_get_level(P10_3) == 1)
{
if(camera_work_type == mt9v03x_double && mt9v03x_dma_state[1] && gpio_get_level(P33_7) == 0)
{
mt9v03x_dma_state[1] = 0;
mt9v03x_dma_restart_1();
mt9v03x_gather_flag = 1;
}
else if(mt9v03x_gather_flag == 0)
{
mt9v03x_dma_restart_2();
mt9v03x_gather_flag = 2;
}
}
else
{
if(mt9v03x_gather_flag == 2)
{
// 采集完成
// 一副图像从采集开始到采集结束耗时与当前分辨率和帧率有关
dma_disable(MT9V03X_2_DMA_CH);
if(camera_work_type == mt9v03x_double)
{
if(gpio_get_level(P33_7))
{
mt9v03x_dma_state[1] = 1;
}
else
{
mt9v03x_dma_restart_1();
mt9v03x_gather_flag = 1;
}
}
else
{
mt9v03x_dma_restart_2();
}
module_num = IfxStm_getAddress((IfxStm_Index)(IfxCpu_getCoreId()));
if(mt9v03x_time[1] == 0)
{
mt9v03x_time[1] = IfxStm_getLower(module_num);
}
else
{
temp_time = (uint32)((uint64)(IfxStm_getLower(module_num) - mt9v03x_time[1]) * 1000 / IfxStm_getFrequency(module_num));
if(temp_time >= 1000)
{
mt9v03x_time[1] = IfxStm_getLower(module_num);
mt9v03x_fps[1] = mt9v03x_fps_count - 1;
mt9v03x_fps_count = 0;
}
}
mt9v03x_fps_count ++;
mt9v03x_finish_flag_2 = 1;
}
}
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 mt9v03x单独设置曝光时间
// 参数说明 init_type 选择要设置的摄像头
// 参数说明 light 曝光时间,没有单位,数越大图像越亮
// 返回参数 unsigned char 0:配置成功 1:配置失败
// 使用示例 mt9v03x_set_exposure_time_sccb(mt9v03x_1,100);
//-------------------------------------------------------------------------------------------------------------------
uint8 mt9v03x_set_exposure_time_sccb(m9v03x_double_init_type_enum init_type,unsigned short int light)
{
uint8 return_state = 0;
switch(init_type)
{
case mt9v03x_1:
{
mt9v03x_set_exposure_time_sccb_1(light);
return_state = 1;
}break;
case mt9v03x_2:
{
mt9v03x_set_exposure_time_sccb_2(light);
return_state = 1;
}break;
case mt9v03x_double:
{
mt9v03x_set_exposure_time_sccb_1(light);
mt9v03x_set_exposure_time_sccb_2(light);
return_state = 1;
}break;
default:break;
}
return return_state;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 MT9V03X 双摄像头初始化
// 参数说明 init_type 初始化方式
// 返回参数 uint8 1-失败 0-成功
// 使用示例 zf_log(mt9v03x_double_init(mt9v03x_1), "mt9v03x init error");
// 备注信息 注意:双摄版本不再兼容串口版本摄像头 修改摄像头初始化通讯类型详见摄像头资料说明
//-------------------------------------------------------------------------------------------------------------------
uint8 mt9v03x_double_init(m9v03x_double_init_type_enum init_type)
{
//-------------------该函数仅用于TC系列 V3.0 双摄主板 摄像头初始化----------------------
//-------------------该函数仅用于TC系列 V3.0 双摄主板 摄像头初始化----------------------
//-------------------该函数仅用于TC系列 V3.0 双摄主板 摄像头初始化----------------------
uint8 return_state = 0;
uint32 interrupt_state = interrupt_global_disable(); // 关闭全局中断
// cpu0_dsram 段不会被启动代码自动清零,必须手动初始化所有状态变量
mt9v03x_finish_flag_1 = 0;
mt9v03x_finish_flag_2 = 0;
mt9v03x_gather_flag = 0;
mt9v03x_dma_state[0] = 0;
mt9v03x_dma_state[1] = 0;
mt9v03x_time[0] = 0;
mt9v03x_time[1] = 0;
mt9v03x_fps[0] = 0;
mt9v03x_fps[1] = 0;
mt9v03x_link_list_num_1 = 0;
mt9v03x_link_list_num_2 = 0;
memset(mt9v03x_image_1, 0, sizeof(mt9v03x_image_1));
memset(mt9v03x_image_2, 0, sizeof(mt9v03x_image_2));
system_delay_ms(500);
camera_work_type = init_type;
switch(init_type)
{
case mt9v03x_1:
{
do
{
// 使用SCCB通讯
set_camera_type(CAMERA_GRAYSCALE_1, mt9v03x_vsync_handler_1, NULL, NULL);
soft_iic_init(&mt9v03x_iic_struct_1, 0, MT9V03X_1_COF_IIC_DELAY, MT9V03X_1_COF_IIC_SCL, MT9V03X_1_COF_IIC_SDA);
mt9v03x_sccb_check_id_1(&mt9v03x_iic_struct_1);
if(mt9v03x_set_config_sccb_1(&mt9v03x_iic_struct_1,mt9v03x_set_confing_buffer_1))
{
// SCCB通讯失败
zf_log(0, "MT9V03X 1 set sccb error.");
return_state = 1;
break;
}
mt9v03x_link_list_num_1 = camera_init(MT9V03X_1_DATA_ADD, mt9v03x_image_1[0], MT9V03X_1_IMAGE_SIZE);
IfxDma_disableChannelInterrupt(&MODULE_DMA, MT9V03X_1_DMA_CH);
}while(0);
}break;
case mt9v03x_2:
{
do
{
// 使用SCCB通讯
set_camera_type(CAMERA_GRAYSCALE_2, mt9v03x_vsync_handler_2, NULL, NULL);
soft_iic_init(&mt9v03x_iic_struct_2, 0, MT9V03X_2_COF_IIC_DELAY, MT9V03X_2_COF_IIC_SCL, MT9V03X_2_COF_IIC_SDA);
mt9v03x_sccb_check_id_2(&mt9v03x_iic_struct_2);
if(mt9v03x_set_config_sccb_2(&mt9v03x_iic_struct_2,mt9v03x_set_confing_buffer_1))
{
// SCCB通讯失败
zf_log(0, "MT9V03X 2 set sccb error.");
return_state = 1;
break;
}
mt9v03x_link_list_num_2 = camera_init(MT9V03X_2_DATA_ADD, mt9v03x_image_2[0], MT9V03X_2_IMAGE_SIZE);
IfxDma_disableChannelInterrupt(&MODULE_DMA, MT9V03X_2_DMA_CH);
}while(0);
}break;
case mt9v03x_double:
{
do
{
// 使用SCCB通讯
set_camera_type(CAMERA_GRAYSCALE_1, mt9v03x_vsync_handler_1, NULL, NULL);
soft_iic_init(&mt9v03x_iic_struct_1, 0, MT9V03X_1_COF_IIC_DELAY, MT9V03X_1_COF_IIC_SCL, MT9V03X_1_COF_IIC_SDA);
mt9v03x_sccb_check_id_1(&mt9v03x_iic_struct_1);
if(mt9v03x_set_config_sccb_1(&mt9v03x_iic_struct_1,mt9v03x_set_confing_buffer_1))
{
// SCCB通讯失败
zf_log(0, "MT9V03X 1 set sccb error.");
return_state = 1;
break;
}
mt9v03x_link_list_num_1 = camera_init(MT9V03X_1_DATA_ADD, mt9v03x_image_1[0], MT9V03X_1_IMAGE_SIZE);
IfxDma_disableChannelInterrupt(&MODULE_DMA, MT9V03X_1_DMA_CH);
system_delay_ms(MT9V03X_INIT_INTV_DELAY); //修改这个延时可以增加高帧率的运行时长
// 使用SCCB通讯
set_camera_type(CAMERA_GRAYSCALE_2, mt9v03x_vsync_handler_2, NULL, NULL);
soft_iic_init(&mt9v03x_iic_struct_2, 0, MT9V03X_2_COF_IIC_DELAY, MT9V03X_2_COF_IIC_SCL, MT9V03X_2_COF_IIC_SDA);
mt9v03x_sccb_check_id_2(&mt9v03x_iic_struct_2);
if(mt9v03x_set_config_sccb_2(&mt9v03x_iic_struct_2,mt9v03x_set_confing_buffer_1))
{
// SCCB通讯失败
zf_log(0, "MT9V03X 2 set sccb error.");
return_state = 1;
break;
}
mt9v03x_link_list_num_2 = camera_init(MT9V03X_2_DATA_ADD, mt9v03x_image_2[0], MT9V03X_2_IMAGE_SIZE);
IfxDma_disableChannelInterrupt(&MODULE_DMA, MT9V03X_2_DMA_CH);
}while(0);
}break;
default:break;
}
interrupt_global_enable(interrupt_state); // 打开全局中断
return return_state;
}
@@ -0,0 +1,185 @@
/*********************************************************************************************************************
* 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_mt9v03x_double
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 ADS v1.10.2
* 适用平台 TC264D
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2025-07-09 pudding first version
********************************************************************************************************************/
#ifndef _zf_device_mt9v03x_double_h_
#define _zf_device_mt9v03x_double_h_
#include "zf_common_typedef.h"
#include "zf_device_type.h"
//================================================定义 MT9V03X 双摄像头 基本配置================================================
#define MT9V03X_1_COF_IIC_DELAY (800) // 总钻风摄像头1 IIC 延时
#define MT9V03X_1_COF_IIC_SCL (P33_13) // 总钻风摄像头1 IIC-SCL 引脚
#define MT9V03X_1_COF_IIC_SDA (P32_4) // 总钻风摄像头1 IIC-SDA 引脚
#define MT9V03X_1_DMA_CH (IfxDma_ChannelId_7)
#define MT9V03X_1_PCLK_PIN (ERU_CH1_REQ10_P14_3) // 总钻风摄像头1 PCLK 触发信号 TIM_ETR 引脚禁止随意修改
#define MT9V03X_1_VSYNC_PIN (ERU_CH4_REQ8_P33_7) // 总钻风摄像头1 场中断引脚
#define MT9V03X_1_DATA_PIN (P00_0) // 总钻风摄像头1 数据引脚 这里是 只能是 GPIOx0 或者 GPIOx8 开始 连续八个引脚例如 P00_0-P00_7
#define MT9V03X_1_DATA_ADD (get_port_in_addr(MT9V03X_1_DATA_PIN))
#define MT9V03X_1_INIT_TIMEOUT (0x0080) // 总钻风摄像头1 默认的摄像头初始化超时时间 毫秒为单位
#define MT9V03X_2_COF_IIC_DELAY (800) // 总钻风摄像头2 IIC 延时
#define MT9V03X_2_COF_IIC_SCL (P13_1) // 总钻风摄像头2 IIC-SCL 引脚
#define MT9V03X_2_COF_IIC_SDA (P13_0) // 总钻风摄像头2 IIC-SDA 引脚
#define MT9V03X_2_DMA_CH (IfxDma_ChannelId_6)
#define MT9V03X_2_PCLK_PIN (ERU_CH2_REQ2_P10_2) // 总钻风摄像头2 PCLK 触发信号 TIM_ETR 引脚禁止随意修改
#define MT9V03X_2_VSYNC_PIN (ERU_CH3_REQ3_P10_3) // 总钻风摄像头2 场中断引脚
#define MT9V03X_2_DATA_PIN (P02_0) // 总钻风摄像头2 数据引脚 这里是 只能是 GPIOx0 或者 GPIOx8 开始 连续八个引脚例如 P00_0-P00_7
#define MT9V03X_2_DATA_ADD (get_port_in_addr(MT9V03X_2_DATA_PIN))
#define MT9V03X_2_INIT_TIMEOUT (0x0080) // 总钻风摄像头2 默认的摄像头初始化超时时间 毫秒为单位
#define MT9V03X_INIT_INTV_DELAY (0) //摄像头初始化间隔延时,调节这个延时可增加高帧率运行时长。范围0-3(单位MS)
//================================================定义 MT9V03X 双摄像头 基本配置================================================
//================================================定义 MT9V03X 双摄像头 参数配置================================================
#define MT9V03X_1_W (140) // 总钻风摄像头1 图像宽度 范围 [1-752]
#define MT9V03X_1_H (80) // 总钻风摄像头1 图像高度 范围 [1-480]
#define MT9V03X_1_IMAGE_SIZE (MT9V03X_1_W * MT9V03X_1_H) // 总钻风摄像头1 整体图像大小不能超过 65535
#define MT9V03X_1_AUTO_EXP_DEF ( 0 ) // 总钻风摄像头1 自动曝光设置 默认不开启自动曝光设置 范围 [0-63] 0为关闭
// 如果自动曝光开启 EXP_TIME命令设置自动曝光时间的上限
// 一般情况是不需要开启自动曝光设置 如果遇到光线非常不均匀的情况可以尝试设置自动曝光,增加图像稳定性
#define MT9V03X_1_EXP_TIME_DEF ( 250 ) // 总钻风摄像头1 曝光时间 摄像头收到后会自动计算出最大曝光时间,如果设置过大则设置为计算出来的最大曝光值
#define MT9V03X_1_FPS_DEF ( 50 ) // 总钻风摄像头1 图像帧率 摄像头收到后会自动计算出最大FPS,如果过大则设置为计算出来的最大FPS
#define MT9V03X_1_LR_OFFSET_DEF ( 0 ) // 总钻风摄像头1 图像左右偏移量 正值 右偏移 负值 左偏移 列为188 376 752时无法设置偏移
// 总钻风摄像头1 摄像头收偏移数据后会自动计算最大偏移,如果超出则设置计算出来的最大偏移
#define MT9V03X_1_UD_OFFSET_DEF ( 0 ) // 总钻风摄像头1 图像上下偏移量 正值 上偏移 负值 下偏移 行为120 240 480时无法设置偏移
// 摄像头收偏移数据后会自动计算最大偏移,如果超出则设置计算出来的最大偏移
#define MT9V03X_1_GAIN_DEF ( 15 ) // 总钻风摄像头1 图像增益 范围 [16-64] 增益可以在曝光时间固定的情况下改变图像亮暗程度
#define MT9V03X_1_PCLK_MODE_DEF ( 0 ) // 总钻风摄像头1 像素时钟模式 范围 [0-1] 默认:0 可选参数为:[0:不输出消隐信号,1:输出消隐信号]
// 通常都设置为0,如果使用CH32V307的DVP接口或STM32的DCMI接口采集需要设置为1
// 仅总钻风 MT9V034 V1.5 以及以上版本支持该命令
#define MT9V03X_2_W (140) // 总钻风摄像头2 图像宽度 范围 [1-752]
#define MT9V03X_2_H (80) // 总钻风摄像头2 图像高度 范围 [1-480]
#define MT9V03X_2_IMAGE_SIZE (MT9V03X_2_W * MT9V03X_2_H) // 总钻风摄像头2 整体图像大小不能超过 65535
#define MT9V03X_2_AUTO_EXP_DEF ( 0 ) // 总钻风摄像头2 自动曝光设置 默认不开启自动曝光设置 范围 [0-63] 0为关闭
// 如果自动曝光开启 EXP_TIME命令设置自动曝光时间的上限
// 一般情况是不需要开启自动曝光设置 如果遇到光线非常不均匀的情况可以尝试设置自动曝光,增加图像稳定性 光,增加图像稳定性
#define MT9V03X_2_EXP_TIME_DEF ( 512 ) // 总钻风摄像头2 曝光时间 摄像头收到后会自动计算出最大曝光时间,如果设置过大则设置为计算出来的最大曝光值
#define MT9V03X_2_FPS_DEF ( 50 ) // 总钻风摄像头2 图像帧率 摄像头收到后会自动计算出最大FPS,如果过大则设置为计算出来的最大FPS
#define MT9V03X_2_LR_OFFSET_DEF ( 0 ) // 总钻风摄像头2 图像左右偏移量 正值 右偏移 负值 左偏移 列为188 376 752时无法设置偏移
// 总钻风摄像头2 摄像头收偏移数据后会自动计算最大偏移,如果超出则设置计算出来的最大偏移
#define MT9V03X_2_UD_OFFSET_DEF ( 0 ) // 总钻风摄像头2 图像上下偏移量 正值 上偏移 负值 下偏移 行为120 240 480时无法设置偏移
// 摄像头收偏移数据后会自动计算最大偏移,如果超出则设置计算出来的最大偏移
#define MT9V03X_2_GAIN_DEF ( 32 ) // 总钻风摄像头2 图像增益 范围 [16-64] 增益可以在曝光时间固定的情况下改变图像亮暗程度
#define MT9V03X_2_PCLK_MODE_DEF ( 0 ) // 总钻风摄像头2 像素时钟模式 范围 [0-1] 默认:0 可选参数为:[0:不输出消隐信号,1:输出消隐信号]
// 通常都设置为0,如果使用CH32V307的DVP接口或STM32的DCMI接口采集需要设置为1
// 仅总钻风 MT9V034 V1.5 以及以上版本支持该命令
//================================================定义 MT9V03X 双摄像头 参数配置================================================
//================================================定义 MT9V03X 双摄像头 参数结构体===============================================
typedef enum
{
MT9V03X_DOUBLE_INIT = 0, // 摄像头初始化命令
MT9V03X_DOUBLE_AUTO_EXP, // 自动曝光命令
MT9V03X_DOUBLE_EXP_TIME, // 曝光时间命令
MT9V03X_DOUBLE_FPS, // 摄像头帧率命令
MT9V03X_DOUBLE_SET_COL, // 图像列命令
MT9V03X_DOUBLE_SET_ROW, // 图像行命令
MT9V03X_DOUBLE_LR_OFFSET, // 图像左右偏移命令
MT9V03X_DOUBLE_UD_OFFSET, // 图像上下偏移命令
MT9V03X_DOUBLE_GAIN, // 图像偏移命令
MT9V03X_DOUBLE_PCLK_MODE, // 像素时钟模式命令(仅总钻风MT9V034 V1.5以及以上版本支持该命令)
MT9V03X_DOUBLE_CONFIG_FINISH, // 非命令位,主要用来占位计数
MT9V03X_DOUBLE_COLOR_GET_WHO_AM_I = 0xEF,
MT9V03X_DOUBLE_SET_EXP_TIME = 0XF0, // 单独设置曝光时间命令
MT9V03X_DOUBLE_GET_STATUS, // 获取摄像头配置命令
MT9V03X_DOUBLE_GET_VERSION, // 固件版本号命令
MT9V03X_DOUBLE_SET_ADDR = 0XFE, // 寄存器地址命令
MT9V03X_DOUBLE_SET_DATA // 寄存器数据命令
}m9v03x_double_cmd_enum;
// 摄像头接口类型枚举
typedef enum
{
mt9v03x_1, // 仅初始化摄像头 1 将仅采集摄像头1
mt9v03x_2, // 仅初始化摄像头 2 将仅采集摄像头2
mt9v03x_double, // 双摄同时初始化 稳定模式 DMA 严格交替 采集两个摄像头
// 注意: DMA只有一个 采集时 若两个摄像头同时输出 将无法保持正常帧率采集双摄数据 整体帧率将除以2
// 注意: 由于摄像头个体差异 双摄像头输出将逐渐重合 较长时间工作时 将导致出现上述情况
// 注意: 双摄高帧率运行时可能重合导致实际帧率减半 可通过双摄初始化之间的延时来进行调节
}m9v03x_double_init_type_enum;
//================================================定义 MT9V03X 双摄像头 参数结构体===============================================
//================================================声明 MT9V03X 全局变量================================================
extern vuint8 mt9v03x_finish_flag_1; // 总钻风摄像头1 单幅图像采集完成标志位
extern vuint8 mt9v03x_finish_flag_2; // 总钻风摄像头2 单幅图像采集完成标志位
extern uint8 mt9v03x_image_1[MT9V03X_1_H][MT9V03X_1_W]; // 总钻风摄像头1 图像数据存储数组
extern uint8 mt9v03x_image_2[MT9V03X_2_H][MT9V03X_2_W]; // 总钻风摄像头2 图像数据存储数组
extern uint32 mt9v03x_fps[2]; // 总钻风摄像头实际采集帧率
extern int16 mt9v03x_set_confing_buffer_1[MT9V03X_DOUBLE_CONFIG_FINISH][2];
extern int16 mt9v03x_set_confing_buffer_2[MT9V03X_DOUBLE_CONFIG_FINISH][2];
//================================================声明 MT9V03X 全局变量================================================
//================================================声明 MT9V03X 基础函数================================================
//-------------------该函数仅用于TC系列 V3.0 双摄主板 摄像头初始化----------------------
//-------------------该函数仅用于TC系列 V3.0 双摄主板 摄像头初始化----------------------
//-------------------该函数仅用于TC系列 V3.0 双摄主板 摄像头初始化----------------------
uint8 mt9v03x_double_init(m9v03x_double_init_type_enum init_mode); // MT9V03X 摄像头初始化
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 mt9v03x单独设置曝光时间
// 参数说明 init_type 选择要设置的摄像头
// 参数说明 light 曝光时间,没有单位,数越大图像越亮
// 返回参数 unsigned char 0:配置成功 1:配置失败
// 使用示例 mt9v03x_set_exposure_time_sccb(mt9v03x_1,100);
//-------------------------------------------------------------------------------------------------------------------
uint8 mt9v03x_set_exposure_time_sccb(m9v03x_double_init_type_enum init_type,unsigned short int light);
//================================================声明 MT9V03X 基础函数================================================
#endif
+764
View File
@@ -0,0 +1,764 @@
/*********************************************************************************************************************
* 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_soft_spi.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 (0 ) // 软件 SPI 的时钟延时周期 数值越小 SPI 通信速率越快
#define OLED_D0_PIN (P15_3) // 软件 SPI SCK 引脚
#define OLED_D1_PIN (P15_5) // 软件 SPI MOSI 引脚
//====================================================软件 SPI 驱动====================================================
#else
//====================================================硬件 SPI 驱动====================================================
#define OLED_SPI_SPEED (30*1000*1000) // 硬件 SPI 速率
#define OLED_SPI (SPI_2) // 硬件 SPI 号
#define OLED_D0_PIN (SPI2_SCLK_P15_3 ) // 硬件 SPI SCK 引脚
#define OLED_D1_PIN (SPI2_MOSI_P15_5) // 硬件 SPI MOSI 引脚
#define OLED_D1_PIN_IN (SPI2_MISO_P15_4) // 硬件 SPI MISO 引脚 OLED没有MISO引脚,但是这里任然需要定义,在spi的初始化时需要使用
//====================================================硬件 SPI 驱动====================================================
#endif
#define OLED_RES_PIN (P15_1) // 液晶复位引脚定义
#define OLED_DC_PIN (P15_0 ) // 液晶命令位引脚定义
#define OLED_CS_PIN (P15_2 ) // 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_1_W, MT9V03X_1_H, 128, 64, (x)))
//===================================================定义 OLED 扩展配置=================================================
#endif
+551
View File
@@ -0,0 +1,551 @@
/*********************************************************************************************************************
* 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_ov7725
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 ADS v1.10.2
* 适用平台 TC264D
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2022-09-15 pudding first version
********************************************************************************************************************/
/*********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* TXD/SCL 查看 zf_device_ov7725.h 中 OV7725_COF_UART_TX 或 OV7725_COF_IIC_SCL 宏定义
* RXD/SDA 查看 zf_device_ov7725.h 中 OV7725_COF_UART_RX 或 OV7725_COF_IIC_SDA 宏定义
* PCLK 查看 zf_device_ov7725.h 中 OV7725_PCLK_PIN 宏定义
* VSY 查看 zf_device_ov7725.h 中 OV7725_VSYNC_PIN 宏定义
* D0-D7 查看 zf_device_ov7725.h 中 OV7725_DATA_PIN 宏定义 从该定义开始的连续八个引脚
* VCC 3.3V电源
* GND 电源地
* 其余引脚悬空
* ------------------------------------
********************************************************************************************************************/
#include "zf_common_interrupt.h"
#include "zf_common_debug.h"
#include "zf_common_fifo.h"
#include "zf_driver_delay.h"
#include "zf_driver_dma.h"
#include "zf_driver_exti.h"
#include "zf_driver_gpio.h"
#include "zf_driver_soft_iic.h"
#include "zf_driver_uart.h"
#include "zf_device_camera.h"
#include "zf_device_type.h"
#include "isr_config.h"
#include "zf_device_ov7725.h"
vuint8 ov7725_finish_flag = 0;
uint8 ov7725_image_binary [OV7725_H][OV7725_W / 8]; // 图像保存数组
uint8 ov7725_uart_dma_init_flag; // 重新初始化DMA的标志位
uint8 ov7725_dma_int_num = 0;
uint8 ov7725_lost_flag = 1;
uint8 ov7725_link_list_num = 0;
// 需要配置到摄像头的数据 不允许在这修改参数
static uint16 ov7725_set_confing_buffer [OV7725_CONFIG_FINISH][2]=
{
{OV7725_INIT, 0}, // 初始化命令
{OV7725_RESERVE, 0}, // 保留
{OV7725_CONTRAST, OV7725_CONTRAST_DEF}, // 阈值设置
{OV7725_FPS, OV7725_FPS_DEF}, // 帧率
{OV7725_COL, OV7725_W}, // 图像宽度
{OV7725_ROW, OV7725_H} // 图像高度
};
// 从摄像头内部获取到的配置数据 不允许在这修改参数
static uint16 ov7725_get_confing_buffer [OV7725_CONFIG_FINISH - 1][2]=
{
{OV7725_RESERVE, 0}, // 保留
{OV7725_CONTRAST, 0}, // 阈值设置
{OV7725_FPS, 0}, // 帧率
{OV7725_COL, 0}, // 图像宽度
{OV7725_ROW, 0} // 图像高度
};
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 配置摄像头内部配置信息
// 参数说明 buff 发送配置信息的地址
// 返回参数 uint8 1-失败 0-成功
// 使用示例 if(ov7725_set_config(ov7725_set_confing_buffer)){}
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
static uint8 ov7725_set_config (uint16 buff[OV7725_CONFIG_FINISH][2])
{
uint8 return_state = 1;
uint8 uart_buffer[4];
uint16 temp = 0;
uint16 timeout_count = 0;
uint32 loop_count = 0;
uint32 uart_buffer_index = 0;
for(loop_count = OV7725_ROW; OV7725_SET_DATA > loop_count; loop_count --)
{
uart_buffer[0] = 0xA5;
uart_buffer[1] = (uint8)buff[loop_count][0];
temp = buff[loop_count][1];
uart_buffer[2] = temp >> 8;
uart_buffer[3] = (uint8)temp;
uart_write_buffer(OV7725_COF_UART, uart_buffer, 4);
system_delay_ms(10);
}
do
{
if(3 <= fifo_used(&camera_receiver_fifo))
{
uart_buffer_index = 3;
fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN);
if((0xff == uart_buffer[1]) || (0xff == uart_buffer[2]))
{
return_state = 0;
break;
}
}
system_delay_ms(1);
}while(OV7725_INIT_TIMEOUT > timeout_count ++);
// 以上部分对摄像头配置的数据全部都会保存在摄像头上51单片机的eeprom中
// 利用set_exposure_time函数单独配置的曝光数据不存储在eeprom中
return return_state;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 获取摄像头内部配置信息
// 参数说明 buff 接收配置信息的地址
// 返回参数 uint8 1-失败 0-成功
// 使用示例 if(ov7725_get_config(ov7725_get_confing_buffer)){}
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
static uint8 ov7725_get_config (uint16 buff[OV7725_CONFIG_FINISH - 1][2])
{
uint8 return_state = 0;
uint8 uart_buffer[4];
uint16 temp = 0;
uint16 timeout_count = 0;
uint32 loop_count = 0;
uint32 uart_buffer_index = 0;
for(loop_count = OV7725_ROW - 1; 1 <= loop_count; loop_count --)
{
uart_buffer[0] = 0xA5;
uart_buffer[1] = OV7725_GET_STATUS;
temp = buff[loop_count][0];
uart_buffer[2] = temp >> 8;
uart_buffer[3] = (uint8)temp;
uart_write_buffer(OV7725_COF_UART, uart_buffer, 4);
system_delay_ms(10);
timeout_count = 0;
do
{
if(3 <= fifo_used(&camera_receiver_fifo))
{
uart_buffer_index = 3;
fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN);
buff[loop_count][1] = uart_buffer[1] << 8 | uart_buffer[2];
break;
}
system_delay_ms(1);
}while(OV7725_INIT_TIMEOUT > timeout_count ++);
if(OV7725_INIT_TIMEOUT < timeout_count) // 超时
{
return_state = 1;
break;
}
}
return return_state;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 小钻风摄像头内部寄存器初始化
// 参数说明 void
// 返回参数 uint8 1-失败 0-成功
// 使用示例 if(ov7725_iic_init()){}
// 备注信息 内部使用 用户无需调用
//-------------------------------------------------------------------------------------------------------------------
static uint8 ov7725_iic_init (void)
{
soft_iic_info_struct ov7725_iic_struct;
uint8 ov7725_idcode = 0;
uint8 return_state = 0;
uart_rx_interrupt(OV7725_COF_UART, 0);
soft_iic_init(&ov7725_iic_struct, OV7725_DEV_ADD, OV7725_COF_IIC_DELAY, OV7725_COF_IIC_SCL, OV7725_COF_IIC_SDA);
soft_iic_sccb_write_register(&ov7725_iic_struct, OV7725_COM7, 0x80); // 复位摄像头
system_delay_ms(50);
do
{
ov7725_idcode = soft_iic_sccb_read_register(&ov7725_iic_struct, OV7725_VER);
if(OV7725_ID != ov7725_idcode)
{
return_state = 1; // 校验摄像头ID号
break;
}
// ID号确认无误 然后配置寄存器
soft_iic_sccb_write_register(&ov7725_iic_struct, OV7725_COM4 , 0xC1);
soft_iic_sccb_write_register(&ov7725_iic_struct, OV7725_CLKRC , 0x01);
soft_iic_sccb_write_register(&ov7725_iic_struct, OV7725_COM2 , 0x03);
soft_iic_sccb_write_register(&ov7725_iic_struct, OV7725_COM3 , 0xD0);
soft_iic_sccb_write_register(&ov7725_iic_struct, OV7725_COM7 , 0x40);
soft_iic_sccb_write_register(&ov7725_iic_struct, OV7725_COM8 , 0xCE); // 0xCE:关闭自动曝光 0xCF:开启自动曝光
soft_iic_sccb_write_register(&ov7725_iic_struct, OV7725_HSTART , 0x3F);
soft_iic_sccb_write_register(&ov7725_iic_struct, OV7725_HSIZE , 0x50);
soft_iic_sccb_write_register(&ov7725_iic_struct, OV7725_VSTRT , 0x03);
soft_iic_sccb_write_register(&ov7725_iic_struct, OV7725_VSIZE , 0x78);
soft_iic_sccb_write_register(&ov7725_iic_struct, OV7725_HREF , 0x00);
soft_iic_sccb_write_register(&ov7725_iic_struct, OV7725_SCAL0 , 0x0A);
soft_iic_sccb_write_register(&ov7725_iic_struct, OV7725_AWB_Ctrl0 , 0xE0);
soft_iic_sccb_write_register(&ov7725_iic_struct, OV7725_DSPAuto , 0xff);
soft_iic_sccb_write_register(&ov7725_iic_struct, OV7725_DSP_Ctrl2 , 0x0C);
soft_iic_sccb_write_register(&ov7725_iic_struct, OV7725_DSP_Ctrl3 , 0x00);
soft_iic_sccb_write_register(&ov7725_iic_struct, OV7725_DSP_Ctrl4 , 0x00);
if(OV7725_W == 80)
{
soft_iic_sccb_write_register(&ov7725_iic_struct, OV7725_HOutSize, 0x14);
}
else if(OV7725_W == 160)
{
soft_iic_sccb_write_register(&ov7725_iic_struct, OV7725_HOutSize, 0x28);
}
else if(OV7725_W == 240)
{
soft_iic_sccb_write_register(&ov7725_iic_struct, OV7725_HOutSize, 0x3c);
}
else if(OV7725_W == 320)
{
soft_iic_sccb_write_register(&ov7725_iic_struct, OV7725_HOutSize, 0x50);
}
if(OV7725_H == 60)
{
soft_iic_sccb_write_register(&ov7725_iic_struct, OV7725_VOutSize, 0x1E);
}
else if(OV7725_H == 120)
{
soft_iic_sccb_write_register(&ov7725_iic_struct, OV7725_VOutSize, 0x3c);
}
else if(OV7725_H == 180)
{
soft_iic_sccb_write_register(&ov7725_iic_struct, OV7725_VOutSize, 0x5a);
}
else if(OV7725_H == 240)
{
soft_iic_sccb_write_register(&ov7725_iic_struct, OV7725_VOutSize, 0x78);
}
soft_iic_sccb_write_register(&ov7725_iic_struct, OV7725_REG28 , 0x01);
soft_iic_sccb_write_register(&ov7725_iic_struct, OV7725_EXHCH , 0x10);
soft_iic_sccb_write_register(&ov7725_iic_struct, OV7725_EXHCL , 0x1F);
soft_iic_sccb_write_register(&ov7725_iic_struct, OV7725_GAM1 , 0x0c);
soft_iic_sccb_write_register(&ov7725_iic_struct, OV7725_GAM2 , 0x16);
soft_iic_sccb_write_register(&ov7725_iic_struct, OV7725_GAM3 , 0x2a);
soft_iic_sccb_write_register(&ov7725_iic_struct, OV7725_GAM4 , 0x4e);
soft_iic_sccb_write_register(&ov7725_iic_struct, OV7725_GAM5 , 0x61);
soft_iic_sccb_write_register(&ov7725_iic_struct, OV7725_GAM6 , 0x6f);
soft_iic_sccb_write_register(&ov7725_iic_struct, OV7725_GAM7 , 0x7b);
soft_iic_sccb_write_register(&ov7725_iic_struct, OV7725_GAM8 , 0x86);
soft_iic_sccb_write_register(&ov7725_iic_struct, OV7725_GAM9 , 0x8e);
soft_iic_sccb_write_register(&ov7725_iic_struct, OV7725_GAM10 , 0x97);
soft_iic_sccb_write_register(&ov7725_iic_struct, OV7725_GAM11 , 0xa4);
soft_iic_sccb_write_register(&ov7725_iic_struct, OV7725_GAM12 , 0xaf);
soft_iic_sccb_write_register(&ov7725_iic_struct, OV7725_GAM13 , 0xc5);
soft_iic_sccb_write_register(&ov7725_iic_struct, OV7725_GAM14 , 0xd7);
soft_iic_sccb_write_register(&ov7725_iic_struct, OV7725_GAM15 , 0xe8);
soft_iic_sccb_write_register(&ov7725_iic_struct, OV7725_SLOP , 0x20);
soft_iic_sccb_write_register(&ov7725_iic_struct, OV7725_LC_RADI , 0x00);
soft_iic_sccb_write_register(&ov7725_iic_struct, OV7725_LC_COEF , 0x13);
soft_iic_sccb_write_register(&ov7725_iic_struct, OV7725_LC_XC , 0x08);
soft_iic_sccb_write_register(&ov7725_iic_struct, OV7725_LC_COEFB , 0x14);
soft_iic_sccb_write_register(&ov7725_iic_struct, OV7725_LC_COEFR , 0x17);
soft_iic_sccb_write_register(&ov7725_iic_struct, OV7725_LC_CTR , 0x05);
soft_iic_sccb_write_register(&ov7725_iic_struct, OV7725_BDBase , 0x99);
soft_iic_sccb_write_register(&ov7725_iic_struct, OV7725_BDMStep , 0x03);
soft_iic_sccb_write_register(&ov7725_iic_struct, OV7725_SDE , 0x04);
soft_iic_sccb_write_register(&ov7725_iic_struct, OV7725_BRIGHT , 0x00);
soft_iic_sccb_write_register(&ov7725_iic_struct, OV7725_CNST , 0x40);
soft_iic_sccb_write_register(&ov7725_iic_struct, OV7725_SIGN , 0x06);
soft_iic_sccb_write_register(&ov7725_iic_struct, OV7725_UVADJ0 , 0x11);
soft_iic_sccb_write_register(&ov7725_iic_struct, OV7725_UVADJ1 , 0x02);
}while(0);
return return_state;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 小钻风摄像头串口通信回调
// 参数说明 void
// 返回参数 void
// 使用示例 ov7725_uart_callback();
//-------------------------------------------------------------------------------------------------------------------
static void ov7725_uart_handler (void)
{
uint8 data = 0;
uart_query_byte(OV7725_COF_UART, &data);
if(0xA5 == data)
{
fifo_clear(&camera_receiver_fifo);
}
fifo_write_element(&camera_receiver_fifo, data);
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 小钻风摄像头场中断
// 参数说明 void
// 返回参数 void
// 使用示例 ov7725_vsync_handler();
//-------------------------------------------------------------------------------------------------------------------
static void ov7725_vsync_handler(void)
{
exti_flag_clear(OV7725_VSYNC_PIN);
ov7725_dma_int_num = 0;
if((ov7725_uart_dma_init_flag || ov7725_lost_flag) && camera_type == CAMERA_BIN_UART)
{
ov7725_uart_dma_init_flag = 0;
IfxDma_resetChannel(&MODULE_DMA, OV7725_DMA_CH);
ov7725_link_list_num = dma_init(OV7725_DMA_CH,
OV7725_DATA_ADD,
ov7725_image_binary[0],
OV7725_PCLK_PIN,
EXTI_TRIGGER_RISING,
OV7725_IMAGE_SIZE);
dma_enable(OV7725_DMA_CH);
}
else
{
if(ov7725_link_list_num == 1)
{
dma_set_destination(OV7725_DMA_CH, ov7725_image_binary[0]);
}
dma_enable(OV7725_DMA_CH);
}
ov7725_lost_flag = 1;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 小钻风摄像头DMA完成中断
// 参数说明 void
// 返回参数 void
// 使用示例 ov7725_dma_handler();
//-------------------------------------------------------------------------------------------------------------------
static void ov7725_dma_handler(void)
{
clear_dma_flag(OV7725_DMA_CH);
if(IfxDma_getChannelTransactionRequestLost(&MODULE_DMA, OV7725_DMA_CH))
{//图像有错位
ov7725_finish_flag = 0;
dma_disable(OV7725_DMA_CH);
IfxDma_clearChannelTransactionRequestLost(&MODULE_DMA, OV7725_DMA_CH);
ov7725_uart_dma_init_flag = 1;
}
else
{
ov7725_dma_int_num++;
if(ov7725_dma_int_num >= ov7725_link_list_num)
{
ov7725_dma_int_num = 0;
ov7725_lost_flag = 0;
ov7725_finish_flag = 1;
dma_disable(OV7725_DMA_CH);
}
}
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 获取摄像头固件 ID
// 参数说明 void
// 返回参数 void
// 使用示例 ov7725_uart_get_id(); // 调用该函数前请先初始化串口
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
uint16 ov7725_uart_get_id (void)
{
uint16 temp = 0;
uint8 uart_buffer[4];
uint16 timeout_count = 0;
uint16 return_value = 0;
uint32 uart_buffer_index = 0;
uart_buffer[0] = 0xA5;
uart_buffer[1] = OV7725_GET_WHO_AM_I;
temp = 0;
uart_buffer[2] = temp >> 8;
uart_buffer[3] = (uint8)temp;
uart_write_buffer(OV7725_COF_UART, uart_buffer, 4);
temp = 0;
do
{
if(3 <= fifo_used(&camera_receiver_fifo))
{
uart_buffer_index = 3;
fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN);
return_value = uart_buffer[1] << 8 | uart_buffer[2];
break;
}
system_delay_ms(1);
}while(OV7725_INIT_TIMEOUT > timeout_count ++);
return return_value;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 获取摄像头固件版本
// 参数说明 void
// 返回参数 void
// 使用示例 ov7725_get_version(); // 调用该函数前请先初始化串口
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
uint16 ov7725_get_version (void)
{
uint16 temp = 0;
uint8 uart_buffer[4];
uint16 timeout_count = 0;
uint16 return_value = 0;
uint32 uart_buffer_index = 0;
uart_buffer[0] = 0xA5;
uart_buffer[1] = OV7725_GET_STATUS;
temp = OV7725_GET_VERSION;
uart_buffer[2] = temp >> 8;
uart_buffer[3] = (uint8)temp;
uart_write_buffer(OV7725_COF_UART, uart_buffer, 4);
do
{
if(3 <= fifo_used(&camera_receiver_fifo))
{
uart_buffer_index = 3;
fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN);
return_value = uart_buffer[1] << 8 | uart_buffer[2];
break;
}
system_delay_ms(1);
}while(OV7725_INIT_TIMEOUT > timeout_count ++);
return return_value;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 OV7725 摄像头初始化
// 参数说明 NULL
// 返回参数 void
// 使用示例 ov7725_init();
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
uint8 ov7725_init (void)
{
uint16 out_time = 0;
uint8 return_state = 0;
gpio_init(OV7725_VSYNC_PORT_PIN, GPI, GPIO_LOW, GPI_FLOATING_IN);
do
{
while(0 == gpio_get_level(OV7725_VSYNC_PORT_PIN))
{
system_delay_ms(1);
out_time ++;
if(OV7725_INIT_TIMEOUT < out_time)
{
// 如果程序在输出了断言信息 并且提示出错位置在这里
// 那大概率没有正确连接小钻风摄像头
// 检查一下接线和供电有没有问题 如果没问题可能就是坏了
zf_log(0, "OV7725 check error.");
return_state = 1;
break;
}
}
set_camera_type(CAMERA_BIN_UART, ov7725_vsync_handler, ov7725_dma_handler, ov7725_uart_handler);
camera_fifo_init();
uart_init(OV7725_COF_UART, OV7725_COF_BAUR, OV7725_COF_UART_RX, OV7725_COF_UART_TX);
uart_rx_interrupt(OV7725_COF_UART, 1);
system_delay_ms(200);
// 获取所有参数
if(ov7725_get_config(ov7725_get_confing_buffer))
{
uart_rx_interrupt(OV7725_COF_UART, 0);
system_delay_ms(200);
set_camera_type(CAMERA_BIN_IIC, ov7725_vsync_handler, ov7725_dma_handler, NULL); // 设置连接摄像头类型
if(ov7725_iic_init())
{
zf_log(0, "OV7725 IIC error.");
set_camera_type(NO_CAMERE, NULL, NULL, NULL);
return_state = 1;
zf_log(0, "ov7725 set config error.");
break;
}
}
else
{
// 设置所有参数
if(ov7725_set_config(ov7725_set_confing_buffer))
{
// 如果程序在输出了断言信息 并且提示出错位置在这里
// 那么就是串口通信出错并超时退出了
// 检查一下接线有没有问题 如果没问题可能就是坏了
zf_log(0, "OV7725 set confing error.");
uart_rx_interrupt(OV7725_COF_UART, 0);
set_camera_type(NO_CAMERE, NULL, NULL, NULL);
return_state = 1;
break;
}
// 获取所有参数
if(ov7725_get_config(ov7725_get_confing_buffer))
{
// 如果程序在输出了断言信息 并且提示出错位置在这里
// 那么就是串口通信出错并超时退出了
// 检查一下接线有没有问题 如果没问题可能就是坏了
zf_log(0, "OV7725 get confing error.");
uart_rx_interrupt(OV7725_COF_UART, 0);
set_camera_type(NO_CAMERE, NULL, NULL, NULL);
return_state = 1;
break;
}
}
ov7725_link_list_num = camera_init(OV7725_DATA_ADD, ov7725_image_binary[0], OV7725_IMAGE_SIZE);
}while(0);
return return_state;
}
+278
View File
@@ -0,0 +1,278 @@
/*********************************************************************************************************************
* 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_ov7725
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 ADS v1.10.2
* 适用平台 TC264D
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2022-09-15 pudding first version
* 2023-04-28 pudding 增加中文注释说明
********************************************************************************************************************/
/*********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* TXD/SCL 查看 zf_device_ov7725.h 中 OV7725_COF_UART_TX 或 OV7725_COF_IIC_SCL 宏定义
* RXD/SDA 查看 zf_device_ov7725.h 中 OV7725_COF_UART_RX 或 OV7725_COF_IIC_SDA 宏定义
* PCLK 查看 zf_device_ov7725.h 中 OV7725_PCLK_PIN 宏定义
* VSY 查看 zf_device_ov7725.h 中 OV7725_VSYNC_PIN 宏定义
* D0-D7 查看 zf_device_ov7725.h 中 OV7725_DATA_PIN 宏定义 从该定义开始的连续八个引脚
* VCC 3.3V电源
* GND 电源地
* 其余引脚悬空
* ------------------------------------
********************************************************************************************************************/
#ifndef _zf_device_ov7725_h_
#define _zf_device_ov7725_h_
#include "zf_device_type.h"
//================================================定义 OV7725 基本配置================================================
#define OV7725_COF_UART (UART_1) // 小钻风配置串口
#define OV7725_COF_BAUR (9600) // 小钻风配置串口波特率
#define OV7725_COF_UART_TX (UART1_RX_P02_3) // 小钻风 UART-TX 引脚 要接在单片机 RX 上
#define OV7725_COF_UART_RX (UART1_TX_P02_2) // 小钻风 UART-RX 引脚 要接在单片机 TX 上
#define OV7725_COF_IIC_DELAY (640 ) // 小钻风 IIC 延时
#define OV7725_COF_IIC_SCL (P33_13) // 小钻风 IIC-SCL 引脚
#define OV7725_COF_IIC_SDA (P32_4) // 小钻风 IIC-SDA 引脚
#define OV7725_DMA_CH (IfxDma_ChannelId_7) // ERU触发DMA通道禁止随意修改
#define OV7725_PCLK_PIN (ERU_CH1_REQ10_P14_3) // GPIO触发TIM引脚禁止随意修改
#define OV7725_VSYNC_PIN (ERU_CH4_REQ8_P33_7 ) // 场中断引脚
#define OV7725_VSYNC_PORT_PIN (P33_7 ) // 场中断引脚
#define OV7725_DATA_PIN (P00_0 ) // 数据引脚 这里是 只能是 GPIOx0 或者 GPIOx8 开始 连续八个引脚例如 F0-F7
#define OV7725_DATA_ADD get_port_in_addr(OV7725_DATA_PIN)
#define OV7725_INIT_TIMEOUT (0x0080) // 默认的摄像头初始化超时时间 毫秒为单位
//================================================定义 OV7725 基本配置================================================
//================================================定义 OV7725 参数配置================================================
#define OV7725_W (160) // 图像宽度 80/160/240/320
#define OV7725_H (120) // 图像高度 60/120/180/240
#define OV7725_IMAGE_SIZE (OV7725_W * OV7725_H / 8) // 整体图像大小 OV7725_IMAGE_SIZE 不能超过 65535
#define OV7725_CONTRAST_DEF (0x30) // 阈值设置 摄像头二值化阈值 过大和过小的数值会被摄像头自动修正
#define OV7725_FPS_DEF (50 ) // 帧率设置 最高 150 帧 但最小分辨率才能达到最高帧率
//================================================定义 OV7725 参数配置================================================
//==============================================定义 OV7725 IIC 内部地址==============================================
#define OV7725_ID (0x21) // 摄像头ID号
#define OV7725_GAIN (0x00) // 以下为摄像头寄存器
#define OV7725_BLUE (0x01)
#define OV7725_RED (0x02)
#define OV7725_GREEN (0x03)
#define OV7725_BAVG (0x05)
#define OV7725_GAVG (0x06)
#define OV7725_RAVG (0x07)
#define OV7725_AECH (0x08)
#define OV7725_COM2 (0x09)
#define OV7725_PID (0x0A)
#define OV7725_VER (0x0B)
#define OV7725_COM3 (0x0C)
#define OV7725_COM4 (0x0D)
#define OV7725_COM5 (0x0E)
#define OV7725_COM6 (0x0F)
#define OV7725_AEC (0x10)
#define OV7725_CLKRC (0x11)
#define OV7725_COM7 (0x12)
#define OV7725_COM8 (0x13)
#define OV7725_COM9 (0x14)
#define OV7725_COM10 (0x15)
#define OV7725_REG16 (0x16)
#define OV7725_HSTART (0x17)
#define OV7725_HSIZE (0x18)
#define OV7725_VSTRT (0x19)
#define OV7725_VSIZE (0x1A)
#define OV7725_PSHFT (0x1B)
#define OV7725_MIDH (0x1C)
#define OV7725_MIDL (0x1D)
#define OV7725_LAEC (0x1F)
#define OV7725_COM11 (0x20)
#define OV7725_BDBase (0x22)
#define OV7725_BDMStep (0x23)
#define OV7725_AEW (0x24)
#define OV7725_AEB (0x25)
#define OV7725_VPT (0x26)
#define OV7725_REG28 (0x28)
#define OV7725_HOutSize (0x29)
#define OV7725_EXHCH (0x2A)
#define OV7725_EXHCL (0x2B)
#define OV7725_VOutSize (0x2C)
#define OV7725_ADVFL (0x2D)
#define OV7725_ADVFH (0x2E)
#define OV7725_YAVE (0x2F)
#define OV7725_LumHTh (0x30)
#define OV7725_LumLTh (0x31)
#define OV7725_HREF (0x32)
#define OV7725_DM_LNL (0x33)
#define OV7725_DM_LNH (0x34)
#define OV7725_ADoff_B (0x35)
#define OV7725_ADoff_R (0x36)
#define OV7725_ADoff_Gb (0x37)
#define OV7725_ADoff_Gr (0x38)
#define OV7725_Off_B (0x39)
#define OV7725_Off_R (0x3A)
#define OV7725_Off_Gb (0x3B)
#define OV7725_Off_Gr (0x3C)
#define OV7725_COM12 (0x3D)
#define OV7725_COM13 (0x3E)
#define OV7725_COM14 (0x3F)
#define OV7725_COM16 (0x41)
#define OV7725_TGT_B (0x42)
#define OV7725_TGT_R (0x43)
#define OV7725_TGT_Gb (0x44)
#define OV7725_TGT_Gr (0x45)
#define OV7725_LC_CTR (0x46)
#define OV7725_LC_XC (0x47)
#define OV7725_LC_YC (0x48)
#define OV7725_LC_COEF (0x49)
#define OV7725_LC_RADI (0x4A)
#define OV7725_LC_COEFB (0x4B)
#define OV7725_LC_COEFR (0x4C)
#define OV7725_FixGain (0x4D)
#define OV7725_AREF1 (0x4F)
#define OV7725_AREF6 (0x54)
#define OV7725_UFix (0x60)
#define OV7725_VFix (0x61)
#define OV7725_AWBb_blk (0x62)
#define OV7725_AWB_Ctrl0 (0x63)
#define OV7725_DSP_Ctrl1 (0x64)
#define OV7725_DSP_Ctrl2 (0x65)
#define OV7725_DSP_Ctrl3 (0x66)
#define OV7725_DSP_Ctrl4 (0x67)
#define OV7725_AWB_bias (0x68)
#define OV7725_AWBCtrl1 (0x69)
#define OV7725_AWBCtrl2 (0x6A)
#define OV7725_AWBCtrl3 (0x6B)
#define OV7725_AWBCtrl4 (0x6C)
#define OV7725_AWBCtrl5 (0x6D)
#define OV7725_AWBCtrl6 (0x6E)
#define OV7725_AWBCtrl7 (0x6F)
#define OV7725_AWBCtrl8 (0x70)
#define OV7725_AWBCtrl9 (0x71)
#define OV7725_AWBCtrl10 (0x72)
#define OV7725_AWBCtrl11 (0x73)
#define OV7725_AWBCtrl12 (0x74)
#define OV7725_AWBCtrl13 (0x75)
#define OV7725_AWBCtrl14 (0x76)
#define OV7725_AWBCtrl15 (0x77)
#define OV7725_AWBCtrl16 (0x78)
#define OV7725_AWBCtrl17 (0x79)
#define OV7725_AWBCtrl18 (0x7A)
#define OV7725_AWBCtrl19 (0x7B)
#define OV7725_AWBCtrl20 (0x7C)
#define OV7725_AWBCtrl21 (0x7D)
#define OV7725_GAM1 (0x7E)
#define OV7725_GAM2 (0x7F)
#define OV7725_GAM3 (0x80)
#define OV7725_GAM4 (0x81)
#define OV7725_GAM5 (0x82)
#define OV7725_GAM6 (0x83)
#define OV7725_GAM7 (0x84)
#define OV7725_GAM8 (0x85)
#define OV7725_GAM9 (0x86)
#define OV7725_GAM10 (0x87)
#define OV7725_GAM11 (0x88)
#define OV7725_GAM12 (0x89)
#define OV7725_GAM13 (0x8A)
#define OV7725_GAM14 (0x8B)
#define OV7725_GAM15 (0x8C)
#define OV7725_SLOP (0x8D)
#define OV7725_DNSTh (0x8E)
#define OV7725_EDGE0 (0x8F)
#define OV7725_EDGE1 (0x90)
#define OV7725_DNSOff (0x91)
#define OV7725_EDGE2 (0x92)
#define OV7725_EDGE3 (0x93)
#define OV7725_MTX1 (0x94)
#define OV7725_MTX2 (0x95)
#define OV7725_MTX3 (0x96)
#define OV7725_MTX4 (0x97)
#define OV7725_MTX5 (0x98)
#define OV7725_MTX6 (0x99)
#define OV7725_MTX_Ctrl (0x9A)
#define OV7725_BRIGHT (0x9B)
#define OV7725_CNST (0x9C)
#define OV7725_UVADJ0 (0x9E)
#define OV7725_UVADJ1 (0x9F)
#define OV7725_SCAL0 (0xA0)
#define OV7725_SCAL1 (0xA1)
#define OV7725_SCAL2 (0xA2)
#define OV7725_SDE (0xA6)
#define OV7725_USAT (0xA7)
#define OV7725_VSAT (0xA8)
#define OV7725_HUECOS (0xA9)
#define OV7725_HUESIN (0xAA)
#define OV7725_SIGN (0xAB)
#define OV7725_DSPAuto (0xAC)
#define OV7725_DEV_ADD (0x42 >> 1)
//==============================================定义 OV7725 IIC 内部地址==============================================
//===============================================定义 OV7725 参数结构体================================================
typedef enum
{
OV7725_INIT = 0x00,
OV7725_RESERVE,
OV7725_CONTRAST,
OV7725_FPS,
OV7725_COL,
OV7725_ROW,
OV7725_CONFIG_FINISH,
OV7725_GET_WHO_AM_I = 0xEF,
OV7725_GET_STATUS = 0xF1,
OV7725_GET_VERSION = 0xF2,
OV7725_SET_ADDR = 0xFE,
OV7725_SET_DATA = 0xFF,
}ov7725_cmd_enum;
//===============================================定义 OV7725 参数结构体================================================
//===============================================声明 OV7725 全局变量=================================================
extern vuint8 ov7725_finish_flag; // 一场图像采集完成标志位
extern uint8 ov7725_image_binary[OV7725_H][OV7725_W / 8]; // 图像保存数组
//===============================================声明 OV7725 全局变量=================================================
//===============================================声明 OV7725 基础函数=================================================
uint16 ov7725_uart_get_id (void); // 获取摄像头固件 ID
uint16 ov7725_get_version (void); // 获取摄像头固件版本
uint8 ov7725_init (void); // OV7725 摄像头初始化
//===============================================声明 OV7725 基础函数=================================================
#endif
+609
View File
@@ -0,0 +1,609 @@
/*********************************************************************************************************************
* 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_scc8660
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 ADS v1.10.2
* 适用平台 TC264D
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2022-09-15 pudding first version
* 2024-02-02 pudding 新增无MCU凌瞳驱动
********************************************************************************************************************/
/*********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* TXD 查看 zf_device_scc8660.h 中 SCC8660_COF_UART_TX 宏定义
* RXD 查看 zf_device_scc8660.h 中 SCC8660_COF_UART_RX 宏定义
* PCLK 查看 zf_device_scc8660.h 中 SCC8660_PCLK_PIN 宏定义
* VSY 查看 zf_device_scc8660.h 中 SCC8660_VSYNC_PIN 宏定义
* D0-D7 查看 zf_device_scc8660.h 中 SCC8660_DATA_PIN 宏定义 从该定义开始的连续八个引脚
* VCC 3.3V电源
* GND 电源地
* 其余引脚悬空
* ------------------------------------
********************************************************************************************************************/
#include "zf_common_interrupt.h"
#include "zf_common_debug.h"
#include "zf_common_fifo.h"
#include "zf_driver_delay.h"
#include "zf_driver_dma.h"
#include "zf_driver_exti.h"
#include "zf_driver_gpio.h"
#include "zf_driver_uart.h"
#include "zf_driver_soft_iic.h"
#include "zf_device_camera.h"
#include "zf_device_type.h"
#include "zf_device_config.h"
#include "isr_config.h"
#include "zf_device_scc8660.h"
vuint8 scc8660_finish_flag = 0; // 一场图像采集完成标志位
IFX_ALIGN(4) uint16 scc8660_image[SCC8660_H][SCC8660_W];
uint8 scc8660_link_list_num;
uint8 scc8660_lost_flag = 1; // 图像丢失标志位
uint8 scc8660_dma_int_num; // 当前DMA中断次数
uint8 scc8660_dma_init_flag; // 是否需要重新初始化
static scc8660_type_enum scc8660_type;
// 需要配置到摄像头的数据 不允许在这修改参数
static int16 scc8660_set_confing_buffer[SCC8660_CONFIG_FINISH][2]=
{
{SCC8660_INIT, 0}, // 摄像头开始初始化
{SCC8660_AUTO_EXP, SCC8660_AUTO_EXP_DEF}, // 自动曝光
{SCC8660_BRIGHT, SCC8660_BRIGHT_DEF}, // 亮度设置
{SCC8660_FPS, SCC8660_FPS_DEF}, // 图像帧率
{SCC8660_SET_COL, SCC8660_W * 4}, // 图像列数
{SCC8660_SET_ROW, SCC8660_H}, // 图像行数
{SCC8660_PCLK_DIV, SCC8660_PCLK_DIV_DEF}, // PCLK分频系数
{SCC8660_PCLK_MODE, SCC8660_PCLK_MODE_DEF}, // PCLK模式
{SCC8660_COLOR_MODE, SCC8660_COLOR_MODE_DEF}, // 图像色彩模式
{SCC8660_DATA_FORMAT, SCC8660_DATA_FORMAT_DEF}, // 输出数据格式
{SCC8660_MANUAL_WB, SCC8660_MANUAL_WB_DEF} // 手动白平衡
};
// 从摄像头内部获取到的配置数据 不允许在这修改参数
static int16 scc8660_get_confing_buffer[SCC8660_CONFIG_FINISH - 1][2]=
{
{SCC8660_AUTO_EXP, 0},
{SCC8660_BRIGHT, 0}, // 亮度设置
{SCC8660_FPS, 0}, // 图像帧率
{SCC8660_SET_COL, 0}, // 图像列数
{SCC8660_SET_ROW, 0}, // 图像行数
{SCC8660_PCLK_DIV, 0}, // PCLK分频系数
{SCC8660_PCLK_MODE, 0}, // PCLK模式
{SCC8660_COLOR_MODE, 0}, // 图像色彩模式
{SCC8660_DATA_FORMAT, 0}, // 输出数据格式
{SCC8660_MANUAL_WB, 0}, // 白平衡设置
};
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 配置摄像头内部配置信息 内部调用
// 参数说明 buff 发送配置信息的地址
// 返回参数 uint8 1-失败 0-成功
// 使用示例 if(scc8660_set_config(scc8660_set_confing_buffer)){}
// 备注信息 调用该函数前请先初始化串口
//-------------------------------------------------------------------------------------------------------------------
static uint8 scc8660_set_config (int16 buff[SCC8660_CONFIG_FINISH][2])
{
uint8 return_state = 1;
uint8 uart_buffer[4];
uint16 temp;
uint16 timeout_count = 0;
uint32 loop_count = 0;
uint32 uart_buffer_index = 0;
// 设置参数 具体请参看问题锦集手册
// 开始配置摄像头并重新初始化
for(loop_count = SCC8660_MANUAL_WB; loop_count < SCC8660_SET_REG_DATA; loop_count --)
{
uart_buffer[0] = 0xA5;
uart_buffer[1] = (uint8)buff[loop_count][0];
temp = buff[loop_count][1];
uart_buffer[2] = temp >> 8;
uart_buffer[3] = (uint8)temp;
uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4);
system_delay_ms(2);
}
do
{
if(3 <= fifo_used(&camera_receiver_fifo))
{
uart_buffer_index = 3;
fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN);
if((0xff == uart_buffer[1]) || (0xff == uart_buffer[2]))
{
return_state = 0;
break;
}
}
system_delay_ms(1);
}while(SCC8660_INIT_TIMEOUT > timeout_count ++);
// 以上部分对摄像头配置的数据全部都会保存在摄像头上51单片机的eeprom中
// 利用set_exposure_time函数单独配置的曝光数据不存储在eeprom中
return return_state;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 获取摄像头内部配置信息 内部调用
// 参数说明 buff 接收配置信息的地址
// 返回参数 uint8 1-失败 0-成功
// 使用示例 if(scc8660_get_config(scc8660_get_confing_buffer)){}
// 备注信息 调用该函数前请先初始化串口
//-------------------------------------------------------------------------------------------------------------------
static uint8 scc8660_get_config (int16 buff[SCC8660_CONFIG_FINISH-1][2])
{
uint8 return_state = 0;
uint8 uart_buffer[4];
uint16 temp;
uint16 timeout_count = 0;
uint32 loop_count = 0;
uint32 uart_buffer_index = 0;
for(loop_count = SCC8660_MANUAL_WB - 1; loop_count >= 1; loop_count --)
{
uart_buffer[0] = 0xA5;
uart_buffer[1] = SCC8660_GET_STATUS;
temp = buff[loop_count][0];
uart_buffer[2] = temp >> 8;
uart_buffer[3] = (uint8)temp;
uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4);
timeout_count = 0;
do
{
if(3 <= fifo_used(&camera_receiver_fifo))
{
uart_buffer_index = 3;
fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN);
buff[loop_count][1] = uart_buffer[1] << 8 | uart_buffer[2];
break;
}
system_delay_ms(1);
}while(SCC8660_INIT_TIMEOUT > timeout_count ++);
if(timeout_count > SCC8660_INIT_TIMEOUT) // 超时
{
return_state = 1;
break;
}
}
return return_state;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 SCC8660摄像头串口通信回调
// 参数说明 void
// 返回参数 void
// 使用示例 scc8660_uart_callback();
//-------------------------------------------------------------------------------------------------------------------
static void scc8660_uart_callback (void)
{
uint8 data = 0;
uart_query_byte(SCC8660_COF_UART, &data);
if(0xA5 == data)
{
fifo_clear(&camera_receiver_fifo);
}
fifo_write_element(&camera_receiver_fifo, data);
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 获取摄像头 ID
// 参数说明 void
// 返回参数 uint16 0-获取错误 N-版本号
// 使用示例 scc8660_get_id();
// 备注信息 调用该函数前请先初始化串口
//-------------------------------------------------------------------------------------------------------------------
uint16 scc8660_get_id (void)
{
uint16 temp;
uint8 uart_buffer[4];
uint16 timeout_count = 0;
uint16 return_value = 0;
uint32 uart_buffer_index = 0;
uart_buffer[0] = 0xA5;
uart_buffer[1] = SCC8660_GET_WHO_AM_I;
temp = 0;
uart_buffer[2] = temp >> 8;
uart_buffer[3] = (uint8)temp;
uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4);
do
{
if(3 <= fifo_used(&camera_receiver_fifo))
{
uart_buffer_index = 3;
fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN);
return_value = uart_buffer[1] << 8 | uart_buffer[2];
break;
}
system_delay_ms(1);
}while(SCC8660_INIT_TIMEOUT > timeout_count ++);
return return_value;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 单独设置摄像头曝光时间
// 参数说明 light 设置曝光时间越大图像越亮,摄像头收到后会根据分辨率及FPS计算最大曝光时间如果设置的数据过大,那么摄像头将会设置这个最大值
// 返回参数 uint16 数据
// 使用示例 scc8660_get_parameter();
// 备注信息 调用该函数前请先初始化串口
//-------------------------------------------------------------------------------------------------------------------
uint16 scc8660_get_parameter (uint16 config)
{
uint8 uart_buffer[4];
uint16 timeout_count = 0;
uint16 return_value = 0;
uint32 uart_buffer_index = 0;
uart_buffer[0] = 0xA5;
uart_buffer[1] = SCC8660_GET_WHO_AM_I;
uart_buffer[2] = 0x00;
uart_buffer[3] = (uint8)config;
uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4);
do
{
if(3 <= fifo_used(&camera_receiver_fifo))
{
uart_buffer_index = 3;
fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN);
return_value = uart_buffer[1] << 8 | uart_buffer[2];
break;
}
system_delay_ms(1);
}while(SCC8660_INIT_TIMEOUT > timeout_count ++);
return return_value;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 获取彩色摄像头固件版本
// 参数说明 void
// 返回参数 uint16 版本号
// 使用示例 scc8660_get_version();
// 备注信息 调用该函数前请先初始化摄像头配置串口
//-------------------------------------------------------------------------------------------------------------------
uint16 scc8660_get_version (void)
{
uint16 temp;
uint8 uart_buffer[4];
uint16 timeout_count = 0;
uint16 return_value = 0;
uint32 uart_buffer_index = 0;
uart_buffer[0] = 0xA5;
uart_buffer[1] = SCC8660_GET_STATUS;
temp = SCC8660_GET_VERSION;
uart_buffer[2] = temp >> 8;
uart_buffer[3] = (uint8)temp;
uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4);
do
{
if(3 <= fifo_used(&camera_receiver_fifo))
{
uart_buffer_index = 3;
fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN);
return_value = uart_buffer[1] << 8 | uart_buffer[2];
break;
}
system_delay_ms(1);
}while(SCC8660_INIT_TIMEOUT > timeout_count ++);
return return_value;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 单独设置图像亮度
// 参数说明 data 需要设置的亮度值
// 返回参数 uint8 1-失败 0-成功
// 使用示例 scc8660_set_brightness(data);
// 备注信息 调用该函数前请先初始化摄像头配置串口 通过该函数设置的参数,不会被51单片机保存
//-------------------------------------------------------------------------------------------------------------------
uint8 scc8660_set_brightness (uint16 data)
{
uint8 return_state = 0;
if(SCC8660_UART == scc8660_type)
{
uint8 uart_buffer[4];
uint16 temp;
uint16 timeout_count = 0;
uint32 uart_buffer_index = 0;
uart_buffer[0] = 0xA5;
uart_buffer[1] = SCC8660_SET_BRIGHT;
uart_buffer[2] = data >> 8;
uart_buffer[3] = (uint8)data;
uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4);
do
{
if(3 <= fifo_used(&camera_receiver_fifo))
{
uart_buffer_index = 3;
fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN);
temp = uart_buffer[1] << 8 | uart_buffer[2];
break;
}
system_delay_ms(1);
}while(SCC8660_INIT_TIMEOUT > timeout_count ++);
if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count))
{
return_state = 1;
}
}
else
{
return_state = scc8660_set_brightness_sccb(data);
}
return return_state;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 单独设置白平衡
// 参数说明 data 需要设置的亮度值
// 返回参数 uint8 1-失败 0-成功
// 使用示例 scc8660_set_white_balance(data);
// 备注信息 通过该函数设置的参数,不会被51单片机保存 调用该函数前请先初始化摄像头配置串口
//-------------------------------------------------------------------------------------------------------------------
uint8 scc8660_set_white_balance (uint16 data)
{
uint8 return_state = 0;
if(SCC8660_UART == scc8660_type)
{
uint8 uart_buffer[4];
uint16 temp;
uint16 timeout_count = 0;
uint32 uart_buffer_index = 0;
uart_buffer[0] = 0xA5;
uart_buffer[1] = SCC8660_SET_MANUAL_WB;
uart_buffer[2] = data >> 8;
uart_buffer[3] = (uint8)data;
uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4);
do
{
if(3 <= fifo_used(&camera_receiver_fifo))
{
uart_buffer_index = 3;
fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN);
temp = uart_buffer[1] << 8 | uart_buffer[2];
break;
}
system_delay_ms(1);
}while(SCC8660_INIT_TIMEOUT > timeout_count ++);
if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count))
{
return_state = 1;
}
}
else
{
return_state = scc8660_set_manual_wb_sccb(data);
}
return return_state;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 对摄像头内部寄存器进行写操作
// 参数说明 addr 摄像头内部寄存器地址
// 参数说明 data 需要写入的数据
// 返回参数 uint8 1-失败 0-成功
// 使用示例 scc8660_set_reg(addr, data);
// 备注信息 调用该函数前请先初始化串口
//-------------------------------------------------------------------------------------------------------------------
uint8 scc8660_set_reg (uint8 addr, uint16 data)
{
uint8 return_state = 0;
if(SCC8660_UART == scc8660_type)
{
uint8 uart_buffer[4];
uint16 temp;
uint16 timeout_count = 0;
uint32 uart_buffer_index = 0;
uart_buffer[0] = 0xA5;
uart_buffer[1] = SCC8660_SET_REG_ADDR;
uart_buffer[2] = 0x00;
uart_buffer[3] = (uint8)addr;
uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4);
system_delay_ms(10);
uart_buffer[0] = 0xA5;
uart_buffer[1] = SCC8660_SET_REG_DATA;
temp = data;
uart_buffer[2] = temp >> 8;
uart_buffer[3] = (uint8)temp;
uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4);
do
{
if(3 <= fifo_used(&camera_receiver_fifo))
{
uart_buffer_index = 3;
fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN);
temp = uart_buffer[1] << 8 | uart_buffer[2];
break;
}
system_delay_ms(1);
}while(SCC8660_INIT_TIMEOUT > timeout_count ++);
if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count))
{
return_state = 1;
}
}
else
{
return_state = scc8660_set_reg_sccb(addr, data);
}
return return_state;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 SCC8660摄像头场中断
// 参数说明 void
// 返回参数 void
// 使用示例 scc8660_vsync_handler();
//-------------------------------------------------------------------------------------------------------------------
static void scc8660_vsync_handler(void)
{
exti_flag_clear(SCC8660_VSYNC_PIN);
scc8660_dma_int_num = 0;
if(scc8660_dma_init_flag || scc8660_lost_flag)
{
scc8660_dma_init_flag = 0;
IfxDma_resetChannel(&MODULE_DMA, SCC8660_DMA_CH);
scc8660_link_list_num = dma_init(SCC8660_DMA_CH,
SCC8660_DATA_ADD,
(uint8 *)scc8660_image[0],
SCC8660_PCLK_PIN,
EXTI_TRIGGER_RISING,
SCC8660_IMAGE_SIZE);
dma_enable(SCC8660_DMA_CH);
}
else
{
if(1 == scc8660_link_list_num)
{
dma_set_destination(SCC8660_DMA_CH, (uint8 *)scc8660_image[0]); // 没有采用链接传输模式 重新设置目的地址
}
dma_enable(SCC8660_DMA_CH);
}
scc8660_lost_flag = 1;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 SCC8660摄像头DMA完成中断
// 参数说明 void
// 返回参数 void
// 使用示例 scc8660_dma_handler();
//-------------------------------------------------------------------------------------------------------------------
static void scc8660_dma_handler(void)
{
clear_dma_flag(SCC8660_DMA_CH);
if(IfxDma_getChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH)) // 图像错位判断
{
scc8660_finish_flag = 0;
dma_disable(SCC8660_DMA_CH);
IfxDma_clearChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH);
scc8660_dma_init_flag = 1;
}
else
{
scc8660_dma_int_num++;
if(scc8660_dma_int_num >= scc8660_link_list_num)
{
// 采集完成
// 一副图像从采集开始到采集结束耗时3.8MS左右(50FPS、188*120分辨率)
scc8660_dma_int_num = 0;
scc8660_lost_flag = 0;
scc8660_finish_flag = 1;
dma_disable(SCC8660_DMA_CH);
}
}
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 SCC8660 摄像头初始化
// 参数说明 void
// 返回参数 uint8 1-失败 0-成功
// 使用示例 scc8660_init();
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
uint8 scc8660_init (void)
{
uint8 return_state = 0;
soft_iic_info_struct scc8660_iic_struct;
// 初始化之前拉高场与像素引脚
gpio_init(P02_0, GPO, GPIO_HIGH, GPO_PUSH_PULL);
gpio_init(P02_1, GPO, GPIO_HIGH, GPO_PUSH_PULL);
do
{
system_delay_ms(200);
set_camera_type(CAMERA_COLOR, scc8660_vsync_handler, scc8660_dma_handler, NULL); // 设置连接摄像头类型
// 首先尝试SCCB通讯
scc8660_type = SCC8660_SCCB;
soft_iic_init(&scc8660_iic_struct, 0, SCC8660_COF_IIC_DELAY, SCC8660_COF_IIC_SCL, SCC8660_COF_IIC_SDA);
if(scc8660_set_config_sccb(&scc8660_iic_struct, scc8660_set_confing_buffer))
{
// SCCB通讯失败,尝试串口通讯
scc8660_type = SCC8660_UART;
camera_fifo_init();
set_camera_type(CAMERA_COLOR, scc8660_vsync_handler, scc8660_dma_handler, &scc8660_uart_callback); // 设置连接摄像头类型
uart_init (SCC8660_COF_UART, SCC8660_COF_BAUR, SCC8660_COF_UART_RX, SCC8660_COF_UART_TX); //初始换串口 配置摄像头
uart_rx_interrupt(SCC8660_COF_UART, 1);
fifo_clear(&camera_receiver_fifo);
if(scc8660_set_config(scc8660_set_confing_buffer))
{
// 如果程序在输出了断言信息 并且提示出错位置在这里
// 那么就是通信出错并超时退出了
// 检查一下接线有没有问题 如果没问题可能就是坏了
zf_log(0, "SCC8660 set config error.");
set_camera_type(NO_CAMERE, NULL, NULL, NULL);
return_state = 1;
break;
}
// 获取配置便于查看配置是否正确
if(scc8660_get_config(scc8660_get_confing_buffer))
{
// 如果程序在输出了断言信息 并且提示出错位置在这里
// 那么就是串口通信出错并超时退出了
// 检查一下接线有没有问题 如果没问题可能就是坏了
zf_log(0, "SCC8660 get config error.");
set_camera_type(NO_CAMERE, NULL, NULL, NULL);
return_state = 1;
break;
}
}
scc8660_link_list_num = camera_init(SCC8660_DATA_ADD, (uint8 *)scc8660_image[0], SCC8660_IMAGE_SIZE);
}while(0);
return return_state;
}
+143
View File
@@ -0,0 +1,143 @@
/*********************************************************************************************************************
* 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_scc8660
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 ADS v1.10.2
* 适用平台 TC264D
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2022-09-15 pudding first version
* 2024-02-02 pudding 新增无MCU凌瞳驱动
********************************************************************************************************************/
/*********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* TXD 查看 zf_device_scc8660.h 中 SCC8660_COF_UART_TX 宏定义
* RXD 查看 zf_device_scc8660.h 中 SCC8660_COF_UART_RX 宏定义
* PCLK 查看 zf_device_scc8660.h 中 SCC8660_PCLK_PIN 宏定义
* VSY 查看 zf_device_scc8660.h 中 SCC8660_VSYNC_PIN 宏定义
* D0-D7 查看 zf_device_scc8660.h 中 SCC8660_DATA_PIN 宏定义 从该定义开始的连续八个引脚
* VCC 3.3V电源
* GND 电源地
* 其余引脚悬空
* ------------------------------------
********************************************************************************************************************/
#ifndef _zf_device_scc8660_h_
#define _zf_device_scc8660_h_
#include "zf_device_type.h"
//================================================定义 SCC8660 基本配置================================================
#define SCC8660_COF_UART (UART_1) // 配置摄像头所使用到的串口
#define SCC8660_COF_BAUR (9600 ) // 凌瞳 配置串口波特率
#define SCC8660_COF_UART_TX (UART1_RX_P02_3) // 凌瞳 UART-TX 引脚 要接在单片机 RX 上
#define SCC8660_COF_UART_RX (UART1_TX_P02_2) // 凌瞳 UART-RX 引脚 要接在单片机 TX 上
#define SCC8660_COF_IIC_DELAY (800) // 凌瞳 IIC 延时
#define SCC8660_COF_IIC_SCL (P33_13) // 凌瞳 IIC-SCL 引脚
#define SCC8660_COF_IIC_SDA (P32_4) // 凌瞳 IIC-SDA 引脚
#define SCC8660_DMA_CH (IfxDma_ChannelId_7)
#define SCC8660_PCLK_PIN (ERU_CH1_REQ10_P14_3) // PCLK 触发信号 TIM_ETR 引脚禁止随意修改
#define SCC8660_VSYNC_PIN (ERU_CH4_REQ8_P33_7 ) // 场中断引脚
#define SCC8660_DATA_PIN (P00_0) // 数据引脚 这里是 只能是 GPIOx0 或者 GPIOx8 开始 连续八个引脚例如 F0-F7
#define SCC8660_DATA_ADD (get_port_in_addr(SCC8660_DATA_PIN))
#define SCC8660_INIT_TIMEOUT (0x00F0) // 默认的摄像头初始化超时时间 毫秒为单位
//================================================定义 SCC8660 基本配置================================================
//================================================定义 SCC8660 参数配置(仅支持凌瞳高帧率版本)===========================
#define SCC8660_W (160) // 图像宽度 可选参数为:160 80 40
#define SCC8660_H (120) // 图像高度 可选参数为:120 160 240
#define SCC8660_IMAGE_SIZE (SCC8660_W * 2 * SCC8660_H) // 整体图像大小 SCC8660_W*2*SCC8660_H 不能超过 65535
#define SCC8660_AUTO_EXP_DEF (0 ) // 自动曝光 默认不开启自动曝光设置 范围 [0-1] 0为关闭
#define SCC8660_BRIGHT_DEF (500) // 亮度设置 手动曝光默认:300 手动曝光时:参数范围0-65535 自动曝光推荐值:100 自动曝光时参数设置范围0-255
#define SCC8660_FPS_DEF (60 ) // 图像帧率 默认:50 可选参数为:60 50 30 25。 实际帧率还需要看SCC8660_PCLK_DIV参数的设置
#define SCC8660_PCLK_DIV_DEF (2 ) // PCLK分频系数 默认:5 可选参数为:<0:1/1> <1:2/3> <2:1/2> <3:1/3> <4:1/4> <5:1/8>
// 分频系数越大,PCLK频率越低,降低PCLK可以减轻DVP接口的干扰,但降低PCLK频率则会影响帧率。若无特殊需求请保持默认。
// 例如设置FPS为50帧,但是pclk分频系数选择的为5,则摄像头输出的帧率为50*(1/8)=6.25帧
// 其他参数不变的情况下,SCC8660_PCLK_DIV参数越大图像会越亮
#define SCC8660_PCLK_MODE_DEF (0 ) // PCLK模式 默认:0 可选参数为:[0,1] 0:不输出消隐信号 1:输出消隐信号 <通常都设置为0,如果使用STM32的DCMI接口采集需要设置为1>
#define SCC8660_COLOR_MODE_DEF (0 ) // 图像色彩模式 默认:0 可选参数为:[0,1] 0:正常彩色模式 1:鲜艳模式(色彩饱和度提高)
#define SCC8660_DATA_FORMAT_DEF (0 ) // 输出数据格式 默认:0 可选参数为:[0-3] 0:RGB565 1:RGB565(字节交换) 2:YUV422(YUYV) 3:YUV422(UYVY)
#define SCC8660_MANUAL_WB_DEF (0 ) // 手动白平衡 默认:0 可选参数为:[0,0x65-0xa0] 0:关闭手动白平衡,启用自动白平衡 其他:手动白平衡 手动白平衡时 参数范围0x65-0xa0
//================================================定义 SCC8660 参数配置(仅支持凌瞳高帧率版本)===========================
//===============================================定义 SCC8660 参数结构体================================================
typedef enum
{
SCC8660_INIT = 0x00, // 摄像头初始化命令
SCC8660_AUTO_EXP, // 自动曝光命令
SCC8660_BRIGHT, // 亮度命令
SCC8660_FPS, // 摄像头帧率命令
SCC8660_SET_COL, // 图像列命令
SCC8660_SET_ROW, // 图像行命令
SCC8660_PCLK_DIV, // 像素时钟分频命令
SCC8660_PCLK_MODE, // 像素时钟模式命令
SCC8660_COLOR_MODE, // 色彩模式命令
SCC8660_DATA_FORMAT, // 数据格式命令
SCC8660_MANUAL_WB, // 手动白平衡命令
SCC8660_CONFIG_FINISH, // 非命令位,主要用来占位计数
SCC8660_GET_WHO_AM_I = 0xEF, // 我是谁命令,用于判断摄像头型号
SCC8660_SET_BRIGHT = 0xF0, // 单独设置亮度
SCC8660_GET_STATUS = 0XF1, // 获取摄像头配置命令
SCC8660_GET_VERSION = 0xF2, // 固件版本号
SCC8660_SET_MANUAL_WB = 0xF3, // 单独设置手动白平衡
SCC8660_SET_REG_ADDR = 0xFE,
SCC8660_SET_REG_DATA = 0xFF,
}scc8660_cmd_enum;
//===============================================定义 SCC8660 参数结构体================================================
//===============================================摄像头类型枚举体=======================================================
typedef enum
{
SCC8660_UART,
SCC8660_SCCB,
}scc8660_type_enum;
//===============================================摄像头类型枚举体=======================================================
//===============================================声明 SCC8660 全局变量=================================================
extern vuint8 scc8660_finish_flag; // 一场图像采集完成标志位
extern uint16 scc8660_image[SCC8660_H][SCC8660_W]; // 图像保存数组
//===============================================声明 SCC8660 全局变量=================================================
//===============================================声明 SCC8660 基础函数=================================================
uint16 scc8660_get_id (void); // 获取摄像头 ID
uint16 scc8660_get_parameter (uint16 config); // 单独设置摄像头曝光时间
uint16 scc8660_get_version (void); // 获取彩色摄像头固件版本
uint8 scc8660_set_brightness (uint16 data); // 单独设置图像亮度
uint8 scc8660_set_white_balance (uint16 data); // 单独设置白平衡
uint8 scc8660_set_reg (uint8 addr, uint16 data); // 对摄像头内部寄存器进行写操作
uint8 scc8660_init (void); // SCC8660 摄像头初始化
//===============================================声明 SCC8660 基础函数=================================================
#endif
File diff suppressed because it is too large. Load diff
+173
View File
@@ -0,0 +1,173 @@
/*********************************************************************************************************************
* 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_tft180
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 ADS v1.10.2
* 适用平台 TC264D
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2022-09-15 pudding first version
* 2023-04-28 pudding 增加中文注释说明
********************************************************************************************************************/
/*********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* 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"
//=================================================定义 TFT180 基本配置================================================
#define TFT180_USE_SOFT_SPI (0) // 默认使用硬件 SPI 方式驱动 建议使用硬件 SPI 方式驱动
#if TFT180_USE_SOFT_SPI // 这两段 颜色正常的才是正确的 颜色灰的就是没有用的
//====================================================软件 SPI 驱动====================================================
#define TFT180_SOFT_SPI_DELAY (0 ) // 软件 SPI 的时钟延时周期 数值越小 SPI 通信速率越快
#define TFT180_SCL_PIN (P15_3) // 软件 SPI SCK 引脚
#define TFT180_SDA_PIN (P15_5) // 软件 SPI MOSI 引脚
//====================================================软件 SPI 驱动====================================================
#else
//====================================================硬件 SPI 驱动====================================================
#define TFT180_SPI_SPEED (60*1000*1000) // 硬件 SPI 速率
#define TFT180_SPI (SPI_2) // 硬件 SPI 号
#define TFT180_SCL_PIN (SPI2_SCLK_P15_3) // 硬件 SPI SCK 引脚
#define TFT180_SDA_PIN (SPI2_MOSI_P15_5) // 硬件 SPI MOSI 引脚
#define TFT180_SDA_PIN_IN (SPI2_MISO_P15_4) // 硬件 SPI MISO 引脚 TFT没有MISO引脚,但是这里任然需要定义,在spi的初始化时需要使用
//====================================================硬件 SPI 驱动====================================================
#endif
#define TFT180_RES_PIN (P15_1) // 液晶复位引脚定义
#define TFT180_DC_PIN (P15_0) // 液晶命令位引脚定义
#define TFT180_CS_PIN (P15_2) // CS 片选引脚
#define TFT180_BL_PIN (P15_4) // 液晶背光引脚定义
#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)))
//=================================================定义 TFT180 基本配置================================================
//=================================================定义 TFT180 参数结构体===============================================
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;
extern uint16 tft180_width_max ;
extern uint16 tft180_height_max;
//=================================================定义 TFT180 参数结构体===============================================
//=================================================声明 TFT180 基础函数================================================
void tft180_clear (void); // TFT180 清屏函数
void tft180_full (const uint16 color); // TFT180 屏幕填充函数
void tft180_set_dir (tft180_dir_enum dir); // TFT180 设置显示方向
void tft180_set_font (tft180_font_size_enum font); // TFT180 设置显示字体
void tft180_set_color (const uint16 pen, const uint16 bgcolor); // TFT180 设置显示颜色
void tft180_draw_point (uint16 x, uint16 y, const uint16 color); // TFT180 画点函数
void tft180_draw_line (uint16 x_start, uint16 y_start, uint16 x_end, uint16 y_end, const uint16 color); // TFT180 画线函数
void tft180_show_char (uint16 x, uint16 y, const char dat); // TFT180 显示字符
void tft180_show_string (uint16 x, uint16 y, const char dat[]); // TFT180 显示字符串
void tft180_show_int (uint16 x,uint16 y, const int32 dat, uint8 num); // TFT180 显示32位有符号 (去除整数部分无效的0)
void tft180_show_uint (uint16 x,uint16 y, const uint32 dat, uint8 num); // TFT180 显示32位无符号 (去除整数部分无效的0)
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); // TFT180 显示二值图像 数据每八个点组成一个字节数据
void tft180_show_gray_image (uint16 x, uint16 y, const uint8 *image, uint16 width, uint16 height, uint16 dis_width, uint16 dis_height, uint8 threshold); // TFT180 显示 8bit 灰度图像 带二值化阈值
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); // TFT180 显示 RGB565 彩色图像
void tft180_show_wave (uint16 x, uint16 y, const uint16 *wave, uint16 width, uint16 value_max, uint16 dis_width, uint16 dis_value_max); // TFT180 显示波形
void tft180_show_chinese (uint16 x, uint16 y, uint8 size, const uint8 *chinese_buffer, uint8 number, const uint16 color); // TFT180 汉字显示
// 1.8寸TFT屏幕初始化
void tft180_init (void);
//=================================================声明 TFT180 基础函数================================================
//=================================================声明 TFT180 扩展函数================================================
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 TFT180 显示小钻风图像
// 参数说明 p 图像数组指针
// 参数说明 width 图像实际宽度
// 参数说明 height 图像实际高度
// 返回参数 void
// 使用示例 tft180_displayimage7725(ov7725_image_binary[0], OV7725_W, OV7725_H);
// 备注信息 拓展的一键显示函数,默认无缩放,从屏幕坐标起始点开始显示
//-------------------------------------------------------------------------------------------------------------------
#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], MT9V03X_W, MT9V03X_H);
// 备注信息 拓展的一键显示函数,默认无缩放,从屏幕坐标起始点开始显示
//-------------------------------------------------------------------------------------------------------------------
#define tft180_displayimage03x(p, width, height) (tft180_show_gray_image(0, 0, (p), MT9V03X_1_W, MT9V03X_1_H, (width), (height), 0))
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 TFT180 显示凌瞳图像
// 参数说明 p 图像数组指针
// 参数说明 width 图像实际宽度
// 参数说明 height 图像实际高度
// 返回参数 void
// 使用示例 tft180_displayimage8660(scc8660_image[0], SCC8660_W, SCC8660_H);
// 备注信息 拓展的一键显示函数,默认无缩放,从屏幕坐标起始点开始显示
//-------------------------------------------------------------------------------------------------------------------
#define tft180_displayimage8660(p, width, height) (tft180_show_rgb565_image(0, 0, (p), SCC8660_W, SCC8660_H, (width), (height), 1))
//=================================================声明 TFT180 扩展函数================================================
#endif
+134
View File
@@ -0,0 +1,134 @@
/*********************************************************************************************************************
* 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_tsl1401
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 ADS v1.10.2
* 适用平台 TC264D
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2022-09-15 pudding 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 电源地
* ------------------------------------
********************************************************************************************************************/
#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_driver_uart.h"
#include "zf_device_tsl1401.h"
uint16 tsl1401_data[2][TSL1401_DATA_LEN]; // TSL1401 数据存放数组
static uint8 tsl1401_init_state = 0; // TSL1401 初始化标志位
vuint8 tsl1401_finish_flag; // TSL1401 数据准备就绪标志位
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 TSL1401 线阵 CCD 数据采集
// 参数说明 void
// 返回参数 void
// 使用示例 tsl1401_collect_pit_handler();
// 备注信息 该函数在 isr.c 中对应 TSL1401_PIT_INDEX 的中断服务函数调用
//-------------------------------------------------------------------------------------------------------------------
void tsl1401_collect_pit_handler (void)
{
if(!tsl1401_init_state) return;
uint8 i = 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);
tsl1401_data[0][i] = adc_convert(TSL1401_AO_PIN);
tsl1401_data[1][i] = adc_convert(TSL1401_AO_PIN1);
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();
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
void tsl1401_init (void)
{
adc_init(TSL1401_AO_PIN, TSL1401_AD_RESOLUTION);
adc_init(TSL1401_AO_PIN1, 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_init_state = 1;
}
+83
View File
@@ -0,0 +1,83 @@
/*********************************************************************************************************************
* 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_tsl1401
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 ADS v1.10.2
* 适用平台 TC264D
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2022-09-15 pudding first version
* 2023-04-28 pudding 增加中文注释说明
********************************************************************************************************************/
/*********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* 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_device_type.h"
//=================================================定义 TSL1401 基本配置================================================
#define TSL1401_AO_PIN (ADC0_CH4_A4) // 对应第一个 TSL1401 的 AO 引脚
#define TSL1401_AO_PIN1 (ADC0_CH5_A5) // 对应第二个 TSL1401 的 AO 引脚
// TSL1401 的控制引脚定义 多个 TSL1401 建议将控制引脚直接并联
#define TSL1401_CLK_PIN (P00_0) // TSL1401 的 CLK 引脚定义
#define TSL1401_SI_PIN (P00_1) // 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)))
// TSL1401 的周期采集部分定义 使用到哪个 PIT 就要把 放在哪个 PIT 的中断服务函数下
#define TSL1401_EXPOSURE_TIME (10 ) // 定义 TSL1401 曝光时间 单位 MS
#define TSL1401_PIT_INDEX (CCU61_CH1) // 使用周期中断
#define TSL1401_AD_RESOLUTION (ADC_8BIT) // ADC 精度 8bit
#define TSL1401_DATA_LEN (128 ) // TSL1401 数据长度
//=================================================定义 TSL1401 基本配置================================================
//=================================================声明 TSL1401 全局变量=================================================
extern uint16 tsl1401_data[2][TSL1401_DATA_LEN]; // TSL1401 数据存放数组
extern vuint8 tsl1401_finish_flag; // TSL1401 数据采集完成标志
//=================================================声明 TSL1401 全局变量=================================================
//=================================================声明 TSL1401 基础函数=================================================
void tsl1401_collect_pit_handler (void); // TSL1401 线阵 CCD 数据采集
void tsl1401_send_data (uart_index_enum uart_n, uint8 index); // TSL1401 线阵 CCD 图像发送至上位机查看图像
void tsl1401_init (void); // TSL1401 线阵 CCD 初始化
//=================================================声明 TSL1401 基础函数=================================================
#endif
+125
View File
@@ -0,0 +1,125 @@
/*********************************************************************************************************************
* 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_type
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 ADS v1.10.2
* 适用平台 TC264D
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2022-09-15 pudding first version
* 2023-05-26 pudding 新增SPI WIFI 中断回调指针
* 2024-01-16 pudding 移除SPI WIFI 中断回调指针 SPI WIFI将不再使用外部
********************************************************************************************************************/
#include "zf_device_type.h"
static void type_default_callback(void);
camera_type_enum camera_type = NO_CAMERE; // 摄像头类型变量
callback_function camera_uart_handler_1 = type_default_callback; // 串口通讯中断函数指针,根据初始化时设置的函数进行跳转
callback_function camera_vsync_handler_1 = type_default_callback; // 场中断函数指针,根据初始化时设置的函数进行跳转
callback_function camera_dma_handler_1 = type_default_callback; // DMA完成中断函数指针,根据初始化时设置的函数进行跳转
callback_function camera_uart_handler_2 = type_default_callback; // 串口通讯中断函数指针,根据初始化时设置的函数进行跳转
callback_function camera_vsync_handler_2 = type_default_callback; // 场中断函数指针,根据初始化时设置的函数进行跳转
callback_function camera_dma_handler_2 = type_default_callback; // DMA完成中断函数指针,根据初始化时设置的函数进行跳转
wireless_type_enum wireless_type = NO_WIRELESS;
callback_function wireless_module_uart_handler = type_default_callback; // 无线串口接收中断函数指针,根据初始化时设置的函数进行跳转
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;
if(type_set == CAMERA_GRAYSCALE_2 || type_set == CAMERA_GRAYSCALE_SINGLE)
{
camera_uart_handler_2 = ((uart_callback == NULL) ? (type_default_callback) : (uart_callback));
camera_vsync_handler_2 = ((vsync_callback == NULL) ? (type_default_callback) : (vsync_callback));
camera_dma_handler_2 = ((dma_callback == NULL) ? (type_default_callback) : (dma_callback));
}
else
{
camera_uart_handler_1 = ((uart_callback == NULL) ? (type_default_callback) : (uart_callback));
camera_vsync_handler_1 = ((vsync_callback == NULL) ? (type_default_callback) : (vsync_callback));
camera_dma_handler_1 = ((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;
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));
}
+104
View File
@@ -0,0 +1,104 @@
/*********************************************************************************************************************
* 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_type
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 ADS v1.10.2
* 适用平台 TC264D
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2022-09-15 pudding first version
* 2023-04-28 pudding 增加中文注释说明
* 2023-05-26 pudding 新增SPI WIFI 中断回调指针
********************************************************************************************************************/
#ifndef _zf_device_type_h_
#define _zf_device_type_h_
#include "zf_common_debug.h"
//==============================================定义 外设 参数结构体==================================================
typedef enum
{
NO_CAMERE = 0, // 无摄像头
CAMERA_BIN_IIC, // 小钻风 IIC 版本
CAMERA_BIN_UART, // 小钻风 UART 版本
CAMERA_GRAYSCALE_SINGLE, // 总钻风 单摄 版本
CAMERA_GRAYSCALE_1, // 总钻风 1
CAMERA_GRAYSCALE_2, // 总钻风 2
CAMERA_COLOR, // 凌瞳
}camera_type_enum;
typedef enum
{
NO_WIRELESS = 0, // 无设备
WIRELESS_UART, // 无线串口
BLE6A20, // 蓝牙串口
BLUETOOTH_CH9141, // 蓝牙 CH9141
WIFI_UART, // 串口 WiFi
RECEIVER_UART, // 枪式遥控器
}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_uart_handler_1 ; // 串口通讯中断函数指针,根据初始化时设置的函数进行跳转
extern callback_function camera_vsync_handler_1 ; // 场中断函数指针,根据初始化时设置的函数进行跳转
extern callback_function camera_dma_handler_1 ; // DMA完成中断函数指针,根据初始化时设置的函数进行跳转
extern callback_function camera_uart_handler_2 ; // 串口通讯中断函数指针,根据初始化时设置的函数进行跳转
extern callback_function camera_vsync_handler_2 ; // 场中断函数指针,根据初始化时设置的函数进行跳转
extern callback_function camera_dma_handler_2 ; // DMA完成中断函数指针,根据初始化时设置的函数进行跳转
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_camera_type_2 (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
@@ -0,0 +1,135 @@
/*********************************************************************************************************************
* 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_uart_receiver
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 ADS v1.10.2
* 适用平台 TC264D
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2022-11-04 JKS first version
* 2025-02-07 pudding 修改部分语句
********************************************************************************************************************/
/*********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* TXD 查看 zf_device_uart_receiver.h 中 UART_RECEVIER_RX_PIN 宏定义
* GND 电源地
* 5V 5V电源
* ------------------------------------
********************************************************************************************************************/
#include "zf_device_type.h"
#include "zf_driver_uart.h"
#include "zf_driver_timer.h"
#include "zf_device_uart_receiver.h"
uart_receiver_struct uart_receiver ; // 串口接收机通道数据与状态
uint8 uart_receiver_data[REV_DATA_LEN] = {0}; // 接收器原始数据
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 获取两次调用uart_receiver_interval_time函数时间间隔
// 参数说明 void
// 返回参数 uint32 返回从开始到现在的时间(单位1us)
// 使用示例 uint32 time = uart_receiver_interval_time();
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
static uint32 uart_receiver_interval_time (void)
{
static uint32 time_last = 0;
uint32 time, interval_time;
uint32 stm_clk;
stm_clk = IfxStm_getFrequency(IfxStm_getAddress((IfxStm_Index)(IfxCpu_getCoreId())));
time = IfxStm_getLower(IfxStm_getAddress((IfxStm_Index)(IfxCpu_getCoreId())));
interval_time = time - time_last;
time_last = time;
interval_time = (uint32)((uint64)interval_time * 1000000 / stm_clk);
return interval_time;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 SBUS数据解析
// 参数说明 *remote_data 接收遥控器数据的地址
// 参数说明 *bufer 原始数据
// 返回参数 void
// 使用示例
// 备注信息 对sbus数据解析进行解析
//-------------------------------------------------------------------------------------------------------------------
static void uart_receiver_analysis (uart_receiver_struct *remote_data,uint8 * buffer)
{
uint8 num = 0;
remote_data->channel[num++] = (buffer[1] |buffer[ 2] << 8 ) & 0x07FF;
remote_data->channel[num++] = (buffer[2] >> 3 | buffer[3] << 5 ) & 0x07FF;
remote_data->channel[num++] = (buffer[3] >> 6 | buffer[4] << 2 | buffer[5] << 10 ) & 0x07FF;
remote_data->channel[num++] = (buffer[5] >> 1 | buffer[6] << 7 ) & 0x07FF;
remote_data->channel[num++] = (buffer[6] >> 4 | buffer[7] << 4 ) & 0x07FF;
remote_data->channel[num++] = (buffer[7] >> 7 | buffer[8] << 1 | buffer[9] << 9 ) & 0x07FF;
remote_data->state = (SBUS_ABNORMAL_STATE == (buffer[23] & SBUS_ABNORMAL_STATE)) ? 0 : 1;
uart_receiver.finsh_flag = 1;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 串口接收机模块 串口中断回调函数
// 参数说明 void
// 返回参数 void
// 使用示例 uart_receiver_callback();
// 备注信息 该函数在 ISR 文件 串口中断程序通过uart_receiver_uart_handler函数指针被调用
//-------------------------------------------------------------------------------------------------------------------
void uart_receiver_callback(void)
{
static vuint8 length = 0;
if (uart_receiver_interval_time() > 3000)
{
length = 0;
}
uart_receiver_data[length++] = uart_read_byte(UART_RECEVIER_UART_INDEX);
if ( (REV_DATA_LEN == length) // 如果帧长、帧头、帧尾满足协议
&& (FRAME_STAR == uart_receiver_data[0])
&& (FRAME_END == uart_receiver_data[24]))
{
uart_receiver_analysis(&uart_receiver, uart_receiver_data);
}
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 串口接收机初始化
// 参数说明 void
// 返回参数 void
// 使用示例 uart_receiver_init();
//-------------------------------------------------------------------------------------------------------------------
void uart_receiver_init(void)
{
uart_sbus_init(UART_RECEVIER_UART_INDEX, SBUS_UART_BAUDRATE, UART_RECEVIER_TX_PIN, UART_RECEVIER_RX_PIN);
// 设置串口中断回调函数
set_wireless_type(RECEIVER_UART, uart_receiver_callback);
}
@@ -0,0 +1,72 @@
/*********************************************************************************************************************
* 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_uart_receiver
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 ADS v1.10.2
* 适用平台 TC264D
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2022-11-04 JKS first version
* 2025-02-07 pudding 修改部分语句
********************************************************************************************************************/
/*********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* TXD 查看 zf_device_uart_receiver.h 中 UART_RECEVIER_RX_PIN 宏定义
* GND 电源地
* 5V 5V电源
* ------------------------------------
********************************************************************************************************************/
#ifndef _zf_device_uart_receiver_h
#define _zf_device_uart_receiver_h
#include "zf_common_typedef.h"
#define UART_RECEVIER_UART_INDEX UART_2 // 定义串口接收机使用的串口
#define UART_RECEVIER_TX_PIN UART2_TX_P10_5 // 遥控器接收机没有这个引脚,仅用于串口初始化时占位使用
#define UART_RECEVIER_RX_PIN UART2_RX_P10_6 // 串口接收机的TX引脚 连接单片机的RX引脚
#define SBUS_UART_BAUDRATE (100000) // 指定 SBUS 串口所使用的的串口波特率 (用户不可修改)
#define UART_RECEVIER_CHANNEL_NUM ( 6 ) // 定义遥控器通道数量 (用户不可修改)
#define REV_DATA_LEN ( 25 ) // SBUS帧长
#define FRAME_STAR ( 0X0F ) // 帧头信息
#define FRAME_END ( 0X00 ) // 帧尾信息
#define SBUS_ABNORMAL_STATE ( 0X04 ) // 失控状态
typedef struct
{
uint16 channel[UART_RECEVIER_CHANNEL_NUM]; // CH1-CH6通道数据
uint8 state; // 遥控器状态(1表示正常,否则表示失控)
uint8 finsh_flag; // 1:表示成功接收到一帧遥控器数据
}uart_receiver_struct;
extern uart_receiver_struct uart_receiver; // 串口接收机通道数据与状态
void uart_receiver_init(void);
#endif
@@ -0,0 +1,103 @@
/*********************************************************************************************************************
* 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_virtual_oscilloscope
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 ADS v1.10.2
* 适用平台 TC264D
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2022-09-15 pudding first version
********************************************************************************************************************/
#include "zf_device_virtual_oscilloscope.h"
uint8 virtual_oscilloscope_data[10];
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 CRC 校验
// 参数说明 buff 需要进行 CRC 计算的数据地址
// 参数说明 crc_cnt 需要进行 CRC 计算的数据个数
// 返回参数 uint16 CRC 校验结果
// 使用示例 crc_16 = crc_check(virtual_oscilloscope_data, 8);
// 备注信息 内部使用 用户无需关心
//-------------------------------------------------------------------------------------------------------------------
static uint16 crc_check (uint8 *buff, uint8 crc_cnt)
{
uint16 crc_temp;
uint8 i, j;
crc_temp = 0xffff;
for(i = 0; i < crc_cnt; i ++)
{
crc_temp ^= buff[i];
for(j = 0; 8 > j; j ++)
{
if (crc_temp & 0x01)
{
crc_temp = (crc_temp >> 1) ^ 0xa001;
}
else
{
crc_temp = crc_temp >> 1;
}
}
}
return(crc_temp);
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 虚拟示波器数据转换函数
// 参数说明 data1 要发送的第一个数据
// 参数说明 data2 要发送的第二个数据
// 参数说明 data3 要发送的第三个数据
// 参数说明 data4 要发送的第四个数据
// 返回参数 void
// 使用示例 uint8 data_buffer[10];
// virtual_oscilloscope_data_conversion(100, 200, 300, 400, data_buffer);
// wireless_uart_send_buff(data_buffer, 10);
// 备注信息 这个函数不带发送 他只是处理数据
//-------------------------------------------------------------------------------------------------------------------
void virtual_oscilloscope_data_conversion (const int16 data1, const int16 data2, const int16 data3, const int16 data4)
{
uint16 crc_16 = 0;
virtual_oscilloscope_data[0] = (uint8)((uint16)data1 & 0xff);
virtual_oscilloscope_data[1] = (uint8)((uint16)data1 >> 8);
virtual_oscilloscope_data[2] = (uint8)((uint16)data2 & 0xff);
virtual_oscilloscope_data[3] = (uint8)((uint16)data2 >> 8);
virtual_oscilloscope_data[4] = (uint8)((uint16)data3 & 0xff);
virtual_oscilloscope_data[5] = (uint8)((uint16)data3>>8);
virtual_oscilloscope_data[6] = (uint8)((uint16)data4 & 0xff);
virtual_oscilloscope_data[7] = (uint8)((uint16)data4 >> 8);
crc_16 = crc_check(virtual_oscilloscope_data, 8);
virtual_oscilloscope_data[8] = (uint8)(crc_16 & 0xff);
virtual_oscilloscope_data[9] = (uint8)(crc_16 >> 8);
}
@@ -0,0 +1,51 @@
/*********************************************************************************************************************
* 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_virtual_oscilloscope
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 ADS v1.10.2
* 适用平台 TC264D
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2022-09-15 pudding first version
* 2023-04-28 pudding 增加中文注释说明
********************************************************************************************************************/
#ifndef _zf_device_virtual_oscilloscope_h_
#define _zf_device_virtual_oscilloscope_h_
#include "zf_common_typedef.h"
//=================================================声明 虚拟示波器 全局变量=================================================
extern uint8 virtual_oscilloscope_data[10];
//=================================================声明 虚拟示波器 全局变量=================================================
//=================================================声明 虚拟示波器 基础函数=================================================
void virtual_oscilloscope_data_conversion (const int16 data1, const int16 data2, const int16 data3, const int16 data4);
//=================================================声明 虚拟示波器 基础函数=================================================
#endif
+793
View File
@@ -0,0 +1,793 @@
/*********************************************************************************************************************
* 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_wifi_spi
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 ADS v1.10.2
* 适用平台 TC264D
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2022-09-21 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 // 单位毫秒
#if ((WIFI_SPI_RECVIVE_SIZE < 32) || (WIFI_SPI_RECVIVE_SIZE > 4088))
#error "WIFI_SPI_RECVIVE_SIZE must be >= 32 or <= 4088"
#endif
#if (WIFI_SPI_RECVIVE_SIZE >= WIFI_SPI_RECVIVE_FIFO_SIZE)
#error "WIFI_SPI_RECVIVE_FIFO_SIZE must be > WIFI_SPI_RECVIVE_SIZE"
#endif
#if (WIFI_SPI_TRANSFER_SIZE != 4088)
#error "WIFI_SPI_TRANSFER_SIZE must be == 4088"
#endif
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 命令类型
// 参数说明 *buffer 保存接收到的参数地址
// 参数说明 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 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 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 return_state;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 WIFI SPI 获取系统时间
// 参数说明 time_format 时间格式
// 返回参数 *buffer 保存时间字符串地址 缓冲区大小至少需要30个字节
// 返回参数 buffer_size 缓冲区大小
// 返回参数 uint8 状态 0-成功 1-错误
// 使用示例
// 备注信息 需要连接有网络的热点之后才能获取到正确的时间,并且在调用这个函数之前需要确保WIFI模块中需要接收的数据已经全部接收完毕
// 备注信息 仅WIFI SPI 外接天线版本支持
// 备注信息 输出的信息为字符串信息,可直接printf到串口助手查看
//-------------------------------------------------------------------------------------------------------------------
uint8 wifi_spi_get_time (wifi_spi_time_enum time_format, char *buffer, uint8 buffer_size)
{
uint8 return_state = 1;
wifi_spi_packets_struct temp_packets;
uint8 send_cmd, receive_cmd;
// 接收时间的数组必须大于30个字节
// 并且模块固件必须是V2版本
if((30 <= buffer_size) && (!strncmp(wifi_spi_version, "V2", 2)))
{
send_cmd = WIFI_SPI_GET_TIME1 + time_format - WIFI_SPI_UTC_0;
receive_cmd = WIFI_SPI_REPLY_TIME1 + time_format - WIFI_SPI_UTC_0;
return_state = wifi_spi_get_parameter(send_cmd, &temp_packets, OTHER_TIME_OUT);
if((0 == return_state) && (receive_cmd == temp_packets.head.command))
{
return_state = (uint8)strncmp((const char *)temp_packets.buffer, "OK", 2);
if(0 == return_state)
{
memcpy(buffer, &temp_packets.buffer[3], temp_packets.head.length - 3);
buffer[temp_packets.head.length - 3] = 0;
}
}
}
return return_state;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 WIFI SPI 扫描热点
// 参数说明 *buffer 保存扫描到的热点信息 包含名称与信号强度,每个信号强度后面会跟一个换行符
// 参数说明 buffer_size 缓冲区的长度
// 返回参数 uint8 状态 0-成功 1-错误
// 使用示例
// 备注信息 仅WIFI SPI 外接天线版本支持
// 备注信息 输出的信息为字符串信息,可直接printf到串口助手查看
// 备注信息 每一行包含一个wifi名称与密码
//-------------------------------------------------------------------------------------------------------------------
uint8 wifi_spi_wifi_scan (char *buffer, uint16 buffer_size)
{
uint8 return_state;
// 模块必须是V2版本的固件才支持此功能
if(!strncmp(wifi_spi_version, "V2", 2))
{
return_state = wifi_spi_set_parameter(WIFI_SPI_SET_WIFI_SCAN, NULL, 0, WIFI_CONNECT_TIME_OUT);
if(0 == return_state)
{
#if (0 == WIFI_SPI_READ_TRANSFER)
wifi_spi_send_buffer(NULL, 0);
#endif
while(0 == wifi_spi_read_buffer((uint8 *)buffer, buffer_size))
{
system_delay_ms(10);
}
}
}
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 数据块发送函数并同步接收数据
// 参数说明 *buff 需要发送的数据地址
// 参数说明 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 = (uint16) (length > WIFI_SPI_TRANSFER_SIZE ? WIFI_SPI_TRANSFER_SIZE : 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 字符串发送函数并同步接收数据
// 参数说明 *string 需要发送的字符串
// 返回参数 void
// 使用示例 wifi_spi_send_string("123");
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
void wifi_spi_send_string(const char *string)
{
wifi_spi_send_buffer((uint8*)string, strlen(string));
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 WIFI SPI 读取缓冲区
// 参数说明 *buff 接收缓冲区
// 参数说明 length 读取数据长度
// 返回参数 uint32 实际读取数据长度
// 使用示例 wifi_spi_read_buffer(buffer, 100);
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
uint32 wifi_spi_read_buffer (uint8 *buffer, uint32 length)
{
zf_assert(NULL != buffer);
uint32 fifo_read_length;
uint32 write_length = 0;
wifi_spi_packets_struct temp_packets;
// 首先判断FIFO中是否有数据,如果有则先从FIFO读取
if(fifo_used(&wifi_spi_fifo))
{
fifo_read_length = fifo_used(&wifi_spi_fifo);
fifo_read_length = length < fifo_read_length ? length : fifo_read_length;
fifo_read_buffer(&wifi_spi_fifo, buffer, &fifo_read_length, FIFO_READ_AND_CLEAN);
buffer += fifo_read_length;
length -= fifo_read_length;
write_length += fifo_read_length;
}
#if(1 == WIFI_SPI_READ_TRANSFER)
if(WIFI_SPI_IDLE == wifi_spi_mutex)
{
wifi_spi_mutex = WIFI_SPI_BUSY; // 将通讯状态设置为忙
do
{
if( (WIFI_SPI_RECVIVE_SIZE > wifi_spi_fifo.size) || // 如果缓冲区空间不够则不再读取
(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)) &&
(temp_packets.head.length)
)
{
if(length)
{
fifo_read_length = length >= temp_packets.head.length ? temp_packets.head.length : length;
memcpy(buffer, temp_packets.buffer, fifo_read_length);
buffer += fifo_read_length;
length -= fifo_read_length;
write_length += fifo_read_length;
if(fifo_read_length < temp_packets.head.length) // 外部缓冲不足多余部分写入FIFO
{
fifo_write_buffer(&wifi_spi_fifo, temp_packets.buffer + fifo_read_length, temp_packets.head.length - fifo_read_length);
}
}
else // 全部写入FIFO
{
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
return write_length;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 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_MODE3, 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();
if(NULL == wifi_ssid)
{
// 初始化的时候不需要连接WIFI
break;
}
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;
}
+170
View File
@@ -0,0 +1,170 @@
/*********************************************************************************************************************
* 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_wifi_spi
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 ADS v1.10.2
* 适用平台 TC264D
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2024-01-18 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_3 ) // 定义使用的SPI号
#define WIFI_SPI_SPEED (20 * 1000 * 1000 ) // 硬件 SPI 速率
#define WIFI_SPI_SCK_PIN (SPI3_SCLK_P22_3 ) // 定义SPI_SCK引脚
#define WIFI_SPI_MOSI_PIN (SPI3_MOSI_P22_0 ) // 定义SPI_MOSI引脚
#define WIFI_SPI_MISO_PIN (SPI3_MISO_P22_1 ) // 定义SPI_MISO引脚 IPS没有MISO引脚,但是这里任然需要定义,在spi的初始化时需要使用
#define WIFI_SPI_CS_PIN (P22_2 ) // 定义SPI_CS引脚 采用软件CS引脚
#define WIFI_SPI_INT_PIN (P15_8 ) // 定义握手引脚
#define WIFI_SPI_RST_PIN (P23_1 ) // 定义复位引脚
#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 "10.171.99.185" // 连接目标的 IP
#define WIFI_SPI_TARGET_PORT "8086" // 连接目标的端口
#define WIFI_SPI_LOCAL_PORT "6666" // 本机的端口 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_SET_WIFI_SCAN = 0x12, // 开始扫描WIFI
WIFI_SPI_SET_READ_LENGTH = 0x13, // 设置最大读取长度
WIFI_SPI_GET_VERSION = 0x20, // 获取模块版本
WIFI_SPI_GET_MAC_ADDR = 0x21, // 获取模块MAC地址
WIFI_SPI_GET_IP_ADDR = 0x22, // 获取模块IP地址
WIFI_SPI_GET_TIME1 = 0x23, // 获取时间 格式1
WIFI_SPI_GET_TIME2 = 0x24, // 获取时间 格式2
WIFI_SPI_GET_TIME3 = 0x25, // 获取时间 格式3
// 从机回传的命令
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_REPLY_TIME1 = 0xA3, // 从机回复时间
WIFI_SPI_REPLY_TIME2 = 0xA4, // 从机回复时间
WIFI_SPI_REPLY_TIME3 = 0xA5, // 从机回复时间
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;
typedef enum
{
WIFI_SPI_UTC_0 = 1, // 世界时间
WIFI_SPI_GMT, // 世界时间 转换为GMT格式,后缀增加GMT 一般用于对接云端大模型使用
WIFI_SPI_UTC_8, // 北京时间
}wifi_spi_time_enum;
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_get_time (wifi_spi_time_enum time_format, char *buffer, uint8 buffer_size);
uint8 wifi_spi_wifi_scan (char *buffer, uint16 buffer_size);
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
+159
View File
@@ -0,0 +1,159 @@
/*********************************************************************************************************************
* 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_wifi_uart
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 ADS v1.10.2
* 适用平台 TC264D
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2022-09-15 pudding first version
* 2023-04-28 pudding 增加中文注释说明
********************************************************************************************************************/
/*********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* 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"
//==============================================定义 WIFI_UART 基本配置===================================================
#define WIFI_UART_INDEX (UART_2) // WIFI 模块 所使用到的串口
#define WIFI_UART_TX_PIN (UART2_RX_P10_6) // 连接 WIFI 模块 TX
#define WIFI_UART_RX_PIN (UART2_TX_P10_5) // 连接 WIFI 模块 RX
#define WIFI_UART_BAUD (115200) // 模块工作波特率
#define WIFI_UART_RTS_PIN (P33_8) // 定义流控位引脚 指示当前模块是否可以接受数据 0-可以继续接收 1-不可以继续接收
#define WIFI_UART_HARDWARE_RST (1) // 定义是否使用硬件复位引脚 0-使用软件复位 1-使用硬件 RST
#if WIFI_UART_HARDWARE_RST // 建议使用硬件复位引脚 否则容易出现单片机复位后无法正常初始化模块
#define WIFI_UART_RST_PIN (P11_6) // 定义硬件复位引脚
#endif
//==============================================定义 WIFI_UART 基本配置===================================================
//==============================================定义 WIFI_UART 基本参数===================================================
#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.137.1" // 连接目标的 IP
#define WIFI_UART_TARGET_PORT "8080" // 连接目标的端口
#define WIFI_UART_LOCAL_PORT "8080" // 本机端口
#endif
//==============================================定义 WIFI_UART 基本参数===================================================
//==============================================定义 WIFI_UART 参数结构体==================================================
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;
//==============================================定义 WIFI_UART 参数结构体==================================================
//==============================================定义 WIFI_UART 全局变量===================================================
extern wifi_uart_information_struct wifi_uart_information;
//==============================================定义 WIFI_UART 全局变量===================================================
//==============================================定义 WIFI_UART 基础函数===================================================
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 模块初始化函数
//==============================================定义 WIFI_UART 基础函数===================================================
#endif
@@ -0,0 +1,294 @@
/*********************************************************************************************************************
* 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_wireless_uart
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 ADS v1.10.2
* 适用平台 TC264D
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2022-09-15 pudding 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;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 无线转串口模块 发送摄像头图像至上位机查看图像
// 参数说明 *image_addr 需要发送的图像地址
// 参数说明 image_size 图像的大小
// 返回参数 void
// 使用示例 wireless_uart_send_image(&mt9v03x_image[0][0], MT9V03X_IMAGE_SIZE);
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
void wireless_uart_send_image (const uint8 *image_addr, uint32 image_size)
{
zf_assert(NULL != image_addr);
extern uint8 camera_send_image_frame_header[4];
wireless_uart_send_buffer(camera_send_image_frame_header, 4);
wireless_uart_send_buffer((uint8 *)image_addr, image_size);
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 无线转串口模块 读取缓冲
// 参数说明 *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)
{
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);
#elif(1 == WIRELESS_UART_AUTO_BAUD_RATE) // 开启自动波特率
uint8 rts_init_status = 0;
uint16 time_count = 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;
}
time_count = 0;
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,103 @@
/*********************************************************************************************************************
* 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_wireless_uart
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 ADS v1.10.2
* 适用平台 TC264D
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2022-09-15 pudding first version
* 2023-04-28 pudding 增加中文注释说明
********************************************************************************************************************/
/*********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* 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_2) // 无线串口对应使用的串口号
#define WIRELESS_UART_BUAD_RATE (115200) // 无线串口对应使用的串口波特率
#define WIRELESS_UART_TX_PIN (UART2_RX_P10_6) // 无线串口对应模块的 TX 要接到单片机的 RX
#define WIRELESS_UART_RX_PIN (UART2_TX_P10_5) // 无线串口对应模块的 RX 要接到单片机的 TX
#define WIRELESS_UART_RTS_PIN (P33_8) // 无线串口对应模块的 RTS 引脚
//====================================================自动波特率====================================================
// 注意事项1:无线转串口模块版本是V2.0以下的是无法开启自动波特率的。
// 注意事项2:开启自动波特率务必连接RTS引脚 否则会开启失败。
// 注意事项3:模块自动波特率失败的话 可以尝试断电重启
// 开启自动波特率务必阅读上面三条 注意事项
// 开启自动波特率务必阅读上面三条 注意事项
// 开启自动波特率务必阅读上面三条 注意事项
// 0:关闭自动波特率
// 1:开启自动波特率 自动波特率的作用是修改 WIRELESS_UART_BAUD 之后不需要对模块进行配置 模块会自动设置为对应的波特率
#define WIRELESS_UART_AUTO_BAUD_RATE ( 1 )
//====================================================自动波特率====================================================
#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);
void wireless_uart_send_image (const uint8 *image_addr, uint32 image_size);
uint32 wireless_uart_read_buffer (uint8 *buff, uint32 len);
void wireless_uart_callback (void);
uint8 wireless_uart_init (void);
//================================================声明 无线串口 基础函数===================================================
#endif
@@ -0,0 +1,99 @@
如需获取详细资料可联系淘宝店铺客服:https://seekfree.taobao.com/
如需获取详细资料可联系淘宝店铺客服:https://seekfree.taobao.com/
如需获取详细资料可联系淘宝店铺客服:https://seekfree.taobao.com/
本文件主要用于说明 zf_device 目录下各个文件所对应的外设模块
本文件主要用于说明 zf_device 目录下各个文件所对应的外设模块
本文件主要用于说明 zf_device 目录下各个文件所对应的外设模块
=================================================== 测距模块 ===================================================
zf_device_dl1a.h TOF 测距模块 DL1A 频率:33hz 最大距离:1.2 米
zf_device_dl1b.h TOF 测距模块 DL1B 频率:100hz 最大距离:1.4 米
=================================================== 测距模块 ===================================================
==================================================== 陀螺仪 ====================================================
zf_device_mpu6050.h MPU6050 六轴陀螺仪 传统 IIC 通讯
zf_device_icm20602.h ICM20602 六轴陀螺仪 支持 SPI 采值
zf_device_imu660ra.h IMU660RA 六轴陀螺仪 高精度陀螺仪
zf_device_imu963ra.h IMU963RA 九轴陀螺仪 支持地磁计采集
==================================================== 陀螺仪 ====================================================
=================================================== 屏幕显示 ===================================================
zf_device_ips114.h IPS114 液晶屏幕 1.14 寸 分辨率:240 * 135
zf_device_ips200.h IPS200 液晶屏幕 2.0 寸 分辨率:240 * 320
zf_device_tft180.h TFT180 屏幕 1.8寸 分辨率:160 * 128
zf_device_oled.h OLED 液晶屏幕 0.96 寸 分辨率:128 * 64
=================================================== 屏幕显示 ===================================================
================================================== 图像传感器 ==================================================
zf_device_mt9v03x.h MT9V03X 总钻风灰度摄像头
zf_device_ov7725.h OV7725 小钻风硬件二值化摄像头
zf_device_scc8660.h SCC8660 凌瞳彩色摄像头
zf_device_tsl1401.h TSL1401 红孩儿线阵CCD
================================================== 图像传感器 ==================================================
=================================================== 无线通讯 ===================================================
zf_device_ble6a20.h 蓝牙串口模块 无线通讯
zf_device_bluetooth_ch9141.h CH9141 蓝牙通讯模块 蓝牙组网通讯
zf_device_wifi_spi.h WIFI-SPI 高速WIFI无线通讯模块
zf_device_wifi_uart.h WIFI-UART 串口WIFI无线通讯模块
zf_device_wireless_uart.h 无线串口模块
=================================================== 无线通讯 ===================================================
=================================================== 远程遥控 ===================================================
zf_device_uart_receiver.h SUBS 串口遥控器 串口通讯 长距离遥控 2.4G频段
=================================================== 远程遥控 ===================================================
================================================== 其他传感器 ==================================================
zf_device_absolute_encoder.h 360° 位置传感器 绝对式迷你 mini 编码器 分辨率:0.088°
zf_device_menc15a.h 15位高精度磁编码器驱动 位置式
zf_device_gnss.h GPS 及 RTK 定位模块 双频高精度定位模块 亚米级定位
zf_device_key.h GPIO 按键驱动 用于检测主板按键状态
zf_device_virtual_oscilloscope.h VisualScope 虚拟示波器
================================================== 其他传感器 ==================================================