first commit
This commit is contained in:
BIN
libraries/zf_device/libzf_device_config.a
Normal file
BIN
libraries/zf_device/libzf_device_config.a
Normal file
Binary file not shown.
230
libraries/zf_device/zf_device_absolute_encoder.c
Normal file
230
libraries/zf_device/zf_device_absolute_encoder.c
Normal file
@@ -0,0 +1,230 @@
|
||||
/*********************************************************************************************************************
|
||||
* CH32V307VCT6 Opensourec Library 即(CH32V307VCT6 开源库)是一个基于官方 SDK 接口的第三方开源库
|
||||
* Copyright (c) 2022 SEEKFREE 逐飞科技
|
||||
*
|
||||
* 本文件是CH32V307VCT6 开源库的一部分
|
||||
*
|
||||
* CH32V307VCT6 开源库 是免费软件
|
||||
* 您可以根据自由软件基金会发布的 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 文件 版本说明
|
||||
* 开发环境 MounRiver Studio V1.8.1
|
||||
* 适用平台 CH32V307VCT6
|
||||
* 店铺链接 https://seekfree.taobao.com/
|
||||
*
|
||||
* 修改记录
|
||||
* 日期 作者 备注
|
||||
* 2022-09-15 大W first version
|
||||
********************************************************************************************************************/
|
||||
/*********************************************************************************************************************
|
||||
* 接线定义:
|
||||
* ------------------------------------
|
||||
* 模块管脚 单片机管脚
|
||||
* SCLK 查看 zf_device_absolute_encoder.h 中 ABSOLUTE_ENCODER_SCLK_PIN 宏定义
|
||||
* MOSI 查看 zf_device_absolute_encoder.h 中 ABSOLUTE_ENCODER_MOSI_PIN 宏定义
|
||||
* MISO 查看 zf_device_absolute_encoder.h 中 ABSOLUTE_ENCODER_MISO_PIN 宏定义
|
||||
* CS 查看 zf_device_absolute_encoder.h 中 ABSOLUTE_ENCODER_CS_PIN 宏定义
|
||||
* VCC 3.3V电源
|
||||
* GND 电源地
|
||||
* ------------------------------------
|
||||
********************************************************************************************************************/
|
||||
|
||||
#include "zf_common_clock.h"
|
||||
#include "zf_common_debug.h"
|
||||
#include "zf_common_function.h"
|
||||
#include "zf_driver_delay.h"
|
||||
#include "zf_driver_soft_spi.h"
|
||||
#include "zf_driver_spi.h"
|
||||
|
||||
#include "zf_device_absolute_encoder.h"
|
||||
|
||||
static int16 now_location = 0;
|
||||
static int16 last_location = 0;
|
||||
|
||||
#if ABSOLUTE_ENCODER_USE_SOFT_SPI
|
||||
static soft_spi_info_struct absolute_encoder_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; i < 6; i ++)
|
||||
{
|
||||
absolute_encoder_write_register(i + 1, dat[i]); // 写入默认配置参数
|
||||
system_delay_ms(1);
|
||||
}
|
||||
if(time_count ++ > ABSOLUTE_ENCODER_TIMEOUT_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(func_abs(now_location - last_location) > 2048)
|
||||
{
|
||||
result_data = (now_location > 2048 ? (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;
|
||||
}
|
||||
|
||||
90
libraries/zf_device/zf_device_absolute_encoder.h
Normal file
90
libraries/zf_device/zf_device_absolute_encoder.h
Normal file
@@ -0,0 +1,90 @@
|
||||
/*********************************************************************************************************************
|
||||
* CH32V307VCT6 Opensourec Library 即(CH32V307VCT6 开源库)是一个基于官方 SDK 接口的第三方开源库
|
||||
* Copyright (c) 2022 SEEKFREE 逐飞科技
|
||||
*
|
||||
* 本文件是CH32V307VCT6 开源库的一部分
|
||||
*
|
||||
* CH32V307VCT6 开源库 是免费软件
|
||||
* 您可以根据自由软件基金会发布的 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 文件 版本说明
|
||||
* 开发环境 MounRiver Studio V1.8.1
|
||||
* 适用平台 CH32V307VCT6
|
||||
* 店铺链接 https://seekfree.taobao.com/
|
||||
*
|
||||
* 修改记录
|
||||
* 日期 作者 备注
|
||||
* 2022-09-15 大W first version
|
||||
********************************************************************************************************************/
|
||||
/*********************************************************************************************************************
|
||||
* 接线定义:
|
||||
* ------------------------------------
|
||||
* 模块管脚 单片机管脚
|
||||
* SCLK 查看 zf_device_absolute_encoder.h 中 ABSOLUTE_ENCODER_SCLK_PIN 宏定义
|
||||
* MOSI 查看 zf_device_absolute_encoder.h 中 ABSOLUTE_ENCODER_MOSI_PIN 宏定义
|
||||
* MISO 查看 zf_device_absolute_encoder.h 中 ABSOLUTE_ENCODER_MISO_PIN 宏定义
|
||||
* CS 查看 zf_device_absolute_encoder.h 中 ABSOLUTE_ENCODER_CS_PIN 宏定义
|
||||
* VCC 3.3V电源
|
||||
* GND 电源地
|
||||
* ------------------------------------
|
||||
********************************************************************************************************************/
|
||||
|
||||
#ifndef _zf_device_absolute_encoder_h_
|
||||
#define _zf_device_absolute_encoder_h_
|
||||
|
||||
#include "zf_common_typedef.h"
|
||||
|
||||
#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 (B13) // 硬件 SPI SCK 引脚
|
||||
#define ABSOLUTE_ENCODER_MOSI_PIN (B15) // 硬件 SPI MOSI 引脚
|
||||
#define ABSOLUTE_ENCODER_MISO_PIN (B14) // 硬件 SPI MISO 引脚
|
||||
//====================================================软件 SPI 驱动====================================================
|
||||
#else
|
||||
//====================================================硬件 SPI 驱动====================================================
|
||||
#define ABSOLUTE_ENCODER_SPI_SPEED (10 * 1000 * 1000) // 硬件 SPI 速率
|
||||
#define ABSOLUTE_ENCODER_SPI (SPI_2) // 硬件 SPI 号
|
||||
#define ABSOLUTE_ENCODER_SCLK_PIN (SPI2_MAP0_SCK_B13) // 硬件 SPI SCK 引脚
|
||||
#define ABSOLUTE_ENCODER_MOSI_PIN (SPI2_MAP0_MISO_B14) // 硬件 SPI MOSI 引脚
|
||||
#define ABSOLUTE_ENCODER_MISO_PIN (SPI2_MAP0_MOSI_B15) // 硬件 SPI MISO 引脚
|
||||
//====================================================硬件 SPI 驱动====================================================
|
||||
#endif
|
||||
|
||||
#define ABSOLUTE_ENCODER_CS_PIN (B12)
|
||||
#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
|
||||
150
libraries/zf_device/zf_device_aht20.c
Normal file
150
libraries/zf_device/zf_device_aht20.c
Normal file
@@ -0,0 +1,150 @@
|
||||
/*********************************************************************************************************************
|
||||
* CH32V307VCT6 Opensourec Library 即(CH32V307VCT6 开源库)是一个基于官方 SDK 接口的第三方开源库
|
||||
* Copyright (c) 2022 SEEKFREE 逐飞科技
|
||||
*
|
||||
* 本文件是CH32V307VCT6 开源库的一部分
|
||||
*
|
||||
* CH32V307VCT6 开源库 是免费软件
|
||||
* 您可以根据自由软件基金会发布的 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_aht20
|
||||
* 公司名称 成都逐飞科技有限公司
|
||||
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
|
||||
* 开发环境 MounRiver Studio V1.8.1
|
||||
* 适用平台 CH32V307VCT6
|
||||
* 店铺链接 https://seekfree.taobao.com/
|
||||
*
|
||||
* 修改记录
|
||||
* 日期 作者 备注
|
||||
* 2022-09-15 大W first version
|
||||
********************************************************************************************************************/
|
||||
/*********************************************************************************************************************
|
||||
* 接线定义:
|
||||
* ------------------------------------
|
||||
* 模块管脚 单片机管脚
|
||||
* 软件 IIC 通信引脚对应关系
|
||||
* SCL 查看 zf_device_aht20.h 中 AHT20_SOFT_IIC_SCL 宏定义
|
||||
* SDA 查看 zf_device_aht20.h 中 AHT20_SOFT_IIC_SDA 宏定义
|
||||
* VCC 3.3V电源
|
||||
* GND 电源地
|
||||
* 其余引脚悬空
|
||||
*
|
||||
* 硬件 IIC 通信引脚对应关系
|
||||
* SCL 查看 zf_device_aht20.h 中 AHT20_IIC_SCL 宏定义
|
||||
* SDA 查看 zf_device_aht20.h 中 AHT20_IIC_SDA 宏定义
|
||||
* VCC 3.3V电源
|
||||
* GND 电源地
|
||||
* 其余引脚悬空
|
||||
* ------------------------------------
|
||||
********************************************************************************************************************/
|
||||
|
||||
#include "zf_device_aht20.h"
|
||||
|
||||
float aht_temperature = 0, aht_humidity = 0;
|
||||
|
||||
#if AHT20_USE_SOFT_IIC
|
||||
static soft_iic_info_struct aht20_iic_struct;
|
||||
|
||||
#define aht20_write_register(reg, data) (soft_iic_write_8bit_register(&aht20_iic_struct, (reg), (data)))
|
||||
#define aht20_write_registers(reg, data, len) (soft_iic_write_8bit_registers(&aht20_iic_struct, (reg), (data), (len)))
|
||||
#define aht20_read_register(reg) (soft_iic_read_8bit_register(&aht20_iic_struct, (reg)))
|
||||
#define aht20_read_registers(reg, data, len) (soft_iic_read_8bit_registers(&aht20_iic_struct, (reg), (data), (len)))
|
||||
#else
|
||||
#define aht20_write_register(reg, data) (iic_write_8bit_register(AHT20_IIC, AHT20_DEV_ADDR, (reg), (data)))
|
||||
#define aht20_write_registers(reg, data, len) (iic_write_8bit_registers(AHT20_IIC, AHT20_DEV_ADDR, (reg), (data), (len)))
|
||||
#define aht20_read_register(reg) (iic_read_8bit_register(AHT20_IIC, AHT20_DEV_ADDR, (reg)))
|
||||
#define aht20_read_registers(reg, data, len) (iic_read_8bit_registers(AHT20_IIC, AHT20_DEV_ADDR, (reg), (data), (len)))
|
||||
#endif
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 AHT20 自检函数
|
||||
// 参数说明 NULL
|
||||
// 返回参数 uint8 0 - 初始化成功 1 - 初始化失败
|
||||
// 使用示例 调用该函数前,请先调用模拟IIC的初始化
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
static uint8 aht20_self1_check(void)
|
||||
{
|
||||
uint8 return_state = 0;
|
||||
uint16 timeout_count = 0;
|
||||
uint8 send_data[2] = {0x08, 0x00};
|
||||
while((AHT20_CAL_ENABLE & aht20_read_register(AHT20_READ_STATE)) != AHT20_CAL_ENABLE)
|
||||
{
|
||||
//卡在这里原因有以下几点
|
||||
//1 AHT20 坏了,如果是新的这样的概率极低
|
||||
//2 接线错误或者没有接好
|
||||
//3 可能你需要外接上拉电阻,上拉到3.3V
|
||||
aht20_write_registers(AHT20_SELF_INIT, send_data, 2);
|
||||
system_delay_ms(10);
|
||||
if(timeout_count ++ > AHT20_TIMEOUT_COUNT)
|
||||
{
|
||||
return_state = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return return_state;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 获取 AHT20 温湿度数据
|
||||
// 参数说明 void
|
||||
// 返回参数 void
|
||||
// 使用示例 aht20_read_data(); // 执行该函数后,直接查看对应的变量即可
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
void aht20_read_data (void)
|
||||
{
|
||||
uint32 temp_data;
|
||||
uint8 data_buffer[6] = {0x33, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
aht20_write_registers(AHT20_MEASURE_CMD, data_buffer, 2);
|
||||
system_delay_ms(75);
|
||||
data_buffer[0] = AHT20_STATE_BUSY;
|
||||
while(data_buffer[0] & aht20_read_register(AHT20_READ_STATE))
|
||||
{
|
||||
system_delay_ms(1);
|
||||
}
|
||||
aht20_read_registers(AHT20_READ_STATE, data_buffer, 6);
|
||||
|
||||
temp_data = data_buffer[1];
|
||||
temp_data = (temp_data << 8) + data_buffer[2];
|
||||
temp_data = (temp_data << 4) + (data_buffer[3]>>4 & 0x0f);
|
||||
aht_humidity = ((double)temp_data/0x100000)*100;
|
||||
|
||||
temp_data = (data_buffer[3] & 0x0f);
|
||||
temp_data = (temp_data << 8) + data_buffer[4];
|
||||
temp_data = (temp_data << 8) + data_buffer[5];
|
||||
aht_temperature = ((double)temp_data/0x100000)*200-50;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 初始化 AHT20
|
||||
// 参数说明 NULL
|
||||
// 返回参数 uint8 0 - 初始化成功 1 - 初始化失败
|
||||
// 使用示例 调用该函数前,请先调用模拟IIC的初始化
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
uint8 aht20_init (void)
|
||||
{
|
||||
uint8 return_state = 0;
|
||||
#if AHT20_USE_SOFT_IIC
|
||||
soft_iic_init(&aht20_iic_struct, AHT20_DEV_ADDR, AHT20_SOFT_IIC_DELAY, AHT20_SCL_PIN, AHT20_SDA_PIN);
|
||||
#else
|
||||
iic_init(AHT20_IIC, AHT20_DEV_ADDR, AHT20_IIC_SPEED, AHT20_SCL_PIN, AHT20_SDA_PIN);
|
||||
#endif
|
||||
system_delay_ms(40); // 上电延时
|
||||
|
||||
return_state = aht20_self1_check();
|
||||
return return_state;
|
||||
}
|
||||
100
libraries/zf_device/zf_device_aht20.h
Normal file
100
libraries/zf_device/zf_device_aht20.h
Normal file
@@ -0,0 +1,100 @@
|
||||
/*********************************************************************************************************************
|
||||
* CH32V307VCT6 Opensourec Library 即(CH32V307VCT6 开源库)是一个基于官方 SDK 接口的第三方开源库
|
||||
* Copyright (c) 2022 SEEKFREE 逐飞科技
|
||||
*
|
||||
* 本文件是CH32V307VCT6 开源库的一部分
|
||||
*
|
||||
* CH32V307VCT6 开源库 是免费软件
|
||||
* 您可以根据自由软件基金会发布的 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_aht20
|
||||
* 公司名称 成都逐飞科技有限公司
|
||||
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
|
||||
* 开发环境 MounRiver Studio V1.8.1
|
||||
* 适用平台 CH32V307VCT6
|
||||
* 店铺链接 https://seekfree.taobao.com/
|
||||
*
|
||||
* 修改记录
|
||||
* 日期 作者 备注
|
||||
* 2022-09-15 大W first version
|
||||
********************************************************************************************************************/
|
||||
/*********************************************************************************************************************
|
||||
* 接线定义:
|
||||
* ------------------------------------
|
||||
* 模块管脚 单片机管脚
|
||||
* 软件 IIC 通信引脚对应关系
|
||||
* SCL 查看 zf_device_aht20.h 中 AHT20_SOFT_IIC_SCL 宏定义
|
||||
* SDA 查看 zf_device_aht20.h 中 AHT20_SOFT_IIC_SDA 宏定义
|
||||
* VCC 3.3V电源
|
||||
* GND 电源地
|
||||
* 其余引脚悬空
|
||||
*
|
||||
* 硬件 IIC 通信引脚对应关系
|
||||
* SCL 查看 zf_device_aht20.h 中 AHT20_IIC_SCL 宏定义
|
||||
* SDA 查看 zf_device_aht20.h 中 AHT20_IIC_SDA 宏定义
|
||||
* VCC 3.3V电源
|
||||
* GND 电源地
|
||||
* 其余引脚悬空
|
||||
* ------------------------------------
|
||||
********************************************************************************************************************/
|
||||
|
||||
#ifndef _zf_device_aht20_h_
|
||||
#define _zf_device_aht20_h_
|
||||
|
||||
#include "zf_common_clock.h"
|
||||
#include "zf_common_debug.h"
|
||||
|
||||
#include "zf_driver_delay.h"
|
||||
|
||||
#include "zf_driver_soft_iic.h"
|
||||
|
||||
#define AHT20_USE_SOFT_IIC (1) // 默认使用软件 IIC 方式驱动 建议使用软件 IIC 方式
|
||||
#if AHT20_USE_SOFT_IIC // 这两段 颜色正常的才是正确的 颜色灰的就是没有用的
|
||||
//====================================================软件 IIC 驱动====================================================
|
||||
#define AHT20_SOFT_IIC_DELAY (10 ) // 软件 IIC 的时钟延时周期 数值越小 IIC 通信速率越快
|
||||
#define AHT20_SCL_PIN (B10) // 软件 IIC SCL 引脚 连接 MPU6050 的 SCL 引脚
|
||||
#define AHT20_SDA_PIN (B11) // 软件 IIC SDA 引脚 连接 MPU6050 的 SDA 引脚
|
||||
//====================================================软件 IIC 驱动====================================================
|
||||
#else
|
||||
//====================================================硬件 IIC 驱动====================================================
|
||||
#define AHT20_IIC_SPEED (400000 ) // 硬件 IIC 通信速率 最高 400KHz 不建议低于 40KHz
|
||||
#define AHT20_IIC (IIC_2 ) // 硬件 IIC SCL 引脚 连接 MPU6050 的 SCL 引脚
|
||||
#define AHT20_SCL_PIN (IIC2_SCL_B10) // 硬件 IIC SCL 引脚 连接 MPU6050 的 SCL 引脚
|
||||
#define AHT20_SDA_PIN (IIC2_SDA_B11) // 硬件 IIC SDA 引脚 连接 MPU6050 的 SDA 引脚
|
||||
//====================================================硬件 IIC 驱动====================================================
|
||||
#endif
|
||||
|
||||
#define AHT20_TIMEOUT_COUNT (0x001F) // MPU6050 超时计数
|
||||
|
||||
//================================================定义 AHT20 内部地址================================================
|
||||
#define AHT20_DEV_ADDR (0x38)
|
||||
|
||||
#define AHT20_READ_STATE (0x71)
|
||||
#define AHT20_CAL_ENABLE (0x08)
|
||||
#define AHT20_STATE_BUSY (0x80)
|
||||
|
||||
#define AHT20_MEASURE_CMD (0xAC)
|
||||
|
||||
#define AHT20_SELF_INIT (0xBE)
|
||||
//================================================定义 AHT20 内部地址================================================
|
||||
|
||||
extern float aht_temperature, aht_humidity;
|
||||
|
||||
void aht20_read_data (void);
|
||||
uint8 aht20_init (void);
|
||||
|
||||
#endif
|
||||
272
libraries/zf_device/zf_device_bluetooth_ch9141.c
Normal file
272
libraries/zf_device/zf_device_bluetooth_ch9141.c
Normal file
@@ -0,0 +1,272 @@
|
||||
/*********************************************************************************************************************
|
||||
* CH32V307VCT6 Opensourec Library 即(CH32V307VCT6 开源库)是一个基于官方 SDK 接口的第三方开源库
|
||||
* Copyright (c) 2022 SEEKFREE 逐飞科技
|
||||
*
|
||||
* 本文件是CH32V307VCT6 开源库的一部分
|
||||
*
|
||||
* CH32V307VCT6 开源库 是免费软件
|
||||
* 您可以根据自由软件基金会发布的 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 文件 版本说明
|
||||
* 开发环境 MounRiver Studio V1.8.1
|
||||
* 适用平台 CH32V307VCT6
|
||||
* 店铺链接 https://seekfree.taobao.com/
|
||||
*
|
||||
* 修改记录
|
||||
* 日期 作者 备注
|
||||
* 2022-01-10 大W 对换CH1和CH2的引脚号
|
||||
* 2022-03-16 大W 删除配对操作,可以使用配对上位机进行配对
|
||||
* 2022-09-15 大W first version
|
||||
********************************************************************************************************************/
|
||||
/*********************************************************************************************************************
|
||||
* 接线定义:
|
||||
* ------------------------------------
|
||||
* 模块管脚 单片机管脚
|
||||
* TX 查看 zf_device_bluetooth_ch9141.h 中 BLUETOOTH_CH9141_TX_PIN 宏定义
|
||||
* RX 查看 zf_device_bluetooth_ch9141.h 中 BLUETOOTH_CH9141_RX_PIN 宏定义
|
||||
* RTS 查看 zf_device_bluetooth_ch9141.h 中 BLUETOOTH_CH9141_RTS_PIN 宏定义
|
||||
* VCC 3.3V电源
|
||||
* GND 电源地
|
||||
* ------------------------------------
|
||||
********************************************************************************************************************/
|
||||
|
||||
#include "zf_common_clock.h"
|
||||
#include "zf_common_debug.h"
|
||||
#include "zf_common_fifo.h"
|
||||
|
||||
#include "zf_device_type.h"
|
||||
|
||||
#include "zf_driver_gpio.h"
|
||||
#include "zf_driver_uart.h"
|
||||
#include "zf_driver_delay.h"
|
||||
|
||||
#include "zf_device_bluetooth_ch9141.h"
|
||||
|
||||
static fifo_struct bluetooth_ch9141_fifo;
|
||||
static uint8 bluetooth_ch9141_buffer[BLUETOOTH_CH9141_BUFFER_SIZE]; // 数据存放数组
|
||||
|
||||
static uint8 bluetooth_ch9141_data;
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 蓝牙转串口模块 发送数据
|
||||
// 参数说明 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(buff != NULL);
|
||||
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(str != NULL);
|
||||
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(image_addr != NULL);
|
||||
uint16 time_count = 0;
|
||||
|
||||
extern uint8 camera_send_image_frame_header[4];
|
||||
bluetooth_ch9141_send_buffer(camera_send_image_frame_header, 4);
|
||||
bluetooth_ch9141_send_buffer((uint8 *)image_addr, image_size);
|
||||
|
||||
while(0 != image_size)
|
||||
{
|
||||
if(!gpio_get_level(BLUETOOTH_CH9141_RTS_PIN)) // 如果RTS为低电平 则继续发送数据
|
||||
{
|
||||
// system_delay_ms(5);
|
||||
if(30 <= image_size) // 数据分 30byte 每包发送
|
||||
{
|
||||
uart_write_buffer(BLUETOOTH_CH9141_INDEX, image_addr, 30); // 发送数据
|
||||
image_addr += 30; // 地址偏移
|
||||
image_size -= 30; // 数量
|
||||
time_count = 0;
|
||||
}
|
||||
else // 不足 30byte 的数据一次性发送完毕
|
||||
{
|
||||
uart_write_buffer(BLUETOOTH_CH9141_INDEX, image_addr, image_size);// 发送数据
|
||||
image_size = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else // 如果RTS为高电平 则模块忙
|
||||
{
|
||||
if(BLUETOOTH_CH9141_TIMEOUT_COUNT <= (++ time_count)) // 超出了最大等待时间
|
||||
{
|
||||
break; // 退出发送
|
||||
}
|
||||
system_delay_ms(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 蓝牙转串口模块 读取函数
|
||||
// 参数说明 buff 存储的数据地址
|
||||
// 参数说明 len 长度
|
||||
// 返回参数 uint32 实际读取字节数
|
||||
// 使用示例 bluetooth_ch9141_read_buff(buff, 16);
|
||||
// 备注信息
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
uint32 bluetooth_ch9141_read_buffer (uint8 *buff, uint32 len)
|
||||
{
|
||||
zf_assert(buff != NULL);
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
75
libraries/zf_device/zf_device_bluetooth_ch9141.h
Normal file
75
libraries/zf_device/zf_device_bluetooth_ch9141.h
Normal file
@@ -0,0 +1,75 @@
|
||||
/*********************************************************************************************************************
|
||||
* CH32V307VCT6 Opensourec Library 即(CH32V307VCT6 开源库)是一个基于官方 SDK 接口的第三方开源库
|
||||
* Copyright (c) 2022 SEEKFREE 逐飞科技
|
||||
*
|
||||
* 本文件是CH32V307VCT6 开源库的一部分
|
||||
*
|
||||
* CH32V307VCT6 开源库 是免费软件
|
||||
* 您可以根据自由软件基金会发布的 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 文件 版本说明
|
||||
* 开发环境 MounRiver Studio V1.8.1
|
||||
* 适用平台 CH32V307VCT6
|
||||
* 店铺链接 https://seekfree.taobao.com/
|
||||
*
|
||||
* 修改记录
|
||||
* 日期 作者 备注
|
||||
* 2022-01-10 大W 对换CH1和CH2的引脚号
|
||||
* 2022-03-16 大W 删除配对操作,可以使用配对上位机进行配对
|
||||
* 2022-09-15 大W first version
|
||||
********************************************************************************************************************/
|
||||
/*********************************************************************************************************************
|
||||
* 接线定义:
|
||||
* ------------------------------------
|
||||
* 模块管脚 单片机管脚
|
||||
* TX 查看 zf_device_bluetooth_ch9141.h 中 BLUETOOTH_CH9141_TX_PIN 宏定义
|
||||
* RX 查看 zf_device_bluetooth_ch9141.h 中 BLUETOOTH_CH9141_RX_PIN 宏定义
|
||||
* RTS 查看 zf_device_bluetooth_ch9141.h 中 BLUETOOTH_CH9141_RTS_PIN 宏定义
|
||||
* VCC 3.3V电源
|
||||
* GND 电源地
|
||||
* ------------------------------------
|
||||
********************************************************************************************************************/
|
||||
|
||||
#ifndef _zf_device_bluetooth_ch9141_h_
|
||||
#define _zf_device_bluetooth_ch9141_h_
|
||||
|
||||
#include "zf_common_typedef.h"
|
||||
|
||||
#define BLUETOOTH_CH9141_INDEX UART_7 // 蓝牙模块 1 对应使用的串口号
|
||||
#define BLUETOOTH_CH9141_BUAD_RATE 115200 // 蓝牙模块 1 对应使用的串口波特率
|
||||
#define BLUETOOTH_CH9141_TX_PIN UART7_MAP3_RX_E13 // 蓝牙模块 1 对应模块的 TX 要接到单片机的 RX
|
||||
#define BLUETOOTH_CH9141_RX_PIN UART7_MAP3_TX_E12 // 蓝牙模块 1 对应模块的 RX 要接到单片机的 TX
|
||||
#define BLUETOOTH_CH9141_RTS_PIN E8 // 蓝牙模块 1 对应模块的 RTS 引脚
|
||||
|
||||
#define BLUETOOTH_CH9141_BUFFER_SIZE 64
|
||||
#define BLUETOOTH_CH9141_TIMEOUT_COUNT 500
|
||||
|
||||
|
||||
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);
|
||||
#endif
|
||||
|
||||
101
libraries/zf_device/zf_device_camera.c
Normal file
101
libraries/zf_device/zf_device_camera.c
Normal file
@@ -0,0 +1,101 @@
|
||||
/*********************************************************************************************************************
|
||||
* CH32V307VCT6 Opensourec Library 即(CH32V307VCT6 开源库)是一个基于官方 SDK 接口的第三方开源库
|
||||
* Copyright (c) 2022 SEEKFREE 逐飞科技
|
||||
*
|
||||
* 本文件是CH32V307VCT6 开源库的一部分
|
||||
*
|
||||
* CH32V307VCT6 开源库 是免费软件
|
||||
* 您可以根据自由软件基金会发布的 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 文件 版本说明
|
||||
* 开发环境 MounRiver Studio V1.8.1
|
||||
* 适用平台 CH32V307VCT6
|
||||
* 店铺链接 https://seekfree.taobao.com/
|
||||
*
|
||||
* 修改记录
|
||||
* 日期 作者 备注
|
||||
* 2021-12-02 大W 增加串口发送图像到上位机函数
|
||||
* 2022-09-15 大W first version
|
||||
********************************************************************************************************************/
|
||||
|
||||
|
||||
#include "zf_common_debug.h"
|
||||
#include "zf_common_interrupt.h"
|
||||
#include "zf_driver_exti.h"
|
||||
#include "zf_driver_timer.h"
|
||||
#include "zf_device_type.h"
|
||||
#include "zf_device_mt9v03x_dvp.h"
|
||||
#include "zf_device_scc8660_dvp.h"
|
||||
|
||||
#include "zf_device_camera.h"
|
||||
|
||||
|
||||
uint8 camera_receiver_buffer[CAMERA_RECEIVER_BUFFER_SIZE];
|
||||
|
||||
uint8 camera_send_image_frame_header[4] = {0x00, 0xFF, 0x01, 0x01};
|
||||
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 摄像头二进制图像数据解压为十六进制八位数据 小钻风用
|
||||
// 参数说明 *data1 摄像头图像数组
|
||||
// 参数说明 *data2 存放解压数据的地址
|
||||
// 参数说明 image_size 图像的大小
|
||||
// 返回参数 void
|
||||
// 使用示例 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(data1 != NULL);
|
||||
zf_assert(data2 != NULL);
|
||||
uint8 i = 8;
|
||||
|
||||
while(image_size --)
|
||||
{
|
||||
i = 8;
|
||||
while(i --)
|
||||
{
|
||||
*data2 ++ = (((*data1 >> i) & 0x01) ? 255 : 0);
|
||||
}
|
||||
data1 ++;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 摄像头图像发送至上位机查看图像
|
||||
// 参数说明 uartn 使用的串口号
|
||||
// 参数说明 *image_addr 需要发送的图像地址
|
||||
// 参数说明 image_size 图像的大小
|
||||
// 返回参数 void
|
||||
// 使用示例 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(image_addr != NULL);
|
||||
// 发送命令
|
||||
uart_write_buffer(uartn, camera_send_image_frame_header, 4);
|
||||
|
||||
// 发送图像
|
||||
uart_write_buffer(uartn, (uint8 *)image_addr, image_size);
|
||||
}
|
||||
|
||||
|
||||
|
||||
53
libraries/zf_device/zf_device_camera.h
Normal file
53
libraries/zf_device/zf_device_camera.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/*********************************************************************************************************************
|
||||
* CH32V307VCT6 Opensourec Library 即(CH32V307VCT6 开源库)是一个基于官方 SDK 接口的第三方开源库
|
||||
* Copyright (c) 2022 SEEKFREE 逐飞科技
|
||||
*
|
||||
* 本文件是CH32V307VCT6 开源库的一部分
|
||||
*
|
||||
* CH32V307VCT6 开源库 是免费软件
|
||||
* 您可以根据自由软件基金会发布的 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 文件 版本说明
|
||||
* 开发环境 MounRiver Studio V1.8.1
|
||||
* 适用平台 CH32V307VCT6
|
||||
* 店铺链接 https://seekfree.taobao.com/
|
||||
*
|
||||
* 修改记录
|
||||
* 日期 作者 备注
|
||||
* 2021-12-02 大W 增加串口发送图像到上位机函数
|
||||
* 2022-09-15 大W first version
|
||||
********************************************************************************************************************/
|
||||
|
||||
#ifndef _zf_device_camera_h_
|
||||
#define _zf_device_camera_h_
|
||||
|
||||
#include "zf_common_fifo.h"
|
||||
#include "zf_driver_uart.h"
|
||||
|
||||
#define CAMERA_RECEIVER_BUFFER_SIZE (8)
|
||||
|
||||
extern uint8 camera_receiver_buffer[CAMERA_RECEIVER_BUFFER_SIZE];
|
||||
|
||||
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);
|
||||
|
||||
|
||||
#endif
|
||||
53
libraries/zf_device/zf_device_config.h
Normal file
53
libraries/zf_device/zf_device_config.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/*********************************************************************************************************************
|
||||
* CH32V307VCT6 Opensourec Library 即(CH32V307VCT6 开源库)是一个基于官方 SDK 接口的第三方开源库
|
||||
* Copyright (c) 2022 SEEKFREE 逐飞科技
|
||||
*
|
||||
* 本文件是CH32V307VCT6 开源库的一部分
|
||||
*
|
||||
* CH32V307VCT6 开源库 是免费软件
|
||||
* 您可以根据自由软件基金会发布的 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_driver_adc
|
||||
* 公司名称 成都逐飞科技有限公司
|
||||
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
|
||||
* 开发环境 MounRiver Studio V1.8.1
|
||||
* 适用平台 CH32V307VCT6
|
||||
* 店铺链接 https://seekfree.taobao.com/
|
||||
*
|
||||
* 修改记录
|
||||
* 日期 作者 备注
|
||||
* 2022-09-15 大W first version
|
||||
********************************************************************************************************************/
|
||||
#ifndef _zf_device_config_h_
|
||||
#define _zf_device_config_h_
|
||||
|
||||
extern const unsigned char image_frame_header[4];
|
||||
extern const unsigned char imu660ra_config_file[8192];
|
||||
extern const unsigned char dl1b_config_file[135];
|
||||
|
||||
|
||||
unsigned char mt9v03x_sccb_check_id (void *soft_iic_obj);
|
||||
unsigned char mt9v03x_sccb_set_config (const short int buff[10][2]);
|
||||
unsigned char mt9v03x_sccb_set_exposure_time (unsigned short int light);
|
||||
unsigned char mt9v03x_sccb_set_reg (unsigned char addr, unsigned short int data);
|
||||
|
||||
unsigned char scc8660_sccb_check_id (void *soft_iic_obj);
|
||||
unsigned char scc8660_sccb_set_config (const short int buff[11][2]);
|
||||
unsigned char scc8660_sccb_set_brightness (unsigned short int brightness);
|
||||
unsigned char scc8660_sccb_set_manual_wb (unsigned short int manual_wb);
|
||||
unsigned char scc8660_sccb_set_reg (unsigned char reg, unsigned short int data);
|
||||
#endif
|
||||
628
libraries/zf_device/zf_device_detector.c
Normal file
628
libraries/zf_device/zf_device_detector.c
Normal file
@@ -0,0 +1,628 @@
|
||||
/*********************************************************************************************************************
|
||||
* CH32V307VCT6 Opensourec Library 即(CH32V307VCT6 开源库)是一个基于官方 SDK 接口的第三方开源库
|
||||
* Copyright (c) 2022 SEEKFREE 逐飞科技
|
||||
*
|
||||
* 本文件是CH32V307VCT6 开源库的一部分
|
||||
*
|
||||
* CH32V307VCT6 开源库 是免费软件
|
||||
* 您可以根据自由软件基金会发布的 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 文件 版本说明
|
||||
* 开发环境 MounRiver Studio V1.8.1
|
||||
* 适用平台 CH32V307VCT6
|
||||
* 店铺链接 https://seekfree.taobao.com/
|
||||
*
|
||||
* 修改记录
|
||||
* 日期 作者 备注
|
||||
* 2023-05-25 大W first version
|
||||
********************************************************************************************************************/
|
||||
|
||||
#include "zf_driver_uart.h"
|
||||
#include "zf_common_fifo.h"
|
||||
#include "zf_device_wireless_uart.h"
|
||||
#include "zf_device_bluetooth_ch9141.h"
|
||||
#include "zf_device_wifi_uart.h"
|
||||
#include "zf_device_wifi_spi.h"
|
||||
|
||||
#include "zf_device_detector.h"
|
||||
|
||||
|
||||
typedef uint32 (*detector_transfer_callback_function) (const uint8 *buff, uint32 length);
|
||||
typedef uint32 (*detector_receive_callback_function) (uint8 *buff, uint32 length);
|
||||
|
||||
detector_transfer_type_enum detector_transfer_type; // 数据传输方式
|
||||
|
||||
detector_transfer_callback_function detector_transfer_callback; // 数据发送函数指针
|
||||
detector_receive_callback_function detector_receive_callback; // 数据接收函数指针
|
||||
|
||||
detector_oscilloscope_struct detector_oscilloscope_data; // 虚拟示波器数据
|
||||
static detector_camera_struct detector_camera_data; // 图像上位机协议数据
|
||||
static detector_camera_dot_struct detector_camera_dot_data; // 图像上位机打点协议数据
|
||||
static detector_camera_buffer_struct detector_camera_buffer; // 图像以及边界缓冲区信息
|
||||
|
||||
static fifo_struct detector_fifo;
|
||||
static uint8 detector_buffer[DETECTOR_BUFFER_SIZE]; // 数据存放数组
|
||||
float detector_parameter[DETECTOR_SET_PARAMETR_COUNT]; // 保存接收到的参数
|
||||
|
||||
////-------------------------------------------------------------------------------------------------------------------
|
||||
//// 函数简介 滴答客有线串口发送函数
|
||||
//// 参数说明 *buff 需要发送的数据地址
|
||||
//// 参数说明 length 需要发送的长度
|
||||
//// 返回参数 uint32 剩余未发送数据长度
|
||||
//// 使用示例
|
||||
////-------------------------------------------------------------------------------------------------------------------
|
||||
//uint32 detector_debug_uart_transfer (const uint8 *buff, uint32 length)
|
||||
//{
|
||||
// uart_write_buffer(DEBUG_UART_INDEX, buff, length);
|
||||
// return 0;
|
||||
//}
|
||||
|
||||
////-------------------------------------------------------------------------------------------------------------------
|
||||
//// 函数简介 滴答客有线串口接收函数
|
||||
//// 参数说明 *buff 需要接收的数据地址
|
||||
//// 参数说明 length 需要接收的长度
|
||||
//// 返回参数 uint32 实际接收长度
|
||||
//// 使用示例
|
||||
////-------------------------------------------------------------------------------------------------------------------
|
||||
//uint32 detector_debug_uart_receive (uint8 *buff, uint32 length)
|
||||
//{
|
||||
// return debug_read_ring_buffer(buff, length);
|
||||
//}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 滴答客自定义字节发送函数
|
||||
// 参数说明 data 需要发送的数据地址
|
||||
// 返回参数 uint8
|
||||
// 使用示例
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
static uint8 detector_custom_write_byte(const uint8 data)
|
||||
{
|
||||
// 自行实现字节发送
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 滴答客自定义发送函数
|
||||
// 参数说明 *buff 需要发送的数据地址
|
||||
// 参数说明 length 需要发送的长度
|
||||
// 返回参数 uint32 剩余未发送数据长度
|
||||
// 使用示例 如果数据传输方式并不在支持范围则可以自行实现
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
uint32 detector_custom_transfer (const uint8 *buff, uint32 length)
|
||||
{
|
||||
uint32 send_length;
|
||||
send_length = length;
|
||||
|
||||
while(send_length--)
|
||||
{
|
||||
detector_custom_write_byte(*buff);
|
||||
buff++;
|
||||
}
|
||||
|
||||
return send_length;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 滴答客自定义接收函数 按字节接收
|
||||
// 参数说明 *data 需要发送的数据地址
|
||||
// 返回参数 uint8 0:接收成功 1:接收失败
|
||||
// 注意事项 detector_custom_receive_byte 与 detector_custom_receive函数 只需要调用其中一个函数即可
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
uint8 detector_custom_receive_byte (uint8 data)
|
||||
{
|
||||
uint8 return_state = 0;
|
||||
// 自行实现字节发送
|
||||
if(FIFO_SUCCESS != fifo_write_buffer(&detector_fifo, &data, 1))
|
||||
{
|
||||
return_state = 1;
|
||||
}
|
||||
return return_state;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 滴答客自定义接收函数 按数组接收
|
||||
// 参数说明 *buff 需要发送的数据地址
|
||||
// 参数说明 length 需要发送的长度
|
||||
// 返回参数 uint8 0:接收成功 1:接收失败
|
||||
// 注意事项 detector_custom_receive_byte 与 detector_custom_receive函数 只需要调用其中一个函数即可
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
uint8 detector_custom_receive (uint8 *buff, uint32 length)
|
||||
{
|
||||
uint8 return_state = 0;
|
||||
|
||||
// 将接收到的数据写入FIFO
|
||||
if(FIFO_SUCCESS != fifo_write_buffer(&detector_fifo, buff, length))
|
||||
{
|
||||
return_state = 1;
|
||||
}
|
||||
|
||||
return return_state;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 滴答客发送函数
|
||||
// 参数说明 *send_data 需要发送的数据地址
|
||||
// 参数说明 send_length 需要发送的长度
|
||||
// 返回参数 uint32 剩余未发送数据长度
|
||||
// 使用示例
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
static uint32 detector_transfer (void *send_data, uint32 send_length)
|
||||
{
|
||||
return detector_transfer_callback((const uint8 *)send_data, send_length);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 滴答客求和函数
|
||||
// 参数说明 *buffer 需要校验的数据地址
|
||||
// 参数说明 length 校验长度
|
||||
// 返回参数 uint8 和值
|
||||
// 使用示例
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
static uint8 detector_sum (uint8 *buffer, uint32 length)
|
||||
{
|
||||
uint8 temp_sum = 0;
|
||||
|
||||
while(length--)
|
||||
{
|
||||
temp_sum += *buffer++;
|
||||
}
|
||||
|
||||
return temp_sum;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 滴答客 图像发送函数
|
||||
// 参数说明 camera_type 摄像头类型
|
||||
// 参数说明 *image_addr 图像首地址
|
||||
// 参数说明 boundary_num 图像中包含边界数量
|
||||
// 参数说明 width 图像宽度
|
||||
// 参数说明 height 图像高度
|
||||
// 返回参数 void
|
||||
// 使用示例
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
void detector_camera_data_send (detector_image_type_enum camera_type, void *image_addr, uint8 boundary_num, uint16 width, uint16 height)
|
||||
{
|
||||
uint32 image_size = 0;
|
||||
|
||||
detector_camera_data.head = DETECTOR_SEND_HEAD;
|
||||
detector_camera_data.function = DETECTOR_CAMERA_FUNCTION;
|
||||
detector_camera_data.camera_type = (camera_type << 5) | ((image_addr != NULL ? 0 : 1) << 4) | boundary_num;
|
||||
// 写入包长度信息,仅包含协议部分
|
||||
detector_camera_data.length = sizeof(detector_camera_struct);
|
||||
detector_camera_data.image_width = width;
|
||||
detector_camera_data.image_height = height;
|
||||
|
||||
// 首先发送帧头、功能、摄像头类型、以及宽度高度等信息
|
||||
detector_transfer(&detector_camera_data, sizeof(detector_camera_struct));
|
||||
|
||||
// 根据摄像头类型计算图像大小
|
||||
switch(camera_type)
|
||||
{
|
||||
case DETECTOR_OV7725_BIN:
|
||||
{
|
||||
image_size = width * height / 8;
|
||||
}break;
|
||||
|
||||
case DETECTOR_MT9V03X:
|
||||
{
|
||||
image_size = width * height;
|
||||
}break;
|
||||
|
||||
case DETECTOR_SCC8660:
|
||||
{
|
||||
image_size = width * height * 2;
|
||||
}break;
|
||||
}
|
||||
|
||||
// 发送图像数据
|
||||
if(NULL != image_addr)
|
||||
{
|
||||
detector_transfer(image_addr, image_size);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 滴答客 图像边线绘制函数
|
||||
// 参数说明 boundary_id 边线ID
|
||||
// 参数说明 dot_num 点数量
|
||||
// 参数说明 *dot_x 横坐标数据首地址
|
||||
// 参数说明 *dot_y 纵坐标数据首地址
|
||||
// 参数说明 width 图像宽度
|
||||
// 参数说明 height 图像高度
|
||||
// 返回参数 void
|
||||
// 使用示例
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
void detector_camera_dot_send (detector_camera_buffer_struct *buffer)
|
||||
{
|
||||
uint8 i;
|
||||
uint16 dot_bytes = 0; // 点字节数量
|
||||
wifi_spi_send_multi_struct multi_buffer;
|
||||
|
||||
dot_bytes = detector_camera_dot_data.dot_num;
|
||||
|
||||
if(detector_camera_dot_data.dot_type & (1 << 5))
|
||||
{
|
||||
dot_bytes *= 2;
|
||||
}
|
||||
|
||||
// 边线发送时 WIFI SPI采用多源地址发送函数,可以极大提高发送速度
|
||||
if(DETECTOR_WIFI_SPI == detector_transfer_type)
|
||||
{
|
||||
multi_buffer.source[0] = (uint8 *)&detector_camera_dot_data;
|
||||
multi_buffer.length[0] = sizeof(detector_camera_dot_struct);
|
||||
|
||||
for(i=0; i < DETECTOR_CAMERA_MAX_BOUNDARY; i++)
|
||||
{
|
||||
multi_buffer.source[i * 2 + 1] = buffer->boundary_x[i];
|
||||
multi_buffer.source[i * 2 + 2] = buffer->boundary_y[i];
|
||||
|
||||
multi_buffer.length[i * 2 + 1] = dot_bytes;
|
||||
multi_buffer.length[i * 2 + 2] = dot_bytes;
|
||||
}
|
||||
|
||||
wifi_spi_send_buffer_multi(&multi_buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 首先发送帧头、功能、边界编号、坐标长度、点个数
|
||||
detector_transfer(&detector_camera_dot_data, sizeof(detector_camera_dot_struct));
|
||||
|
||||
for(i=0; i < DETECTOR_CAMERA_MAX_BOUNDARY; i++)
|
||||
{
|
||||
// 判断是否发送横坐标数据
|
||||
if(NULL != buffer->boundary_x[i])
|
||||
{
|
||||
detector_transfer(buffer->boundary_x[i], dot_bytes);
|
||||
}
|
||||
|
||||
// 判断是否发送纵坐标数据
|
||||
if(NULL != buffer->boundary_y[i])
|
||||
{
|
||||
// 如果没有纵坐标数据,则表示每一行只有一个边界
|
||||
// 指定了横纵坐标数据,这种方式可以实现同一行多个边界的情况,例如搜线算法能够搜索出回弯。
|
||||
detector_transfer(buffer->boundary_y[i], dot_bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 滴答客 虚拟示波器发送函数
|
||||
// 参数说明 *detector_oscilloscope 示波器数据结构体
|
||||
// 返回参数 void
|
||||
// 使用示例 detector_oscilloscope_send(&detector_oscilloscope_data);
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
void detector_oscilloscope_send (detector_oscilloscope_struct *detector_oscilloscope)
|
||||
{
|
||||
uint8 packet_size;
|
||||
|
||||
// 将高四位清空
|
||||
detector_oscilloscope->channel_num &= 0x0f;
|
||||
|
||||
zf_assert(DETECTOR_SET_OSCILLOSCOPE_COUNT >= detector_oscilloscope->channel_num);
|
||||
|
||||
// 帧头
|
||||
detector_oscilloscope->head = DETECTOR_SEND_HEAD;
|
||||
|
||||
// 写入包长度信息
|
||||
packet_size = sizeof(detector_oscilloscope_struct) - (DETECTOR_SET_OSCILLOSCOPE_COUNT - detector_oscilloscope->channel_num) * 4;
|
||||
detector_oscilloscope->length = packet_size;
|
||||
|
||||
// 写入功能字与通道数量
|
||||
detector_oscilloscope->channel_num |= DETECTOR_CAMERA_OSCILLOSCOPE;
|
||||
|
||||
// 和校验计算
|
||||
detector_oscilloscope->check_sum = 0;
|
||||
detector_oscilloscope->check_sum = detector_sum((uint8 *)&detector_oscilloscope_data, packet_size);
|
||||
|
||||
// 数据在调用本函数之前,由用户将需要发送的数据写入detector_oscilloscope_data.data[]
|
||||
|
||||
detector_transfer((uint8 *)detector_oscilloscope, packet_size);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 滴答客图像信息配置函数
|
||||
// 参数说明 camera_type 图像类型
|
||||
// 参数说明 image_addr 图像地址 如果传递NULL参数则表示只发送边线信息到上位机
|
||||
// 参数说明 width 图像宽度
|
||||
// 参数说明 height 图像高度
|
||||
// 返回参数 void
|
||||
// 使用示例 detector_camera_information_config(DETECTOR_MT9V03X, mt9v03x_image[0], MT9V03X_W, MT9V03X_H);
|
||||
// 备注信息
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
void detector_camera_information_config (detector_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height)
|
||||
{
|
||||
detector_camera_dot_data.head = DETECTOR_SEND_HEAD;
|
||||
detector_camera_dot_data.function = DETECTOR_CAMERA_DOT_FUNCTION;
|
||||
// 写入包长度信息
|
||||
detector_camera_dot_data.length = sizeof(detector_camera_dot_struct);
|
||||
|
||||
detector_camera_buffer.camera_type = camera_type;
|
||||
detector_camera_buffer.image_addr = image_addr;
|
||||
detector_camera_buffer.width = width;
|
||||
detector_camera_buffer.height = height;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 滴答客图像边线发送配置函数
|
||||
// 参数说明 boundary_type 边界类型
|
||||
// 参数说明 dot_num 一条边界有多少个点
|
||||
// 参数说明 dot_x1 存放边线1横坐标的地址 如果传递NULL参数则表示不发送边线1
|
||||
// 参数说明 dot_x2 存放边线2横坐标的地址 如果传递NULL参数则表示不发送边线2
|
||||
// 参数说明 dot_x3 存放边线3横坐标的地址 如果传递NULL参数则表示不发送边线3
|
||||
// 参数说明 dot_y1 存放边线1纵坐标的地址 如果传递NULL参数则表示不发送边线1
|
||||
// 参数说明 dot_y2 存放边线2纵坐标的地址 如果传递NULL参数则表示不发送边线2
|
||||
// 参数说明 dot_y3 存放边线3纵坐标的地址 如果传递NULL参数则表示不发送边线3
|
||||
// 返回参数 void
|
||||
// 使用示例 detector_camera_config(X_BOUNDARY, MT9V03X_H, x1_boundary, x2_boundary, x3_boundary, NULL, NULL, NULL); // 图像发送时包含三条边线,边线只有横坐标
|
||||
// 使用示例 detector_camera_config(Y_BOUNDARY, MT9V03X_W, NULL, NULL, NULL, y1_boundary, y2_boundary, y3_boundary); // 图像发送时包含三条边线,边线只有纵坐标
|
||||
// 使用示例 detector_camera_config(XY_BOUNDARY, 160, xy_x1_boundary, xy_x2_boundary, xy_x3_boundary, xy_y1_boundary, xy_y2_boundary, xy_y3_boundary); // 图像发送时包含三条边线,边线包含横纵坐标
|
||||
// 备注信息
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
void detector_camera_boundary_config (detector_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3)
|
||||
{
|
||||
uint8 i = 0;
|
||||
uint8 boundary_num = 0;
|
||||
uint8 boundary_data_type = 0;
|
||||
|
||||
// 检查图像发送缓冲区是否准备就绪, 调用此函数之前需要先调用detector_camera_config设置好图像信息
|
||||
zf_assert(0 != detector_camera_buffer.camera_type);
|
||||
|
||||
detector_camera_dot_data.dot_num = dot_num;
|
||||
|
||||
detector_camera_dot_data.valid_flag = 0;
|
||||
for(i = 0; i < 3; i++)
|
||||
{
|
||||
detector_camera_buffer.boundary_x[i] = NULL;
|
||||
detector_camera_buffer.boundary_y[i] = NULL;
|
||||
}
|
||||
|
||||
switch(boundary_type)
|
||||
{
|
||||
case X_BOUNDARY:
|
||||
{
|
||||
if(NULL != dot_x1)
|
||||
{
|
||||
boundary_num++;
|
||||
detector_camera_dot_data.valid_flag |= 1 << 0;
|
||||
detector_camera_buffer.boundary_x[i++] = dot_x1;
|
||||
}
|
||||
if(NULL != dot_x2)
|
||||
{
|
||||
boundary_num++;
|
||||
detector_camera_dot_data.valid_flag |= 1 << 1;
|
||||
detector_camera_buffer.boundary_x[i++] = dot_x2;
|
||||
}
|
||||
if(NULL != dot_x3)
|
||||
{
|
||||
boundary_num++;
|
||||
detector_camera_dot_data.valid_flag |= 1 << 2;
|
||||
detector_camera_buffer.boundary_x[i++] = dot_x3;
|
||||
}
|
||||
|
||||
if(255 < detector_camera_buffer.height)
|
||||
{
|
||||
boundary_data_type = 1;
|
||||
}
|
||||
}break;
|
||||
|
||||
case Y_BOUNDARY:
|
||||
{
|
||||
if(NULL != dot_y1)
|
||||
{
|
||||
boundary_num++;
|
||||
detector_camera_dot_data.valid_flag |= 1 << 0;
|
||||
detector_camera_buffer.boundary_y[i++] = dot_y1;
|
||||
}
|
||||
if(NULL != dot_y2)
|
||||
{
|
||||
boundary_num++;
|
||||
detector_camera_dot_data.valid_flag |= 1 << 1;
|
||||
detector_camera_buffer.boundary_y[i++] = dot_y2;
|
||||
}
|
||||
if(NULL != dot_y3)
|
||||
{
|
||||
boundary_num++;
|
||||
detector_camera_dot_data.valid_flag |= 1 << 2;
|
||||
detector_camera_buffer.boundary_y[i++] = dot_y3;
|
||||
}
|
||||
|
||||
if(255 < detector_camera_buffer.width)
|
||||
{
|
||||
boundary_data_type = 1;
|
||||
}
|
||||
}break;
|
||||
|
||||
case XY_BOUNDARY:
|
||||
{
|
||||
if((NULL != dot_x1) && (NULL != dot_y1))
|
||||
{
|
||||
boundary_num++;
|
||||
detector_camera_dot_data.valid_flag |= 1 << 0;
|
||||
detector_camera_buffer.boundary_x[i] = dot_x1;
|
||||
detector_camera_buffer.boundary_y[i++] = dot_y1;
|
||||
}
|
||||
if((NULL != dot_x2) && (NULL != dot_y2))
|
||||
{
|
||||
boundary_num++;
|
||||
detector_camera_dot_data.valid_flag |= 1 << 1;
|
||||
detector_camera_buffer.boundary_x[i] = dot_x2;
|
||||
detector_camera_buffer.boundary_y[i++] = dot_y2;
|
||||
}
|
||||
if((NULL != dot_x3) && (NULL != dot_y3))
|
||||
{
|
||||
boundary_num++;
|
||||
detector_camera_dot_data.valid_flag |= 1 << 2;
|
||||
detector_camera_buffer.boundary_x[i] = dot_x3;
|
||||
detector_camera_buffer.boundary_y[i++] = dot_y3;
|
||||
}
|
||||
|
||||
if((255 < detector_camera_buffer.width) || (255 < detector_camera_buffer.height))
|
||||
{
|
||||
boundary_data_type = 1;
|
||||
}
|
||||
}break;
|
||||
|
||||
case NO_BOUNDARY:break;
|
||||
}
|
||||
|
||||
detector_camera_dot_data.dot_type = (boundary_type << 6) | (boundary_data_type << 5) | boundary_num;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 滴答客发送摄像头图像
|
||||
// 参数说明 void
|
||||
// 返回参数 void
|
||||
// 使用示例
|
||||
// 备注信息 在调用图像发送函数之前,请务必调用一次detector_camera_config函数,将对应的参数设置好
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
void detector_camera_send (void)
|
||||
{
|
||||
// 检查图像发送缓冲区是否准备就绪
|
||||
zf_assert(0 != detector_camera_buffer.camera_type);
|
||||
|
||||
detector_camera_data_send(detector_camera_buffer.camera_type, detector_camera_buffer.image_addr, detector_camera_dot_data.dot_type & 0x0f, detector_camera_buffer.width, detector_camera_buffer.height);
|
||||
|
||||
if(detector_camera_dot_data.dot_type & 0x0f)
|
||||
{
|
||||
detector_camera_dot_send(&detector_camera_buffer);
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 滴答客解析接收到的数据
|
||||
// 参数说明 void
|
||||
// 返回参数 void
|
||||
// 使用示例 函数只需要放到周期运行的PIT中断或者主循环即可
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
void detector_data_analysis (void)
|
||||
{
|
||||
uint8 temp_sum;
|
||||
uint32 read_length;
|
||||
detector_parameter_struct *receive_packet;
|
||||
|
||||
// 这里使用uint32进行定义,目的是为了保证数组四字节对齐
|
||||
uint32 temp_buffer[DETECTOR_BUFFER_SIZE / 4];
|
||||
|
||||
// 尝试读取数据, 如果不是自定义的传输方式则从接收回调中读取数据
|
||||
if(DETECTOR_CUSTOM != detector_transfer_type)
|
||||
{
|
||||
read_length = detector_receive_callback((uint8 *)temp_buffer, DETECTOR_BUFFER_SIZE);
|
||||
if(read_length)
|
||||
{
|
||||
// 将读取到的数据写入FIFO
|
||||
fifo_write_buffer(&detector_fifo, (uint8 *)temp_buffer, read_length);
|
||||
}
|
||||
}
|
||||
|
||||
while(sizeof(detector_parameter_struct) <= fifo_used(&detector_fifo))
|
||||
{
|
||||
read_length = sizeof(detector_parameter_struct);
|
||||
fifo_read_buffer(&detector_fifo, (uint8 *)temp_buffer, &read_length, FIFO_READ_ONLY);
|
||||
|
||||
if(DETECTOR_RECEIVE_HEAD != ((uint8 *)temp_buffer)[0])
|
||||
{
|
||||
// 没有帧头则从FIFO中去掉第一个数据
|
||||
read_length = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 找到帧头
|
||||
receive_packet = (detector_parameter_struct *)temp_buffer;
|
||||
temp_sum = receive_packet->check_sum;
|
||||
receive_packet->check_sum = 0;
|
||||
if(temp_sum == detector_sum((uint8 *)temp_buffer, sizeof(detector_parameter_struct)))
|
||||
{
|
||||
// 和校验成功保存数据
|
||||
detector_parameter[receive_packet->channel - 1] = receive_packet->data;
|
||||
}
|
||||
else
|
||||
{
|
||||
read_length = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// 丢弃无需使用的数据
|
||||
fifo_read_buffer(&detector_fifo, NULL, &read_length, FIFO_READ_AND_CLEAN);
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 滴答客 初始化
|
||||
// 参数说明 transfer_type 选择使用哪种方式传输数据
|
||||
// 返回参数 void
|
||||
// 使用示例
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
void detector_init (detector_transfer_type_enum transfer_type)
|
||||
{
|
||||
detector_transfer_type = transfer_type;
|
||||
|
||||
fifo_init(&detector_fifo, FIFO_DATA_8BIT, detector_buffer, DETECTOR_BUFFER_SIZE);
|
||||
|
||||
switch(detector_transfer_type)
|
||||
{
|
||||
case DETECTOR_DEBUG_UART:
|
||||
{
|
||||
detector_transfer_callback = debug_send_buffer;
|
||||
detector_receive_callback = debug_read_ring_buffer;
|
||||
}break;
|
||||
|
||||
case DETECTOR_WIRELESS_UART:
|
||||
{
|
||||
detector_transfer_callback = wireless_uart_send_buffer;
|
||||
detector_receive_callback = wireless_uart_read_buffer;
|
||||
}break;
|
||||
|
||||
case DETECTOR_CH9141:
|
||||
{
|
||||
detector_transfer_callback = bluetooth_ch9141_send_buffer;
|
||||
detector_receive_callback = bluetooth_ch9141_read_buffer;
|
||||
}break;
|
||||
|
||||
case DETECTOR_WIFI_UART:
|
||||
{
|
||||
detector_transfer_callback = wifi_uart_send_buffer;
|
||||
detector_receive_callback = wifi_uart_read_buffer;
|
||||
}break;
|
||||
|
||||
case DETECTOR_WIFI_SPI:
|
||||
{
|
||||
detector_transfer_callback = wifi_spi_send_buffer;
|
||||
detector_receive_callback = wifi_spi_read_buffer;
|
||||
}break;
|
||||
|
||||
case DETECTOR_CUSTOM:
|
||||
{
|
||||
// 根据自己的需求 自行实现detector_custom_write_byte函数,完成数据的传输
|
||||
detector_transfer_callback = detector_custom_transfer;
|
||||
|
||||
// 无需设置接收回调
|
||||
|
||||
// 在合适的位置调用detector_custom_receive 或者 detector_custom_receive_byte函数即可实现数据接收
|
||||
// detector_custom_receive 或者 detector_custom_receive_byte函数 只需调用一个函数即可,根据自己的需求是按字节接收数据还是按照数据接收数据
|
||||
// 接收到的数据会被写入detector_fifo中, 以备解析函数使用
|
||||
//detector_receive_callback = detector_custom_receive;
|
||||
|
||||
}break;
|
||||
}
|
||||
}
|
||||
173
libraries/zf_device/zf_device_detector.h
Normal file
173
libraries/zf_device/zf_device_detector.h
Normal file
@@ -0,0 +1,173 @@
|
||||
/*********************************************************************************************************************
|
||||
* CH32V307VCT6 Opensourec Library 即(CH32V307VCT6 开源库)是一个基于官方 SDK 接口的第三方开源库
|
||||
* Copyright (c) 2022 SEEKFREE 逐飞科技
|
||||
*
|
||||
* 本文件是CH32V307VCT6 开源库的一部分
|
||||
*
|
||||
* CH32V307VCT6 开源库 是免费软件
|
||||
* 您可以根据自由软件基金会发布的 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 文件 版本说明
|
||||
* 开发环境 MounRiver Studio V1.8.1
|
||||
* 适用平台 CH32V307VCT6
|
||||
* 店铺链接 https://seekfree.taobao.com/
|
||||
*
|
||||
* 修改记录
|
||||
* 日期 作者 备注
|
||||
* 2023-05-25 大W first version
|
||||
********************************************************************************************************************/
|
||||
|
||||
#ifndef _zf_device_detector_h_
|
||||
#define _zf_device_detector_h_
|
||||
|
||||
#include "zf_common_typedef.h"
|
||||
#include "zf_common_debug.h"
|
||||
|
||||
// 定义接收FIFO大小
|
||||
#define DETECTOR_BUFFER_SIZE ( 0x40 )
|
||||
|
||||
// 定义示波器的最大通道数量
|
||||
#define DETECTOR_SET_OSCILLOSCOPE_COUNT ( 0x08 )
|
||||
|
||||
// 定义参数调试的最大通道数量
|
||||
#define DETECTOR_SET_PARAMETR_COUNT ( 0x08 )
|
||||
|
||||
// 定义图像边线最大数量
|
||||
#define DETECTOR_CAMERA_MAX_BOUNDARY ( 0x08 )
|
||||
|
||||
// 单片机往上位机发送的帧头
|
||||
#define DETECTOR_SEND_HEAD ( 0xAA )
|
||||
|
||||
// 摄像头类
|
||||
#define DETECTOR_CAMERA_FUNCTION ( 0x02 )
|
||||
#define DETECTOR_CAMERA_DOT_FUNCTION ( 0x03 )
|
||||
#define DETECTOR_CAMERA_OSCILLOSCOPE ( 0x10 )
|
||||
|
||||
// 上位机往单片机发送的帧头
|
||||
#define DETECTOR_RECEIVE_HEAD ( 0x55 )
|
||||
|
||||
// 参数设置类
|
||||
#define DETECTOR_RECEIVE_SET_PARAMETER ( 0x20 )
|
||||
|
||||
|
||||
// 数据发送设备枚举
|
||||
typedef enum
|
||||
{
|
||||
DETECTOR_DEBUG_UART, // 调试串口 使用的串口由DEBUG_UART_INDEX宏定义指定
|
||||
DETECTOR_WIRELESS_UART, // 无线转串口
|
||||
DETECTOR_CH9141, // 9141蓝牙
|
||||
DETECTOR_WIFI_UART, // WIFI转串口
|
||||
DETECTOR_WIFI_SPI, // 高速WIFI SPI
|
||||
DETECTOR_CUSTOM, // 自定义通讯方式 需要自行detector_custom_write_byte函数中实现数据发送
|
||||
}detector_transfer_type_enum;
|
||||
|
||||
|
||||
// 摄像头类型枚举
|
||||
typedef enum
|
||||
{
|
||||
// 按照摄像头型号定义
|
||||
DETECTOR_OV7725_BIN = 1,
|
||||
DETECTOR_MT9V03X,
|
||||
DETECTOR_SCC8660,
|
||||
|
||||
// 按照图像类型定义
|
||||
DETECTOR_BINARY = 1,
|
||||
DETECTOR_GRAY,
|
||||
DETECTOR_RGB565,
|
||||
}detector_image_type_enum;
|
||||
|
||||
// 摄像头类型枚举
|
||||
typedef enum
|
||||
{
|
||||
// 按照摄像头型号定义
|
||||
X_BOUNDARY, // 发送的图像中边界信息只包含X,也就是只有横坐标信息,纵坐标根据图像高度得到
|
||||
Y_BOUNDARY, // 发送的图像中边界信息只包含Y,也就是只有纵坐标信息,横坐标根据图像宽度得到,通常很少有这样的需求
|
||||
XY_BOUNDARY, // 发送的图像中边界信息包含X与Y,这样可以指定点在任意位置,就可以方便显示出回弯的效果
|
||||
NO_BOUNDARY, // 发送的图像中没有边线信息
|
||||
}detector_boundary_type_enum;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8 head; // 帧头
|
||||
uint8 channel_num; // 高四位为功能字 低四位为通道数量
|
||||
uint8 check_sum; // 和校验
|
||||
uint8 length; // 包长度
|
||||
float data[DETECTOR_SET_OSCILLOSCOPE_COUNT]; // 通道数据
|
||||
}detector_oscilloscope_struct;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8 head; // 帧头
|
||||
uint8 function; // 功能字
|
||||
uint8 camera_type; // 低四位表示边界数量 第四位表示是否有图像数据 例如0x13:其中3表示一副图像有三条边界(通常是左边界、中线、右边界)、1表示没有图像数据
|
||||
uint8 length; // 包长度(仅包含协议部分)
|
||||
uint16 image_width; // 图像宽度
|
||||
uint16 image_height; // 图像高度
|
||||
}detector_camera_struct;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8 head; // 帧头
|
||||
uint8 function; // 功能字
|
||||
uint8 dot_type; // 点类型 BIT5:1:坐标是16位的 0:坐标是8位的 BIT7-BIT6:0:只有X坐标 1:只有Y坐标 2:X和Y坐标都有 BIT3-BIT0:边界数量
|
||||
uint8 length; // 包长度(仅包含协议部分)
|
||||
uint16 dot_num; // 画点数量
|
||||
uint8 valid_flag; // 通道标识
|
||||
uint8 reserve; // 保留
|
||||
}detector_camera_dot_struct;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void *image_addr; // 摄像头地址
|
||||
uint16 width; // 图像宽度
|
||||
uint16 height; // 图像高度
|
||||
detector_image_type_enum camera_type; // 摄像头类型
|
||||
void *boundary_x[DETECTOR_CAMERA_MAX_BOUNDARY]; // 边界横坐标数组地址
|
||||
void *boundary_y[DETECTOR_CAMERA_MAX_BOUNDARY]; // 边界纵坐标数组地址
|
||||
}detector_camera_buffer_struct;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8 head; // 帧头
|
||||
uint8 function; // 功能字
|
||||
uint8 channel; // 通道
|
||||
uint8 check_sum; // 和校验
|
||||
float data; // 数据
|
||||
}detector_parameter_struct;
|
||||
|
||||
|
||||
extern detector_oscilloscope_struct detector_oscilloscope_data; // 虚拟示波器数据
|
||||
extern float detector_parameter[DETECTOR_SET_PARAMETR_COUNT]; // 保存接收到的参数
|
||||
|
||||
|
||||
void detector_oscilloscope_send (detector_oscilloscope_struct *detector_oscilloscope);
|
||||
|
||||
void detector_camera_information_config (detector_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height);
|
||||
void detector_camera_boundary_config (detector_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3);
|
||||
void detector_camera_send (void);
|
||||
|
||||
void detector_data_analysis (void);
|
||||
void detector_init (detector_transfer_type_enum transfer_type);
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
779
libraries/zf_device/zf_device_dl1a.c
Normal file
779
libraries/zf_device/zf_device_dl1a.c
Normal file
@@ -0,0 +1,779 @@
|
||||
/*********************************************************************************************************************
|
||||
* CH32V307VCT6 Opensourec Library 即(CH32V307VCT6 开源库)是一个基于官方 SDK 接口的第三方开源库
|
||||
* Copyright (c) 2022 SEEKFREE 逐飞科技
|
||||
*
|
||||
* 本文件是CH32V307VCT6 开源库的一部分
|
||||
*
|
||||
* CH32V307VCT6 开源库 是免费软件
|
||||
* 您可以根据自由软件基金会发布的 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 文件 版本说明
|
||||
* 开发环境 MounRiver Studio V1.8.1
|
||||
* 适用平台 CH32V307VCT6
|
||||
* 店铺链接 https://seekfree.taobao.com/
|
||||
*
|
||||
* 修改记录
|
||||
* 日期 作者 备注
|
||||
* 2023-03-18 大W first version
|
||||
********************************************************************************************************************/
|
||||
/*********************************************************************************************************************
|
||||
* 接线定义:
|
||||
* ------------------------------------
|
||||
* 模块管脚 单片机管脚
|
||||
* SCL 查看 zf_device_dl1a.h 中 DL1A_SCL_PIN 宏定义
|
||||
* SDA 查看 zf_device_dl1a.h 中 DL1A_SDA_PIN 宏定义
|
||||
* XS 查看 zf_device_dl1a.h 中 DL1A_XS_PIN 宏定义
|
||||
* VCC 5V 电源
|
||||
* GND 电源地
|
||||
* ------------------------------------
|
||||
********************************************************************************************************************/
|
||||
|
||||
#include "zf_common_debug.h"
|
||||
#include "zf_driver_delay.h"
|
||||
#include "zf_driver_soft_iic.h"
|
||||
#include "zf_device_dl1a.h"
|
||||
#include "zf_device_type.h"
|
||||
|
||||
static uint8 dl1a_init_flag = 0;
|
||||
uint8 dl1a_finsh_flag = 0;
|
||||
uint16 dl1a_distance_mm = 8192;
|
||||
|
||||
#if DL1A_USE_SOFT_IIC
|
||||
static soft_iic_info_struct dl1a_iic_struct;
|
||||
|
||||
#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
|
||||
#define dl1a_write_array(data, len) (iic_write_8bit_array(DL1A_IIC, DL1A_DEV_ADDR, (data), (len)))
|
||||
#define dl1a_write_register(reg, data) (iic_write_8bit_register(DL1A_IIC, DL1A_DEV_ADDR, (reg), (data)))
|
||||
#define dl1a_read_register(reg) (iic_read_8bit_register(DL1A_IIC, DL1A_DEV_ADDR, (reg)))
|
||||
#define dl1a_read_registers(reg, data, len) (iic_read_8bit_registers(DL1A_IIC, DL1A_DEV_ADDR, (reg), (data), (len)))
|
||||
#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(0 <= limit_mcps || 511.99 >= limit_mcps);
|
||||
uint8 data_buffer[3];
|
||||
uint16 limit_mcps_16bit = (uint16)(limit_mcps * (1 << 7));
|
||||
|
||||
data_buffer[0] = DL1A_FINAL_RANGE_CONFIG_MIN_COUNT_RATE_RTN_LIMIT;
|
||||
data_buffer[1] = ((limit_mcps_16bit >> 8) & 0xFF);
|
||||
data_buffer[2] = (limit_mcps_16bit & 0xFF);
|
||||
|
||||
dl1a_write_array(data_buffer, 3);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 返回以毫米为单位的范围读数
|
||||
// 参数说明 void
|
||||
// 返回参数 void
|
||||
// 使用示例 dl1a_get_distance();
|
||||
// 备注信息 在开始单次射程测量后也调用此函数
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
void dl1a_get_distance (void)
|
||||
{
|
||||
if(dl1a_init_flag)
|
||||
{
|
||||
uint8 reg_databuffer[3];
|
||||
|
||||
dl1a_read_registers(DL1A_RESULT_INTERRUPT_STATUS, reg_databuffer, 1);
|
||||
if(0 != (reg_databuffer[0] & 0x07))
|
||||
{
|
||||
// 假设线性度校正增益为默认值 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);
|
||||
dl1a_init_flag = 1;
|
||||
|
||||
#if DL1A_INT_ENABLE
|
||||
exti_init(DL1A_INT_PIN, EXTI_TRIGGER_FALLING);
|
||||
dl1a_int_handler();
|
||||
dl1a_finsh_flag = 0;
|
||||
#endif
|
||||
set_tof_type(TOF_DL1A, dl1a_int_handler);
|
||||
}while(0);
|
||||
|
||||
return return_state;
|
||||
}
|
||||
208
libraries/zf_device/zf_device_dl1a.h
Normal file
208
libraries/zf_device/zf_device_dl1a.h
Normal file
@@ -0,0 +1,208 @@
|
||||
/*********************************************************************************************************************
|
||||
* CH32V307VCT6 Opensourec Library 即(CH32V307VCT6 开源库)是一个基于官方 SDK 接口的第三方开源库
|
||||
* Copyright (c) 2022 SEEKFREE 逐飞科技
|
||||
*
|
||||
* 本文件是CH32V307VCT6 开源库的一部分
|
||||
*
|
||||
* CH32V307VCT6 开源库 是免费软件
|
||||
* 您可以根据自由软件基金会发布的 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 文件 版本说明
|
||||
* 开发环境 MounRiver Studio V1.8.1
|
||||
* 适用平台 CH32V307VCT6
|
||||
* 店铺链接 https://seekfree.taobao.com/
|
||||
*
|
||||
* 修改记录
|
||||
* 日期 作者 备注
|
||||
* 2023-03-18 大W first version
|
||||
********************************************************************************************************************/
|
||||
/*********************************************************************************************************************
|
||||
* 接线定义:
|
||||
* ------------------------------------
|
||||
* 模块管脚 单片机管脚
|
||||
* SCL 查看 zf_device_dl1a.h 中 DL1A_SCL_PIN 宏定义
|
||||
* SDA 查看 zf_device_dl1a.h 中 DL1A_SDA_PIN 宏定义
|
||||
* XS 查看 zf_device_dl1a.h 中 DL1A_XS_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 通信速率
|
||||
|
||||
#define DL1A_USE_SOFT_IIC ( 1 ) // 默认使用软件 IIC 方式驱动 建议使用软件 IIC 方式
|
||||
#if DL1A_USE_SOFT_IIC // 这两段 颜色正常的才是正确的 颜色灰的就是没有用的
|
||||
//====================================================软件 IIC 驱动====================================================
|
||||
#define DL1A_SOFT_IIC_DELAY ( 10 ) // 软件 IIC 的时钟延时周期 数值越小 IIC 通信速率越快
|
||||
#define DL1A_SCL_PIN ( D6 ) // 软件 IIC SCL 引脚 连接 DL1A 的 SCL 引脚
|
||||
#define DL1A_SDA_PIN ( D5 ) // 软件 IIC SDA 引脚 连接 DL1A 的 SDA 引脚
|
||||
//====================================================软件 IIC 驱动====================================================
|
||||
#else
|
||||
//====================================================硬件 IIC 驱动====================================================
|
||||
#define DL1A_IIC_SPEED ( 40*1000 ) // 硬件 IIC 通信速率 最高 400KHz 不建议低于 40KHz
|
||||
#define DL1A_IIC ( 暂不支持 ) // 硬件 IIC SCL 引脚 连接 DL1A 的 SCL 引脚
|
||||
#define DL1A_SCL_PIN ( 暂不支持 ) // 硬件 IIC SCL 引脚 连接 DL1A 的 SCL 引脚
|
||||
#define DL1A_SDA_PIN ( 暂不支持 ) // 硬件 IIC SDA 引脚 连接 DL1A 的 SDA 引脚
|
||||
//====================================================硬件 IIC 驱动====================================================
|
||||
#endif
|
||||
|
||||
#define DL1A_XS_PIN ( E10 )
|
||||
#define DL1A_INT_ENABLE ( 0 ) // 是否启用 INT 引脚 启用则会自动更新数据
|
||||
#if DL1A_INT_ENABLE
|
||||
#define DL1A_INT_PIN ( C13 ) // 未定义引脚,可以不接。
|
||||
#endif
|
||||
#define DL1A_TIMEOUT_COUNT (0x00FF) // 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 内部地址================================================
|
||||
|
||||
#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 )
|
||||
|
||||
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;
|
||||
|
||||
extern uint8 dl1a_finsh_flag;
|
||||
extern uint16 dl1a_distance_mm;
|
||||
|
||||
void dl1a_get_distance (void);
|
||||
|
||||
uint8 dl1a_init (void);
|
||||
|
||||
#endif
|
||||
|
||||
217
libraries/zf_device/zf_device_dl1b.c
Normal file
217
libraries/zf_device/zf_device_dl1b.c
Normal file
@@ -0,0 +1,217 @@
|
||||
/*********************************************************************************************************************
|
||||
* MM32F527X-E9P Opensourec Library 即(MM32F527X-E9P 开源库)是一个基于官方 SDK 接口的第三方开源库
|
||||
* Copyright (c) 2022 SEEKFREE 逐飞科技
|
||||
*
|
||||
* 本文件是 MM32F527X-E9P 开源库的一部分
|
||||
*
|
||||
* MM32F527X-E9P 开源库 是免费软件
|
||||
* 您可以根据自由软件基金会发布的 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 文件 版本说明
|
||||
* 开发环境 MounRiver Studio V1.8.1
|
||||
* 适用平台 CH32V307VCT6
|
||||
* 店铺链接 https://seekfree.taobao.com/
|
||||
*
|
||||
* 修改记录
|
||||
* 日期 作者 备注
|
||||
* 2022-08-10 Teternal first version
|
||||
********************************************************************************************************************/
|
||||
/*********************************************************************************************************************
|
||||
* 接线定义:
|
||||
* ------------------------------------
|
||||
* 模块管脚 单片机管脚
|
||||
* SCL 查看 zf_device_dl1b.h 中 DL1B_SCL_PIN 宏定义
|
||||
* SDA 查看 zf_device_dl1b.h 中 DL1B_SDA_PIN 宏定义
|
||||
* XS 查看 zf_device_dl1b.h 中 DL1B_XS_PIN 宏定义
|
||||
* VCC 5V 电源
|
||||
* GND 电源地
|
||||
* ------------------------------------
|
||||
********************************************************************************************************************/
|
||||
|
||||
#include "zf_common_debug.h"
|
||||
|
||||
#include "zf_driver_delay.h"
|
||||
#include "zf_driver_exti.h"
|
||||
#include "zf_driver_soft_iic.h"
|
||||
|
||||
#include "zf_device_dl1b.h"
|
||||
#include "zf_device_config.h"
|
||||
#include "zf_device_type.h"
|
||||
|
||||
static uint8 dl1b_init_flag = 0;
|
||||
uint8 dl1b_finsh_flag = 0;
|
||||
uint16 dl1b_distance_mm = 8192;
|
||||
|
||||
#if DL1B_USE_SOFT_IIC
|
||||
static soft_iic_info_struct dl1b_iic_struct;
|
||||
|
||||
#define dl1b_transfer_8bit_array(tdata, tlen, rdata, rlen) (soft_iic_transfer_8bit_array(&dl1b_iic_struct, (tdata), (tlen), (rdata), (rlen)))
|
||||
#else
|
||||
#define dl1b_transfer_8bit_array(tdata, tlen, rdata, rlen) (iic_transfer_8bit_array(DL1B_IIC, DL1B_DEV_ADDR, (tdata), (tlen), (rdata), (rlen)))
|
||||
#endif
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 返回以毫米为单位的范围读数
|
||||
// 参数说明 void
|
||||
// 返回参数 void
|
||||
// 使用示例 dl1b_get_distance();
|
||||
// 备注信息 在开始单次射程测量后也调用此函数
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
void dl1b_get_distance (void)
|
||||
{
|
||||
if(dl1b_init_flag)
|
||||
{
|
||||
uint8 data_buffer[3];
|
||||
int16 dl1b_distance_temp = 0;
|
||||
|
||||
data_buffer[0] = DL1B_GPIO__TIO_HV_STATUS >> 8;
|
||||
data_buffer[1] = DL1B_GPIO__TIO_HV_STATUS & 0xFF;
|
||||
dl1b_transfer_8bit_array(data_buffer, 2, &data_buffer[2], 1);
|
||||
|
||||
if(data_buffer[2])
|
||||
{
|
||||
|
||||
data_buffer[0] = DL1B_SYSTEM__INTERRUPT_CLEAR >> 8;
|
||||
data_buffer[1] = DL1B_SYSTEM__INTERRUPT_CLEAR & 0xFF;
|
||||
data_buffer[2] = 0x01;
|
||||
dl1b_transfer_8bit_array(data_buffer, 3, data_buffer, 0);// clear Interrupt
|
||||
|
||||
data_buffer[0] = DL1B_RESULT__RANGE_STATUS >> 8;
|
||||
data_buffer[1] = DL1B_RESULT__RANGE_STATUS & 0xFF;
|
||||
dl1b_transfer_8bit_array(data_buffer, 2, &data_buffer[2], 1);
|
||||
|
||||
if(0x89 == data_buffer[2])
|
||||
{
|
||||
data_buffer[0] = DL1B_RESULT__FINAL_CROSSTALK_CORRECTED_RANGE_MM_SD0 >> 8;
|
||||
data_buffer[1] = DL1B_RESULT__FINAL_CROSSTALK_CORRECTED_RANGE_MM_SD0 & 0xFF;
|
||||
dl1b_transfer_8bit_array(data_buffer, 2, data_buffer, 2);
|
||||
dl1b_distance_temp = data_buffer[0];
|
||||
dl1b_distance_temp = (dl1b_distance_temp << 8) | data_buffer[1];
|
||||
|
||||
if(dl1b_distance_temp > 4000 || dl1b_distance_temp < 0)
|
||||
{
|
||||
dl1b_distance_mm = 8192;
|
||||
dl1b_finsh_flag = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
dl1b_distance_mm = dl1b_distance_temp;
|
||||
dl1b_finsh_flag = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dl1b_distance_mm = 8192;
|
||||
dl1b_finsh_flag = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dl1b_distance_mm = 8192;
|
||||
dl1b_finsh_flag = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 DL1B INT 中断响应处理函数
|
||||
// 参数说明 void
|
||||
// 返回参数 void
|
||||
// 使用示例 dl1b_int_handler();
|
||||
// 备注信息 本函数需要在 DL1B_INT_PIN 对应的外部中断处理函数中调用
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
void dl1b_int_handler (void)
|
||||
{
|
||||
#if DL1B_INT_ENABLE
|
||||
dl1b_get_distance();
|
||||
#endif
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 初始化 DL1B
|
||||
// 参数说明 void
|
||||
// 返回参数 uint8 1-初始化失败 0-初始化成功
|
||||
// 使用示例 dl1b_init();
|
||||
// 备注信息
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
uint8 dl1b_init (void)
|
||||
{
|
||||
uint8 return_state = 0;
|
||||
uint8 data_buffer[2 + sizeof(dl1b_config_file)];
|
||||
uint16 time_out_count = 0;
|
||||
|
||||
#if DL1B_USE_SOFT_IIC
|
||||
soft_iic_init(&dl1b_iic_struct, DL1B_DEV_ADDR, DL1B_SOFT_IIC_DELAY, DL1B_SCL_PIN, DL1B_SDA_PIN);
|
||||
#else
|
||||
iic_init(DL1B_IIC, DL1B_DEV_ADDR, DL1B_IIC_SPEED, DL1B_SCL_PIN, DL1B_SDA_PIN);
|
||||
#endif
|
||||
gpio_init(DL1B_XS_PIN, GPO, GPIO_HIGH, GPO_PUSH_PULL);
|
||||
|
||||
do
|
||||
{
|
||||
system_delay_ms(50);
|
||||
gpio_low(DL1B_XS_PIN);
|
||||
system_delay_ms(10);
|
||||
gpio_high(DL1B_XS_PIN);
|
||||
system_delay_ms(50);
|
||||
|
||||
data_buffer[0] = DL1B_FIRMWARE__SYSTEM_STATUS >> 8;
|
||||
data_buffer[1] = DL1B_FIRMWARE__SYSTEM_STATUS & 0xFF;
|
||||
dl1b_transfer_8bit_array(data_buffer, 2, &data_buffer[2], 1);
|
||||
return_state = (0x01 == (data_buffer[2] & 0x01)) ? (0) : (1);
|
||||
if(1 == return_state)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
data_buffer[0] = DL1B_I2C_SLAVE__DEVICE_ADDRESS >> 8;
|
||||
data_buffer[1] = DL1B_I2C_SLAVE__DEVICE_ADDRESS & 0xFF;
|
||||
memcpy(&data_buffer[2], (uint8 *)dl1b_config_file, sizeof(dl1b_config_file));
|
||||
dl1b_transfer_8bit_array(data_buffer, 2 + sizeof(dl1b_config_file), data_buffer, 0);
|
||||
|
||||
while(1)
|
||||
{
|
||||
data_buffer[0] = DL1B_GPIO__TIO_HV_STATUS >> 8;
|
||||
data_buffer[1] = DL1B_GPIO__TIO_HV_STATUS & 0xFF;
|
||||
dl1b_transfer_8bit_array(data_buffer, 2, &data_buffer[2], 1);
|
||||
if(0x00 == (data_buffer[2] & 0x01))
|
||||
{
|
||||
time_out_count = 0;
|
||||
break;
|
||||
}
|
||||
if(DL1B_TIMEOUT_COUNT < time_out_count ++)
|
||||
{
|
||||
return_state = 1;
|
||||
break;
|
||||
}
|
||||
system_delay_ms(1);
|
||||
}
|
||||
|
||||
dl1b_init_flag = 1;
|
||||
|
||||
#if DL1B_INT_ENABLE
|
||||
exti_init(DL1B_INT_PIN, EXTI_TRIGGER_FALLING);
|
||||
dl1b_int_handler();
|
||||
dl1b_finsh_flag = 0;
|
||||
#endif
|
||||
set_tof_type(TOF_DL1B, dl1b_int_handler);
|
||||
}while(0);
|
||||
|
||||
return return_state;
|
||||
}
|
||||
104
libraries/zf_device/zf_device_dl1b.h
Normal file
104
libraries/zf_device/zf_device_dl1b.h
Normal file
@@ -0,0 +1,104 @@
|
||||
/*********************************************************************************************************************
|
||||
* MM32F527X-E9P Opensourec Library 即(MM32F527X-E9P 开源库)是一个基于官方 SDK 接口的第三方开源库
|
||||
* Copyright (c) 2022 SEEKFREE 逐飞科技
|
||||
*
|
||||
* 本文件是 MM32F527X-E9P 开源库的一部分
|
||||
*
|
||||
* MM32F527X-E9P 开源库 是免费软件
|
||||
* 您可以根据自由软件基金会发布的 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 文件 版本说明
|
||||
* 开发环境 MounRiver Studio V1.8.1
|
||||
* 适用平台 CH32V307VCT6
|
||||
* 店铺链接 https://seekfree.taobao.com/
|
||||
*
|
||||
* 修改记录
|
||||
* 日期 作者 备注
|
||||
* 2022-08-10 Teternal 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 ( D6 ) // 软件 IIC SCL 引脚 连接 DL1B 的 SCL 引脚
|
||||
#define DL1B_SDA_PIN ( D5 ) // 软件 IIC SDA 引脚 连接 DL1B 的 SDA 引脚
|
||||
//====================================================软件 IIC 驱动====================================================
|
||||
#else
|
||||
//====================================================硬件 IIC 驱动====================================================
|
||||
#define DL1B_IIC_SPEED ( 400 * 1000 ) // 硬件 IIC 通信速率 最高 400KHz 不建议低于 40KHz
|
||||
#define DL1B_IIC ( 暂不支持 ) // 硬件 IIC SCL 引脚 连接 DL1B 的 SCL 引脚
|
||||
#define DL1B_SCL_PIN ( 暂不支持 ) // 硬件 IIC SCL 引脚 连接 DL1B 的 SCL 引脚
|
||||
#define DL1B_SDA_PIN ( 暂不支持 ) // 硬件 IIC SDA 引脚 连接 DL1B 的 SDA 引脚
|
||||
//====================================================硬件 IIC 驱动====================================================
|
||||
#endif
|
||||
|
||||
#define DL1B_XS_PIN ( E10 )
|
||||
|
||||
#define DL1B_INT_ENABLE ( 0 ) // 是否启用 INT 引脚 启用则会自动更新数据
|
||||
#if DL1B_INT_ENABLE
|
||||
#define DL1B_INT_PIN ( C13 )
|
||||
#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
|
||||
|
||||
255
libraries/zf_device/zf_device_dm1xa.c
Normal file
255
libraries/zf_device/zf_device_dm1xa.c
Normal file
@@ -0,0 +1,255 @@
|
||||
/*********************************************************************************************************************
|
||||
* CH32V307VCT6 Opensourec Library 即(CH32V307VCT6 开源库)是一个基于官方 SDK 接口的第三方开源库
|
||||
* Copyright (c) 2022 SEEKFREE 逐飞科技
|
||||
*
|
||||
* 本文件是CH32V307VCT6 开源库的一部分
|
||||
*
|
||||
* CH32V307VCT6 开源库 是免费软件
|
||||
* 您可以根据自由软件基金会发布的 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_dm1xa
|
||||
* 公司名称 成都逐飞科技有限公司
|
||||
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
|
||||
* 开发环境 MounRiver Studio V1.8.1
|
||||
* 适用平台 CH32V307VCT6
|
||||
* 店铺链接 https://seekfree.taobao.com/
|
||||
*
|
||||
* 修改记录
|
||||
* 日期 作者 备注
|
||||
* 2023-03-18 大W first version
|
||||
********************************************************************************************************************/
|
||||
/*********************************************************************************************************************
|
||||
* 接线定义:
|
||||
* ------------------------------------
|
||||
* 有去模块(无MCU版本 模块标识型号<DM1TA>)
|
||||
* 模块管脚 单片机管脚
|
||||
* FB 查看 zf_device_dm1xa.h 中 DM1XA_FB_PIN 宏定义
|
||||
* EN 查看 zf_device_dm1xa.h 中 DM1XA_EN_PIN 宏定义
|
||||
* 5V 5V 电源
|
||||
* GND 电源地
|
||||
* ------------------------------------
|
||||
* ------------------------------------
|
||||
* 有来模块(无MCU版本 模块标识型号<DM1RA>)
|
||||
* 模块管脚 单片机管脚
|
||||
* S 查看 zf_device_dm1xa.h 中 DM1XA_S_PIN 宏定义
|
||||
* L 查看 zf_device_dm1xa.h 中 DM1XA_L_PIN 宏定义
|
||||
* 5V 5V 电源
|
||||
* GND 电源地
|
||||
* ------------------------------------
|
||||
********************************************************************************************************************/
|
||||
|
||||
#include "zf_common_debug.h"
|
||||
#include "zf_driver_delay.h"
|
||||
#include "zf_driver_exti.h"
|
||||
#include "zf_driver_timer.h"
|
||||
|
||||
#include "zf_device_dm1xa.h"
|
||||
|
||||
static uint16 dm1xa_distance_mm = 6800;
|
||||
static uint32 dm1xa_plus_count = 0;
|
||||
//static uint32 dm1xa_match_count = 0;
|
||||
static dm1xa_type_enum dm1xa_type = DM1XA_NO_INIT;
|
||||
static dm1xa_ranging_state_enum dm1xa_ranging_state = DM1XA_RECEIVER_RANGING_NO_SIGNAL;
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 DM1XA 声信号 / 反馈信号 外部中断回调函数
|
||||
// 参数说明 void 无
|
||||
// 参数说明 void 无
|
||||
// 使用示例 dm1xa_sound_callback();
|
||||
// 备注信息 这个函数需要放在 DM1XA_FB_PIN / DM1XA_S_PIN 对应的外部中断服务函数里
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
void dm1xa_sound_callback (void)
|
||||
{
|
||||
switch(dm1xa_type)
|
||||
{
|
||||
case DM1XA_NO_INIT: // 未初始化 退出
|
||||
{
|
||||
}break;
|
||||
case DM1XA_CHECK_TYPE: // 初始化阶段
|
||||
{
|
||||
dm1xa_plus_count ++; // 对 FB 或者 sound 信号计数
|
||||
}break;
|
||||
case DM1XA_TRANSMITTER: // DM1TA 模块发起测距
|
||||
{
|
||||
dm1xa_plus_count ++; // 对 FB 信号计数
|
||||
if(DM1XA_FB_SEND <= dm1xa_plus_count) // 达到规定的 DM1XA_FB_SEND 计数
|
||||
{
|
||||
gpio_low(DM1XA_EN_PIN); // 停止发送测距信号
|
||||
dm1xa_plus_count = 0; // 清空计数
|
||||
}
|
||||
}break;
|
||||
case DM1XA_RECEIVER: // DM1RA 获取测距信号
|
||||
{
|
||||
if(DM1XA_RECEIVER_RANGING_WAIT_SOUND == dm1xa_ranging_state) // 已经获取光信号 证明本次信号有效
|
||||
{
|
||||
if(gpio_get_level(DM1XA_S_PIN)) // 声信号为高 是一个完整脉冲
|
||||
{
|
||||
if(150 < timer_get(DM1XA_TIM_INDEX) - dm1xa_plus_count) // 判断这个声信号脉冲是否是低于 150us 的干扰噪声
|
||||
{
|
||||
timer_clear(DM1XA_TIM_INDEX); // 清空时间
|
||||
dm1xa_distance_mm = (float)dm1xa_plus_count * DM1XA_SOUND_SPEED_MM_PER_US; // 计算距离值 毫米单位
|
||||
dm1xa_ranging_state = DM1XA_RECEIVER_RANGING_SUCCESS; // 测距信息更新为完成测距
|
||||
}
|
||||
}
|
||||
else // 声信号为低 证明是脉冲起始
|
||||
{
|
||||
dm1xa_plus_count = timer_get(DM1XA_TIM_INDEX); // 记录声光时间差
|
||||
}
|
||||
}
|
||||
}break;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 DM1XA 光信号 外部中断回调函数
|
||||
// 参数说明 void 无
|
||||
// 参数说明 void 无
|
||||
// 使用示例 dm1xa_light_callback();
|
||||
// 备注信息 这个函数需要放在 DM1XA_EN_PIN / DM1XA_L_PIN 对应的外部中断服务函数里
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
void dm1xa_light_callback (void)
|
||||
{
|
||||
switch(dm1xa_type)
|
||||
{
|
||||
case DM1XA_NO_INIT: // 未初始化 退出
|
||||
case DM1XA_CHECK_TYPE: // 初始化阶段
|
||||
case DM1XA_TRANSMITTER: // DM1TA 模块发起测距
|
||||
{
|
||||
}break;
|
||||
case DM1XA_RECEIVER: // DM1RA 获取测距信号
|
||||
{
|
||||
timer_clear(DM1XA_TIM_INDEX); // 清空时间 准备获取声光时间差
|
||||
dm1xa_ranging_state = DM1XA_RECEIVER_RANGING_WAIT_SOUND; // 标记获取到光信号
|
||||
}break;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 DM1RA 模块 获取测距结果数据
|
||||
// 参数说明 void 无
|
||||
// 返回参数 uint16 距离信息 6800 为超时默认距离
|
||||
// 使用示例 uint16 distance_mm = dm1xa_receiver_ranging();
|
||||
// 备注信息 更新距离信息
|
||||
//
|
||||
// 需要注意 dm1xa_receiver_ranging 的调用周期务必控制在 10-20ms 这个区间
|
||||
// 调用周期决定了最大测距距离 换算公式基本等于 period * 343.2 mm
|
||||
// 那么 10-20ms 的调用周期区间对应 3432-6864mm 的最大测距范围
|
||||
// 如果 dm1xa_receiver_ranging 的调用周期不在这个范围
|
||||
// 那么可能出现本驱动的测距信息异常
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
uint16 dm1xa_receiver_ranging (void)
|
||||
{
|
||||
switch(dm1xa_ranging_state)
|
||||
{
|
||||
case DM1XA_RECEIVER_RANGING_NO_SIGNAL: // 无测距信号
|
||||
case DM1XA_RECEIVER_RANGING_WAIT_SOUND: // 正获取测距信号
|
||||
{
|
||||
if(DM1XA_RECEIVER_TIMEROUT_US <= timer_get(DM1XA_TIM_INDEX)) // 如果距离上次光信号不超过 30ms
|
||||
{
|
||||
dm1xa_distance_mm = 6800; // 恢复默认最大输出值
|
||||
}
|
||||
}break;
|
||||
case DM1XA_RECEIVER_RANGING_SUCCESS: // 完成测距信息
|
||||
{
|
||||
dm1xa_ranging_state = DM1XA_RECEIVER_RANGING_NO_SIGNAL; // 标记测距信号恢复默认
|
||||
}break;
|
||||
default:
|
||||
{
|
||||
}break;
|
||||
}
|
||||
return dm1xa_distance_mm;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 DM1TA 模块 发送一组测距信号
|
||||
// 参数说明 void 无
|
||||
// 返回参数 void 无
|
||||
// 使用示例 dm1xa_transmitter_ranging();
|
||||
// 备注信息 发送完成后它会自己通过定时器控制
|
||||
// 这个函数用于使用 DM1TA 发起一次测距
|
||||
// 随后 DM1RA 将自动触发一次测距更新距离信息
|
||||
//
|
||||
// 需要注意 dm1xa_transmitter_ranging 的调用周期务必控制在 10-20ms 这个区间
|
||||
// 调用周期决定了最大测距距离 换算公式基本等于 period * 343.2 mm
|
||||
// 那么 10-20ms 的调用周期区间对应 3432-6864mm 的最大测距范围
|
||||
// 如果 dm1xa_transmitter_ranging 的调用周期不在这个范围
|
||||
// 那么可能出现本驱动的测距信息异常
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
void dm1xa_transmitter_ranging (void)
|
||||
{
|
||||
gpio_high(DM1XA_EN_PIN); // 拉高 EN 开启一次测距信息发送
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 初始化 超声波 模块
|
||||
// 参数说明 void 无
|
||||
// 返回参数 dm1xa_error_code_enum DM1XA_NO_ERROR-初始化成功
|
||||
// 使用示例 dm1xa_init();
|
||||
// 备注信息 会自动识别是 DM1TA 模块还是 DM1RA 模块
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
dm1xa_error_code_enum dm1xa_init (void)
|
||||
{
|
||||
dm1xa_error_code_enum return_state = DM1XA_NO_ERROR;
|
||||
|
||||
do
|
||||
{
|
||||
dm1xa_distance_mm = 0;
|
||||
dm1xa_type = DM1XA_CHECK_TYPE; // 模块状态标记为类型确认模式
|
||||
|
||||
gpio_init(DM1XA_S_PIN, GPI, GPIO_LOW, GPI_PULL_DOWN); // 两个引脚设置为下拉输入模式
|
||||
gpio_init(DM1XA_L_PIN, GPI, GPIO_LOW, GPI_PULL_DOWN); // 两个引脚设置为下拉输入模式
|
||||
|
||||
int16 i = DM1XA_INIT_MAX_COUNT;
|
||||
while(i --)
|
||||
{
|
||||
if(gpio_get_level(DM1XA_S_PIN) && gpio_get_level(DM1XA_L_PIN)) // 两个都是高电平 那么可能是 DM1RA 模块
|
||||
{
|
||||
dm1xa_type = DM1XA_RECEIVER;
|
||||
dm1xa_ranging_state = DM1XA_RECEIVER_RANGING_NO_SIGNAL;
|
||||
exti_init(DM1XA_S_PIN, EXTI_TRIGGER_BOTH); // 引脚初始化为外部中断输入
|
||||
exti_init(DM1XA_L_PIN, EXTI_TRIGGER_FALLING); // 引脚初始化为外部中断输入
|
||||
timer_init(DM1XA_TIM_INDEX, TIMER_US); // 微秒计时
|
||||
timer_clear(DM1XA_TIM_INDEX); // 清空计数
|
||||
timer_start(DM1XA_TIM_INDEX); // 启动定时器
|
||||
break;
|
||||
}
|
||||
system_delay_us(100);
|
||||
}
|
||||
if(0 > i)
|
||||
{
|
||||
exti_init(DM1XA_FB_PIN, EXTI_TRIGGER_FALLING);
|
||||
gpio_init(DM1XA_EN_PIN, GPO, GPIO_LOW, GPO_PUSH_PULL);
|
||||
dm1xa_plus_count = 0;
|
||||
gpio_high(DM1XA_EN_PIN);
|
||||
system_delay_us(210);
|
||||
gpio_low(DM1XA_EN_PIN);
|
||||
if(6 < dm1xa_plus_count && 10 > dm1xa_plus_count)
|
||||
{
|
||||
dm1xa_type = DM1XA_TRANSMITTER;
|
||||
dm1xa_plus_count = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
dm1xa_type = DM1XA_NO_INIT;
|
||||
return_state = DM1XA_TYPE_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}while(0);
|
||||
|
||||
return return_state;
|
||||
}
|
||||
121
libraries/zf_device/zf_device_dm1xa.h
Normal file
121
libraries/zf_device/zf_device_dm1xa.h
Normal file
@@ -0,0 +1,121 @@
|
||||
/*********************************************************************************************************************
|
||||
* CH32V307VCT6 Opensourec Library 即(CH32V307VCT6 开源库)是一个基于官方 SDK 接口的第三方开源库
|
||||
* Copyright (c) 2022 SEEKFREE 逐飞科技
|
||||
*
|
||||
* 本文件是CH32V307VCT6 开源库的一部分
|
||||
*
|
||||
* CH32V307VCT6 开源库 是免费软件
|
||||
* 您可以根据自由软件基金会发布的 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_dm1xa
|
||||
* 公司名称 成都逐飞科技有限公司
|
||||
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
|
||||
* 开发环境 MounRiver Studio V1.8.1
|
||||
* 适用平台 CH32V307VCT6
|
||||
* 店铺链接 https://seekfree.taobao.com/
|
||||
*
|
||||
* 修改记录
|
||||
* 日期 作者 备注
|
||||
* 2023-03-18 大W first version
|
||||
********************************************************************************************************************/
|
||||
/*********************************************************************************************************************
|
||||
* 接线定义:
|
||||
* ------------------------------------
|
||||
* 有去模块(无MCU版本 模块标识型号<DM1TA>)
|
||||
* 模块管脚 单片机管脚
|
||||
* FB 查看 zf_device_dm1xa.h 中 DM1XA_FB_PIN 宏定义
|
||||
* EN 查看 zf_device_dm1xa.h 中 DM1XA_EN_PIN 宏定义
|
||||
* 5V 5V 电源
|
||||
* GND 电源地
|
||||
* ------------------------------------
|
||||
* ------------------------------------
|
||||
* 有来模块(无MCU版本 模块标识型号<DM1RA>)
|
||||
* 模块管脚 单片机管脚
|
||||
* S 查看 zf_device_dm1xa.h 中 DM1XA_S_PIN 宏定义
|
||||
* L 查看 zf_device_dm1xa.h 中 DM1XA_L_PIN 宏定义
|
||||
* 5V 5V 电源
|
||||
* GND 电源地
|
||||
* ------------------------------------
|
||||
********************************************************************************************************************/
|
||||
|
||||
#ifndef _ZF_DEVICE_DM1XA_H_
|
||||
#define _ZF_DEVICE_DM1XA_H_
|
||||
|
||||
#include "zf_common_typedef.h"
|
||||
|
||||
// 需要注意 dm1xa_transmitter_ranging / dm1xa_receiver_ranging 的调用周期
|
||||
// 务必控制在 10-20ms 这个区间
|
||||
//
|
||||
// 调用周期决定了最大测距距离 换算公式基本等于 period * 343.2 mm
|
||||
// 那么 10-20ms 的调用周期区间对应 3432-6864mm 的最大测距范围
|
||||
//
|
||||
// 如果 dm1xa_transmitter_ranging / dm1xa_receiver_ranging
|
||||
// 的调用周期不在 10-20ms 这个区间
|
||||
// 那么可能出现本驱动的测距信息异常
|
||||
|
||||
// DM1TA 模块 引脚对应
|
||||
#define DM1XA_FB_PIN ( E15 )
|
||||
#define DM1XA_EN_PIN ( E14 )
|
||||
|
||||
// DM1RA 模块 引脚对应
|
||||
#define DM1XA_S_PIN ( E15 )
|
||||
#define DM1XA_L_PIN ( E14 )
|
||||
|
||||
#define DM1XA_TIM_INDEX ( TIM_7 ) // 固定使用一个定时器
|
||||
|
||||
#define DM1XA_SOUND_SPEED_MM_PER_US ( 0.34 ) // 定义声速 340M/s = 0.34 mm/us
|
||||
|
||||
#define DM1XA_FB_SEND ( 10 ) // 每次测距 EN 上脉冲时长为 DM1XA_FB_SEND * 1000 / 38 微秒
|
||||
#if (DM1XA_FB_SEND < 6 || DM1XA_FB_SEND > 100) // 每次测距的载波数 最小 6 最大 100
|
||||
#error "DM1XA_FB_SEND error, it must be between 6 and 100"
|
||||
#endif
|
||||
|
||||
#define DM1XA_INIT_MAX_COUNT ( 100 ) // 初始化尝试次数
|
||||
#define DM1XA_RECEIVER_TIMEROUT_US ( 30000 ) // 超时设置 这里不允许用户修改
|
||||
|
||||
// DM1XA 模块错误识别码 用户不允许更改
|
||||
typedef enum
|
||||
{
|
||||
DM1XA_NO_ERROR,
|
||||
DM1XA_TYPE_ERROR,
|
||||
}dm1xa_error_code_enum;
|
||||
|
||||
// DM1XA 模块错误识别码 用户不允许更改
|
||||
typedef enum
|
||||
{
|
||||
DM1XA_RECEIVER_RANGING_NO_SIGNAL,
|
||||
DM1XA_RECEIVER_RANGING_WAIT_SOUND,
|
||||
DM1XA_RECEIVER_RANGING_SUCCESS,
|
||||
}dm1xa_ranging_state_enum;
|
||||
|
||||
// DM1XA 模块类型 用户不允许更改
|
||||
typedef enum
|
||||
{
|
||||
DM1XA_NO_INIT,
|
||||
DM1XA_CHECK_TYPE,
|
||||
DM1XA_TRANSMITTER,
|
||||
DM1XA_RECEIVER,
|
||||
}dm1xa_type_enum;
|
||||
|
||||
void dm1xa_sound_callback (void);
|
||||
void dm1xa_light_callback (void);
|
||||
|
||||
uint16 dm1xa_receiver_ranging (void);
|
||||
void dm1xa_transmitter_ranging (void);
|
||||
dm1xa_error_code_enum dm1xa_init (void);
|
||||
|
||||
#endif
|
||||
540
libraries/zf_device/zf_device_gps_tau1201.c
Normal file
540
libraries/zf_device/zf_device_gps_tau1201.c
Normal file
@@ -0,0 +1,540 @@
|
||||
/*********************************************************************************************************************
|
||||
* CH32V307VCT6 Opensourec Library 即(CH32V307VCT6 开源库)是一个基于官方 SDK 接口的第三方开源库
|
||||
* Copyright (c) 2022 SEEKFREE 逐飞科技
|
||||
*
|
||||
* 本文件是CH32V307VCT6 开源库的一部分
|
||||
*
|
||||
* CH32V307VCT6 开源库 是免费软件
|
||||
* 您可以根据自由软件基金会发布的 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 文件
|
||||
* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明)
|
||||
*
|
||||
* 文件名称 isr
|
||||
* 公司名称 成都逐飞科技有限公司
|
||||
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
|
||||
* 开发环境 MounRiver Studio V1.8.1
|
||||
* 适用平台 CH32V307VCT6
|
||||
* 店铺链接 https://seekfree.taobao.com/
|
||||
*
|
||||
* 修改记录
|
||||
* 日期 作者 备注
|
||||
* 2022-08-10 Teternal first version
|
||||
* 2022-09-21 SeekFree 修改了处理结构 使得指令区分存放 解决了随机解析时丢失指令的问题
|
||||
********************************************************************************************************************/
|
||||
/*********************************************************************************************************************
|
||||
* 接线定义:
|
||||
* ------------------------------------
|
||||
* 模块管脚 单片机管脚
|
||||
* RX 查看 zf_device_gps_tau1201.h 中 GPS_TAU1201_RX 宏定义
|
||||
* TX 查看 zf_device_gps_tau1201.h 中 GPS_TAU1201_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_gps_tau1201.h"
|
||||
|
||||
#define GPS_TAU1201_BUFFER_SIZE ( 128 )
|
||||
|
||||
uint8 gps_tau1201_flag = 0; // 1:采集完成等待处理数据 0:没有采集完成
|
||||
gps_info_struct gps_tau1201; // GPS解析之后的数据
|
||||
|
||||
static uint8 gps_tau1201_state = 0; // 1:GPS初始化完成
|
||||
static fifo_struct gps_tau1201_receiver_fifo; //
|
||||
static uint8 gps_tau1201_receiver_buffer[GPS_TAU1201_BUFFER_SIZE]; // 数据存放数组
|
||||
|
||||
gps_state_enum gps_gga_state = GPS_STATE_RECEIVING; // gga 语句状态
|
||||
gps_state_enum gps_rmc_state = GPS_STATE_RECEIVING; // rmc 语句状态
|
||||
|
||||
static uint8 gps_gga_buffer[GPS_TAU1201_BUFFER_SIZE];
|
||||
static uint8 gps_rmc_buffer[GPS_TAU1201_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(&gps->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 接收到的语句信息
|
||||
// 参数说明 *gps 保存解析后的数据
|
||||
// 返回参数 uint8 1:解析成功 0:数据有问题不能解析
|
||||
// 使用示例 gps_gnrmc_parse((char *)data_buffer, &gps_tau1201);
|
||||
// 备注信息 内部使用
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
static uint8 gps_gnrmc_parse (char *line, gps_info_struct *gps)
|
||||
{
|
||||
uint8 state = 0, temp = 0;
|
||||
|
||||
double latitude = 0; // 纬度
|
||||
double longitude = 0; // 经度
|
||||
|
||||
float lati_cent_tmp = 0, lati_second_tmp = 0;
|
||||
float 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)];
|
||||
|
||||
gps->state = 0;
|
||||
if('A' == state) // 如果数据有效 则解析数据
|
||||
{
|
||||
return_state = 1;
|
||||
gps->state = 1;
|
||||
gps -> ns = buf[get_parameter_index(4, buf)];
|
||||
gps -> 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)]);
|
||||
|
||||
gps->latitude_degree = (int)latitude / 100; // 纬度转换为度分秒
|
||||
lati_cent_tmp = (latitude - gps->latitude_degree * 100);
|
||||
gps->latitude_cent = (int)lati_cent_tmp;
|
||||
lati_second_tmp = (lati_cent_tmp - gps->latitude_cent) * 10000;
|
||||
gps->latitude_second = (int)lati_second_tmp;
|
||||
|
||||
gps->longitude_degree = (int)longitude / 100; // 经度转换为度分秒
|
||||
long_cent_tmp = (longitude - gps->longitude_degree * 100);
|
||||
gps->longitude_cent = (int)long_cent_tmp;
|
||||
long_second_tmp = (long_cent_tmp - gps->longitude_cent) * 10000;
|
||||
gps->longitude_second = (int)long_second_tmp;
|
||||
|
||||
gps->latitude = gps->latitude_degree + (double)gps->latitude_cent / 60 + (double)gps->latitude_second / 600000;
|
||||
gps->longitude = gps->longitude_degree + (double)gps->longitude_cent / 60 + (double)gps->longitude_second / 600000;
|
||||
|
||||
speed_tmp = get_float_number(&buf[get_parameter_index(7, buf)]); // 速度(海里/小时)
|
||||
gps->speed = speed_tmp * 1.85f; // 转换为公里/小时
|
||||
gps->direction = get_float_number(&buf[get_parameter_index(8, buf)]); // 角度
|
||||
}
|
||||
|
||||
// 在定位没有生效前也是有时间数据的,可以直接解析
|
||||
gps->time.hour = (buf[7] - '0') * 10 + (buf[8] - '0'); // 时间
|
||||
gps->time.minute = (buf[9] - '0') * 10 + (buf[10] - '0');
|
||||
gps->time.second = (buf[11] - '0') * 10 + (buf[12] - '0');
|
||||
temp = get_parameter_index(9, buf);
|
||||
gps->time.day = (buf[temp + 0] - '0') * 10 + (buf[temp + 1] - '0'); // 日期
|
||||
gps->time.month = (buf[temp + 2] - '0') * 10 + (buf[temp + 3] - '0');
|
||||
gps->time.year = (buf[temp + 4] - '0') * 10 + (buf[temp + 5] - '0') + 2000;
|
||||
|
||||
utc_to_btc(&gps->time);
|
||||
|
||||
return return_state;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 GGA语句解析
|
||||
// 参数说明 *line 接收到的语句信息
|
||||
// 参数说明 *gps 保存解析后的数据
|
||||
// 返回参数 uint8 1:解析成功 0:数据有问题不能解析
|
||||
// 使用示例 gps_gngga_parse((char *)data_buffer, &gps_tau1201);
|
||||
// 备注信息 内部使用
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
static uint8 gps_gngga_parse (char *line, gps_info_struct *gps)
|
||||
{
|
||||
uint8 state = 0;
|
||||
char *buf = line;
|
||||
uint8 return_state = 0;
|
||||
|
||||
state = buf[get_parameter_index(2, buf)];
|
||||
|
||||
if(',' != state)
|
||||
{
|
||||
gps->satellite_used = (uint8)get_int_number(&buf[get_parameter_index(7, buf)]);
|
||||
gps->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;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 计算从第一个点到第二个点的距离
|
||||
// 参数说明 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 gps_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 == gps_rmc_state)
|
||||
{
|
||||
gps_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, &gps_tau1201);
|
||||
}
|
||||
gps_rmc_state = GPS_STATE_RECEIVING;
|
||||
|
||||
if(GPS_STATE_RECEIVED == gps_gga_state)
|
||||
{
|
||||
gps_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, &gps_tau1201);
|
||||
}
|
||||
gps_gga_state = GPS_STATE_RECEIVING;
|
||||
|
||||
}while(0);
|
||||
return return_state;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 GPS串口回调函数
|
||||
// 参数说明 void
|
||||
// 返回参数 void
|
||||
// 使用示例 gps_uart_callback();
|
||||
// 备注信息 此函数需要在串口接收中断内进行调用
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
void gps_uart_callback (void)
|
||||
{
|
||||
uint8 temp_gps[6];
|
||||
uint32 temp_length = 0;
|
||||
|
||||
if(gps_tau1201_state)
|
||||
{
|
||||
uint8 dat;
|
||||
while(uart_query_byte(GPS_TAU1201_UART, &dat))
|
||||
{
|
||||
fifo_write_buffer(&gps_tau1201_receiver_fifo, &dat, 1);
|
||||
}
|
||||
|
||||
if('\n' == dat)
|
||||
{
|
||||
// 读取前6个数据 用于判断语句类型
|
||||
temp_length = 6;
|
||||
fifo_read_buffer(&gps_tau1201_receiver_fifo, temp_gps, &temp_length, FIFO_READ_ONLY);
|
||||
|
||||
// 根据不同类型将数据拷贝到不同的缓冲区
|
||||
if(0 == strncmp((char *)&temp_gps[3], "RMC", 3))
|
||||
{
|
||||
// 如果没有在解析数据则更新缓冲区的数据
|
||||
if(GPS_STATE_PARSING != gps_rmc_state)
|
||||
{
|
||||
gps_rmc_state = GPS_STATE_RECEIVED;
|
||||
temp_length = fifo_used(&gps_tau1201_receiver_fifo);
|
||||
fifo_read_buffer(&gps_tau1201_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 != gps_gga_state)
|
||||
{
|
||||
gps_gga_state = GPS_STATE_RECEIVED;
|
||||
temp_length = fifo_used(&gps_tau1201_receiver_fifo);
|
||||
fifo_read_buffer(&gps_tau1201_receiver_fifo, gps_gga_buffer, &temp_length, FIFO_READ_AND_CLEAN);
|
||||
}
|
||||
}
|
||||
|
||||
// 统一将FIFO清空
|
||||
fifo_clear(&gps_tau1201_receiver_fifo);
|
||||
|
||||
gps_tau1201_flag = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 GPS初始化
|
||||
// 参数说明 void
|
||||
// 返回参数 void
|
||||
// 使用示例 gps_init();
|
||||
// 备注信息
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
void gps_init (void)
|
||||
{
|
||||
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};
|
||||
|
||||
fifo_init(&gps_tau1201_receiver_fifo, FIFO_DATA_8BIT, gps_tau1201_receiver_buffer, GPS_TAU1201_BUFFER_SIZE);
|
||||
system_delay_ms(500); // 等待GPS启动后开始初始化
|
||||
uart_init(GPS_TAU1201_UART, 115200, GPS_TAU1201_RX, GPS_TAU1201_TX);
|
||||
|
||||
uart_write_buffer(GPS_TAU1201_UART, (uint8 *)set_rate, sizeof(set_rate)); // 设置GPS更新速率为10hz 如果不调用此语句则默认为1hz
|
||||
system_delay_ms(200);
|
||||
|
||||
uart_write_buffer(GPS_TAU1201_UART, (uint8 *)open_rmc, sizeof(open_rmc)); // 开启rmc语句
|
||||
system_delay_ms(50);
|
||||
uart_write_buffer(GPS_TAU1201_UART, (uint8 *)open_gga, sizeof(open_gga)); // 开启gga语句
|
||||
system_delay_ms(50);
|
||||
uart_write_buffer(GPS_TAU1201_UART, (uint8 *)close_gll, sizeof(close_gll));
|
||||
system_delay_ms(50);
|
||||
uart_write_buffer(GPS_TAU1201_UART, (uint8 *)close_gsa, sizeof(close_gsa));
|
||||
system_delay_ms(50);
|
||||
uart_write_buffer(GPS_TAU1201_UART, (uint8 *)close_grs, sizeof(close_grs));
|
||||
system_delay_ms(50);
|
||||
uart_write_buffer(GPS_TAU1201_UART, (uint8 *)close_gsv, sizeof(close_gsv));
|
||||
system_delay_ms(50);
|
||||
uart_write_buffer(GPS_TAU1201_UART, (uint8 *)close_vtg, sizeof(close_vtg));
|
||||
system_delay_ms(50);
|
||||
uart_write_buffer(GPS_TAU1201_UART, (uint8 *)close_zda, sizeof(close_zda));
|
||||
system_delay_ms(50);
|
||||
uart_write_buffer(GPS_TAU1201_UART, (uint8 *)close_gst, sizeof(close_gst));
|
||||
system_delay_ms(50);
|
||||
uart_write_buffer(GPS_TAU1201_UART, (uint8 *)close_txt, sizeof(close_txt));
|
||||
system_delay_ms(50);
|
||||
uart_write_buffer(GPS_TAU1201_UART, (uint8 *)close_txt_ant, sizeof(close_txt_ant));
|
||||
system_delay_ms(50);
|
||||
|
||||
gps_tau1201_state = 1;
|
||||
uart_rx_interrupt(GPS_TAU1201_UART, 1);
|
||||
}
|
||||
120
libraries/zf_device/zf_device_gps_tau1201.h
Normal file
120
libraries/zf_device/zf_device_gps_tau1201.h
Normal file
@@ -0,0 +1,120 @@
|
||||
/*********************************************************************************************************************
|
||||
* CH32V307VCT6 Opensourec Library 即(CH32V307VCT6 开源库)是一个基于官方 SDK 接口的第三方开源库
|
||||
* Copyright (c) 2022 SEEKFREE 逐飞科技
|
||||
*
|
||||
* 本文件是CH32V307VCT6 开源库的一部分
|
||||
*
|
||||
* CH32V307VCT6 开源库 是免费软件
|
||||
* 您可以根据自由软件基金会发布的 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 文件
|
||||
* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明)
|
||||
*
|
||||
* 文件名称 isr
|
||||
* 公司名称 成都逐飞科技有限公司
|
||||
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
|
||||
* 开发环境 MounRiver Studio V1.8.1
|
||||
* 适用平台 CH32V307VCT6
|
||||
* 店铺链接 https://seekfree.taobao.com/
|
||||
*
|
||||
* 修改记录
|
||||
* 日期 作者 备注
|
||||
* 2022-08-10 Teternal first version
|
||||
* 2022-09-21 SeekFree 修改了处理结构 使得指令区分存放 解决了随机解析时丢失指令的问题
|
||||
********************************************************************************************************************/
|
||||
/*********************************************************************************************************************
|
||||
* 接线定义:
|
||||
* ------------------------------------
|
||||
* 模块管脚 单片机管脚
|
||||
* RX 查看 zf_device_gps_tau1201.h 中 GPS_TAU1201_RX 宏定义
|
||||
* TX 查看 zf_device_gps_tau1201.h 中 GPS_TAU1201_TX 宏定义
|
||||
* VCC 3.3V电源
|
||||
* GND 电源地
|
||||
* ------------------------------------
|
||||
********************************************************************************************************************/
|
||||
|
||||
#ifndef _zf_device_gps_tau1201_h_
|
||||
#define _zf_device_gps_tau1201_h_
|
||||
|
||||
#include "zf_common_typedef.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
//引脚配置
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
#define GPS_TAU1201_UART (UART_8)
|
||||
#define GPS_TAU1201_RX (UART8_MAP3_TX_E14) // GPS RX引脚连接到单片机此
|
||||
#define GPS_TAU1201_TX (UART8_MAP3_RX_E15) // 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 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; // 秒
|
||||
uint16 longitude_degree; // 度
|
||||
uint16 longitude_cent; // 分
|
||||
uint16 longitude_second; // 秒
|
||||
|
||||
double latitude; // 经度
|
||||
double longitude; // 纬度
|
||||
|
||||
int8 ns; // 纬度半球 N(北半球)或 S(南半球)
|
||||
int8 ew; // 经度半球 E(东经)或 W(西经)
|
||||
|
||||
float speed; // 速度(公里/每小时)
|
||||
float direction; // 地面航向(000.0~359.9 度,以真北方为参考基准)
|
||||
|
||||
// 下面两个个信息从GNGGA语句中获取
|
||||
uint8 satellite_used; // 用于定位的卫星数量
|
||||
float height; // 高度
|
||||
}gps_info_struct;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GPS_STATE_RECEIVING, // 正在接收数据
|
||||
GPS_STATE_RECEIVED, // 数据接收完成
|
||||
GPS_STATE_PARSING, // 正在解析
|
||||
}gps_state_enum;
|
||||
|
||||
extern gps_info_struct gps_tau1201;
|
||||
extern uint8 gps_tau1201_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 gps_data_parse (void);
|
||||
|
||||
void gps_uart_callback (void);
|
||||
|
||||
void gps_init (void);
|
||||
|
||||
#endif
|
||||
345
libraries/zf_device/zf_device_icm20602.c
Normal file
345
libraries/zf_device/zf_device_icm20602.c
Normal file
@@ -0,0 +1,345 @@
|
||||
/*********************************************************************************************************************
|
||||
* CH32V307VCT6 Opensourec Library 即(CH32V307VCT6 开源库)是一个基于官方 SDK 接口的第三方开源库
|
||||
* Copyright (c) 2022 SEEKFREE 逐飞科技
|
||||
*
|
||||
* 本文件是CH32V307VCT6 开源库的一部分
|
||||
*
|
||||
* CH32V307VCT6 开源库 是免费软件
|
||||
* 您可以根据自由软件基金会发布的 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 文件 版本说明
|
||||
* 开发环境 MounRiver Studio V1.8.1
|
||||
* 适用平台 CH32V307VCT6
|
||||
* 店铺链接 https://seekfree.taobao.com/
|
||||
*
|
||||
* 修改记录
|
||||
* 日期 作者 备注
|
||||
* 2022-09-15 大W first version
|
||||
********************************************************************************************************************/
|
||||
/*********************************************************************************************************************
|
||||
* 接线定义:
|
||||
* ------------------------------------
|
||||
* 模块管脚 单片机管脚
|
||||
* //------------------硬件 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 中 IPS114_CS_PIN 宏定义
|
||||
* //------------------硬件 SPI 引脚------------------//
|
||||
* //------------------软件 IIC 引脚------------------//
|
||||
* SCL/SPC 查看 zf_device_icm20602.h 中 ICM20602_SCL_PIN 宏定义
|
||||
* SDA/DSI 查看 zf_device_icm20602.h 中 ICM20602_SDA_PIN 宏定义
|
||||
* //------------------软件 IIC 引脚------------------//
|
||||
* 电源引脚
|
||||
* VCC 3.3V电源
|
||||
* GND 电源地
|
||||
* ------------------------------------
|
||||
********************************************************************************************************************/
|
||||
|
||||
#include "zf_common_clock.h"
|
||||
#include "zf_common_debug.h"
|
||||
#include "zf_driver_delay.h"
|
||||
#include "zf_driver_spi.h"
|
||||
#include "zf_driver_soft_iic.h"
|
||||
|
||||
#include "zf_device_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)
|
||||
{
|
||||
default:
|
||||
{
|
||||
zf_log(0, "ICM20602_ACC_SAMPLE_DEFAULT set error.");
|
||||
return_state = 1;
|
||||
}break;
|
||||
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;
|
||||
}
|
||||
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)
|
||||
{
|
||||
default:
|
||||
{
|
||||
zf_log(0, "ICM20602_GYRO_SAMPLE_DEFAULT set error.");
|
||||
return_state = 1;
|
||||
}break;
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
201
libraries/zf_device/zf_device_icm20602.h
Normal file
201
libraries/zf_device/zf_device_icm20602.h
Normal file
@@ -0,0 +1,201 @@
|
||||
/*********************************************************************************************************************
|
||||
* CH32V307VCT6 Opensourec Library 即(CH32V307VCT6 开源库)是一个基于官方 SDK 接口的第三方开源库
|
||||
* Copyright (c) 2022 SEEKFREE 逐飞科技
|
||||
*
|
||||
* 本文件是CH32V307VCT6 开源库的一部分
|
||||
*
|
||||
* CH32V307VCT6 开源库 是免费软件
|
||||
* 您可以根据自由软件基金会发布的 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 文件 版本说明
|
||||
* 开发环境 MounRiver Studio V1.8.1
|
||||
* 适用平台 CH32V307VCT6
|
||||
* 店铺链接 https://seekfree.taobao.com/
|
||||
*
|
||||
* 修改记录
|
||||
* 日期 作者 备注
|
||||
* 2022-09-15 大W first version
|
||||
********************************************************************************************************************/
|
||||
/*********************************************************************************************************************
|
||||
* 接线定义:
|
||||
* ------------------------------------
|
||||
* 模块管脚 单片机管脚
|
||||
* //------------------硬件 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 中 IPS114_CS_PIN 宏定义
|
||||
* //------------------硬件 SPI 引脚------------------//
|
||||
* //------------------软件 IIC 引脚------------------//
|
||||
* SCL/SPC 查看 zf_device_icm20602.h 中 ICM20602_SCL_PIN 宏定义
|
||||
* SDA/DSI 查看 zf_device_icm20602.h 中 ICM20602_SDA_PIN 宏定义
|
||||
* //------------------软件 IIC 引脚------------------//
|
||||
* 电源引脚
|
||||
* VCC 3.3V电源
|
||||
* GND 电源地
|
||||
* ------------------------------------
|
||||
********************************************************************************************************************/
|
||||
|
||||
#ifndef _zf_device_icm20602_h_
|
||||
#define _zf_device_icm20602_h_
|
||||
|
||||
#include "zf_common_typedef.h"
|
||||
|
||||
|
||||
#define ICM20602_USE_SOFT_IIC 0 // 默认使用硬件 SPI 方式驱动
|
||||
#if ICM20602_USE_SOFT_IIC // 这两段 颜色正常的才是正确的 颜色灰的就是没有用的
|
||||
//====================================================软件 IIC 驱动====================================================
|
||||
#define ICM20602_SOFT_IIC_DELAY 100 // 软件 IIC 的时钟延时周期 数值越小 IIC 通信速率越快
|
||||
#define ICM20602_SCL_PIN B3 // 软件 IIC SCL 引脚 连接 MPU6050 的 SCL 引脚
|
||||
#define ICM20602_SDA_PIN B5 // 软件 IIC SDA 引脚 连接 MPU6050 的 SDA 引脚
|
||||
//====================================================软件 IIC 驱动====================================================
|
||||
#else
|
||||
//====================================================硬件 SPI 驱动====================================================
|
||||
#define ICM20602_SPI_SPEED (10*1000*1000) // 硬件 SPI 速率
|
||||
#define ICM20602_SPI SPI_3 // 硬件 SPI 号
|
||||
#define ICM20602_SPC_PIN SPI3_MAP0_SCK_B3 // 硬件 SPI SCK 引脚
|
||||
#define ICM20602_SDI_PIN SPI3_MAP0_MOSI_B5 // 硬件 SPI MOSI 引脚
|
||||
#define ICM20602_SDO_PIN SPI3_MAP0_MISO_B4 // 硬件 SPI MISO 引脚
|
||||
//====================================================硬件 SPI 驱动====================================================
|
||||
#endif
|
||||
#define ICM20602_CS_PIN C10 // 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 内部地址================================================
|
||||
#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 )
|
||||
//================================================定义 ICM20602 内部地址================================================
|
||||
|
||||
extern int16 icm20602_gyro_x, icm20602_gyro_y, icm20602_gyro_z; // 三轴陀螺仪数据
|
||||
extern int16 icm20602_acc_x, icm20602_acc_y, icm20602_acc_z; // 三轴加速度计数据
|
||||
extern float icm20602_transition_factor[2];
|
||||
|
||||
void icm20602_get_acc (void);
|
||||
void icm20602_get_gyro (void);
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 将 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])
|
||||
|
||||
uint8 icm20602_init (void);
|
||||
|
||||
#endif
|
||||
|
||||
338
libraries/zf_device/zf_device_imu660ra.c
Normal file
338
libraries/zf_device/zf_device_imu660ra.c
Normal file
@@ -0,0 +1,338 @@
|
||||
/*********************************************************************************************************************
|
||||
* CH32V307VCT6 Opensourec Library 即(CH32V307VCT6 开源库)是一个基于官方 SDK 接口的第三方开源库
|
||||
* Copyright (c) 2022 SEEKFREE 逐飞科技
|
||||
*
|
||||
* 本文件是CH32V307VCT6 开源库的一部分
|
||||
*
|
||||
* CH32V307VCT6 开源库 是免费软件
|
||||
* 您可以根据自由软件基金会发布的 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 文件 版本说明
|
||||
* 开发环境 MounRiver Studio V1.8.1
|
||||
* 适用平台 CH32V307VCT6
|
||||
* 店铺链接 https://seekfree.taobao.com/
|
||||
*
|
||||
* 修改记录
|
||||
* 日期 作者 备注
|
||||
* 2022-09-15 大W first version
|
||||
********************************************************************************************************************/
|
||||
/*********************************************************************************************************************
|
||||
* 接线定义:
|
||||
* ------------------------------------
|
||||
* 模块管脚 单片机管脚
|
||||
* // 硬件 SPI 引脚
|
||||
* SCL/SPC 查看 zf_device_imu660ra.h 中 IMU660RA_SPC_PIN 宏定义
|
||||
* SDA/DSI 查看 zf_device_imu660ra.h 中 IMU660RA_SDI_PIN 宏定义
|
||||
* SA0/SDO 查看 zf_device_imu660ra.h 中 IMU660RA_SDO_PIN 宏定义
|
||||
* CS 查看 zf_device_imu660ra.h 中 IMU660RA_CS_PIN 宏定义
|
||||
* VCC 3.3V电源
|
||||
* GND 电源地
|
||||
* 其余引脚悬空
|
||||
*
|
||||
* // 软件 IIC 引脚
|
||||
* SCL/SPC 查看 zf_device_imu660ra.h 中 IMU660RA_SCL_PIN 宏定义
|
||||
* SDA/DSI 查看 zf_device_imu660ra.h 中 IMU660RA_SDA_PIN 宏定义
|
||||
* VCC 3.3V电源
|
||||
* GND 电源地
|
||||
* 其余引脚悬空
|
||||
* ------------------------------------
|
||||
********************************************************************************************************************/
|
||||
|
||||
#include "zf_common_debug.h"
|
||||
#include "zf_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(timeout_count ++ > IMU660RA_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
|
||||
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(m/s^2)
|
||||
// 设置为 0x01 加速度计量程为 ±4 g 获取到的加速度计数据除以 8192 可以转化为带物理单位的数据 单位 g(m/s^2)
|
||||
// 设置为 0x02 加速度计量程为 ±8 g 获取到的加速度计数据除以 4096 可以转化为带物理单位的数据 单位 g(m/s^2)
|
||||
// 设置为 0x03 加速度计量程为 ±16 g 获取到的加速度计数据除以 2048 可以转化为带物理单位的数据 单位 g(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;
|
||||
}
|
||||
|
||||
|
||||
151
libraries/zf_device/zf_device_imu660ra.h
Normal file
151
libraries/zf_device/zf_device_imu660ra.h
Normal file
@@ -0,0 +1,151 @@
|
||||
/*********************************************************************************************************************
|
||||
* CH32V307VCT6 Opensourec Library 即(CH32V307VCT6 开源库)是一个基于官方 SDK 接口的第三方开源库
|
||||
* Copyright (c) 2022 SEEKFREE 逐飞科技
|
||||
*
|
||||
* 本文件是CH32V307VCT6 开源库的一部分
|
||||
*
|
||||
* CH32V307VCT6 开源库 是免费软件
|
||||
* 您可以根据自由软件基金会发布的 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 文件 版本说明
|
||||
* 开发环境 MounRiver Studio V1.8.1
|
||||
* 适用平台 CH32V307VCT6
|
||||
* 店铺链接 https://seekfree.taobao.com/
|
||||
*
|
||||
* 修改记录
|
||||
* 日期 作者 备注
|
||||
* 2022-09-15 大W first version
|
||||
********************************************************************************************************************/
|
||||
/*********************************************************************************************************************
|
||||
* 接线定义:
|
||||
* ------------------------------------
|
||||
* 模块管脚 单片机管脚
|
||||
* // 硬件 SPI 引脚
|
||||
* SCL/SPC 查看 zf_device_imu660ra.h 中 IMU660RA_SPC_PIN 宏定义
|
||||
* SDA/DSI 查看 zf_device_imu660ra.h 中 IMU660RA_SDI_PIN 宏定义
|
||||
* SA0/SDO 查看 zf_device_imu660ra.h 中 IMU660RA_SDO_PIN 宏定义
|
||||
* CS 查看 zf_device_imu660ra.h 中 IMU660RA_CS_PIN 宏定义
|
||||
* VCC 3.3V电源
|
||||
* GND 电源地
|
||||
* 其余引脚悬空
|
||||
*
|
||||
* // 软件 IIC 引脚
|
||||
* SCL/SPC 查看 zf_device_imu660ra.h 中 IMU660RA_SCL_PIN 宏定义
|
||||
* SDA/DSI 查看 zf_device_imu660ra.h 中 IMU660RA_SDA_PIN 宏定义
|
||||
* VCC 3.3V电源
|
||||
* GND 电源地
|
||||
* 其余引脚悬空
|
||||
* ------------------------------------
|
||||
********************************************************************************************************************/
|
||||
#ifndef _zf_device_imu660ra_h_
|
||||
#define _zf_device_imu660ra_h_
|
||||
|
||||
#include "zf_common_typedef.h"
|
||||
|
||||
#define IMU660RA_USE_SOFT_IIC (0) // 默认使用硬件 SPI 方式驱动
|
||||
#if IMU660RA_USE_SOFT_IIC // 这两段 颜色正常的才是正确的 颜色灰的就是没有用的
|
||||
//====================================================软件 IIC 驱动====================================================
|
||||
#define IMU660RA_SOFT_IIC_DELAY (10 ) // 软件 IIC 的时钟延时周期 数值越小 IIC 通信速率越快
|
||||
#define IMU660RA_SCL_PIN (B13) // 软件 IIC SCL 引脚 连接 IMU660RA 的 SCL 引脚
|
||||
#define IMU660RA_SDA_PIN (B15) // 软件 IIC SDA 引脚 连接 IMU660RA 的 SDA 引脚
|
||||
//====================================================软件 IIC 驱动====================================================
|
||||
#else
|
||||
|
||||
//====================================================硬件 SPI 驱动====================================================
|
||||
#define IMU660RA_SPI_SPEED (10*1000*1000) // 硬件 SPI 速率
|
||||
#define IMU660RA_SPI SPI_3 // 硬件 SPI 号
|
||||
#define IMU660RA_SPC_PIN SPI3_MAP0_SCK_B3 // 硬件 SPI SCK 引脚
|
||||
#define IMU660RA_SDI_PIN SPI3_MAP0_MOSI_B5 // 硬件 SPI MOSI 引脚
|
||||
#define IMU660RA_SDO_PIN SPI3_MAP0_MISO_B4 // 硬件 SPI MISO 引脚
|
||||
|
||||
//====================================================硬件 SPI 驱动====================================================
|
||||
#endif
|
||||
#define IMU660RA_CS_PIN (C10) // 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 内部地址================================================
|
||||
|
||||
extern int16 imu660ra_gyro_x, imu660ra_gyro_y, imu660ra_gyro_z; // 三轴陀螺仪数据 gyro (陀螺仪)
|
||||
extern int16 imu660ra_acc_x, imu660ra_acc_y, imu660ra_acc_z; // 三轴加速度计数据 acc (accelerometer 加速度计)
|
||||
extern float imu660ra_transition_factor[2];
|
||||
|
||||
void imu660ra_get_acc (void); // 获取 IMU660RA 加速度计数据
|
||||
void imu660ra_get_gyro (void); // 获取 IMU660RA 陀螺仪数据
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 将 IMU660RA 加速度计数据转换为实际物理数据
|
||||
// 参数说明 acc_value 任意轴的加速度计数据
|
||||
// 返回参数 void
|
||||
// 使用示例 float data = imu660ra_acc_transition(imu660ra_acc_x); // 单位为 g(m/s^2)
|
||||
// 备注信息
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
#define imu660ra_acc_transition(acc_value) ((float)(acc_value) / imu660ra_transition_factor[0])
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 将 IMU660RA 陀螺仪数据转换为实际物理数据
|
||||
// 参数说明 gyro_value 任意轴的陀螺仪数据
|
||||
// 返回参数 void
|
||||
// 使用示例 float data = imu660ra_gyro_transition(imu660ra_gyro_x); // 单位为 °/s
|
||||
// 备注信息
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
#define imu660ra_gyro_transition(gyro_value) ((float)(gyro_value) / imu660ra_transition_factor[1])
|
||||
|
||||
uint8 imu660ra_init (void); // 初始化 IMU660RA
|
||||
|
||||
#endif
|
||||
|
||||
531
libraries/zf_device/zf_device_imu963ra.c
Normal file
531
libraries/zf_device/zf_device_imu963ra.c
Normal file
@@ -0,0 +1,531 @@
|
||||
/*/*********************************************************************************************************************
|
||||
* CH32V307VCT6 Opensourec Library 即(CH32V307VCT6 开源库)是一个基于官方 SDK 接口的第三方开源库
|
||||
* Copyright (c) 2022 SEEKFREE 逐飞科技
|
||||
*
|
||||
* 本文件是CH32V307VCT6 开源库的一部分
|
||||
*
|
||||
* CH32V307VCT6 开源库 是免费软件
|
||||
* 您可以根据自由软件基金会发布的 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 文件 版本说明
|
||||
* 开发环境 MounRiver Studio V1.8.1
|
||||
* 适用平台 CH32V307VCT6
|
||||
* 店铺链接 https://seekfree.taobao.com/
|
||||
*
|
||||
* 修改记录
|
||||
* 日期 作者 备注
|
||||
* 2022-09-15 大W first version
|
||||
********************************************************************************************************************/
|
||||
/*********************************************************************************************************************
|
||||
* 接线定义:
|
||||
* ------------------------------------
|
||||
* 模块管脚 单片机管脚
|
||||
* // 硬件 SPI 引脚
|
||||
* SCL/SPC 查看 zf_device_imu963ra.h 中 IMU963RA_SPC_PIN 宏定义
|
||||
* SDA/DSI 查看 zf_device_imu963ra.h 中 IMU963RA_SDI_PIN 宏定义
|
||||
* SA0/SDO 查看 zf_device_imu963ra.h 中 IMU963RA_SDO_PIN 宏定义
|
||||
* CS 查看 zf_device_imu963ra.h 中 IMU963RA_CS_PIN 宏定义
|
||||
* VCC 3.3V电源
|
||||
* GND 电源地
|
||||
* 其余引脚悬空
|
||||
*
|
||||
* // 软件 IIC 引脚
|
||||
* SCL/SPC 查看 zf_device_imu963ra.h 中 IMU963RA_SCL_PIN 宏定义
|
||||
* SDA/DSI 查看 zf_device_imu963ra.h 中 IMU963RA_SDA_PIN 宏定义
|
||||
* VCC 3.3V电源
|
||||
* GND 电源地
|
||||
* 其余引脚悬空
|
||||
* ------------------------------------
|
||||
********************************************************************************************************************/
|
||||
|
||||
#include "zf_common_clock.h"
|
||||
#include "zf_common_debug.h"
|
||||
#include "zf_driver_delay.h"
|
||||
#include "zf_driver_spi.h"
|
||||
#include "zf_driver_soft_iic.h"
|
||||
|
||||
#include "zf_device_imu963ra.h"
|
||||
|
||||
int16 imu963ra_gyro_x = 0, imu963ra_gyro_y = 0, imu963ra_gyro_z = 0;
|
||||
int16 imu963ra_acc_x = 0, imu963ra_acc_y = 0, imu963ra_acc_z = 0;
|
||||
int16 imu963ra_mag_x = 0, imu963ra_mag_y = 0, imu963ra_mag_z = 0;
|
||||
float imu963ra_transition_factor[3] = {4098, 14.3, 3000};
|
||||
|
||||
#if IMU963RA_USE_SOFT_IIC
|
||||
static soft_iic_info_struct imu963ra_iic_struct;
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 IMU963RA 写寄存器
|
||||
// 参数说明 reg 寄存器地址
|
||||
// 参数说明 data 数据
|
||||
// 返回参数 void
|
||||
// 使用示例 imu963ra_write_acc_gyro_register(IMU963RA_SLV0_CONFIG, 0x00);
|
||||
// 备注信息 内部调用
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
#define imu963ra_write_acc_gyro_register(reg,data) (soft_iic_write_8bit_register(&imu963ra_iic_struct,reg,data))
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 IMU963RA 读寄存器
|
||||
// 参数说明 reg 寄存器地址
|
||||
// 返回参数 uint8 数据
|
||||
// 使用示例 imu963ra_read_acc_gyro_register(IMU963RA_STATUS_MASTER);
|
||||
// 备注信息 内部调用
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
#define imu963ra_read_acc_gyro_register(reg) (soft_iic_sccb_read_register(&imu963ra_iic_struct,reg))
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 IMU963RA 读数据 内部调用
|
||||
// 参数说明 reg 寄存器地址
|
||||
// 参数说明 data 数据缓冲区
|
||||
// 参数说明 len 数据长度
|
||||
// 返回参数 void
|
||||
// 使用示例 imu963ra_read_acc_gyro_registers(IMU963RA_OUTX_L_A, dat, 6);
|
||||
// 备注信息 内部调用
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
#define imu963ra_read_acc_gyro_registers(reg,data,len) (soft_iic_read_8bit_registers(&imu963ra_iic_struct,reg,data,len))
|
||||
#else
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 IMU963RA 写寄存器
|
||||
// 参数说明 reg 寄存器地址
|
||||
// 参数说明 data 数据
|
||||
// 返回参数 void
|
||||
// 使用示例 imu963ra_write_acc_gyro_register(IMU963RA_SLV0_CONFIG, 0x00);
|
||||
// 备注信息 内部调用
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
static void imu963ra_write_acc_gyro_register(uint8 reg, uint8 data)
|
||||
{
|
||||
IMU963RA_CS(0);
|
||||
spi_write_8bit_register(IMU963RA_SPI, reg | IMU963RA_SPI_W, data);
|
||||
|
||||
IMU963RA_CS(1);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 IMU963RA 读寄存器
|
||||
// 参数说明 reg 寄存器地址
|
||||
// 返回参数 uint8 数据
|
||||
// 使用示例 imu963ra_read_acc_gyro_register(IMU963RA_STATUS_MASTER);
|
||||
// 备注信息 内部调用
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
static uint8 imu963ra_read_acc_gyro_register(uint8 reg)
|
||||
{
|
||||
uint8 data = 0;
|
||||
IMU963RA_CS(0);
|
||||
data = spi_read_8bit_register(IMU963RA_SPI, reg | IMU963RA_SPI_R);
|
||||
|
||||
IMU963RA_CS(1);
|
||||
return data;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 IMU963RA 读数据 内部调用
|
||||
// 参数说明 reg 寄存器地址
|
||||
// 参数说明 data 数据缓冲区
|
||||
// 参数说明 len 数据长度
|
||||
// 返回参数 void
|
||||
// 使用示例 imu963ra_read_acc_gyro_registers(IMU963RA_OUTX_L_A, dat, 6);
|
||||
// 备注信息 内部调用
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
static void imu963ra_read_acc_gyro_registers(uint8 reg, uint8 *data, uint32 len)
|
||||
{
|
||||
IMU963RA_CS(0);
|
||||
spi_read_8bit_registers(IMU963RA_SPI, reg | IMU963RA_SPI_R, data, len);
|
||||
|
||||
IMU963RA_CS(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 IMU963RA 作为 IIC 主机向磁力计写数据
|
||||
// 参数说明 addr 目标地址
|
||||
// 参数说明 reg 目标寄存器
|
||||
// 参数说明 data 数据
|
||||
// 返回参数 uint8 1-失败 0-成功
|
||||
// 使用示例 imu963ra_write_mag_register(IMU963RA_MAG_ADDR, IMU963RA_MAG_CONTROL2, 0x80);
|
||||
// 备注信息 内部调用
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
static uint8 imu963ra_write_mag_register (uint8 addr, uint8 reg, uint8 data)
|
||||
{
|
||||
uint8 return_state = 0;
|
||||
uint16 timeout_count = 0;
|
||||
|
||||
addr = addr << 1;
|
||||
imu963ra_write_acc_gyro_register(IMU963RA_SLV0_CONFIG, 0x00); // 从机0配置清除
|
||||
imu963ra_write_acc_gyro_register(IMU963RA_SLV0_ADD, addr | 0); // 设置地磁计地址(注意这里需要设置8位的I2C地址) 0x2C
|
||||
imu963ra_write_acc_gyro_register(IMU963RA_SLV0_SUBADD, reg); // 需要写入的寄存器地址
|
||||
imu963ra_write_acc_gyro_register(IMU963RA_DATAWRITE_SLV0, data); // 需要写入的数据
|
||||
imu963ra_write_acc_gyro_register(IMU963RA_MASTER_CONFIG, 0x4C); // 仅在第一个周期启用通讯 开启上拉 I2C主机使能
|
||||
|
||||
// 等待通讯成功
|
||||
while(0 == (0x80 & imu963ra_read_acc_gyro_register(IMU963RA_STATUS_MASTER)))
|
||||
{
|
||||
if(IMU963RA_TIMEOUT_COUNT < timeout_count ++)
|
||||
{
|
||||
return_state = 1;
|
||||
break;
|
||||
}
|
||||
system_delay_ms(2);
|
||||
}
|
||||
return return_state;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 IMU963RA 作为 IIC 主机向磁力计读数据
|
||||
// 参数说明 addr 目标地址
|
||||
// 参数说明 reg 目标寄存器
|
||||
// 返回参数 uint8 读取的数据
|
||||
// 使用示例 imu963ra_read_mag_register(IMU963RA_MAG_ADDR, IMU963RA_MAG_CHIP_ID);
|
||||
// 备注信息 内部调用
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
static uint8 imu963ra_read_mag_register (uint8 addr, uint8 reg)
|
||||
{
|
||||
uint16 timeout_count = 0;
|
||||
|
||||
addr = addr << 1;
|
||||
imu963ra_write_acc_gyro_register(IMU963RA_SLV0_ADD, addr | 1); // 设置地磁计地址(注意这里需要设置8位的I2C地址) 0x2C
|
||||
imu963ra_write_acc_gyro_register(IMU963RA_SLV0_SUBADD, reg); // 需要读取的寄存器地址
|
||||
imu963ra_write_acc_gyro_register(IMU963RA_SLV0_CONFIG, 0x01);
|
||||
imu963ra_write_acc_gyro_register(IMU963RA_MASTER_CONFIG, 0x4C); // 仅在第一个周期启用通讯 开启上拉 I2C主机使能
|
||||
|
||||
// 等待通讯成功
|
||||
while(0 == (0x01 & imu963ra_read_acc_gyro_register(IMU963RA_STATUS_MASTER)))
|
||||
{
|
||||
if(IMU963RA_TIMEOUT_COUNT < timeout_count ++)
|
||||
{
|
||||
break;
|
||||
}
|
||||
system_delay_ms(2);
|
||||
}
|
||||
|
||||
return (imu963ra_read_acc_gyro_register(IMU963RA_SENSOR_HUB_1)); // 返回读取到的数据
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 IMU963RA 作为 IIC 主机向磁力计自动写数据
|
||||
// 参数说明 addr 目标地址
|
||||
// 参数说明 reg 目标寄存器
|
||||
// 返回参数 void
|
||||
// 使用示例 imu963ra_connect_mag(IMU963RA_MAG_ADDR, IMU963RA_MAG_OUTX_L);
|
||||
// 备注信息 内部调用
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
static void imu963ra_connect_mag (uint8 addr, uint8 reg)
|
||||
{
|
||||
addr = addr << 1;
|
||||
|
||||
imu963ra_write_acc_gyro_register(IMU963RA_SLV0_ADD, addr | 1); // 设置地磁计地址(注意这里需要设置8位的I2C地址) 0x2C
|
||||
imu963ra_write_acc_gyro_register(IMU963RA_SLV0_SUBADD, reg); // 需要读取的寄存器地址
|
||||
imu963ra_write_acc_gyro_register(IMU963RA_SLV0_CONFIG, 0x06);
|
||||
imu963ra_write_acc_gyro_register(IMU963RA_MASTER_CONFIG, 0x6C); // 仅在第一个周期启用通讯 开启上拉 I2C主机使能
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 IMU963RA 六轴自检 内部调用
|
||||
// 参数说明 void
|
||||
// 返回参数 uint8 1-自检失败 0-自检成功
|
||||
// 使用示例 imu963ra_acc_gyro_self_check();
|
||||
// 备注信息 内部调用
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
static uint8 imu963ra_acc_gyro_self_check (void)
|
||||
{
|
||||
uint8 return_state = 0;
|
||||
uint8 dat = 0;
|
||||
uint16 timeout_count = 0;
|
||||
|
||||
while(0x6B != dat) // 判断 ID 是否正确
|
||||
{
|
||||
if(IMU963RA_TIMEOUT_COUNT < timeout_count ++)
|
||||
{
|
||||
return_state = 1;
|
||||
break;
|
||||
}
|
||||
dat = imu963ra_read_acc_gyro_register(IMU963RA_WHO_AM_I);
|
||||
system_delay_ms(10);
|
||||
}
|
||||
return return_state;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 IMU963RA 磁力计自检 内部调用
|
||||
// 参数说明 void
|
||||
// 返回参数 uint8 1-自检失败 0-自检成功
|
||||
// 使用示例 imu963ra_mag_self_check();
|
||||
// 备注信息 内部调用
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
static uint8 imu963ra_mag_self_check (void)
|
||||
{
|
||||
uint8 return_state = 0;
|
||||
uint8 dat = 0;
|
||||
uint16 timeout_count = 0;
|
||||
|
||||
while(0xff != dat) // 判断 ID 是否正确
|
||||
{
|
||||
if(IMU963RA_TIMEOUT_COUNT < timeout_count ++)
|
||||
{
|
||||
return_state = 1;
|
||||
break;
|
||||
}
|
||||
dat = imu963ra_read_mag_register(IMU963RA_MAG_ADDR, IMU963RA_MAG_CHIP_ID);
|
||||
system_delay_ms(10);
|
||||
}
|
||||
return return_state;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 获取 IMU963RA 加速度计数据
|
||||
// 参数说明 void
|
||||
// 返回参数 void
|
||||
// 使用示例 imu963ra_get_acc();
|
||||
// 备注信息 执行该函数后,直接查看对应的变量即可
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
void imu963ra_get_acc (void)
|
||||
{
|
||||
uint8 dat[6];
|
||||
|
||||
imu963ra_read_acc_gyro_registers(IMU963RA_OUTX_L_A, dat, 6);
|
||||
imu963ra_acc_x = (int16)(((uint16)dat[1]<<8 | dat[0]));
|
||||
imu963ra_acc_y = (int16)(((uint16)dat[3]<<8 | dat[2]));
|
||||
imu963ra_acc_z = (int16)(((uint16)dat[5]<<8 | dat[4]));
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 获取IMU963RA陀螺仪数据
|
||||
// 参数说明 void
|
||||
// 返回参数 void
|
||||
// 使用示例 imu963ra_get_gyro();
|
||||
// 备注信息 执行该函数后,直接查看对应的变量即可
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
void imu963ra_get_gyro (void)
|
||||
{
|
||||
uint8 dat[6];
|
||||
|
||||
imu963ra_read_acc_gyro_registers(IMU963RA_OUTX_L_G, dat, 6);
|
||||
imu963ra_gyro_x = (int16)(((uint16)dat[1]<<8 | dat[0]));
|
||||
imu963ra_gyro_y = (int16)(((uint16)dat[3]<<8 | dat[2]));
|
||||
imu963ra_gyro_z = (int16)(((uint16)dat[5]<<8 | dat[4]));
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 获取 IMU963RA 磁力计数据
|
||||
// 参数说明 void
|
||||
// 返回参数 void
|
||||
// 使用示例 imu963ra_get_mag();
|
||||
// 备注信息 执行该函数后,直接查看对应的变量即可
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
void imu963ra_get_mag (void)
|
||||
{
|
||||
uint8 temp_status;
|
||||
uint8 dat[6];
|
||||
|
||||
imu963ra_write_acc_gyro_register(IMU963RA_FUNC_CFG_ACCESS, 0x40);
|
||||
temp_status = imu963ra_read_acc_gyro_register(IMU963RA_STATUS_MASTER);
|
||||
if(0x01 & temp_status)
|
||||
{
|
||||
imu963ra_read_acc_gyro_registers(IMU963RA_SENSOR_HUB_1, dat, 6);
|
||||
imu963ra_mag_x = (int16)(((uint16)dat[1] << 8 | dat[0]));
|
||||
imu963ra_mag_y = (int16)(((uint16)dat[3] << 8 | dat[2]));
|
||||
imu963ra_mag_z = (int16)(((uint16)dat[5] << 8 | dat[4]));
|
||||
}
|
||||
imu963ra_write_acc_gyro_register(IMU963RA_FUNC_CFG_ACCESS, 0x00);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 初始化 IMU963RA
|
||||
// 参数说明 void
|
||||
// 返回参数 uint8 1-初始化失败 0-初始化成功
|
||||
// 使用示例 imu963ra_init();
|
||||
// 备注信息
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
uint8 imu963ra_init (void)
|
||||
{
|
||||
uint8 return_state = 0;
|
||||
system_delay_ms(10); // 上电延时
|
||||
|
||||
#if IMU963RA_USE_SOFT_IIC
|
||||
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;
|
||||
}
|
||||
279
libraries/zf_device/zf_device_imu963ra.h
Normal file
279
libraries/zf_device/zf_device_imu963ra.h
Normal file
@@ -0,0 +1,279 @@
|
||||
/*/*********************************************************************************************************************
|
||||
* CH32V307VCT6 Opensourec Library 即(CH32V307VCT6 开源库)是一个基于官方 SDK 接口的第三方开源库
|
||||
* Copyright (c) 2022 SEEKFREE 逐飞科技
|
||||
*
|
||||
* 本文件是CH32V307VCT6 开源库的一部分
|
||||
*
|
||||
* CH32V307VCT6 开源库 是免费软件
|
||||
* 您可以根据自由软件基金会发布的 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 文件 版本说明
|
||||
* 开发环境 MounRiver Studio V1.8.1
|
||||
* 适用平台 CH32V307VCT6
|
||||
* 店铺链接 https://seekfree.taobao.com/
|
||||
*
|
||||
* 修改记录
|
||||
* 日期 作者 备注
|
||||
* 2022-09-15 大W first version
|
||||
********************************************************************************************************************/
|
||||
/*********************************************************************************************************************
|
||||
* 接线定义:
|
||||
* ------------------------------------
|
||||
* 模块管脚 单片机管脚
|
||||
* // 硬件 SPI 引脚
|
||||
* SCL/SPC 查看 zf_device_imu963ra.h 中 IMU963RA_SPC_PIN 宏定义
|
||||
* SDA/DSI 查看 zf_device_imu963ra.h 中 IMU963RA_SDI_PIN 宏定义
|
||||
* SA0/SDO 查看 zf_device_imu963ra.h 中 IMU963RA_SDO_PIN 宏定义
|
||||
* CS 查看 zf_device_imu963ra.h 中 IMU963RA_CS_PIN 宏定义
|
||||
* VCC 3.3V电源
|
||||
* GND 电源地
|
||||
* 其余引脚悬空
|
||||
|
||||
* // 软件 IIC 引脚
|
||||
* SCL/SPC 查看 zf_device_imu963ra.h 中 IMU963RA_SCL_PIN 宏定义
|
||||
* SDA/DSI 查看 zf_device_imu963ra.h 中 IMU963RA_SDA_PIN 宏定义
|
||||
* VCC 3.3V电源
|
||||
* GND 电源地
|
||||
* 其余引脚悬空
|
||||
* ------------------------------------
|
||||
********************************************************************************************************************/
|
||||
|
||||
#ifndef _zf_device_imu963ra_h
|
||||
#define _zf_device_imu963ra_h
|
||||
|
||||
#include "zf_common_typedef.h"
|
||||
|
||||
#define IMU963RA_USE_SOFT_IIC (0) // 默认使用硬件 SPI 方式驱动
|
||||
#if IMU963RA_USE_SOFT_IIC // 这两段 颜色正常的才是正确的 颜色灰的就是没有用的
|
||||
//====================================================软件 IIC 驱动====================================================
|
||||
#define IMU963RA_SOFT_IIC_DELAY (10 ) // 软件 IIC 的时钟延时周期 数值越小 IIC 通信速率越快
|
||||
#define IMU963RA_SCL_PIN (B3) // 软件 IIC SCL 引脚 连接 IMU963RA 的 SCL 引脚
|
||||
#define IMU963RA_SDA_PIN (B5) // 软件 IIC SDA 引脚 连接 IMU963RA 的 SDA 引脚
|
||||
//====================================================软件 IIC 驱动====================================================
|
||||
#else
|
||||
//====================================================硬件 SPI 驱动====================================================
|
||||
#define IMU963RA_SPI_SPEED (10*1000*1000 ) // 硬件 SPI 速率
|
||||
#define IMU963RA_SPI (SPI_3 ) // 硬件 SPI 号
|
||||
#define IMU963RA_SPC_PIN (SPI3_MAP0_SCK_B3 ) // 硬件 SPI SCK 引脚
|
||||
#define IMU963RA_SDI_PIN (SPI3_MAP0_MOSI_B5) // 硬件 SPI MOSI 引脚
|
||||
#define IMU963RA_SDO_PIN (SPI3_MAP0_MISO_B4) // 硬件 SPI MISO 引脚
|
||||
//====================================================硬件 SPI 驱动====================================================
|
||||
#endif
|
||||
#define IMU963RA_CS_PIN (C10) // 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 内部地址================================================
|
||||
#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_PIN_CTRL ( 0x02 )
|
||||
#define IMU963RA_S4S_TPH_L ( 0x04 )
|
||||
#define IMU963RA_S4S_TPH_H ( 0x05 )
|
||||
#define IMU963RA_S4S_RR ( 0x06 )
|
||||
#define IMU963RA_FIFO_CTRL1 ( 0x07 )
|
||||
#define IMU963RA_FIFO_CTRL2 ( 0x08 )
|
||||
#define IMU963RA_FIFO_CTRL3 ( 0x09 )
|
||||
#define IMU963RA_FIFO_CTRL4 ( 0x0A )
|
||||
#define IMU963RA_COUNTER_BDR_REG1 ( 0x0B )
|
||||
#define IMU963RA_COUNTER_BDR_REG2 ( 0x0C )
|
||||
#define IMU963RA_INT1_CTRL ( 0x0D )
|
||||
#define IMU963RA_INT2_CTRL ( 0x0E )
|
||||
#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_CTRL8_XL ( 0x17 )
|
||||
#define IMU963RA_CTRL9_XL ( 0x18 )
|
||||
#define IMU963RA_CTRL10_C ( 0x19 )
|
||||
#define IMU963RA_ALL_INT_SRC ( 0x1A )
|
||||
#define IMU963RA_WAKE_UP_SRC ( 0x1B )
|
||||
#define IMU963RA_TAP_SRC ( 0x1C )
|
||||
#define IMU963RA_D6D_SRC ( 0x1D )
|
||||
#define IMU963RA_STATUS_REG ( 0x1E )
|
||||
#define IMU963RA_OUT_TEMP_L ( 0x20 )
|
||||
#define IMU963RA_OUT_TEMP_H ( 0x21 )
|
||||
#define IMU963RA_OUTX_L_G ( 0x22 )
|
||||
#define IMU963RA_OUTX_H_G ( 0x23 )
|
||||
#define IMU963RA_OUTY_L_G ( 0x24 )
|
||||
#define IMU963RA_OUTY_H_G ( 0x25 )
|
||||
#define IMU963RA_OUTZ_L_G ( 0x26 )
|
||||
#define IMU963RA_OUTZ_H_G ( 0x27 )
|
||||
#define IMU963RA_OUTX_L_A ( 0x28 )
|
||||
#define IMU963RA_OUTX_H_A ( 0x29 )
|
||||
#define IMU963RA_OUTY_L_A ( 0x2A )
|
||||
#define IMU963RA_OUTY_H_A ( 0x2B )
|
||||
#define IMU963RA_OUTZ_L_A ( 0x2C )
|
||||
#define IMU963RA_OUTZ_H_A ( 0x2D )
|
||||
#define IMU963RA_EMB_FUNC_STATUS_MAINPAGE ( 0x35 )
|
||||
#define IMU963RA_FSM_STATUS_A_MAINPAGE ( 0x36 )
|
||||
#define IMU963RA_FSM_STATUS_B_MAINPAGE ( 0x37 )
|
||||
#define IMU963RA_STATUS_MASTER_MAINPAGE ( 0x39 )
|
||||
#define IMU963RA_FIFO_STATUS1 ( 0x3A )
|
||||
#define IMU963RA_FIFO_STATUS2 ( 0x3B )
|
||||
#define IMU963RA_TIMESTAMP0 ( 0x40 )
|
||||
#define IMU963RA_TIMESTAMP1 ( 0x41 )
|
||||
#define IMU963RA_TIMESTAMP2 ( 0x42 )
|
||||
#define IMU963RA_TIMESTAMP3 ( 0x43 )
|
||||
#define IMU963RA_TAP_CFG0 ( 0x56 )
|
||||
#define IMU963RA_TAP_CFG1 ( 0x57 )
|
||||
#define IMU963RA_TAP_CFG2 ( 0x58 )
|
||||
#define IMU963RA_TAP_THS_6D ( 0x59 )
|
||||
#define IMU963RA_INT_DUR2 ( 0x5A )
|
||||
#define IMU963RA_WAKE_UP_THS ( 0x5B )
|
||||
#define IMU963RA_WAKE_UP_DUR ( 0x5C )
|
||||
#define IMU963RA_FREE_FALL ( 0x5D )
|
||||
#define IMU963RA_MD1_CFG ( 0x5E )
|
||||
#define IMU963RA_MD2_CFG ( 0x5F )
|
||||
#define IMU963RA_S4S_ST_CMD_CODE ( 0x60 )
|
||||
#define IMU963RA_S4S_DT_REG ( 0x61 )
|
||||
#define IMU963RA_I3C_BUS_AVB ( 0x62 )
|
||||
#define IMU963RA_INTERNAL_FREQ_FINE ( 0x63 )
|
||||
#define IMU963RA_INT_OIS ( 0x6F )
|
||||
#define IMU963RA_CTRL1_OIS ( 0x70 )
|
||||
#define IMU963RA_CTRL2_OIS ( 0x71 )
|
||||
#define IMU963RA_CTRL3_OIS ( 0x72 )
|
||||
#define IMU963RA_X_OFS_USR ( 0x73 )
|
||||
#define IMU963RA_Y_OFS_USR ( 0x74 )
|
||||
#define IMU963RA_Z_OFS_USR ( 0x75 )
|
||||
#define IMU963RA_FIFO_DATA_OUT_TAG ( 0x78 )
|
||||
#define IMU963RA_FIFO_DATA_OUT_X_L ( 0x79 )
|
||||
#define IMU963RA_FIFO_DATA_OUT_X_H ( 0x7A )
|
||||
#define IMU963RA_FIFO_DATA_OUT_Y_L ( 0x7B )
|
||||
#define IMU963RA_FIFO_DATA_OUT_Y_H ( 0x7C )
|
||||
#define IMU963RA_FIFO_DATA_OUT_Z_L ( 0x7D )
|
||||
#define IMU963RA_FIFO_DATA_OUT_Z_H ( 0x7E )
|
||||
|
||||
// 集线器功能相关寄存器 需要将FUNC_CFG_ACCESS的SHUB_REG_ACCESS位设置为1才能正确访问
|
||||
#define IMU963RA_SENSOR_HUB_1 ( 0x02 )
|
||||
#define IMU963RA_SENSOR_HUB_2 ( 0x03 )
|
||||
#define IMU963RA_SENSOR_HUB_3 ( 0x04 )
|
||||
#define IMU963RA_SENSOR_HUB_4 ( 0x05 )
|
||||
#define IMU963RA_SENSOR_HUB_5 ( 0x06 )
|
||||
#define IMU963RA_SENSOR_HUB_6 ( 0x07 )
|
||||
#define IMU963RA_SENSOR_HUB_7 ( 0x08 )
|
||||
#define IMU963RA_SENSOR_HUB_8 ( 0x09 )
|
||||
#define IMU963RA_SENSOR_HUB_9 ( 0x0A )
|
||||
#define IMU963RA_SENSOR_HUB_10 ( 0x0B )
|
||||
#define IMU963RA_SENSOR_HUB_11 ( 0x0C )
|
||||
#define IMU963RA_SENSOR_HUB_12 ( 0x0D )
|
||||
#define IMU963RA_SENSOR_HUB_13 ( 0x0E )
|
||||
#define IMU963RA_SENSOR_HUB_14 ( 0x0F )
|
||||
#define IMU963RA_SENSOR_HUB_15 ( 0x10 )
|
||||
#define IMU963RA_SENSOR_HUB_16 ( 0x11 )
|
||||
#define IMU963RA_SENSOR_HUB_17 ( 0x12 )
|
||||
#define IMU963RA_SENSOR_HUB_18 ( 0x13 )
|
||||
#define IMU963RA_MASTER_CONFIG ( 0x14 )
|
||||
#define IMU963RA_SLV0_ADD ( 0x15 )
|
||||
#define IMU963RA_SLV0_SUBADD ( 0x16 )
|
||||
#define IMU963RA_SLV0_CONFIG ( 0x17 )
|
||||
#define IMU963RA_SLV1_ADD ( 0x18 )
|
||||
#define IMU963RA_SLV1_SUBADD ( 0x19 )
|
||||
#define IMU963RA_SLV1_CONFIG ( 0x1A )
|
||||
#define IMU963RA_SLV2_ADD ( 0x1B )
|
||||
#define IMU963RA_SLV2_SUBADD ( 0x1C )
|
||||
#define IMU963RA_SLV2_CONFIG ( 0x1D )
|
||||
#define IMU963RA_SLV3_ADD ( 0x1E )
|
||||
#define IMU963RA_SLV3_SUBADD ( 0x1F )
|
||||
#define IMU963RA_SLV3_CONFIG ( 0x20 )
|
||||
#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 )
|
||||
//================================================定义 IMU963RA 内部地址================================================
|
||||
|
||||
extern int16 imu963ra_acc_x, imu963ra_acc_y, imu963ra_acc_z;
|
||||
extern int16 imu963ra_gyro_x, imu963ra_gyro_y, imu963ra_gyro_z;
|
||||
extern int16 imu963ra_mag_x, imu963ra_mag_y, imu963ra_mag_z;
|
||||
extern float imu963ra_transition_factor[3];
|
||||
|
||||
void imu963ra_get_acc (void);
|
||||
void imu963ra_get_gyro (void);
|
||||
void imu963ra_get_mag (void);
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 将 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])
|
||||
|
||||
uint8 imu963ra_init (void);
|
||||
|
||||
#endif
|
||||
1076
libraries/zf_device/zf_device_ips114.c
Normal file
1076
libraries/zf_device/zf_device_ips114.c
Normal file
File diff suppressed because it is too large
Load Diff
165
libraries/zf_device/zf_device_ips114.h
Normal file
165
libraries/zf_device/zf_device_ips114.h
Normal file
@@ -0,0 +1,165 @@
|
||||
/*********************************************************************************************************************
|
||||
* CH32V307VCT6 Opensourec Library 即(CH32V307VCT6 开源库)是一个基于官方 SDK 接口的第三方开源库
|
||||
* Copyright (c) 2022 SEEKFREE 逐飞科技
|
||||
*
|
||||
* 本文件是CH32V307VCT6 开源库的一部分
|
||||
*
|
||||
* CH32V307VCT6 开源库 是免费软件
|
||||
* 您可以根据自由软件基金会发布的 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 文件 版本说明
|
||||
* 开发环境 MounRiver Studio V1.8.1
|
||||
* 适用平台 CH32V307VCT6
|
||||
* 店铺链接 https://seekfree.taobao.com/
|
||||
*
|
||||
* 修改记录
|
||||
* 日期 作者 备注
|
||||
* 2022-09-15 大W first version
|
||||
********************************************************************************************************************/
|
||||
/*********************************************************************************************************************
|
||||
* 接线定义:
|
||||
* ------------------------------------
|
||||
* 模块管脚 单片机管脚
|
||||
* SCL 查看 zf_device_ips114.h 中 IPS114_SCL_PIN 宏定义
|
||||
* SDA 查看 zf_device_ips114.h 中 IPS114_SDA_PIN 宏定义
|
||||
* RST 查看 zf_device_ips114.h 中 IPS114_RST_PIN 宏定义
|
||||
* DC 查看 zf_device_ips114.h 中 IPS114_DC_PIN 宏定义
|
||||
* CS 查看 zf_device_ips114.h 中 IPS114_CS_PIN 宏定义
|
||||
* BLK 查看 zf_device_ips114.h 中 IPS114_BLK_PIN 宏定义
|
||||
* VCC 3.3V电源
|
||||
* GND 电源地
|
||||
* 最大分辨率 135 * 240
|
||||
* ------------------------------------
|
||||
********************************************************************************************************************/
|
||||
|
||||
#ifndef _zf_device_ips114_h_
|
||||
#define _zf_device_ips114_h_
|
||||
|
||||
#include "zf_common_typedef.h"
|
||||
|
||||
#define IPS114_USE_SOFT_SPI (0) // 默认使用硬件 SPI 方式驱动 建议使用硬件 SPI 方式驱动
|
||||
#if IPS114_USE_SOFT_SPI // 这两段 颜色正常的才是正确的 颜色灰的就是没有用的
|
||||
//====================================================软件 SPI 驱动====================================================
|
||||
#define IPS114_SOFT_SPI_DELAY (1 ) // 软件 SPI 的时钟延时周期 数值越小 SPI 通信速率越快
|
||||
#define IPS114_SCL_PIN (D4) // 软件 SPI SCK 引脚
|
||||
#define IPS114_SDA_PIN (D6) // 软件 SPI MOSI 引脚
|
||||
//====================================================软件 SPI 驱动====================================================
|
||||
#else
|
||||
//====================================================硬件 SPI 驱动====================================================
|
||||
#define IPS114_SPI_SPEED (72 * 1000 * 1000) // 硬件 SPI 速率 这里设置为系统时钟二分频
|
||||
#define IPS114_SPI (SPI_2) // 硬件 SPI 号
|
||||
#define IPS114_SCL_PIN (SPI2_MAP0_SCK_B13) // 硬件 SPI SCK 引脚
|
||||
#define IPS114_SDA_PIN (SPI2_MAP0_MOSI_B15) // 硬件 SPI MOSI 引脚
|
||||
//====================================================硬件 SPI 驱动====================================================
|
||||
#endif
|
||||
|
||||
//#define IPS114_RST_PIN (B7 ) // 液晶复位引脚定义
|
||||
//#define IPS114_DC_PIN (D7 ) // 液晶命令位引脚定义
|
||||
//#define IPS114_CS_PIN (D4 ) // CS 片选引脚
|
||||
//#define IPS114_BLK_PIN (D0 ) // 液晶背光引脚定义
|
||||
|
||||
#define IPS114_RST_PIN (D8 ) // 液晶复位引脚定义
|
||||
#define IPS114_DC_PIN (D9 ) // 液晶命令位引脚定义
|
||||
#define IPS114_CS_PIN (D10 ) // CS 片选引脚
|
||||
#define IPS114_BLK_PIN (D11 ) // 液晶背光引脚定义
|
||||
|
||||
|
||||
#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)))
|
||||
|
||||
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;
|
||||
|
||||
void ips114_clear (void);
|
||||
void ips114_full (const uint16 color);
|
||||
void ips114_set_dir (ips114_dir_enum dir);
|
||||
void ips114_set_font (ips114_font_size_enum font);
|
||||
void ips114_set_color (const uint16 pen, const uint16 bgcolor);
|
||||
void ips114_draw_point (uint16 x, uint16 y, const uint16 color);
|
||||
void ips114_draw_line (uint16 x_start, uint16 y_start, uint16 x_end, uint16 y_end, const uint16 color);
|
||||
|
||||
void ips114_show_char (uint16 x, uint16 y, const char dat);
|
||||
void ips114_show_string (uint16 x, uint16 y, const char dat[]);
|
||||
void ips114_show_int (uint16 x,uint16 y, const int32 dat, uint8 num);
|
||||
void ips114_show_uint (uint16 x,uint16 y, const uint32 dat, uint8 num);
|
||||
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);
|
||||
void ips114_show_gray_image (uint16 x, uint16 y, const uint8 *image, uint16 width, uint16 height, uint16 dis_width, uint16 dis_height, uint8 threshold);
|
||||
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);
|
||||
|
||||
void ips114_show_wave (uint16 x, uint16 y, const uint16 *wave, uint16 width, uint16 value_max, uint16 dis_width, uint16 dis_value_max);
|
||||
void ips114_show_chinese (uint16 x, uint16 y, uint8 size, const uint8 *chinese_buffer, uint8 number, const uint16 color);
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 IPS114 显示小钻风图像
|
||||
// 参数说明 p 图像数组
|
||||
// 参数说明 width 显示宽度
|
||||
// 参数说明 height 显示高度
|
||||
// 返回参数 void
|
||||
// 使用示例 ips114_displayimage7725(ov7725_image_binary[0], 80, 60);
|
||||
// 备注信息
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
#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], 94, 60);
|
||||
// 备注信息 如果要显示二值化图像就去调用 ips114_show_gray_image 函数
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
#define ips114_displayimage03x(p, width, height) (ips114_show_gray_image(0, 0, (p), MT9V03X_W, MT9V03X_H, (width), (height), 0))
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 IPS114 显示凌瞳图像
|
||||
// 参数说明 p 图像数组
|
||||
// 参数说明 width 显示宽度
|
||||
// 参数说明 height 显示高度
|
||||
// 返回参数 void
|
||||
// 使用示例 ips114_displayimage8660(scc8660_image[0], 80, 60);
|
||||
// 备注信息
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
#define ips114_displayimage8660(p, width, height) (ips114_show_rgb565_image(0, 0, (p), SCC8660_W, SCC8660_H, (width), (height), 1))
|
||||
|
||||
void ips114_init (void);
|
||||
|
||||
#endif
|
||||
1296
libraries/zf_device/zf_device_ips200.c
Normal file
1296
libraries/zf_device/zf_device_ips200.c
Normal file
File diff suppressed because it is too large
Load Diff
210
libraries/zf_device/zf_device_ips200.h
Normal file
210
libraries/zf_device/zf_device_ips200.h
Normal file
@@ -0,0 +1,210 @@
|
||||
/*********************************************************************************************************************
|
||||
* CH32V307VCT6 Opensourec Library 即(CH32V307VCT6 开源库)是一个基于官方 SDK 接口的第三方开源库
|
||||
* Copyright (c) 2022 SEEKFREE 逐飞科技
|
||||
*
|
||||
* 本文件是CH32V307VCT6 开源库的一部分
|
||||
*
|
||||
* CH32V307VCT6 开源库 是免费软件
|
||||
* 您可以根据自由软件基金会发布的 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 文件 版本说明
|
||||
* 开发环境 MounRiver Studio V1.8.1
|
||||
* 适用平台 CH32V307VCT6
|
||||
* 店铺链接 https://seekfree.taobao.com/
|
||||
*
|
||||
* 修改记录
|
||||
* 日期 作者 备注
|
||||
* 2022-09-15 大W first version
|
||||
********************************************************************************************************************/
|
||||
/*********************************************************************************************************************
|
||||
* 接线定义:
|
||||
* ------------------------------------
|
||||
* 模块管脚 单片机管脚
|
||||
* // 双排排针 并口两寸屏 硬件引脚
|
||||
* 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 宏定义
|
||||
* // 单排排针 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"
|
||||
|
||||
|
||||
// --------------------单排两寸屏幕SPI接口引脚定义--------------------//
|
||||
|
||||
#define IPS200_USE_SOFT_SPI (0 ) // 默认使用硬件 SPI 方式驱动 建议使用硬件 SPI 方式驱动
|
||||
#if IPS200_USE_SOFT_SPI // 这两段 颜色正常的才是正确的 颜色灰的就是没有用的
|
||||
//====================================================软件 SPI 驱动====================================================
|
||||
// 如果使用的是单排排针的两寸屏幕 SPI 驱动控制引脚 可以修改
|
||||
#define IPS200_SOFT_SPI_DELAY (1 ) // 软件 SPI 的时钟延时周期 数值越小 SPI 通信速率越快
|
||||
#define IPS200_SCL_PIN (B13) // 软件 SPI SCK 引脚
|
||||
#define IPS200_SDA_PIN (B15) // 软件 SPI MOSI 引脚
|
||||
//====================================================软件 SPI 驱动====================================================
|
||||
#else
|
||||
//====================================================硬件 SPI 驱动====================================================
|
||||
// 如果使用的是单排排针的两寸屏幕 SPI 驱动控制引脚 可以修改
|
||||
#define IPS200_SPI_SPEED (72 * 1000 * 1000 ) // 硬件 SPI 速率 这里设置为系统时钟二分频
|
||||
#define IPS200_SPI (SPI_2 ) // 硬件 SPI 号
|
||||
#define IPS200_SCL_PIN_SPI (SPI2_MAP0_SCK_B13 ) // 硬件 SPI SCK 引脚
|
||||
#define IPS200_SDA_PIN_SPI (SPI2_MAP0_MOSI_B15) // 硬件 SPI MOSI 引脚
|
||||
//====================================================硬件 SPI 驱动====================================================
|
||||
#endif
|
||||
|
||||
// 如果使用的是单排排针的两寸屏幕 SPI 驱动控制引脚 可以修改
|
||||
#define IPS200_RST_PIN_SPI (B7 ) // 液晶复位引脚定义
|
||||
#define IPS200_DC_PIN_SPI (D7 ) // 液晶命令位引脚定义
|
||||
#define IPS200_CS_PIN_SPI (D4 )
|
||||
#define IPS200_BLk_PIN_SPI (D0 )
|
||||
|
||||
|
||||
// --------------------单排两寸屏幕SPI接口引脚定义--------------------//
|
||||
|
||||
|
||||
|
||||
// --------------------双排两寸屏幕并口引脚定义--------------------//
|
||||
#define IPS200_RD_PIN_PARALLEL8 (B13)
|
||||
#define IPS200_WR_PIN_PARALLEL8 (B15)
|
||||
#define IPS200_RS_PIN_PARALLEL8 (B7 )
|
||||
#define IPS200_RST_PIN_PARALLEL8 (D7 )
|
||||
#define IPS200_CS_PIN_PARALLEL8 (D4 )
|
||||
#define IPS200_BL_PIN_PARALLEL8 (D0 )
|
||||
|
||||
//8个数据引脚必须连续 例如B0-B7,B6-B13等等。
|
||||
//--------------数据端口寄存器--------------
|
||||
#define IPS200_DATAPORT GPIOE
|
||||
|
||||
//--------------数据端口起始地址偏移--------------
|
||||
#define DATA_START_NUM 0
|
||||
|
||||
//例:D1-D8 IPS200_DATAPORT设置为GPIOD DATA_START_NUM设置为1
|
||||
//例:C5-C12 IPS200_DATAPORT设置为GPIOC DATA_START_NUM设置为5
|
||||
// --------------------双排SPI接口两寸屏幕引脚定义--------------------//
|
||||
|
||||
#define IPS200_DEFAULT_DISPLAY_DIR (IPS200_PORTAIT) // 默认的显示方向
|
||||
#define IPS200_DEFAULT_PENCOLOR (RGB565_RED ) // 默认的画笔颜色
|
||||
#define IPS200_DEFAULT_BGCOLOR (RGB565_WHITE ) // 默认的背景颜色
|
||||
#define IPS200_DEFAULT_DISPLAY_FONT (IPS200_8X16_FONT) // 默认的字体模式
|
||||
|
||||
// 控制语句
|
||||
#define IPS200_RD(x) ((x) ? (gpio_high(IPS200_RD_PIN_PARALLEL8)) : (gpio_low(IPS200_RD_PIN_PARALLEL8)))
|
||||
#define IPS200_WR(x) ((x) ? (gpio_high(IPS200_WR_PIN_PARALLEL8)) : (gpio_low(IPS200_WR_PIN_PARALLEL8)))
|
||||
#define IPS200_RST(x) ((x) ? (gpio_high(ips_rst_pin)) : (gpio_low(ips_rst_pin)))
|
||||
#define IPS200_BL(x) ((x) ? (gpio_high(ips_bl_pin)) : (gpio_low(ips_bl_pin)))
|
||||
#define IPS200_RS(x) ((x) ? (gpio_high(IPS200_RS_PIN_PARALLEL8)) : (gpio_low(IPS200_RS_PIN_PARALLEL8)))
|
||||
|
||||
#define IPS200_DC(x) ((x) ? (gpio_high(IPS200_DC_PIN_SPI)) : (gpio_low(IPS200_DC_PIN_SPI)))
|
||||
#define IPS200_CS(x) ((x) ? (gpio_high(ips_cs_pin)) : (gpio_low(ips_cs_pin)))
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
IPS200_TYPE_SPI, // SPI 驱动
|
||||
IPS200_TYPE_PARALLEL8, // 并口驱动
|
||||
}ips200_type_enum;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
IPS200_PORTAIT = 0, // 竖屏模式
|
||||
IPS200_PORTAIT_180 = 1, // 竖屏模式 旋转180
|
||||
IPS200_CROSSWISE = 2, // 横屏模式
|
||||
IPS200_CROSSWISE_180 = 3, // 横屏模式 旋转180
|
||||
}ips200_dir_enum;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
IPS200_6X8_FONT = 0, // 6x8 字体
|
||||
IPS200_8X16_FONT = 1, // 8x16 字体
|
||||
IPS200_16X16_FONT = 2, // 16x16 字体 目前不支持
|
||||
}ips200_font_size_enum;
|
||||
|
||||
void ips200_clear (void);
|
||||
void ips200_full (const uint16 color);
|
||||
void ips200_set_dir (ips200_dir_enum dir);
|
||||
void ips200_set_font (ips200_font_size_enum font);
|
||||
void ips200_set_color (const uint16 pen, const uint16 bgcolor);
|
||||
void ips200_draw_point (uint16 x, uint16 y, const uint16 color);
|
||||
void ips200_draw_line (uint16 x_start, uint16 y_start, uint16 x_end, uint16 y_end, const uint16 color);
|
||||
|
||||
void ips200_show_char (uint16 x, uint16 y, const char dat);
|
||||
void ips200_show_string (uint16 x, uint16 y, const char dat[]);
|
||||
void ips200_show_int (uint16 x, uint16 y, const int32 dat, uint8 num);
|
||||
void ips200_show_uint (uint16 x, uint16 y, const uint32 dat, uint8 num);
|
||||
void ips200_show_float (uint16 x, uint16 y, const double dat, uint8 num, uint8 pointnum);
|
||||
|
||||
void ips200_show_binary_image (uint16 x, uint16 y, const uint8 *image, uint16 width, uint16 height, uint16 dis_width, uint16 dis_height);
|
||||
void ips200_show_gray_image (uint16 x, uint16 y, const uint8 *image, uint16 width, uint16 height, uint16 dis_width, uint16 dis_height, uint8 threshold);
|
||||
void ips200_show_rgb565_image (uint16 x, uint16 y, const uint16 *image, uint16 width, uint16 height, uint16 dis_width, uint16 dis_height, uint8 color_mode);
|
||||
|
||||
void ips200_show_wave (uint16 x, uint16 y, const uint16 *wave, uint16 width, uint16 value_max, uint16 dis_width, uint16 dis_value_max);
|
||||
void ips200_show_chinese (uint16 x, uint16 y, uint8 size, const uint8 *chinese_buffer, uint8 number, const uint16 color);
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 IPS200 显示小钻风图像
|
||||
// 参数说明 p 图像数组
|
||||
// 参数说明 width 显示宽度
|
||||
// 参数说明 height 显示高度
|
||||
// 返回参数 void
|
||||
// 使用示例 ips200_displayimage7725(ov7725_image_binary[0], 80, 60);
|
||||
// 备注信息
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
#define ips200_displayimage7725(p, width, height) (ips200_show_binary_image(0, 0, (p), OV7725_W, OV7725_H, (width), (height)))
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 IPS200 显示总钻风图像 不带二值化 显示灰度图像
|
||||
// 参数说明 p 图像数组
|
||||
// 参数说明 width 显示宽度
|
||||
// 参数说明 height 显示高度
|
||||
// 返回参数 void
|
||||
// 使用示例 ips200_displayimage03x(mt9v03x_image[0], 94, 60);
|
||||
// 备注信息 如果要显示二值化图像就去调用 ips200_show_gray_image 函数
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
#define ips200_displayimage03x(p, width, height) (ips200_show_gray_image(0, 0, (p), MT9V03X_W, MT9V03X_H, (width), (height), 0))
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 IPS200 显示凌瞳图像
|
||||
// 参数说明 p 图像数组
|
||||
// 参数说明 width 显示宽度
|
||||
// 参数说明 height 显示高度
|
||||
// 返回参数 void
|
||||
// 使用示例 ips200_displayimage8660(scc8660_image[0], 80, 60);
|
||||
// 备注信息
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
#define ips200_displayimage8660(p, width, height) (ips200_show_rgb565_image(0, 0, (p), SCC8660_W, SCC8660_H, (width), (height), 1))
|
||||
|
||||
void ips200_init (ips200_type_enum type_select);
|
||||
|
||||
#endif
|
||||
148
libraries/zf_device/zf_device_k24c02.c
Normal file
148
libraries/zf_device/zf_device_k24c02.c
Normal file
@@ -0,0 +1,148 @@
|
||||
/*********************************************************************************************************************
|
||||
* CH32V307VCT6 Opensourec Library 即(CH32V307VCT6 开源库)是一个基于官方 SDK 接口的第三方开源库
|
||||
* Copyright (c) 2022 SEEKFREE 逐飞科技
|
||||
*
|
||||
* 本文件是CH32V307VCT6 开源库的一部分
|
||||
*
|
||||
* CH32V307VCT6 开源库 是免费软件
|
||||
* 您可以根据自由软件基金会发布的 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_k24c02
|
||||
* 公司名称 成都逐飞科技有限公司
|
||||
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
|
||||
* 开发环境 MounRiver Studio V1.8.1
|
||||
* 适用平台 CH32V307VCT6
|
||||
* 店铺链接 https://seekfree.taobao.com/
|
||||
*
|
||||
* 修改记录
|
||||
* 日期 作者 备注
|
||||
* 2022-09-15 大W first version
|
||||
********************************************************************************************************************/
|
||||
/*********************************************************************************************************************
|
||||
* 接线定义:
|
||||
* ------------------------------------
|
||||
* 模块管脚 单片机管脚
|
||||
* 软件 IIC 通信引脚对应关系
|
||||
* SCL 查看 zf_device_k24c02.h 中 K24C02_SCL_PIN 宏定义
|
||||
* SDA 查看 zf_device_k24c02.h 中 K24C02_SDA_PIN 宏定义
|
||||
* 硬件 IIC 通信引脚对应关系
|
||||
* SCL 查看 zf_device_k24c02.h 中 K24C02_SCL_PIN 宏定义
|
||||
* SDA 查看 zf_device_k24c02.h 中 K24C02_SDA_PIN 宏定义
|
||||
* ------------------------------------
|
||||
********************************************************************************************************************/
|
||||
|
||||
#include "zf_common_clock.h"
|
||||
#include "zf_common_debug.h"
|
||||
#include "zf_driver_delay.h"
|
||||
#include "zf_driver_iic.h"
|
||||
#include "zf_driver_soft_iic.h"
|
||||
|
||||
#include "zf_device_k24c02.h"
|
||||
|
||||
#if K24C02_USE_SOFT_IIC
|
||||
static soft_iic_info_struct k24c02_iic_struct;
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 K24C02 IIC 写寄存器数据
|
||||
// 参数说明 reg 寄存器
|
||||
// 参数说明 *data 数据缓冲区
|
||||
// 参数说明 len 数据长度
|
||||
// 返回参数 void
|
||||
// 使用示例 k24c02_write_registers(page_num*8, (uint8 *)&k24c02_union_buffer[0], K24C02_PAGE_SIZE);
|
||||
// 备注信息 内部调用
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
#define k24c02_write_registers(reg, data, len) (soft_iic_write_8bit_registers(&k24c02_iic_struct, (reg), (data), (len)))
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 K24C02 IIC 读寄存器数据
|
||||
// 参数说明 reg 寄存器
|
||||
// 参数说明 *data 数据缓冲区
|
||||
// 参数说明 len 数据长度
|
||||
// 返回参数 void
|
||||
// 使用示例 k24c02_read_registers(page_num*8, (uint8 *)&k24c02_union_buffer[0], K24C02_PAGE_SIZE);
|
||||
// 备注信息 内部调用
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
#define k24c02_read_registers(reg, data, len) (soft_iic_read_8bit_registers(&k24c02_iic_struct, (reg), (data), (len)))
|
||||
#else
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 K24C02 IIC 写寄存器数据
|
||||
// 参数说明 reg 寄存器
|
||||
// 参数说明 *data 数据缓冲区
|
||||
// 参数说明 len 数据长度
|
||||
// 返回参数 void
|
||||
// 使用示例 k24c02_write_registers(page_num*8, (uint8 *)&k24c02_union_buffer[0], K24C02_PAGE_SIZE);
|
||||
// 备注信息 内部调用
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
#define k24c02_write_registers(reg, data, len) (iic_write_8bit_registers(K24C02_IIC, K24C02_DEV_ADDR, (reg), (data), (len)))
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 K24C02 IIC 读寄存器数据
|
||||
// 参数说明 reg 寄存器
|
||||
// 参数说明 *data 数据缓冲区
|
||||
// 参数说明 len 数据长度
|
||||
// 返回参数 void
|
||||
// 使用示例 k24c02_read_registers(page_num*8, (uint8 *)&k24c02_union_buffer[0], K24C02_PAGE_SIZE);
|
||||
// 备注信息 内部调用
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
#define k24c02_read_registers(reg, data, len) (iic_read_8bit_registers(K24C02_IIC, K24C02_DEV_ADDR, (reg), (data), (len)))
|
||||
#endif
|
||||
|
||||
k24c02_data_union k24c02_union_buffer[K24C02_DATA_BUFFER_SIZE];
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 K24C02 读指定的页码数据到缓冲区
|
||||
// 参数说明 page_num 指定的页码
|
||||
// 返回参数 void
|
||||
// 使用示例 k24c02_read_page_to_buffer(K24C02_PAGE_0);
|
||||
// 备注信息 数据更新到缓冲区 调用本函数后直接读取缓冲区即可
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
void k24c02_read_page_to_buffer (k24c02_page_enum page_num)
|
||||
{
|
||||
k24c02_read_registers(page_num*8, (uint8 *)&k24c02_union_buffer[0], K24C02_PAGE_SIZE);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 K24C02 将缓冲区数据写入指定页码
|
||||
// 参数说明 page_num 指定的页码
|
||||
// 返回参数 void
|
||||
// 使用示例 k24c02_write_page_from_buffer(K24C02_PAGE_0);
|
||||
// 备注信息 将数据缓冲区的数据写入 K24C02 的指定页码
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
uint8 k24c02_write_page_from_buffer (k24c02_page_enum page_num)
|
||||
{
|
||||
uint8 return_state = 0;
|
||||
k24c02_write_registers(page_num*8, (uint8 *)&k24c02_union_buffer[0], K24C02_PAGE_SIZE);
|
||||
return return_state;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// brief 初始化 K24C02
|
||||
// param void
|
||||
// return uint8 1-初始化失败 0-初始化成功
|
||||
// 使用示例 k24c02_init();
|
||||
// 备注信息
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
uint8 k24c02_init (void)
|
||||
{
|
||||
uint8 return_state = 0;
|
||||
#if K24C02_USE_SOFT_IIC
|
||||
soft_iic_init(&k24c02_iic_struct, K24C02_DEV_ADDR, K24C02_SOFT_IIC_DELAY, K24C02_SCL_PIN, K24C02_SDA_PIN);
|
||||
#else
|
||||
iic_init(K24C02_IIC, K24C02_DEV_ADDR, K24C02_IIC_SPEED, K24C02_SCL_PIN, K24C02_SDA_PIN);
|
||||
#endif
|
||||
return return_state;
|
||||
}
|
||||
112
libraries/zf_device/zf_device_k24c02.h
Normal file
112
libraries/zf_device/zf_device_k24c02.h
Normal file
@@ -0,0 +1,112 @@
|
||||
/*********************************************************************************************************************
|
||||
* CH32V307VCT6 Opensourec Library 即(CH32V307VCT6 开源库)是一个基于官方 SDK 接口的第三方开源库
|
||||
* Copyright (c) 2022 SEEKFREE 逐飞科技
|
||||
*
|
||||
* 本文件是CH32V307VCT6 开源库的一部分
|
||||
*
|
||||
* CH32V307VCT6 开源库 是免费软件
|
||||
* 您可以根据自由软件基金会发布的 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_k24c02
|
||||
* 公司名称 成都逐飞科技有限公司
|
||||
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
|
||||
* 开发环境 MounRiver Studio V1.8.1
|
||||
* 适用平台 CH32V307VCT6
|
||||
* 店铺链接 https://seekfree.taobao.com/
|
||||
*
|
||||
* 修改记录
|
||||
* 日期 作者 备注
|
||||
* 2022-09-15 大W first version
|
||||
********************************************************************************************************************/
|
||||
/*********************************************************************************************************************
|
||||
* 接线定义:
|
||||
* ------------------------------------
|
||||
* 模块管脚 单片机管脚
|
||||
* 软件 IIC 通信引脚对应关系
|
||||
* SCL 查看 zf_device_k24c02.h 中 K24C02_SCL_PIN 宏定义
|
||||
* SDA 查看 zf_device_k24c02.h 中 K24C02_SDA_PIN 宏定义
|
||||
* 硬件 IIC 通信引脚对应关系
|
||||
* SCL 查看 zf_device_k24c02.h 中 K24C02_SCL_PIN 宏定义
|
||||
* SDA 查看 zf_device_k24c02.h 中 K24C02_SDA_PIN 宏定义
|
||||
* ------------------------------------
|
||||
********************************************************************************************************************/
|
||||
|
||||
#ifndef _zf_device_k24c02_h_
|
||||
#define _zf_device_k24c02_h_
|
||||
|
||||
#include "zf_common_typedef.h"
|
||||
|
||||
#define K24C02_USE_SOFT_IIC (1) // 默认使用软件 IIC 方式驱动 建议使用软件 IIC 方式
|
||||
#if K24C02_USE_SOFT_IIC // 这两段 颜色正常的才是正确的 颜色灰的就是没有用的
|
||||
//====================================================软件 IIC 驱动====================================================
|
||||
#define K24C02_SOFT_IIC_DELAY (500) // 软件 IIC 的时钟延时周期 数值越小 IIC 通信速率越快
|
||||
#define K24C02_SCL_PIN (B10 ) // 软件 IIC SCL 引脚 连接 K24C02 的 SCL 引脚
|
||||
#define K24C02_SDA_PIN (B11 ) // 软件 IIC SDA 引脚 连接 K24C02 的 SDA 引脚
|
||||
//====================================================软件 IIC 驱动====================================================
|
||||
#else
|
||||
//====================================================硬件 IIC 驱动====================================================
|
||||
#define K24C02_IIC_SPEED (400000 ) // 硬件 IIC 通信速率 最高 400KHz 不建议低于 40KHz
|
||||
#define K24C02_IIC (IIC_1 ) // 硬件 IIC
|
||||
#define K24C02_SCL_PIN (IIC1_SCL_C6) // 硬件 IIC SCL 引脚 连接 K24C02 的 SCL 引脚
|
||||
#define K24C02_SDA_PIN (IIC1_SDA_C7) // 硬件 IIC SDA 引脚 连接 K24C02 的 SDA 引脚
|
||||
//====================================================硬件 IIC 驱动====================================================
|
||||
#endif
|
||||
|
||||
#define K24C02_TIMEOUT_COUNT (0x00FF) // K24C02 超时计数
|
||||
|
||||
//================================================定义 K24C02 内部地址================================================
|
||||
#define K24C02_DEV_ADDR (0xA0 >> 1) // IIC写入时的地址字节数据 +1为读取
|
||||
//================================================定义 K24C02 内部地址================================================
|
||||
|
||||
#define K24C02_SIZE (256) // 256 byte
|
||||
#define K24C02_PAGE_SIZE (8) // 8 byte
|
||||
#define K24C02_DATA_BUFFER_SIZE (K24C02_PAGE_SIZE / sizeof(k24c02_data_union))// 自动计算每个页能够存下多少个数据
|
||||
|
||||
typedef enum // 枚举 K24C02 页索引 此枚举定义不允许用户修改
|
||||
{
|
||||
K24C02_PAGE_0 , K24C02_PAGE_1 , K24C02_PAGE_2 , K24C02_PAGE_3 ,
|
||||
K24C02_PAGE_4 , K24C02_PAGE_5 , K24C02_PAGE_6 , K24C02_PAGE_7 ,
|
||||
K24C02_PAGE_8 , K24C02_PAGE_9 , K24C02_PAGE_10, K24C02_PAGE_11,
|
||||
K24C02_PAGE_12, K24C02_PAGE_13, K24C02_PAGE_14, K24C02_PAGE_15,
|
||||
K24C02_PAGE_16, K24C02_PAGE_17, K24C02_PAGE_18, K24C02_PAGE_19,
|
||||
K24C02_PAGE_20, K24C02_PAGE_21, K24C02_PAGE_22, K24C02_PAGE_23,
|
||||
K24C02_PAGE_24, K24C02_PAGE_25, K24C02_PAGE_26, K24C02_PAGE_27,
|
||||
K24C02_PAGE_28, K24C02_PAGE_29, K24C02_PAGE_30, K24C02_PAGE_31,
|
||||
}k24c02_page_enum;
|
||||
|
||||
typedef union // 固定的数据缓冲单元格式
|
||||
{
|
||||
float float_type; // float 类型
|
||||
uint32 uint32_type; // uint32 类型
|
||||
int32 int32_type; // int32 类型
|
||||
uint16 uint16_type; // uint16 类型
|
||||
int16 int16_type; // int16 类型
|
||||
uint8 uint8_type; // uint8 类型
|
||||
int8 int8_type; // int8 类型
|
||||
}k24c02_data_union; // 所有类型数据共用同一个 32bit 地址
|
||||
|
||||
extern k24c02_data_union k24c02_union_buffer[K24C02_DATA_BUFFER_SIZE];
|
||||
|
||||
void k24c02_read_page (k24c02_page_enum page_num, uint8 *buf, uint8 len);
|
||||
uint8 k24c02_write_page (k24c02_page_enum page_num, const uint8 *buf, uint8 len);
|
||||
|
||||
void k24c02_read_page_to_buffer (k24c02_page_enum page_num);
|
||||
uint8 k24c02_write_page_from_buffer (k24c02_page_enum page_num);
|
||||
|
||||
uint8 k24c02_init (void);
|
||||
|
||||
#endif
|
||||
148
libraries/zf_device/zf_device_key.c
Normal file
148
libraries/zf_device/zf_device_key.c
Normal file
@@ -0,0 +1,148 @@
|
||||
/*********************************************************************************************************************
|
||||
* CH32V307VCT6 Opensourec Library 即(CH32V307VCT6 开源库)是一个基于官方 SDK 接口的第三方开源库
|
||||
* Copyright (c) 2022 SEEKFREE 逐飞科技
|
||||
*
|
||||
* 本文件是CH32V307VCT6 开源库的一部分
|
||||
*
|
||||
* CH32V307VCT6 开源库 是免费软件
|
||||
* 您可以根据自由软件基金会发布的 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 文件 版本说明
|
||||
* 开发环境 MounRiver Studio V1.8.1
|
||||
* 适用平台 CH32V307VCT6
|
||||
* 店铺链接 https://seekfree.taobao.com/
|
||||
*
|
||||
* 修改记录
|
||||
* 日期 作者 备注
|
||||
* 2022-09-15 大W first version
|
||||
********************************************************************************************************************/
|
||||
/*********************************************************************************************************************
|
||||
* 接线定义:
|
||||
* ------------------------------------
|
||||
* 模块管脚 单片机管脚
|
||||
* // 一般是主板按键对应的引脚
|
||||
* KEY1/S1 查看 zf_device_key.h 中 KEY_LIST[0]
|
||||
* KEY2/S2 查看 zf_device_key.h 中 KEY_LIST[1]
|
||||
* KEY3/S3 查看 zf_device_key.h 中 KEY_LIST[2]
|
||||
* KEY4/S4 查看 zf_device_key.h 中 KEY_LIST[3]
|
||||
* ------------------------------------
|
||||
********************************************************************************************************************/
|
||||
|
||||
#include "zf_common_debug.h"
|
||||
|
||||
#include "zf_device_key.h"
|
||||
|
||||
static uint32 scanner_period = 0; // 按键的扫描周期
|
||||
static uint32 key_press_time[KEY_NUMBER]; // 按键信号持续时长
|
||||
static key_state_enum key_state[KEY_NUMBER]; // 按键状态
|
||||
|
||||
static const gpio_pin_enum key_index[KEY_NUMBER] = KEY_LIST;
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 按键状态扫描
|
||||
// 参数说明 void
|
||||
// 返回参数 void
|
||||
// 使用示例 key_scanner();
|
||||
// 备注信息 这个函数放在主循环或者 PIT 中断中
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
void key_scanner (void)
|
||||
{
|
||||
uint8 i = 0;
|
||||
for(i = 0; KEY_NUMBER > i; i ++)
|
||||
{
|
||||
if(KEY_RELEASE_LEVEL != gpio_get_level(key_index[i])) // 按键按下
|
||||
{
|
||||
key_press_time[i] ++;
|
||||
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 / scanner_period <= key_press_time[i]))
|
||||
{
|
||||
key_state[i] = KEY_SHORT_PRESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
key_state[i] = KEY_RELEASE;
|
||||
}
|
||||
key_press_time[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 获取按键状态
|
||||
// 参数说明 key_n 按键索引
|
||||
// 返回参数 key_state_enum 按键状态
|
||||
// 使用示例 key_get_state(KEY_1);
|
||||
// 备注信息
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
key_state_enum key_get_state (key_index_enum key_n)
|
||||
{
|
||||
return key_state[key_n];
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 清除对应按键状态
|
||||
// 参数说明 key_n 按键索引
|
||||
// 返回参数 void 无
|
||||
// 使用示例 key_clear_state(KEY_1);
|
||||
// 备注信息
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
void key_clear_state (key_index_enum key_n)
|
||||
{
|
||||
key_state[key_n] = KEY_RELEASE;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 清除所有按键状态
|
||||
// 参数说明 void 无
|
||||
// 返回参数 void 无
|
||||
// 使用示例 key_clear_all_state();
|
||||
// 备注信息
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
void key_clear_all_state (void)
|
||||
{
|
||||
key_state[0] = KEY_RELEASE;
|
||||
key_state[1] = KEY_RELEASE;
|
||||
key_state[2] = KEY_RELEASE;
|
||||
key_state[3] = KEY_RELEASE;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 按键初始化
|
||||
// 参数说明 period 按键扫描周期 以毫秒为单位
|
||||
// 返回参数 void
|
||||
// 使用示例 key_init(10);
|
||||
// 备注信息
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
void key_init (uint32 period)
|
||||
{
|
||||
zf_assert(0 < period);
|
||||
uint8 loop_temp = 0;
|
||||
for(loop_temp = 0; KEY_NUMBER > loop_temp; loop_temp ++)
|
||||
{
|
||||
gpio_init(key_index[loop_temp], GPI, GPIO_HIGH, GPI_PULL_UP);
|
||||
key_state[loop_temp] = KEY_RELEASE;
|
||||
}
|
||||
scanner_period = period;
|
||||
}
|
||||
85
libraries/zf_device/zf_device_key.h
Normal file
85
libraries/zf_device/zf_device_key.h
Normal file
@@ -0,0 +1,85 @@
|
||||
/*********************************************************************************************************************
|
||||
* CH32V307VCT6 Opensourec Library 即(CH32V307VCT6 开源库)是一个基于官方 SDK 接口的第三方开源库
|
||||
* Copyright (c) 2022 SEEKFREE 逐飞科技
|
||||
*
|
||||
* 本文件是CH32V307VCT6 开源库的一部分
|
||||
*
|
||||
* CH32V307VCT6 开源库 是免费软件
|
||||
* 您可以根据自由软件基金会发布的 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 文件 版本说明
|
||||
* 开发环境 MounRiver Studio V1.8.1
|
||||
* 适用平台 CH32V307VCT6
|
||||
* 店铺链接 https://seekfree.taobao.com/
|
||||
*
|
||||
* 修改记录
|
||||
* 日期 作者 备注
|
||||
* 2022-09-15 大W first version
|
||||
********************************************************************************************************************/
|
||||
/*********************************************************************************************************************
|
||||
* 接线定义:
|
||||
* ------------------------------------
|
||||
* 模块管脚 单片机管脚
|
||||
* // 一般是主板按键对应的引脚
|
||||
* KEY1/S1 查看 zf_device_key.h 中 KEY_LIST[0]
|
||||
* KEY2/S2 查看 zf_device_key.h 中 KEY_LIST[1]
|
||||
* KEY3/S3 查看 zf_device_key.h 中 KEY_LIST[2]
|
||||
* KEY4/S4 查看 zf_device_key.h 中 KEY_LIST[3]
|
||||
* ------------------------------------
|
||||
********************************************************************************************************************/
|
||||
|
||||
#ifndef _zf_device_key_h_
|
||||
#define _zf_device_key_h_
|
||||
|
||||
#include "zf_common_debug.h"
|
||||
|
||||
#include "zf_driver_gpio.h"
|
||||
|
||||
// 定义按键引脚 用户可以新增可以修改 默认定义四个按键
|
||||
// 定义按键顺序对应下方 key_index_enum 枚举体中定义的顺序
|
||||
// 如果用户可以新增按键 那么需要同步在下方 key_index_enum 枚举体中新增按键
|
||||
#define KEY_LIST {A8 , D8 , B12 , B0 }
|
||||
|
||||
#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
|
||||
219
libraries/zf_device/zf_device_mpu6050.c
Normal file
219
libraries/zf_device/zf_device_mpu6050.c
Normal file
@@ -0,0 +1,219 @@
|
||||
/*********************************************************************************************************************
|
||||
* CH32V307VCT6 Opensourec Library 即(CH32V307VCT6 开源库)是一个基于官方 SDK 接口的第三方开源库
|
||||
* Copyright (c) 2022 SEEKFREE 逐飞科技
|
||||
*
|
||||
* 本文件是CH32V307VCT6 开源库的一部分
|
||||
*
|
||||
* CH32V307VCT6 开源库 是免费软件
|
||||
* 您可以根据自由软件基金会发布的 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 文件 版本说明
|
||||
* 开发环境 MounRiver Studio V1.8.1
|
||||
* 适用平台 CH32V307VCT6
|
||||
* 店铺链接 https://seekfree.taobao.com/
|
||||
*
|
||||
* 修改记录
|
||||
* 日期 作者 备注
|
||||
* 2022-09-15 大W first version
|
||||
********************************************************************************************************************/
|
||||
/*********************************************************************************************************************
|
||||
* 接线定义:
|
||||
* ------------------------------------
|
||||
* 模块管脚 单片机管脚
|
||||
* 软件 IIC 通信引脚对应关系
|
||||
* SCL 查看 zf_device_mpu6050.h 中 MPU6050_SOFT_IIC_SCL 宏定义
|
||||
* SDA 查看 zf_device_mpu6050.h 中 MPU6050_SOFT_IIC_SDA 宏定义
|
||||
* 硬件 IIC 通信引脚对应关系
|
||||
* SCL 查看 zf_device_mpu6050.h 中 MPU6050_IIC_SCL 宏定义
|
||||
* SDA 查看 zf_device_mpu6050.h 中 MPU6050_IIC_SDA 宏定义
|
||||
* ------------------------------------
|
||||
********************************************************************************************************************/
|
||||
|
||||
#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;
|
||||
|
||||
#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
|
||||
#define mpu6050_write_register(reg, data) (iic_write_8bit_register(MPU6050_IIC, MPU6050_DEV_ADDR, (reg), (data)))
|
||||
#define mpu6050_read_register(reg) (iic_read_8bit_register(MPU6050_IIC, MPU6050_DEV_ADDR, (reg)))
|
||||
#define mpu6050_read_registers(reg, data, len) (iic_read_8bit_registers(MPU6050_IIC, MPU6050_DEV_ADDR, (reg), (data), (len)))
|
||||
#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(timeout_count ++ > MPU6050_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(mpu6050_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(mpu6050_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;
|
||||
}
|
||||
123
libraries/zf_device/zf_device_mpu6050.h
Normal file
123
libraries/zf_device/zf_device_mpu6050.h
Normal file
@@ -0,0 +1,123 @@
|
||||
/*********************************************************************************************************************
|
||||
* CH32V307VCT6 Opensourec Library 即(CH32V307VCT6 开源库)是一个基于官方 SDK 接口的第三方开源库
|
||||
* Copyright (c) 2022 SEEKFREE 逐飞科技
|
||||
*
|
||||
* 本文件是CH32V307VCT6 开源库的一部分
|
||||
*
|
||||
* CH32V307VCT6 开源库 是免费软件
|
||||
* 您可以根据自由软件基金会发布的 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 文件 版本说明
|
||||
* 开发环境 MounRiver Studio V1.8.1
|
||||
* 适用平台 CH32V307VCT6
|
||||
* 店铺链接 https://seekfree.taobao.com/
|
||||
*
|
||||
* 修改记录
|
||||
* 日期 作者 备注
|
||||
* 2022-09-15 大W first version
|
||||
********************************************************************************************************************/
|
||||
/*********************************************************************************************************************
|
||||
* 接线定义:
|
||||
* ------------------------------------
|
||||
* 模块管脚 单片机管脚
|
||||
* 软件 IIC 通信引脚对应关系
|
||||
* SCL 查看 zf_device_mpu6050.h 中 MPU6050_SOFT_IIC_SCL 宏定义
|
||||
* SDA 查看 zf_device_mpu6050.h 中 MPU6050_SOFT_IIC_SDA 宏定义
|
||||
* 硬件 IIC 通信引脚对应关系
|
||||
* SCL 查看 zf_device_mpu6050.h 中 MPU6050_IIC_SCL 宏定义
|
||||
* SDA 查看 zf_device_mpu6050.h 中 MPU6050_IIC_SDA 宏定义
|
||||
* ------------------------------------
|
||||
********************************************************************************************************************/
|
||||
|
||||
#ifndef _zf_device_mpu6050_h_
|
||||
#define _zf_device_mpu6050_h_
|
||||
|
||||
#include "zf_common_clock.h"
|
||||
#include "zf_common_debug.h"
|
||||
|
||||
#include "zf_driver_delay.h"
|
||||
|
||||
#include "zf_driver_soft_iic.h"
|
||||
|
||||
#define MPU6050_USE_SOFT_IIC (1) // 默认使用软件 IIC 方式驱动 建议使用软件 IIC 方式
|
||||
#if MPU6050_USE_SOFT_IIC // 这两段 颜色正常的才是正确的 颜色灰的就是没有用的
|
||||
//====================================================软件 IIC 驱动====================================================
|
||||
#define MPU6050_SOFT_IIC_DELAY (10 ) // 软件 IIC 的时钟延时周期 数值越小 IIC 通信速率越快
|
||||
#define MPU6050_SCL_PIN (B3 ) // 软件 IIC SCL 引脚 连接 MPU6050 的 SCL 引脚
|
||||
#define MPU6050_SDA_PIN (B5 ) // 软件 IIC SDA 引脚 连接 MPU6050 的 SDA 引脚
|
||||
//====================================================软件 IIC 驱动====================================================
|
||||
#else
|
||||
//====================================================硬件 IIC 驱动====================================================
|
||||
#define MPU6050_IIC_SPEED (400000 ) // 硬件 IIC 通信速率 最高 400KHz 不建议低于 40KHz
|
||||
#define MPU6050_IIC (暂不支持 ) // 硬件 IIC SCL 引脚 连接 MPU6050 的 SCL 引脚
|
||||
#define MPU6050_SCL_PIN (暂不支持 ) // 硬件 IIC SCL 引脚 连接 MPU6050 的 SCL 引脚
|
||||
#define MPU6050_SDA_PIN (暂不支持 ) // 硬件 IIC SDA 引脚 连接 MPU6050 的 SDA 引脚
|
||||
//====================================================硬件 IIC 驱动====================================================
|
||||
#endif
|
||||
|
||||
#define MPU6050_TIMEOUT_COUNT (0x00FF) // 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_ACCEL_XOUT_L (0x3C)
|
||||
#define MPU6050_ACCEL_YOUT_H (0x3D)
|
||||
#define MPU6050_ACCEL_YOUT_L (0x3E)
|
||||
#define MPU6050_ACCEL_ZOUT_H (0x3F)
|
||||
#define MPU6050_ACCEL_ZOUT_L (0x40)
|
||||
#define MPU6050_GYRO_XOUT_H (0x43)
|
||||
#define MPU6050_GYRO_XOUT_L (0x44)
|
||||
#define MPU6050_GYRO_YOUT_H (0x45)
|
||||
#define MPU6050_GYRO_YOUT_L (0x46)
|
||||
#define MPU6050_GYRO_ZOUT_H (0x47)
|
||||
#define MPU6050_GYRO_ZOUT_L (0x48)
|
||||
#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 内部地址================================================
|
||||
|
||||
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 加速度计)
|
||||
|
||||
void mpu6050_get_acc (void);
|
||||
void mpu6050_get_gyro (void);
|
||||
float mpu6050_acc_transition (int16 acc_value); // 将 MPU6050 加速度计数据转换为实际物理数据
|
||||
float mpu6050_gyro_transition (int16 gyro_value); // 将 MPU6050 陀螺仪数据转换为实际物理数据
|
||||
uint8 mpu6050_init (void);
|
||||
|
||||
#endif
|
||||
660
libraries/zf_device/zf_device_mt9v03x_dvp.c
Normal file
660
libraries/zf_device/zf_device_mt9v03x_dvp.c
Normal file
@@ -0,0 +1,660 @@
|
||||
/*********************************************************************************************************************
|
||||
* CH32V307VCT6 Opensourec Library 即(CH32V307VCT6 开源库)是一个基于官方 SDK 接口的第三方开源库
|
||||
* Copyright (c) 2022 SEEKFREE 逐飞科技
|
||||
*
|
||||
* 本文件是CH32V307VCT6 开源库的一部分
|
||||
*
|
||||
* CH32V307VCT6 开源库 是免费软件
|
||||
* 您可以根据自由软件基金会发布的 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
|
||||
* 公司名称 成都逐飞科技有限公司
|
||||
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
|
||||
* 开发环境 MounRiver Studio V1.8.1
|
||||
* 适用平台 CH32V307VCT6
|
||||
* 店铺链接 https://seekfree.taobao.com/
|
||||
*
|
||||
* 修改记录
|
||||
* 日期 作者 备注
|
||||
* 2021-12-23 大W 摄像头采集完成标志位增加volatile修饰
|
||||
* 2022-03-26 大W 修改部分不重要的注释
|
||||
* 2022-09-15 大W first version
|
||||
********************************************************************************************************************/
|
||||
/*********************************************************************************************************************
|
||||
* 接线定义:
|
||||
* ------------------------------------
|
||||
* 模块管脚 单片机管脚
|
||||
* TXD 查看 zf_device_mt9v03x_dvp.h 中 MT9V03X_COF_UART_TX 宏定义
|
||||
* RXD 查看 zf_device_mt9v03x_dvp.h 中 MT9V03X_COF_UART_RX 宏定义
|
||||
* D0 查看 zf_device_mt9v03x_dvp.h 中 MT9V03X_D0_PIN 宏定义
|
||||
* D1 查看 zf_device_mt9v03x_dvp.h 中 MT9V03X_D1_PIN 宏定义
|
||||
* D2 查看 zf_device_mt9v03x_dvp.h 中 MT9V03X_D2_PIN 宏定义
|
||||
* D3 查看 zf_device_mt9v03x_dvp.h 中 MT9V03X_D3_PIN 宏定义
|
||||
* D4 查看 zf_device_mt9v03x_dvp.h 中 MT9V03X_D4_PIN 宏定义
|
||||
* D5 查看 zf_device_mt9v03x_dvp.h 中 MT9V03X_D5_PIN 宏定义
|
||||
* D6 查看 zf_device_mt9v03x_dvp.h 中 MT9V03X_D6_PIN 宏定义
|
||||
* D7 查看 zf_device_mt9v03x_dvp.h 中 MT9V03X_D7_PIN 宏定义
|
||||
* PCLK 查看 zf_device_mt9v03x_dvp.h 中 MT9V03X_PCLK_PIN 宏定义
|
||||
* VSYNC 查看 zf_device_mt9v03x_dvp.h 中 MT9V03X_VSY_PIN 宏定义
|
||||
* HSYNC 查看 zf_device_mt9v03x_dvp.h 中 MT9V03X_HERF_PIN 宏定义
|
||||
* ------------------------------------
|
||||
********************************************************************************************************************/
|
||||
|
||||
#include "zf_driver_delay.h"
|
||||
#include "zf_driver_dvp.h"
|
||||
#include "zf_driver_soft_iic.h"
|
||||
|
||||
|
||||
#include "zf_device_camera.h"
|
||||
#include "zf_device_type.h"
|
||||
#include "zf_device_mt9v03x_dvp.h"
|
||||
#include "zf_device_config.h"
|
||||
|
||||
vuint8 mt9v03x_finish_flag = 0; // 一场图像采集完成标志位
|
||||
__attribute__((aligned(4))) uint8 mt9v03x_image[MT9V03X_H][MT9V03X_W];
|
||||
|
||||
static fifo_struct *camera_receiver_fifo;
|
||||
static mt9v03x_type_enum mt9v03x_type = MT9V03X_SCCB;
|
||||
static uint16 mt9v03x_version = 0x00;
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 配置摄像头内部配置信息
|
||||
// 参数说明 buff 发送配置信息的地址scc8660_sccb_set_config
|
||||
// 返回参数 uint8 1-失败 0-成功
|
||||
// 使用示例 mt9v03x_set_config(mt9v03x_set_confing_buffer);
|
||||
// 备注信息 内部调用
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
static uint8 mt9v03x_set_config (const int16 buff[MT9V03X_CONFIG_FINISH][2])
|
||||
{
|
||||
uint8 uart_buffer[4];
|
||||
uint8 return_state = 1;
|
||||
uint16 temp_value = 0;
|
||||
uint16 timeout_count = 0;
|
||||
uint32 loop_count = 0;
|
||||
uint32 uart_buffer_index = 0;
|
||||
|
||||
switch(mt9v03x_version)
|
||||
{
|
||||
case 0x0230: loop_count = MT9V03X_PCLK_MODE; break;
|
||||
default: loop_count = MT9V03X_GAIN; break;
|
||||
}
|
||||
// 设置参数 具体请参看问题锦集手册
|
||||
// 开始配置摄像头并重新初始化
|
||||
for(; loop_count < MT9V03X_SET_DATA; loop_count --)
|
||||
{
|
||||
uart_buffer[0] = 0xA5;
|
||||
uart_buffer[1] = buff[loop_count][0];
|
||||
temp_value = buff[loop_count][1];
|
||||
uart_buffer[2] = temp_value >> 8;
|
||||
uart_buffer[3] = (uint8)temp_value;
|
||||
uart_write_buffer(MT9V03X_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(MT9V03X_INIT_TIMEOUT > timeout_count ++);
|
||||
// 以上部分对摄像头配置的数据全部都会保存在摄像头上51单片机的eeprom中
|
||||
// 利用set_exposure_time函数单独配置的曝光数据不存储在eeprom中
|
||||
return return_state;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 获取摄像头内部配置信息
|
||||
// 参数说明 buff 接收配置信息的地址
|
||||
// 返回参数 uint8 1-失败 0-成功
|
||||
// 使用示例 mt9v03x_get_config(mt9v03x_get_confing_buffer);
|
||||
// 备注信息 内部调用
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
static uint8 mt9v03x_get_config (int16 buff[MT9V03X_CONFIG_FINISH - 1][2])
|
||||
{
|
||||
int8 loop_count = 0;
|
||||
uint8 uart_buffer[4];
|
||||
uint8 return_state = 0;
|
||||
uint16 temp_value = 0;
|
||||
uint16 timeout_count = 0;
|
||||
uint32 uart_buffer_index = 0;
|
||||
|
||||
switch(mt9v03x_version)
|
||||
{
|
||||
case 0x0230: loop_count = MT9V03X_PCLK_MODE; break;
|
||||
default: loop_count = MT9V03X_GAIN; break;
|
||||
}
|
||||
|
||||
for(loop_count = loop_count - 1; 0 <= loop_count; loop_count --)
|
||||
{
|
||||
if((0x0230 > mt9v03x_version) && (MT9V03X_PCLK_MODE == buff[loop_count][0]))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
uart_buffer[0] = 0xA5;
|
||||
uart_buffer[1] = MT9V03X_GET_STATUS;
|
||||
temp_value = buff[loop_count][0];
|
||||
uart_buffer[2] = temp_value >> 8;
|
||||
uart_buffer[3] = (uint8)temp_value;
|
||||
uart_write_buffer(MT9V03X_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(MT9V03X_INIT_TIMEOUT > timeout_count ++);
|
||||
if(MT9V03X_INIT_TIMEOUT < timeout_count) // 超时
|
||||
{
|
||||
return_state = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return return_state;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 MT9V03X UART 获取摄像头 ID
|
||||
// 参数说明 void
|
||||
// 返回参数 uint8 0-成功 x-失败
|
||||
// 使用示例 mt9v03x_check_id();
|
||||
// 备注信息 内部调用
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
static uint8 mt9v03x_uart_check_id (void)
|
||||
{
|
||||
uint8 uart_buffer[4] = {0};
|
||||
uint8 return_state = 1;
|
||||
uint16 timeout_count = 0;
|
||||
uint32 uart_buffer_index = 0;
|
||||
|
||||
|
||||
if(fifo_used(camera_receiver_fifo))
|
||||
{
|
||||
fifo_clear(camera_receiver_fifo);
|
||||
}
|
||||
|
||||
uart_write_byte(MT9V03X_COF_UART, 0xFF);
|
||||
uart_buffer[0] = 0xA5;
|
||||
uart_buffer[1] = MT9V03X_COLOR_GET_WHO_AM_I;
|
||||
uart_buffer[2] = 0;
|
||||
uart_buffer[3] = 0;
|
||||
uart_write_buffer(MT9V03X_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);
|
||||
return_state = !(0x01 == uart_buffer[2] || 0x02 == uart_buffer[2]);
|
||||
break;
|
||||
}
|
||||
system_delay_ms(1);
|
||||
}while(MT9V03X_INIT_TIMEOUT > timeout_count ++);
|
||||
|
||||
return return_state;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 MT9V03X 通信串口回调函数
|
||||
// 参数说明 void
|
||||
// 返回参数 void
|
||||
// 使用示例 mt9v03x_uart_handler();
|
||||
// 备注信息
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
static void mt9v03x_uart_handler (void)
|
||||
{
|
||||
uint8 data = 0;
|
||||
uart_query_byte(MT9V03X_COF_UART, &data);
|
||||
if(NULL != camera_receiver_fifo)
|
||||
{
|
||||
if(0xA5 == data)
|
||||
{
|
||||
fifo_clear(camera_receiver_fifo);
|
||||
}
|
||||
|
||||
fifo_write_element(camera_receiver_fifo, data);
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 MT9V03X摄像头场中断
|
||||
// 参数说明 NULL
|
||||
// 返回参数 void
|
||||
// @since v1.0
|
||||
// 使用示例 在isr.c里面先创建对应的中断函数,然后调用该函数(之后别忘记清除中断标志位)
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
void mt9v03x_dvp_handler(void)
|
||||
{
|
||||
//已经修改为循环采集模式。不需要设置地址和开启DVP
|
||||
//DVP->DMA_BUF0 = (uint32)camera_buffer_addr; // 恢复DMA地址
|
||||
mt9v03x_finish_flag = 1; // 摄像头采集完成标志位置1
|
||||
//已经修改为循环采集模式。不需要设置地址和开启DVP
|
||||
//DVP->CR0 |= RB_ENABLE; // 重新打开DVP,采集下一副图像
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 获取摄像头固件版本
|
||||
// 参数说明 void
|
||||
// 返回参数 uint16 0-获取错误 N-版本号
|
||||
// 使用示例 mt9v03x_get_version(); // 调用该函数前请先初始化串口
|
||||
// 备注信息 内部调用
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
uint16 mt9v03x_get_version (void)
|
||||
{
|
||||
uint8 uart_buffer[4];
|
||||
uint16 timeout_count = 0;
|
||||
uint16 return_value = 0;
|
||||
uint32 uart_buffer_index = 0;
|
||||
|
||||
do
|
||||
{
|
||||
uart_buffer[0] = 0xA5;
|
||||
uart_buffer[1] = MT9V03X_GET_STATUS;
|
||||
uart_buffer[2] = (uint8)((MT9V03X_GET_VERSION >> 8) & 0xFF);
|
||||
uart_buffer[3] = (uint8)(MT9V03X_GET_VERSION & 0xFF);
|
||||
uart_write_buffer(MT9V03X_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(MT9V03X_INIT_TIMEOUT > timeout_count ++);
|
||||
}while(0);
|
||||
return return_value;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 单独设置摄像头曝光时间
|
||||
// 参数说明 light 设定曝光时间
|
||||
// 返回参数 uint8 1-失败 0-成功
|
||||
// 使用示例 mt9v03x_set_exposure_time(100); // 调用该函数前请先初始化串口
|
||||
// 备注信息 设置曝光时间越大图像越亮
|
||||
// 摄像头收到后会根据分辨率及FPS计算最大曝光时间如果设置的数据过大
|
||||
// 那么摄像头将会设置这个最大值
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
uint8 mt9v03x_set_exposure_time (uint16 light)
|
||||
{
|
||||
uint8 uart_buffer[4];
|
||||
uint8 *receiver_buffer = NULL;
|
||||
uint8 return_state = 0;
|
||||
uint16 temp_value = 0;
|
||||
uint16 timeout_count = 0;
|
||||
uint32 uart_buffer_index = 0;
|
||||
|
||||
if(MT9V03X_UART == mt9v03x_type)
|
||||
{
|
||||
do
|
||||
{
|
||||
receiver_buffer = (uint8 *)malloc(MT9V03X_COF_BUFFER_SIZE);
|
||||
if(NULL == receiver_buffer)
|
||||
{
|
||||
zf_log(0, "FIFO buffer malloc error.");
|
||||
return_state = 1;
|
||||
break;
|
||||
}
|
||||
camera_receiver_fifo = (fifo_struct *)malloc(sizeof(fifo_struct));
|
||||
if(NULL == camera_receiver_fifo)
|
||||
{
|
||||
zf_log(0, "FIFO malloc error.");
|
||||
return_state = 1;
|
||||
break;
|
||||
}
|
||||
fifo_init(camera_receiver_fifo, FIFO_DATA_8BIT, receiver_buffer, MT9V03X_COF_BUFFER_SIZE);
|
||||
|
||||
uart_buffer[0] = 0xA5;
|
||||
uart_buffer[1] = MT9V03X_SET_EXP_TIME;
|
||||
temp_value = light;
|
||||
uart_buffer[2] = temp_value >> 8;
|
||||
uart_buffer[3] = (uint8)temp_value;
|
||||
uart_write_buffer(MT9V03X_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_value = uart_buffer[1] << 8 | uart_buffer[2];
|
||||
break;
|
||||
}
|
||||
system_delay_ms(1);
|
||||
}while(MT9V03X_INIT_TIMEOUT > timeout_count ++);
|
||||
if((temp_value != light) || (MT9V03X_INIT_TIMEOUT <= timeout_count))
|
||||
{
|
||||
return_state = 1;
|
||||
}
|
||||
}while(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
return_state = mt9v03x_sccb_set_exposure_time(light);
|
||||
}
|
||||
|
||||
free(receiver_buffer);
|
||||
free(camera_receiver_fifo);
|
||||
camera_receiver_fifo = NULL;
|
||||
return return_state;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 对摄像头内部寄存器进行写操作
|
||||
// 参数说明 addr 摄像头内部寄存器地址
|
||||
// 参数说明 data 需要写入的数据
|
||||
// 返回参数 uint8 1-失败 0-成功
|
||||
// 使用示例 mt9v03x_set_reg(addr, data); // 调用该函数前请先初始化串口
|
||||
// 备注信息
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
uint8 mt9v03x_set_reg (uint8 addr, uint16 data)
|
||||
{
|
||||
uint8 uart_buffer[4];
|
||||
uint8 *receiver_buffer = NULL;
|
||||
uint8 return_state = 0;
|
||||
uint16 temp_value = 0;
|
||||
uint16 timeout_count = 0;
|
||||
uint32 uart_buffer_index = 0;
|
||||
|
||||
if(MT9V03X_UART == mt9v03x_type)
|
||||
{
|
||||
do
|
||||
{
|
||||
receiver_buffer = (uint8 *)malloc(MT9V03X_COF_BUFFER_SIZE);
|
||||
if(NULL == receiver_buffer)
|
||||
{
|
||||
zf_log(0, "FIFO buffer malloc error.");
|
||||
return_state = 1;
|
||||
break;
|
||||
}
|
||||
camera_receiver_fifo = (fifo_struct *)malloc(sizeof(fifo_struct));
|
||||
if(NULL == camera_receiver_fifo)
|
||||
{
|
||||
zf_log(0, "FIFO malloc error.");
|
||||
return_state = 1;
|
||||
break;
|
||||
}
|
||||
fifo_init(camera_receiver_fifo, FIFO_DATA_8BIT, receiver_buffer, MT9V03X_COF_BUFFER_SIZE);
|
||||
|
||||
uart_buffer[0] = 0xA5;
|
||||
uart_buffer[1] = MT9V03X_SET_ADDR;
|
||||
temp_value = addr;
|
||||
uart_buffer[2] = temp_value >> 8;
|
||||
uart_buffer[3] = (uint8)temp_value;
|
||||
uart_write_buffer(MT9V03X_COF_UART, uart_buffer, 4);
|
||||
|
||||
system_delay_ms(10);
|
||||
uart_buffer[0] = 0xA5;
|
||||
uart_buffer[1] = MT9V03X_SET_DATA;
|
||||
temp_value = data;
|
||||
uart_buffer[2] = temp_value >> 8;
|
||||
uart_buffer[3] = (uint8)temp_value;
|
||||
uart_write_buffer(MT9V03X_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_value = uart_buffer[1] << 8 | uart_buffer[2];
|
||||
break;
|
||||
}
|
||||
system_delay_ms(1);
|
||||
}while(MT9V03X_INIT_TIMEOUT > timeout_count ++);
|
||||
if((temp_value != data) || (MT9V03X_INIT_TIMEOUT <= timeout_count))
|
||||
{
|
||||
return_state = 1;
|
||||
}
|
||||
}while(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
return_state = mt9v03x_sccb_set_reg(addr, data);
|
||||
}
|
||||
|
||||
free(receiver_buffer);
|
||||
free(camera_receiver_fifo);
|
||||
camera_receiver_fifo = NULL;
|
||||
return return_state;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 MT9V03X SCCB 初始化
|
||||
// 参数说明 void
|
||||
// 返回参数 uint8 0-成功 x-失败
|
||||
// 使用示例 mt9v03x_sccb_init();
|
||||
// 备注信息
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
uint8 mt9v03x_sccb_init (void)
|
||||
{
|
||||
uint8 return_state = 1;
|
||||
|
||||
mt9v03x_type = MT9V03X_SCCB;
|
||||
soft_iic_info_struct mt9v03x_iic_struct;
|
||||
soft_iic_init(
|
||||
&mt9v03x_iic_struct, 0,
|
||||
MT9V03X_COF_IIC_DELAY,
|
||||
MT9V03X_COF_IIC_SCL,
|
||||
MT9V03X_COF_IIC_SDA);
|
||||
|
||||
if(!mt9v03x_sccb_check_id(&mt9v03x_iic_struct))
|
||||
{
|
||||
// 需要配置到摄像头的数据 不允许在这修改参数
|
||||
const int16 mt9v03x_set_confing_buffer[MT9V03X_CONFIG_FINISH][2]=
|
||||
{
|
||||
{MT9V03X_INIT, 0}, // 摄像头开始初始化
|
||||
|
||||
{MT9V03X_AUTO_EXP, MT9V03X_AUTO_EXP_DEF}, // 自动曝光设置
|
||||
{MT9V03X_EXP_TIME, MT9V03X_EXP_TIME_DEF}, // 曝光时间
|
||||
{MT9V03X_FPS, MT9V03X_FPS_DEF}, // 图像帧率
|
||||
{MT9V03X_SET_COL, MT9V03X_W}, // 图像列数量
|
||||
{MT9V03X_SET_ROW, MT9V03X_H}, // 图像行数量
|
||||
{MT9V03X_LR_OFFSET, MT9V03X_LR_OFFSET_DEF}, // 图像左右偏移量
|
||||
{MT9V03X_UD_OFFSET, MT9V03X_UD_OFFSET_DEF}, // 图像上下偏移量
|
||||
{MT9V03X_GAIN, MT9V03X_GAIN_DEF}, // 图像增益
|
||||
{MT9V03X_PCLK_MODE, MT9V03X_PCLK_MODE_DEF}, // 像素时钟模式
|
||||
};
|
||||
return_state = mt9v03x_sccb_set_config(mt9v03x_set_confing_buffer);
|
||||
}
|
||||
|
||||
return return_state;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 MT9V03X UART 初始化
|
||||
// 参数说明 void
|
||||
// 返回参数 uint8 0-成功 x-失败
|
||||
// 使用示例 mt9v03x_uart_init();
|
||||
// 备注信息
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
uint8 mt9v03x_uart_init (void)
|
||||
{
|
||||
uint8 return_state = 1;
|
||||
uint8 loop_count = 0;
|
||||
uint8 *receiver_buffer = NULL;
|
||||
|
||||
mt9v03x_type = MT9V03X_UART;
|
||||
do
|
||||
{
|
||||
receiver_buffer = (uint8 *)malloc(MT9V03X_COF_BUFFER_SIZE); // 申请缓冲区
|
||||
if(NULL == receiver_buffer) // 堆空间不足
|
||||
{
|
||||
zf_log(0, "FIFO buffer malloc error."); // 无法获取数据缓冲区提示
|
||||
return_state = 2; // 异常码
|
||||
break;
|
||||
}
|
||||
camera_receiver_fifo = (fifo_struct *)malloc(sizeof(fifo_struct)); // 申请 FIFO 对象
|
||||
if(NULL == camera_receiver_fifo) // 堆空间不足
|
||||
{
|
||||
zf_log(0, "FIFO malloc error."); // 无法获取 FIFO 对象提示
|
||||
free(receiver_buffer);
|
||||
return_state = 2; // 异常码
|
||||
break;
|
||||
}
|
||||
fifo_init(camera_receiver_fifo, FIFO_DATA_8BIT, receiver_buffer, MT9V03X_COF_BUFFER_SIZE);
|
||||
|
||||
|
||||
|
||||
// 初始化串口 配置摄像头
|
||||
uart_init(MT9V03X_COF_UART, MT9V03X_COF_BAUR, MT9V03X_COF_UART_RX, MT9V03X_COF_UART_TX);
|
||||
uart_rx_interrupt(MT9V03X_COF_UART, 1);
|
||||
|
||||
mt9v03x_version = mt9v03x_get_version();
|
||||
|
||||
if(mt9v03x_version != 0)
|
||||
{
|
||||
if(mt9v03x_uart_check_id())
|
||||
{
|
||||
uart_rx_interrupt(MT9V03X_COF_UART, 0);
|
||||
return_state = 3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 需要配置到摄像头的数据 不允许在这修改参数
|
||||
const int16 mt9v03x_set_confing_buffer[MT9V03X_CONFIG_FINISH][2]=
|
||||
{
|
||||
{MT9V03X_INIT, 0}, // 摄像头开始初始化
|
||||
|
||||
{MT9V03X_AUTO_EXP, MT9V03X_AUTO_EXP_DEF}, // 自动曝光设置
|
||||
{MT9V03X_EXP_TIME, MT9V03X_EXP_TIME_DEF}, // 曝光时间
|
||||
{MT9V03X_FPS, MT9V03X_FPS_DEF}, // 图像帧率
|
||||
{MT9V03X_SET_COL, MT9V03X_W}, // 图像列数量
|
||||
{MT9V03X_SET_ROW, MT9V03X_H}, // 图像行数量
|
||||
{MT9V03X_LR_OFFSET, MT9V03X_LR_OFFSET_DEF}, // 图像左右偏移量
|
||||
{MT9V03X_UD_OFFSET, MT9V03X_UD_OFFSET_DEF}, // 图像上下偏移量
|
||||
{MT9V03X_GAIN, MT9V03X_GAIN_DEF}, // 图像增益
|
||||
{MT9V03X_PCLK_MODE, MT9V03X_PCLK_MODE_DEF}, // 像素时钟模式
|
||||
};
|
||||
|
||||
// 从摄像头内部获取到的配置数据 不允许在这修改参数
|
||||
int16 mt9v03x_get_confing_buffer[MT9V03X_CONFIG_FINISH - 1][2]=
|
||||
{
|
||||
{MT9V03X_AUTO_EXP, 0}, // 自动曝光设置
|
||||
{MT9V03X_EXP_TIME, 0}, // 曝光时间
|
||||
{MT9V03X_FPS, 0}, // 图像帧率
|
||||
{MT9V03X_SET_COL, 0}, // 图像列数量
|
||||
{MT9V03X_SET_ROW, 0}, // 图像行数量
|
||||
{MT9V03X_LR_OFFSET, 0}, // 图像左右偏移量
|
||||
{MT9V03X_UD_OFFSET, 0}, // 图像上下偏移量
|
||||
{MT9V03X_GAIN, 0}, // 图像增益
|
||||
{MT9V03X_PCLK_MODE, 0}, // 像素时钟模式命令 PCLK模式 < 仅总钻风 MT9V034 V1.5 以及以上版本支持该命令 >
|
||||
};
|
||||
|
||||
if(mt9v03x_set_config(mt9v03x_set_confing_buffer)) // 设置总钻风配置
|
||||
{
|
||||
// 如果程序在输出了断言信息 并且提示出错位置在这里
|
||||
// 那么就是串口通信出错并超时退出了
|
||||
// 检查一下接线有没有问题 如果没问题可能就是坏了
|
||||
zf_log(0, "MT9V03X set config error.");
|
||||
uart_rx_interrupt(MT9V03X_COF_UART, 0);
|
||||
return_state = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
// 获取配置便于查看配置是否正确
|
||||
if(mt9v03x_get_config(mt9v03x_get_confing_buffer))
|
||||
{
|
||||
// 如果程序在输出了断言信息 并且提示出错位置在这里
|
||||
// 那么就是串口通信出错并超时退出了
|
||||
// 检查一下接线有没有问题 如果没问题可能就是坏了
|
||||
zf_log(0, "MT9V03X get config error.");
|
||||
uart_rx_interrupt(MT9V03X_COF_UART, 0);
|
||||
return_state = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
for(loop_count = 0; MT9V03X_CONFIG_FINISH - 1 > loop_count; loop_count ++)
|
||||
{
|
||||
if( mt9v03x_set_confing_buffer[loop_count + 1][0] != mt9v03x_get_confing_buffer[loop_count][0] ||
|
||||
mt9v03x_set_confing_buffer[loop_count + 1][1] != mt9v03x_get_confing_buffer[loop_count][1])
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return_state = (MT9V03X_CONFIG_FINISH - 2 <= loop_count) ? 0 : 1;
|
||||
}while(0);
|
||||
|
||||
free(receiver_buffer);
|
||||
free(camera_receiver_fifo);
|
||||
camera_receiver_fifo = NULL;
|
||||
|
||||
return return_state;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 MT9V03X 摄像头初始化
|
||||
// 参数说明 void
|
||||
// 返回参数 uint8 0-成功 x-失败
|
||||
// 使用示例 mt9v03x_init();
|
||||
// 备注信息
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
uint8 mt9v03x_init (void)
|
||||
{
|
||||
|
||||
uint8 return_state = 0;
|
||||
|
||||
do
|
||||
{
|
||||
set_camera_type(CAMERA_GRAYSCALE, NULL, mt9v03x_dvp_handler);
|
||||
if(mt9v03x_sccb_init())
|
||||
{
|
||||
set_camera_type(CAMERA_GRAYSCALE, mt9v03x_uart_handler, mt9v03x_dvp_handler);
|
||||
return_state = mt9v03x_uart_init();
|
||||
}
|
||||
|
||||
if(!return_state)
|
||||
{
|
||||
// DVP引脚初始化
|
||||
dvp_gpio_init(
|
||||
MT9V03X_D0_PIN, MT9V03X_D1_PIN, MT9V03X_D2_PIN, MT9V03X_D3_PIN,
|
||||
MT9V03X_D4_PIN, MT9V03X_D5_PIN, MT9V03X_D6_PIN, MT9V03X_D7_PIN,
|
||||
MT9V03X_PCLK_PIN, MT9V03X_VSY_PIN, MT9V03X_HERF_PIN);
|
||||
|
||||
// DVP接口初始化
|
||||
dvp_camera_init((uint32 *)&mt9v03x_image[0], (uint32 *)&mt9v03x_image[0], MT9V03X_W*MT9V03X_H, MT9V03X_H);
|
||||
break;
|
||||
}
|
||||
set_camera_type(NO_CAMERE, NULL, NULL);
|
||||
}while(0);
|
||||
|
||||
return return_state;
|
||||
}
|
||||
154
libraries/zf_device/zf_device_mt9v03x_dvp.h
Normal file
154
libraries/zf_device/zf_device_mt9v03x_dvp.h
Normal file
@@ -0,0 +1,154 @@
|
||||
/*********************************************************************************************************************
|
||||
* CH32V307VCT6 Opensourec Library 即(CH32V307VCT6 开源库)是一个基于官方 SDK 接口的第三方开源库
|
||||
* Copyright (c) 2022 SEEKFREE 逐飞科技
|
||||
*
|
||||
* 本文件是CH32V307VCT6 开源库的一部分
|
||||
*
|
||||
* CH32V307VCT6 开源库 是免费软件
|
||||
* 您可以根据自由软件基金会发布的 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
|
||||
* 公司名称 成都逐飞科技有限公司
|
||||
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
|
||||
* 开发环境 MounRiver Studio V1.8.1
|
||||
* 适用平台 CH32V307VCT6
|
||||
* 店铺链接 https://seekfree.taobao.com/
|
||||
*
|
||||
* 修改记录
|
||||
* 日期 作者 备注
|
||||
* 2021-12-23 大W 摄像头采集完成标志位增加volatile修饰
|
||||
* 2022-03-26 大W 修改部分不重要的注释
|
||||
* 2022-09-15 大W first version
|
||||
********************************************************************************************************************/
|
||||
/*********************************************************************************************************************
|
||||
* 接线定义:
|
||||
* ------------------------------------
|
||||
* 模块管脚 单片机管脚
|
||||
* TXD 查看 zf_device_mt9v03x.h 中 MT9V03X_COF_UART_TX 宏定义
|
||||
* RXD 查看 zf_device_mt9v03x.h 中 MT9V03X_COF_UART_RX 宏定义
|
||||
* D0 查看 zf_device_mt9v03x.h 中 MT9V03X_D0_PIN 宏定义
|
||||
* D1 查看 zf_device_mt9v03x.h 中 MT9V03X_D1_PIN 宏定义
|
||||
* D2 查看 zf_device_mt9v03x.h 中 MT9V03X_D2_PIN 宏定义
|
||||
* D3 查看 zf_device_mt9v03x.h 中 MT9V03X_D3_PIN 宏定义
|
||||
* D4 查看 zf_device_mt9v03x.h 中 MT9V03X_D4_PIN 宏定义
|
||||
* D5 查看 zf_device_mt9v03x.h 中 MT9V03X_D5_PIN 宏定义
|
||||
* D6 查看 zf_device_mt9v03x.h 中 MT9V03X_D6_PIN 宏定义
|
||||
* D7 查看 zf_device_mt9v03x.h 中 MT9V03X_D7_PIN 宏定义
|
||||
* PCLK 查看 zf_device_mt9v03x.h 中 MT9V03X_PCLK_PIN 宏定义
|
||||
* VSYNC 查看 zf_device_mt9v03x.h 中 MT9V03X_VSY_PIN 宏定义
|
||||
* HSYNC 查看 zf_device_mt9v03x.h 中 MT9V03X_HERF_PIN 宏定义
|
||||
* ------------------------------------
|
||||
********************************************************************************************************************/
|
||||
|
||||
#ifndef _zf_device_mt9v03x_h_
|
||||
#define _zf_device_mt9v03x_h_
|
||||
|
||||
|
||||
#include "zf_common_typedef.h"
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// 引脚配置
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
#define MT9V03X_COF_UART (UART_5 ) // 配置摄像头所使用到的串口
|
||||
#define MT9V03X_COF_BAUR (9600 ) // 总钻风配置串口波特率
|
||||
#define MT9V03X_COF_UART_TX (UART5_MAP0_RX_D2) // 总钻风 UART-TX 引脚 要接在单片机 RX 上
|
||||
#define MT9V03X_COF_UART_RX (UART5_MAP0_TX_C12) // 总钻风 UART-RX 引脚 要接在单片机 TX 上
|
||||
|
||||
#define MT9V03X_COF_IIC_DELAY (500) // 总钻风 IIC 延时
|
||||
#define MT9V03X_COF_IIC_SCL (D2 ) // 总钻风 IIC-SCL 引脚
|
||||
#define MT9V03X_COF_IIC_SDA (C12) // 总钻风 IIC-SDA 引脚
|
||||
|
||||
#define MT9V03X_D0_PIN (A9 )
|
||||
#define MT9V03X_D1_PIN (A10)
|
||||
#define MT9V03X_D2_PIN (C8 )
|
||||
#define MT9V03X_D3_PIN (C9 )
|
||||
#define MT9V03X_D4_PIN (C11)
|
||||
#define MT9V03X_D5_PIN (B6 )
|
||||
#define MT9V03X_D6_PIN (B8 )
|
||||
#define MT9V03X_D7_PIN (B9 )
|
||||
|
||||
#define MT9V03X_PCLK_PIN (A6 )
|
||||
#define MT9V03X_VSY_PIN (A5 )
|
||||
#define MT9V03X_HERF_PIN (A4 )
|
||||
#define MT9V03X_INIT_TIMEOUT (200) // 默认的摄像头初始化超时时间 毫秒为单位
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// 摄像头默认参数配置 在此修改摄像头配置
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
#define MT9V03X_W (188) // 图像宽度 范围 [1-752]
|
||||
#define MT9V03X_H (120) // 图像高度 范围 [1-480]
|
||||
#define MT9V03X_IMAGE_SIZE ( MT9V03X_W * MT9V03X_H ) // 整体图像大小不能超过 65535
|
||||
#define MT9V03X_COF_BUFFER_SIZE ( 64 ) // 配置串口缓冲区大小 不低于 64
|
||||
|
||||
#define MT9V03X_AUTO_EXP_DEF (0 ) // 自动曝光设置 默认不开启自动曝光设置 范围 [0-63] 0为关闭
|
||||
// 如果自动曝光开启 EXP_TIME命令设置自动曝光时间的上限
|
||||
// 一般情况是不需要开启自动曝光设置 如果遇到光线非常不均匀的情况可以尝试设置自动曝光,增加图像稳定性
|
||||
#define MT9V03X_EXP_TIME_DEF (512) // 曝光时间 摄像头收到后会自动计算出最大曝光时间,如果设置过大则设置为计算出来的最大曝光值
|
||||
#define MT9V03X_FPS_DEF (50 ) // 图像帧率 摄像头收到后会自动计算出最大FPS,如果过大则设置为计算出来的最大FPS
|
||||
#define MT9V03X_LR_OFFSET_DEF (0 ) // 图像左右偏移量 正值 右偏移 负值 左偏移 列为188 376 752时无法设置偏移
|
||||
// 摄像头收偏移数据后会自动计算最大偏移,如果超出则设置计算出来的最大偏移
|
||||
#define MT9V03X_UD_OFFSET_DEF (0 ) // 图像上下偏移量 正值 上偏移 负值 下偏移 行为120 240 480时无法设置偏移
|
||||
// 摄像头收偏移数据后会自动计算最大偏移,如果超出则设置计算出来的最大偏移
|
||||
#define MT9V03X_GAIN_DEF (32 ) // 图像增益 范围 [16-64] 增益可以在曝光时间固定的情况下改变图像亮暗程度
|
||||
#define MT9V03X_PCLK_MODE_DEF (1 ) // 像素时钟模式 范围 [0-1] 默认:0 可选参数为:[0:不输出消隐信号,1:输出消隐信号]
|
||||
// 通常都设置为0,如果使用CH32V307的DVP接口或STM32的DCMI接口采集需要设置为1
|
||||
// 仅总钻风 MT9V034 V1.5 以及以上版本支持该命令
|
||||
|
||||
// 摄像头命令枚举
|
||||
typedef enum
|
||||
{
|
||||
MT9V03X_INIT = 0, // 摄像头初始化命令
|
||||
MT9V03X_AUTO_EXP, // 自动曝光命令
|
||||
MT9V03X_EXP_TIME, // 曝光时间命令
|
||||
MT9V03X_FPS, // 摄像头帧率命令
|
||||
MT9V03X_SET_COL, // 图像列命令
|
||||
MT9V03X_SET_ROW, // 图像行命令
|
||||
MT9V03X_LR_OFFSET, // 图像左右偏移命令
|
||||
MT9V03X_UD_OFFSET, // 图像上下偏移命令
|
||||
MT9V03X_GAIN, // 图像偏移命令
|
||||
MT9V03X_PCLK_MODE, // 像素时钟模式命令(仅总钻风MT9V034 V1.5以及以上版本支持该命令)
|
||||
MT9V03X_CONFIG_FINISH, // 非命令位,主要用来占位计数
|
||||
|
||||
MT9V03X_COLOR_GET_WHO_AM_I = 0xEF,
|
||||
MT9V03X_SET_EXP_TIME = 0XF0, // 单独设置曝光时间命令
|
||||
MT9V03X_GET_STATUS, // 获取摄像头配置命令
|
||||
MT9V03X_GET_VERSION, // 固件版本号命令
|
||||
|
||||
MT9V03X_SET_ADDR = 0XFE, // 寄存器地址命令
|
||||
MT9V03X_SET_DATA // 寄存器数据命令
|
||||
}m9v03x_cmd_enum;
|
||||
|
||||
|
||||
// 摄像头接口类型枚举
|
||||
typedef enum
|
||||
{
|
||||
MT9V03X_UART,
|
||||
MT9V03X_SCCB,
|
||||
}mt9v03x_type_enum;
|
||||
|
||||
extern volatile vuint8 mt9v03x_finish_flag;//一场图像采集完成标志位
|
||||
extern uint8 mt9v03x_image[MT9V03X_H][MT9V03X_W];
|
||||
|
||||
void mt9v03x_uart_callback (void);
|
||||
void mt9v03x_handler (void);
|
||||
uint16 mt9v03x_get_version (void);
|
||||
uint8 mt9v03x_set_exposure_time (uint16 light);
|
||||
uint8 mt9v03x_set_reg (uint8 addr, uint16 data);
|
||||
uint8 mt9v03x_init (void);
|
||||
|
||||
#endif
|
||||
765
libraries/zf_device/zf_device_oled.c
Normal file
765
libraries/zf_device/zf_device_oled.c
Normal file
@@ -0,0 +1,765 @@
|
||||
/*********************************************************************************************************************
|
||||
* CH32V307VCT6 Opensourec Library 即(CH32V307VCT6 开源库)是一个基于官方 SDK 接口的第三方开源库
|
||||
* Copyright (c) 2022 SEEKFREE 逐飞科技
|
||||
*
|
||||
* 本文件是CH32V307VCT6 开源库的一部分
|
||||
*
|
||||
* CH32V307VCT6 开源库 是免费软件
|
||||
* 您可以根据自由软件基金会发布的 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 文件 版本说明
|
||||
* 开发环境 MounRiver Studio V1.8.1
|
||||
* 适用平台 CH32V307VCT6
|
||||
* 店铺链接 https://seekfree.taobao.com/
|
||||
*
|
||||
* 修改记录
|
||||
* 日期 作者 备注
|
||||
* 2022-09-15 大W first version
|
||||
********************************************************************************************************************/
|
||||
/*********************************************************************************************************************
|
||||
* 接线定义:
|
||||
* ------------------------------------
|
||||
* 模块管脚 单片机管脚
|
||||
* 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_clock.h"
|
||||
#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(128 > x);
|
||||
zf_assert(8 > y);
|
||||
|
||||
OLED_CS(0);
|
||||
oled_set_coordinate(x, 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(x, 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(x, y);
|
||||
for(i = 0; i < 8; i ++)
|
||||
{
|
||||
oled_write_data(ascii_font_8x16[c][i]);
|
||||
}
|
||||
|
||||
oled_set_coordinate(x, y + 1);
|
||||
for(i = 0; i < 8; 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 需要显示的变量 数据类型 float
|
||||
// 参数说明 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, 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, 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 = (dis_value_max - 1) - value_max_index;
|
||||
oled_set_coordinate(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, SPI_MISO_NULL, 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); // --turn off oled panel
|
||||
oled_write_command(0x00); // ---set low column address
|
||||
oled_write_command(0x10); // ---set high column address
|
||||
oled_write_command(0x40); // --set start line address Set Mapping RAM Display Start Line (0x00~0x3F)
|
||||
oled_write_command(0x81); // --set contrast control register
|
||||
oled_write_command(OLED_BRIGHTNESS); // Set SEG Output Current Brightness
|
||||
|
||||
if(OLED_CROSSWISE == oled_display_dir)
|
||||
{
|
||||
oled_write_command(0xa1); // --Set SEG/Column Mapping 0xa0左右反置 0xa1正常
|
||||
oled_write_command(0xc8); // Set COM/Row Scan Direction 0xc0上下反置 0xc8正常
|
||||
}
|
||||
else
|
||||
{
|
||||
oled_write_command(0xa0); // --Set SEG/Column Mapping 0xa0左右反置 0xa1正常
|
||||
oled_write_command(0xc0); // Set COM/Row Scan Direction 0xc0上下反置 0xc8正常
|
||||
}
|
||||
|
||||
oled_write_command(0xa6); // --set normal display
|
||||
oled_write_command(0xa8); // --set multiplex ratio(1 to 64)
|
||||
oled_write_command(0x3f); // --1/64 duty
|
||||
oled_write_command(0xd3); // -set display offset Shift Mapping RAM Counter (0x00~0x3F)
|
||||
oled_write_command(0x00); // -not offset
|
||||
oled_write_command(0xd5); // --set display clock divide ratio/oscillator frequency
|
||||
oled_write_command(0x80); // --set divide ratio, Set Clock as 100 Frames/Sec
|
||||
oled_write_command(0xd9); // --set pre-charge period
|
||||
oled_write_command(0xf1); // Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
|
||||
oled_write_command(0xda); // --set com pins hardware configuration
|
||||
oled_write_command(0x12);
|
||||
oled_write_command(0xdb); // --set vcomh
|
||||
oled_write_command(0x40); // Set VCOM Deselect Level
|
||||
oled_write_command(0x20); // -Set Page Addressing Mode (0x00/0x01/0x02)
|
||||
oled_write_command(0x02); //
|
||||
oled_write_command(0x8d); // --set Charge Pump enable/disable
|
||||
oled_write_command(0x14); // --set(0x10) disable
|
||||
oled_write_command(0xa4); // Disable Entire Display On (0xa4/0xa5)
|
||||
oled_write_command(0xa6); // Disable Inverse Display On (0xa6/a7)
|
||||
oled_write_command(0xaf); // --turn on oled panel
|
||||
OLED_CS(1);
|
||||
|
||||
oled_clear(); // 初始清屏
|
||||
oled_set_coordinate(0, 0);
|
||||
oled_debug_init();
|
||||
}
|
||||
136
libraries/zf_device/zf_device_oled.h
Normal file
136
libraries/zf_device/zf_device_oled.h
Normal file
@@ -0,0 +1,136 @@
|
||||
/*********************************************************************************************************************
|
||||
* CH32V307VCT6 Opensourec Library 即(CH32V307VCT6 开源库)是一个基于官方 SDK 接口的第三方开源库
|
||||
* Copyright (c) 2022 SEEKFREE 逐飞科技
|
||||
*
|
||||
* 本文件是CH32V307VCT6 开源库的一部分
|
||||
*
|
||||
* CH32V307VCT6 开源库 是免费软件
|
||||
* 您可以根据自由软件基金会发布的 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 文件 版本说明
|
||||
* 开发环境 MounRiver Studio V1.8.1
|
||||
* 适用平台 CH32V307VCT6
|
||||
* 店铺链接 https://seekfree.taobao.com/
|
||||
*
|
||||
* 修改记录
|
||||
* 日期 作者 备注
|
||||
* 2022-09-15 大W first version
|
||||
********************************************************************************************************************/
|
||||
/*********************************************************************************************************************
|
||||
* 接线定义:
|
||||
* ------------------------------------
|
||||
* 模块管脚 单片机管脚
|
||||
* 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"
|
||||
|
||||
#define OLED_USE_SOFT_SPI (0 ) // 默认使用硬件 SPI 方式驱动 建议使用硬件 SPI 方式驱动
|
||||
#if OLED_USE_SOFT_SPI // 这两段 颜色正常的才是正确的 颜色灰的就是没有用的
|
||||
//====================================================软件 SPI 驱动====================================================
|
||||
#define OLED_SOFT_SPI_DELAY (1 ) // 软件 SPI 的时钟延时周期 数值越小 SPI 通信速率越快
|
||||
#define OLED_D0_PIN (D4) // 软件 SPI SCK 引脚
|
||||
#define OLED_D1_PIN (D6) // 软件 SPI MOSI 引脚
|
||||
//====================================================软件 SPI 驱动====================================================
|
||||
#else
|
||||
//====================================================硬件 SPI 驱动====================================================
|
||||
#define OLED_SPI_SPEED (72 * 1000 * 1000) // 硬件 SPI 速率
|
||||
#define OLED_SPI (SPI_2) // 硬件 SPI 号
|
||||
#define OLED_D0_PIN (SPI2_MAP0_SCK_B13 ) // 硬件 SPI SCK 引脚
|
||||
#define OLED_D1_PIN (SPI2_MAP0_MOSI_B15) // 硬件 SPI MOSI 引脚
|
||||
//====================================================硬件 SPI 驱动====================================================
|
||||
#endif
|
||||
|
||||
#define OLED_RES_PIN (B7 ) // 液晶复位引脚定义
|
||||
#define OLED_DC_PIN (D7 ) // 液晶命令位引脚定义
|
||||
#define OLED_CS_PIN (D4 ) // CS 片选引脚
|
||||
|
||||
#define OLED_BRIGHTNESS (0x7f) // 设置OLED亮度 越大越亮 范围0-0XFF
|
||||
#define OLED_DEFAULT_DISPLAY_DIR (OLED_CROSSWISE) // 默认的显示方向
|
||||
#define OLED_DEFAULT_DISPLAY_FONT (OLED_6X8_FONT ) // 默认的字体模式
|
||||
|
||||
#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)))
|
||||
|
||||
typedef enum
|
||||
{
|
||||
OLED_CROSSWISE = 0, // 横屏模式
|
||||
OLED_CROSSWISE_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;
|
||||
|
||||
#define OLED_X_MAX (128)
|
||||
#define OLED_Y_MAX (64 )
|
||||
|
||||
void oled_clear (void);
|
||||
void oled_full (const uint8 color);
|
||||
void oled_set_dir (oled_dir_enum dir);
|
||||
void oled_set_font (oled_font_size_enum font);
|
||||
void oled_draw_point (uint16 x, uint16 y, const uint8 color);
|
||||
|
||||
void oled_show_string (uint16 x, uint16 y, const char ch[]);
|
||||
void oled_show_int (uint16 x, uint16 y, const int32 dat, uint8 num);
|
||||
void oled_show_uint (uint16 x, uint16 y, const uint32 dat, uint8 num);
|
||||
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);
|
||||
void oled_show_gray_image (uint16 x, uint16 y, const uint8 *image, uint16 width, uint16 height, uint16 dis_width, uint16 dis_height, uint8 threshold);
|
||||
|
||||
void oled_show_wave (uint16 x, uint16 y, const uint16 *image, uint16 width, uint16 value_max, uint16 dis_width, uint16 dis_value_max);
|
||||
void oled_show_chinese (uint16 x, uint16 y, uint8 size, const uint8 *chinese_buffer, uint8 number);
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 OLED 128*64 显示小钻风图像
|
||||
// 参数说明 p 图像数组
|
||||
// 返回参数 void
|
||||
// 使用示例 oled_displayimage7725(ov7725_image_binary[0]);
|
||||
// 备注信息
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
#define oled_displayimage7725(p) (oled_show_binary_image(0, 0, (p), OV7725_W, OV7725_H, 128, 64))
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 OLED 128*64 显示总钻风图像 带二值化
|
||||
// 参数说明 p 图像数组
|
||||
// 参数说明 x 二值化显示阈值
|
||||
// 返回参数 void
|
||||
// 使用示例 oled_displayimage03x(mt9v03x_image[0], 127);
|
||||
// 备注信息
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
#define oled_displayimage03x(p,x) (oled_show_gray_image(0, 0, (p), MT9V03X_W, MT9V03X_H, 128, 64, (x)))
|
||||
|
||||
void oled_init (void);
|
||||
|
||||
#endif
|
||||
644
libraries/zf_device/zf_device_scc8660_dvp.c
Normal file
644
libraries/zf_device/zf_device_scc8660_dvp.c
Normal file
@@ -0,0 +1,644 @@
|
||||
/*********************************************************************************************************************
|
||||
* CH32V307VCT6 Opensourec Library 即(CH32V307VCT6 开源库)是一个基于官方 SDK 接口的第三方开源库
|
||||
* Copyright (c) 2022 SEEKFREE 逐飞科技
|
||||
*
|
||||
* 本文件是CH32V307VCT6 开源库的一部分
|
||||
*
|
||||
* CH32V307VCT6 开源库 是免费软件
|
||||
* 您可以根据自由软件基金会发布的 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_dvp_dvp
|
||||
* 公司名称 成都逐飞科技有限公司
|
||||
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
|
||||
* 开发环境 MounRiver Studio V1.8.1
|
||||
* 适用平台 CH32V307VCT6
|
||||
* 店铺链接 https://seekfree.taobao.com/
|
||||
*
|
||||
* 修改记录
|
||||
* 日期 作者 备注
|
||||
* 2022-09-15 大W first version
|
||||
********************************************************************************************************************/
|
||||
/*********************************************************************************************************************
|
||||
*接线定义:
|
||||
* ------------------------------------
|
||||
* 模块管脚 单片机管脚
|
||||
* TXD 查看 zf_device_scc8660_dvp.h 中 SCC8660_COF_UART_TX 宏定义
|
||||
* RXD 查看 zf_device_scc8660_dvp.h 中 SCC8660_COF_UART_RX 宏定义
|
||||
* D0 查看 zf_device_scc8660_dvp.h 中 SCC8660_D0_PIN 宏定义
|
||||
* D1 查看 zf_device_scc8660_dvp.h 中 SCC8660_D1_PIN 宏定义
|
||||
* D2 查看 zf_device_scc8660_dvp.h 中 SCC8660_D2_PIN 宏定义
|
||||
* D3 查看 zf_device_scc8660_dvp.h 中 SCC8660_D3_PIN 宏定义
|
||||
* D4 查看 zf_device_scc8660_dvp.h 中 SCC8660_D4_PIN 宏定义
|
||||
* D5 查看 zf_device_scc8660_dvp.h 中 SCC8660_D5_PIN 宏定义
|
||||
* D6 查看 zf_device_scc8660_dvp.h 中 SCC8660_D6_PIN 宏定义
|
||||
* D7 查看 zf_device_scc8660_dvp.h 中 SCC8660_D7_PIN 宏定义
|
||||
* PCLK 查看 zf_device_scc8660_dvp.h 中 SCC8660_PCLK_PIN 宏定义
|
||||
* VSYNC 查看 zf_device_scc8660_dvp.h 中 SCC8660_VSY_PIN 宏定义
|
||||
* HSYNC 查看 zf_device_scc8660_dvp.h 中 SCC8660_HERF_PIN 宏定义
|
||||
* ------------------------------------
|
||||
********************************************************************************************************************/
|
||||
|
||||
#include "zf_device_type.h"
|
||||
#include "zf_device_camera.h"
|
||||
#include "zf_device_config.h"
|
||||
#include "zf_driver_dvp.h"
|
||||
#include "zf_driver_delay.h"
|
||||
#include "zf_driver_soft_iic.h"
|
||||
#include "zf_device_scc8660_dvp.h"
|
||||
|
||||
vuint8 scc8660_finish_flag = 0; // 一场图像采集完成标志位
|
||||
__attribute__((aligned(4))) uint16 scc8660_image[SCC8660_H][SCC8660_W];
|
||||
|
||||
static fifo_struct *camera_receiver_fifo;
|
||||
static scc8660_type_enum scc8660_type;
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 配置摄像头内部配置信息 内部调用
|
||||
// 参数说明 buff 发送配置信息的地址
|
||||
// 返回参数 uint8 1-失败 0-成功
|
||||
// 使用示例 if(scc8660_set_config(scc8660_set_confing_buffer)){}
|
||||
// 备注信息 调用该函数前请先初始化串口
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
static uint8 scc8660_set_config (const int16 buff[SCC8660_CONFIG_FINISH][2])
|
||||
{
|
||||
uint8 uart_buffer[4];
|
||||
uint8 return_state = 0;
|
||||
// uint16 temp_value = 0;
|
||||
uint16 timeout_count = 0;
|
||||
uint32 loop_count = 0;
|
||||
uint32 uart_buffer_index = 0;
|
||||
|
||||
// 设置参数 具体请参看问题锦集手册
|
||||
// 开始配置摄像头并重新初始化
|
||||
for(loop_count = SCC8660_MANUAL_WB; SCC8660_SET_REG_DATA > loop_count; loop_count --)
|
||||
{
|
||||
uart_buffer[0] = 0xA5; // 帧头
|
||||
uart_buffer[1] = buff[loop_count][0]; // 指令
|
||||
// temp_value = buff[loop_count][1];
|
||||
uart_buffer[2] = buff[loop_count][1] >> 8; // 数据高低位
|
||||
uart_buffer[3] = (uint8)buff[loop_count][1]; // 数据高低位
|
||||
uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); // 数据通过串口发送
|
||||
system_delay_ms(2);
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
if(3 <= fifo_used(camera_receiver_fifo)) // 等待 FIFO 中存入三个数据
|
||||
{
|
||||
uart_buffer_index = 3; // 长度缓冲变量
|
||||
fifo_read_buffer(camera_receiver_fifo, // 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])
|
||||
{
|
||||
int8 loop_count = 0;
|
||||
uint8 uart_buffer[4];
|
||||
uint8 return_state = 0;
|
||||
// uint16 temp_value = 0;
|
||||
uint16 timeout_count = 0;
|
||||
uint32 uart_buffer_index = 0;
|
||||
|
||||
for(loop_count = SCC8660_MANUAL_WB - 1; 0 <= loop_count; loop_count --)
|
||||
{
|
||||
uart_buffer[0] = 0xA5; // 帧头
|
||||
uart_buffer[1] = SCC8660_GET_STATUS; // 获取指令
|
||||
// temp_value = buff[loop_count][0];
|
||||
uart_buffer[2] = buff[loop_count][0] >> 8; // 指令高低位
|
||||
uart_buffer[3] = (uint8)buff[loop_count][0]; // 指令高低位
|
||||
uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); // 数据通过串口发送
|
||||
|
||||
timeout_count = 0;
|
||||
do
|
||||
{
|
||||
if(3 <= fifo_used(camera_receiver_fifo)) // 等待 FIFO 中存入三个数据
|
||||
{
|
||||
uart_buffer_index = 3; // 长度缓冲变量
|
||||
fifo_read_buffer(camera_receiver_fifo, // 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(SCC8660_INIT_TIMEOUT < timeout_count) // 超时
|
||||
{
|
||||
return_state = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return return_state;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 获取摄像头 ID
|
||||
// 参数说明 void
|
||||
// 返回参数 uint16 0-版本号正确 N-版本号错误
|
||||
// 使用示例 scc8660_uart_check_id(); // 调用该函数前请先初始化串口
|
||||
// 备注信息
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
static uint8 scc8660_uart_check_id (void)
|
||||
{
|
||||
uint8 uart_buffer[4];
|
||||
uint8 return_state = 1;
|
||||
uint16 timeout_count = 0;
|
||||
uint32 uart_buffer_index = 0;
|
||||
|
||||
|
||||
if(fifo_used(camera_receiver_fifo))
|
||||
{
|
||||
fifo_clear(camera_receiver_fifo);
|
||||
}
|
||||
|
||||
uart_write_byte(SCC8660_COF_UART, 0xFF);
|
||||
uart_buffer[0] = 0xA5;
|
||||
uart_buffer[1] = SCC8660_GET_WHO_AM_I;
|
||||
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);
|
||||
return_state = !(0x03 == uart_buffer[2]);
|
||||
break;
|
||||
}
|
||||
system_delay_ms(1);
|
||||
}while(SCC8660_INIT_TIMEOUT > timeout_count ++);
|
||||
|
||||
return return_state;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 SCC8660 通信串口回调函数
|
||||
// 参数说明 void
|
||||
// 返回参数 void
|
||||
// 使用示例 scc8660_uart_handler();
|
||||
// 备注信息 通过 zf_device_type.c 的接口调用 用户在使用默认设置时不需要关心
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
static void scc8660_uart_handler (void)
|
||||
{
|
||||
uint8 data = 0;
|
||||
uart_query_byte(SCC8660_COF_UART, &data);
|
||||
if(NULL != camera_receiver_fifo)
|
||||
{
|
||||
if(0xA5 == data)
|
||||
{
|
||||
fifo_clear(camera_receiver_fifo);
|
||||
}
|
||||
fifo_write_element(camera_receiver_fifo, data);
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 SCC8660 场中断回调函数
|
||||
// 参数说明 void
|
||||
// 返回参数 void
|
||||
// 使用示例 scc8660_vsync_handler();
|
||||
// 备注信息 通过 zf_device_type.c 的接口调用 用户在使用默认设置时不需要关心
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
static void scc8660_dvp_handler (void)
|
||||
{
|
||||
scc8660_finish_flag = 1; // 摄像头采集完成标志位置1
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 获取彩色摄像头固件版本 内部调用
|
||||
// 参数说明 void
|
||||
// 返回参数 uint16 版本号
|
||||
// 使用示例 scc8660_get_version(); // 调用该函数前请先初始化摄像头配置串口
|
||||
// 备注信息
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
uint16 scc8660_get_version (void)
|
||||
{
|
||||
uint8 uart_buffer[4];
|
||||
uint16 temp_value = 0;
|
||||
uint16 timeout_count = 0;
|
||||
uint16 return_value = 0;
|
||||
uint32 uart_buffer_index = 0;
|
||||
|
||||
uart_buffer[0] = 0xA5;
|
||||
uart_buffer[1] = SCC8660_GET_STATUS;
|
||||
temp_value = SCC8660_GET_VERSION;
|
||||
uart_buffer[2] = temp_value >> 8;
|
||||
uart_buffer[3] = (uint8)temp_value;
|
||||
|
||||
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 uart_buffer[4];
|
||||
uint8 return_state = 0;
|
||||
uint16 temp_value = 0;
|
||||
uint16 timeout_count = 0;
|
||||
uint32 uart_buffer_index = 0;
|
||||
|
||||
if(SCC8660_UART == scc8660_type)
|
||||
{
|
||||
do
|
||||
{
|
||||
uint8 *receiver_buffer = (uint8 *)malloc(SCC8660_COF_BUFFER_SIZE);
|
||||
if(NULL == receiver_buffer)
|
||||
{
|
||||
zf_log(0, "FIFO buffer malloc error.");
|
||||
return_state = 1;
|
||||
break;
|
||||
}
|
||||
camera_receiver_fifo = (fifo_struct *)malloc(sizeof(fifo_struct));
|
||||
if(NULL == camera_receiver_fifo)
|
||||
{
|
||||
zf_log(0, "FIFO malloc error.");
|
||||
free(receiver_buffer);
|
||||
return_state = 1;
|
||||
break;
|
||||
}
|
||||
fifo_init(camera_receiver_fifo, FIFO_DATA_8BIT, receiver_buffer, SCC8660_COF_BUFFER_SIZE);
|
||||
|
||||
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_value = uart_buffer[1] << 8 | uart_buffer[2];
|
||||
break;
|
||||
}
|
||||
system_delay_ms(1);
|
||||
}while(SCC8660_INIT_TIMEOUT > timeout_count ++);
|
||||
if((temp_value != data) || (SCC8660_INIT_TIMEOUT <= timeout_count))
|
||||
{
|
||||
return_state = 1;
|
||||
}
|
||||
if(NULL != receiver_buffer)
|
||||
{
|
||||
free(receiver_buffer);
|
||||
free(camera_receiver_fifo);
|
||||
camera_receiver_fifo = NULL;
|
||||
}
|
||||
}while(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
return_state = scc8660_sccb_set_brightness(data);
|
||||
}
|
||||
|
||||
return return_state;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 单独设置白平衡
|
||||
// 参数说明 data 需要设置的亮度值
|
||||
// 返回参数 uint8 1-失败 0-成功
|
||||
// 使用示例 scc8660_set_white_balance(data); // 调用该函数前请先初始化摄像头配置串口
|
||||
// 备注信息 通过该函数设置的参数,不会被51单片机保存
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
uint8 scc8660_set_white_balance (uint16 data)
|
||||
{
|
||||
uint8 uart_buffer[4];
|
||||
uint8 return_state = 0;
|
||||
uint16 temp_value = 0;
|
||||
uint16 timeout_count = 0;
|
||||
uint32 uart_buffer_index = 0;
|
||||
|
||||
if(SCC8660_UART == scc8660_type)
|
||||
{
|
||||
do
|
||||
{
|
||||
uint8 *receiver_buffer = (uint8 *)malloc(SCC8660_COF_BUFFER_SIZE);
|
||||
if(NULL == receiver_buffer)
|
||||
{
|
||||
zf_log(0, "FIFO buffer malloc error.");
|
||||
return_state = 1;
|
||||
break;
|
||||
}
|
||||
camera_receiver_fifo = (fifo_struct *)malloc(sizeof(fifo_struct));
|
||||
if(NULL == camera_receiver_fifo)
|
||||
{
|
||||
zf_log(0, "FIFO malloc error.");
|
||||
free(receiver_buffer);
|
||||
return_state = 1;
|
||||
break;
|
||||
}
|
||||
fifo_init(camera_receiver_fifo, FIFO_DATA_8BIT, receiver_buffer, SCC8660_COF_BUFFER_SIZE);
|
||||
|
||||
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_value = uart_buffer[1] << 8 | uart_buffer[2];
|
||||
break;
|
||||
}
|
||||
system_delay_ms(1);
|
||||
}while(SCC8660_INIT_TIMEOUT > timeout_count ++);
|
||||
if((temp_value != data) || (SCC8660_INIT_TIMEOUT <= timeout_count))
|
||||
{
|
||||
return_state = 1;
|
||||
}
|
||||
if(NULL != receiver_buffer)
|
||||
{
|
||||
free(receiver_buffer);
|
||||
free(camera_receiver_fifo);
|
||||
camera_receiver_fifo = NULL;
|
||||
}
|
||||
}while(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
return_state = scc8660_sccb_set_manual_wb(data);
|
||||
}
|
||||
return return_state;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 对摄像头内部寄存器进行写操作
|
||||
// 参数说明 addr 摄像头内部寄存器地址
|
||||
// 参数说明 data 需要写入的数据
|
||||
// 返回参数 uint8 0-成功 1-失败 2-内存申请失败
|
||||
// 使用示例 scc8660_set_reg(addr, data); // 调用该函数前请先初始化串口
|
||||
// 备注信息
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
uint8 scc8660_set_reg (uint8 addr, uint16 data)
|
||||
{
|
||||
uint8 uart_buffer[4];
|
||||
uint8 return_state = 0;
|
||||
uint16 temp_value = 0;
|
||||
uint16 timeout_count = 0;
|
||||
uint32 uart_buffer_index = 0;
|
||||
|
||||
if(SCC8660_UART == scc8660_type)
|
||||
{
|
||||
do
|
||||
{
|
||||
uint8 *receiver_buffer = (uint8 *)malloc(SCC8660_COF_BUFFER_SIZE);
|
||||
if(NULL == receiver_buffer)
|
||||
{
|
||||
return_state = 2;
|
||||
break;
|
||||
}
|
||||
camera_receiver_fifo = (fifo_struct *)malloc(sizeof(fifo_struct));
|
||||
if(NULL == camera_receiver_fifo)
|
||||
{
|
||||
free(receiver_buffer);
|
||||
return_state = 2;
|
||||
break;
|
||||
}
|
||||
fifo_init(camera_receiver_fifo, FIFO_DATA_8BIT, receiver_buffer, SCC8660_COF_BUFFER_SIZE);
|
||||
|
||||
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_value = data;
|
||||
uart_buffer[2] = temp_value >> 8;
|
||||
uart_buffer[3] = (uint8)temp_value;
|
||||
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_value = uart_buffer[1] << 8 | uart_buffer[2];
|
||||
break;
|
||||
}
|
||||
system_delay_ms(1);
|
||||
}while(SCC8660_INIT_TIMEOUT > timeout_count ++);
|
||||
if((temp_value != data) || (SCC8660_INIT_TIMEOUT <= timeout_count))
|
||||
{
|
||||
return_state = 1;
|
||||
}
|
||||
if(NULL != receiver_buffer)
|
||||
{
|
||||
free(receiver_buffer);
|
||||
free(camera_receiver_fifo);
|
||||
camera_receiver_fifo = NULL;
|
||||
}
|
||||
}while(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
return_state = scc8660_sccb_set_reg(addr, data);
|
||||
}
|
||||
return return_state;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 SCC8660 摄像头初始化
|
||||
// 参数说明 void
|
||||
// 返回参数 uint8 1-失败 0-成功
|
||||
// 使用示例 scc8660_init();
|
||||
// 备注信息
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
uint8 scc8660_init (void)
|
||||
{
|
||||
uint8 loop_count = 0;
|
||||
uint8 return_state = 0;
|
||||
uint8 *receiver_buffer = NULL;
|
||||
soft_iic_info_struct scc8660_iic_struct;
|
||||
|
||||
const 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}, // 图像列数
|
||||
{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} // 手动白平衡
|
||||
};
|
||||
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}, // 白平衡设置
|
||||
};
|
||||
|
||||
do
|
||||
{
|
||||
scc8660_type = SCC8660_SCCB; // 先尝试 SCCB 方式通信
|
||||
soft_iic_init(&scc8660_iic_struct, // 配置 SCCB
|
||||
0, // 地址暂设为 0
|
||||
SCC8660_COF_IIC_DELAY, // 时钟延迟
|
||||
SCC8660_COF_IIC_SCL, // SCL 引脚
|
||||
SCC8660_COF_IIC_SDA); // SDA 引脚
|
||||
|
||||
if(!scc8660_sccb_check_id(&scc8660_iic_struct)) // 尝试获取 ID
|
||||
{
|
||||
set_camera_type(CAMERA_COLOR, NULL, scc8660_dvp_handler);
|
||||
return_state = scc8660_sccb_set_config(scc8660_set_confing_buffer); // 获取到 ID 则进行参数配置
|
||||
}
|
||||
else // 没有获取到 ID 则进入下一步
|
||||
{
|
||||
scc8660_type = SCC8660_UART; // 切换到 UART 方式通信
|
||||
set_camera_type(CAMERA_COLOR, scc8660_uart_handler, scc8660_dvp_handler);
|
||||
receiver_buffer = (uint8 *)malloc(SCC8660_COF_BUFFER_SIZE); // 申请串口通信用的缓冲区
|
||||
if(NULL == receiver_buffer) // 堆空间不足
|
||||
{
|
||||
return_state = 2; // 异常码
|
||||
break;
|
||||
}
|
||||
camera_receiver_fifo = (fifo_struct *)malloc(sizeof(fifo_struct)); // 申请 FIFO 对象空间
|
||||
if(NULL == camera_receiver_fifo) // 堆空间不足
|
||||
{
|
||||
return_state = 2; // 异常码
|
||||
break;
|
||||
}
|
||||
fifo_init(camera_receiver_fifo, // 用申请的空间配置 FIFO
|
||||
FIFO_DATA_8BIT, // 数据位宽 8bit
|
||||
receiver_buffer, // 指向申请来的缓冲区
|
||||
SCC8660_COF_BUFFER_SIZE); // 缓冲区大小
|
||||
|
||||
// 初始换串口 配置摄像头
|
||||
uart_init(SCC8660_COF_UART, // 指定 SCC8660 的串口号
|
||||
SCC8660_COF_BAUR, // 通信波特率
|
||||
SCC8660_COF_UART_RX, // 芯片 TX 摄像头模块 RX
|
||||
SCC8660_COF_UART_TX); // 芯片 RX 摄像头模块 TX
|
||||
uart_rx_interrupt(SCC8660_COF_UART, 1); // 开启接收中断
|
||||
|
||||
if(scc8660_uart_check_id()) // 通过 UART 获取摄像头的 ID
|
||||
{
|
||||
uart_rx_interrupt(SCC8660_COF_UART, 0); // 摄像头的类型 ID 不正确 关闭串口接收中断
|
||||
return_state = 3; // 检查一下是不是选错摄像头了
|
||||
break;
|
||||
}
|
||||
do
|
||||
{
|
||||
if(scc8660_set_config(scc8660_set_confing_buffer)) // 通过 UART 发送配置参数
|
||||
{
|
||||
uart_rx_interrupt(SCC8660_COF_UART, 0); // 串口通信出错并超时退出了 关闭串口接收中断
|
||||
return_state = 1; // 检查一下接线有没有问题 如果没问题可能就是坏了
|
||||
break;
|
||||
}
|
||||
if(scc8660_get_config(scc8660_get_confing_buffer)) // 通过 UART 回读配置参数 查看配置是否正确
|
||||
{
|
||||
uart_rx_interrupt(SCC8660_COF_UART, 0); // 串口通信出错并超时退出了 关闭串口接收中断
|
||||
return_state = 1; // 检查一下接线有没有问题 如果没问题可能就是坏了
|
||||
break;
|
||||
}
|
||||
// 对比发送缓冲检查数据 如果数据正确则配置成功
|
||||
for(loop_count = 0; SCC8660_CONFIG_FINISH - 1 > loop_count; loop_count ++)
|
||||
{
|
||||
if( scc8660_set_confing_buffer[loop_count + 1][0] != scc8660_get_confing_buffer[loop_count][0] ||
|
||||
scc8660_set_confing_buffer[loop_count + 1][1] != scc8660_get_confing_buffer[loop_count][1])
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return_state = (SCC8660_CONFIG_FINISH - 1 == loop_count) ? 0 : 1;
|
||||
}while(0);
|
||||
}
|
||||
if(!return_state)
|
||||
{
|
||||
// DVP引脚初始化
|
||||
dvp_gpio_init(
|
||||
SCC8660_D0_PIN, SCC8660_D1_PIN, SCC8660_D2_PIN, SCC8660_D3_PIN,
|
||||
SCC8660_D4_PIN, SCC8660_D5_PIN, SCC8660_D6_PIN, SCC8660_D7_PIN,
|
||||
SCC8660_PCLK_PIN, SCC8660_VSY_PIN, SCC8660_HERF_PIN);
|
||||
|
||||
// DVP接口初始化
|
||||
dvp_camera_init((uint32 *)&scc8660_image[0], (uint32 *)&scc8660_image[0], SCC8660_IMAGE_SIZE, SCC8660_H);
|
||||
break;
|
||||
}
|
||||
set_camera_type(NO_CAMERE, NULL, NULL);
|
||||
}while(0);
|
||||
|
||||
free(receiver_buffer); // 释放缓冲器内存
|
||||
free(camera_receiver_fifo); // 释放 FIFO 内存
|
||||
camera_receiver_fifo = NULL; // FIFO 指针指向 NULL
|
||||
return return_state;
|
||||
}
|
||||
152
libraries/zf_device/zf_device_scc8660_dvp.h
Normal file
152
libraries/zf_device/zf_device_scc8660_dvp.h
Normal file
@@ -0,0 +1,152 @@
|
||||
/*********************************************************************************************************************
|
||||
* CH32V307VCT6 Opensourec Library 即(CH32V307VCT6 开源库)是一个基于官方 SDK 接口的第三方开源库
|
||||
* Copyright (c) 2022 SEEKFREE 逐飞科技
|
||||
*
|
||||
* 本文件是CH32V307VCT6 开源库的一部分
|
||||
*
|
||||
* CH32V307VCT6 开源库 是免费软件
|
||||
* 您可以根据自由软件基金会发布的 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_dvp
|
||||
* 公司名称 成都逐飞科技有限公司
|
||||
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
|
||||
* 开发环境 MounRiver Studio V1.8.1
|
||||
* 适用平台 CH32V307VCT6
|
||||
* 店铺链接 https://seekfree.taobao.com/
|
||||
*
|
||||
* 修改记录
|
||||
* 日期 作者 备注
|
||||
* 2022-09-15 大W first version
|
||||
********************************************************************************************************************/
|
||||
/*********************************************************************************************************************
|
||||
*接线定义:
|
||||
* ------------------------------------
|
||||
* 模块管脚 单片机管脚
|
||||
* TXD 查看 zf_device_scc8660.h 中 SCC8660_COF_UART_TX_DVP 宏定义
|
||||
* RXD 查看 zf_device_scc8660.h 中 SCC8660_COF_UART_RX_DVP 宏定义
|
||||
* D0 查看 zf_device_scc8660.h 中 SCC8660_D0_PIN_DVP 宏定义
|
||||
* D1 查看 zf_device_scc8660.h 中 SCC8660_D1_PIN_DVP 宏定义
|
||||
* D2 查看 zf_device_scc8660.h 中 SCC8660_D2_PIN_DVP 宏定义
|
||||
* D3 查看 zf_device_scc8660.h 中 SCC8660_D3_PIN_DVP 宏定义
|
||||
* D4 查看 zf_device_scc8660.h 中 SCC8660_D4_PIN_DVP 宏定义
|
||||
* D5 查看 zf_device_scc8660.h 中 SCC8660_D5_PIN_DVP 宏定义
|
||||
* D6 查看 zf_device_scc8660.h 中 SCC8660_D6_PIN_DVP 宏定义
|
||||
* D7 查看 zf_device_scc8660.h 中 SCC8660_D7_PIN_DVP 宏定义
|
||||
* PCLK 查看 zf_device_scc8660.h 中 SCC8660_PCLK_PIN_DVP 宏定义
|
||||
* VSYNC 查看 zf_device_scc8660.h 中 SCC8660_VSY_PIN_DVP 宏定义
|
||||
* HSYNC 查看 zf_device_scc8660.h 中 SCC8660_HERF_PIN_DVP 宏定义
|
||||
* ------------------------------------
|
||||
********************************************************************************************************************/
|
||||
|
||||
|
||||
#ifndef _zf_device_scc8660_h_
|
||||
#define _zf_device_scc8660_h_
|
||||
|
||||
#include "zf_common_typedef.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// 引脚配置
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
#define SCC8660_COF_UART UART_5 // 配置摄像头所使用到的串口
|
||||
#define SCC8660_COF_BAUR 9600 // 配置摄像头用的串口波特率 禁止修改
|
||||
#define SCC8660_COF_UART_RX UART5_MAP0_TX_C12 // 摄像头的 UART-RX 引脚 要接在单片机 TX 上
|
||||
#define SCC8660_COF_UART_TX UART5_MAP0_RX_D2 // 摄像头的 UART-TX 引脚 要接在单片机 RX 上
|
||||
|
||||
#define SCC8660_COF_IIC_DELAY (200) // 凌瞳 IIC 延时
|
||||
#define SCC8660_COF_IIC_SCL (D2) // 凌瞳 IIC-SCL 引脚
|
||||
#define SCC8660_COF_IIC_SDA (C12) // 凌瞳 IIC-SDA 引脚
|
||||
|
||||
#define SCC8660_D0_PIN (A9 )
|
||||
#define SCC8660_D1_PIN (A10)
|
||||
#define SCC8660_D2_PIN (C8 )
|
||||
#define SCC8660_D3_PIN (C9 )
|
||||
#define SCC8660_D4_PIN (C11)
|
||||
#define SCC8660_D5_PIN (B6 )
|
||||
#define SCC8660_D6_PIN (B8 )
|
||||
#define SCC8660_D7_PIN (B9 )
|
||||
|
||||
#define SCC8660_PCLK_PIN (A6 )
|
||||
#define SCC8660_VSY_PIN (A5 )
|
||||
#define SCC8660_HERF_PIN (A4 )
|
||||
#define SCC8660_INIT_TIMEOUT (0x0080) // 默认的摄像头初始化超时时间 毫秒为单位
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// 摄像头默认参数配置 在此修改摄像头配置
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
#define SCC8660_W (160) // 实际图像分辨率宽度 可选参数为:160 180
|
||||
#define SCC8660_H (120) // 实际图像分辨率高度 可选参数为:120 160
|
||||
#define SCC8660_IMAGE_SIZE ( SCC8660_W * 2 * SCC8660_H ) // 整体图像大小 SCC8660_W*2*SCC8660_H 不能超过 65535
|
||||
#define SCC8660_COF_BUFFER_SIZE ( 64 ) // 配置串口缓冲区大小
|
||||
|
||||
#define SCC8660_AUTO_EXP_DEF (0 ) // 自动曝光 默认不开启自动曝光设置 范围 [0-1] 0为关闭
|
||||
#define SCC8660_BRIGHT_DEF (300) // 亮度设置 手动曝光默认:300 手动曝光时:参数范围0-65535 自动曝光推荐值:100 自动曝光时参数设置范围0-255
|
||||
#define SCC8660_FPS_DEF (60 ) // 图像帧率 默认:60 可选参数为:60 50 30 25。 实际帧率还需要看SCC8660_PCLK_DIV参数的设置
|
||||
#define SCC8660_PCLK_DIV_DEF (0 ) // PCLK分频系数 默认:0 可选参数为:<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 (1 ) // 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
|
||||
|
||||
// 摄像头命令枚举
|
||||
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;
|
||||
|
||||
// 摄像头接口类型枚举
|
||||
typedef enum
|
||||
{
|
||||
SCC8660_UART,
|
||||
SCC8660_SCCB,
|
||||
}scc8660_type_enum;
|
||||
|
||||
extern vuint8 scc8660_finish_flag; // 一场图像采集完成标志位
|
||||
extern uint16 scc8660_image[SCC8660_H][SCC8660_W];
|
||||
|
||||
uint16 scc8660_get_id (void);
|
||||
uint16 scc8660_get_parameter (uint16 config);
|
||||
uint16 scc8660_get_version (void);
|
||||
uint8 scc8660_set_bright (uint16 data);
|
||||
uint8 scc8660_set_white_balance (uint16 data);
|
||||
uint8 scc8660_set_reg (uint8 addr, uint16 data);
|
||||
|
||||
uint8 scc8660_init (void);
|
||||
|
||||
#endif
|
||||
1030
libraries/zf_device/zf_device_tft180.c
Normal file
1030
libraries/zf_device/zf_device_tft180.c
Normal file
File diff suppressed because it is too large
Load Diff
159
libraries/zf_device/zf_device_tft180.h
Normal file
159
libraries/zf_device/zf_device_tft180.h
Normal file
@@ -0,0 +1,159 @@
|
||||
/*********************************************************************************************************************
|
||||
* CH32V307VCT6 Opensourec Library 即(CH32V307VCT6 开源库)是一个基于官方 SDK 接口的第三方开源库
|
||||
* Copyright (c) 2022 SEEKFREE 逐飞科技
|
||||
*
|
||||
* 本文件是CH32V307VCT6 开源库的一部分
|
||||
*
|
||||
* CH32V307VCT6 开源库 是免费软件
|
||||
* 您可以根据自由软件基金会发布的 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 文件 版本说明
|
||||
* 开发环境 MounRiver Studio V1.8.1
|
||||
* 适用平台 CH32V307VCT6
|
||||
* 店铺链接 https://seekfree.taobao.com/
|
||||
*
|
||||
* 修改记录
|
||||
* 日期 作者 备注
|
||||
* 2022-09-15 大W first version
|
||||
********************************************************************************************************************/
|
||||
/*********************************************************************************************************************
|
||||
* 接线定义:
|
||||
* ------------------------------------
|
||||
* 模块管脚 单片机管脚
|
||||
* SCL 查看 zf_device_tft180.h 中 TFT180_SCL_PIN 宏定义
|
||||
* SDA 查看 zf_device_tft180.h 中 TFT180_SDA_PIN 宏定义
|
||||
* RES 查看 zf_device_tft180.h 中 TFT180_RES_PIN 宏定义
|
||||
* DC 查看 zf_device_tft180.h 中 TFT180_DC_PIN 宏定义
|
||||
* CS 查看 zf_device_tft180.h 中 TFT180_CS_PIN 宏定义
|
||||
* BL 查看 zf_device_tft180.h 中 TFT180_BL_PIN 宏定义
|
||||
* VCC 3.3V电源
|
||||
* GND 电源地
|
||||
* 最大分辨率160*128
|
||||
* ------------------------------------
|
||||
********************************************************************************************************************/
|
||||
|
||||
#ifndef _zf_device_tft180_h_
|
||||
#define _zf_device_tft180_h_
|
||||
|
||||
#include "zf_common_typedef.h"
|
||||
|
||||
#define TFT180_USE_SOFT_SPI (0) // 默认使用硬件 SPI 方式驱动 建议使用硬件 SPI 方式驱动
|
||||
#if TFT180_USE_SOFT_SPI // 这两段 颜色正常的才是正确的 颜色灰的就是没有用的
|
||||
//====================================================软件 SPI 驱动====================================================
|
||||
#define TFT180_SOFT_SPI_DELAY (1 ) // 软件 SPI 的时钟延时周期 数值越小 SPI 通信速率越快
|
||||
#define TFT180_SCL_PIN (B13) // 软件 SPI SCK 引脚
|
||||
#define TFT180_SDA_PIN (B15) // 软件 SPI MOSI 引脚
|
||||
//====================================================软件 SPI 驱动====================================================
|
||||
#else
|
||||
//====================================================硬件 SPI 驱动====================================================
|
||||
#define TFT180_SPI_SPEED (72 * 1000 * 1000) // 硬件 SPI 速率
|
||||
#define TFT180_SPI (SPI_2) // 硬件 SPI 号
|
||||
#define TFT180_SCL_PIN (SPI2_MAP0_SCK_B13) // 硬件 SPI SCK 引脚
|
||||
#define TFT180_SDA_PIN (SPI2_MAP0_MOSI_B15) // 硬件 SPI MOSI 引脚
|
||||
//====================================================硬件 SPI 驱动====================================================
|
||||
#endif
|
||||
|
||||
#define TFT180_RES_PIN (B7) // 液晶复位引脚定义
|
||||
#define TFT180_DC_PIN (D7) // 液晶命令位引脚定义
|
||||
#define TFT180_CS_PIN (D4) // CS 片选引脚
|
||||
#define TFT180_BL_PIN (D0) // 液晶背光引脚定义
|
||||
|
||||
#define TFT180_DEFAULT_DISPLAY_DIR (TFT180_PORTAIT) // 默认的显示方向
|
||||
#define TFT180_DEFAULT_PENCOLOR (RGB565_RED) // 默认的画笔颜色
|
||||
#define TFT180_DEFAULT_BGCOLOR (RGB565_WHITE) // 默认的背景颜色
|
||||
#define TFT180_DEFAULT_DISPLAY_FONT (TFT180_8X16_FONT) // 默认的字体模式
|
||||
|
||||
#define TFT180_DC(x) ((x) ? (gpio_high(TFT180_DC_PIN)) : (gpio_low(TFT180_DC_PIN)))
|
||||
#define TFT180_RST(x) ((x) ? (gpio_high(TFT180_RES_PIN)) : (gpio_low(TFT180_RES_PIN)))
|
||||
#define TFT180_CS(x) ((x) ? (gpio_high(TFT180_CS_PIN)) : (gpio_low(TFT180_CS_PIN)))
|
||||
#define TFT180_BLK(x) ((x) ? (gpio_high(TFT180_BL_PIN)) : (gpio_low(TFT180_BL_PIN)))
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TFT180_PORTAIT = 0, // 竖屏模式
|
||||
TFT180_PORTAIT_180 = 1, // 竖屏模式 旋转180
|
||||
TFT180_CROSSWISE = 2, // 横屏模式
|
||||
TFT180_CROSSWISE_180 = 3, // 横屏模式 旋转180
|
||||
}tft180_dir_enum;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TFT180_6X8_FONT = 0, // 6x8 字体
|
||||
TFT180_8X16_FONT = 1, // 8x16 字体
|
||||
TFT180_16X16_FONT = 2, // 16x16 字体 目前不支持
|
||||
}tft180_font_size_enum;
|
||||
|
||||
void tft180_clear (void);
|
||||
void tft180_full (const uint16 color);
|
||||
void tft180_set_dir (tft180_dir_enum dir);
|
||||
void tft180_set_font (tft180_font_size_enum font);
|
||||
void tft180_set_color (const uint16 pen, const uint16 bgcolor);
|
||||
void tft180_draw_point (uint16 x, uint16 y, const uint16 color);
|
||||
void tft180_draw_line (uint16 x_start, uint16 y_start, uint16 x_end, uint16 y_end, const uint16 color);
|
||||
|
||||
void tft180_show_char (uint16 x, uint16 y, const char dat);
|
||||
void tft180_show_string (uint16 x, uint16 y, const char dat[]);
|
||||
void tft180_show_int (uint16 x,uint16 y, const int32 dat, uint8 num);
|
||||
void tft180_show_uint (uint16 x,uint16 y, const uint32 dat, uint8 num);
|
||||
void tft180_show_float (uint16 x,uint16 y, const double dat, uint8 num, uint8 pointnum);
|
||||
|
||||
void tft180_show_binary_image (uint16 x, uint16 y, const uint8 *image, uint16 width, uint16 height, uint16 dis_width, uint16 dis_height);
|
||||
void tft180_show_gray_image (uint16 x, uint16 y, const uint8 *image, uint16 width, uint16 height, uint16 dis_width, uint16 dis_height, uint8 threshold);
|
||||
void tft180_show_rgb565_image (uint16 x, uint16 y, const uint16 *image, uint16 width, uint16 height, uint16 dis_width, uint16 dis_height, uint8 color_mode);
|
||||
|
||||
void tft180_show_wave (uint16 x, uint16 y, const uint16 *wave, uint16 width, uint16 value_max, uint16 dis_width, uint16 dis_value_max);
|
||||
void tft180_show_chinese (uint16 x, uint16 y, uint8 size, const uint8 *chinese_buffer, uint8 number, const uint16 color);
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 TFT180 显示小钻风图像
|
||||
// 参数说明 p 图像数组
|
||||
// 参数说明 width 显示宽度
|
||||
// 参数说明 height 显示高度
|
||||
// 返回参数 void
|
||||
// 使用示例 tft180_displayimage7725(ov7725_image_binary[0], 80, 60);
|
||||
// 备注信息
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
#define tft180_displayimage7725(p, width, height) (tft180_show_binary_image(0, 0, (p), OV7725_W, OV7725_H, (width), (height)))
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 TFT180 显示总钻风图像 不带二值化 显示灰度图像
|
||||
// 参数说明 p 图像数组
|
||||
// 参数说明 width 显示宽度
|
||||
// 参数说明 height 显示高度
|
||||
// 返回参数 void
|
||||
// 使用示例 tft180_displayimage03x(mt9v03x_image[0], 94, 60);
|
||||
// 备注信息 如果要显示二值化图像就去调用 tft180_show_gray_image 函数
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
#define tft180_displayimage03x(p, width, height) (tft180_show_gray_image(0, 0, (p), MT9V03X_W, MT9V03X_H, (width), (height), 0))
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 TFT180 显示凌瞳图像
|
||||
// 参数说明 p 图像数组
|
||||
// 参数说明 width 显示宽度
|
||||
// 参数说明 height 显示高度
|
||||
// 返回参数 void
|
||||
// 使用示例 tft180_displayimage8660(scc8660_image[0], 80, 60);
|
||||
// 备注信息
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
#define tft180_displayimage8660(p, width, height) (tft180_show_rgb565_image(0, 0, (p), SCC8660_W, SCC8660_H, (width), (height), 1))
|
||||
|
||||
void tft180_init (void);
|
||||
|
||||
#endif
|
||||
|
||||
105
libraries/zf_device/zf_device_type.c
Normal file
105
libraries/zf_device/zf_device_type.c
Normal file
@@ -0,0 +1,105 @@
|
||||
/*********************************************************************************************************************
|
||||
* CH32V307VCT6 Opensourec Library 即(CH32V307VCT6 开源库)是一个基于官方 SDK 接口的第三方开源库
|
||||
* Copyright (c) 2022 SEEKFREE 逐飞科技
|
||||
*
|
||||
* 本文件是CH32V307VCT6 开源库的一部分
|
||||
*
|
||||
* CH32V307VCT6 开源库 是免费软件
|
||||
* 您可以根据自由软件基金会发布的 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 文件 版本说明
|
||||
* 开发环境 MounRiver Studio V1.8.1
|
||||
* 适用平台 CH32V307VCT6
|
||||
* 店铺链接 https://seekfree.taobao.com/
|
||||
*
|
||||
* 修改记录
|
||||
* 日期 作者 备注
|
||||
* 2022-09-15 大W first version
|
||||
********************************************************************************************************************/
|
||||
|
||||
#include "zf_device_type.h"
|
||||
|
||||
|
||||
static void type_default_callback (void);
|
||||
|
||||
camera_type_enum camera_type = NO_CAMERE; // 摄像头类型变量
|
||||
callback_function camera_uart_handler = type_default_callback; // 串口通讯中断函数指针,根据初始化时设置的函数进行跳转
|
||||
callback_function camera_dvp_handler = type_default_callback; // DVP完成中断函数指针,根据初始化时设置的函数进行跳转
|
||||
|
||||
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 uart_callback, callback_function dvp_callback)
|
||||
{
|
||||
camera_type = type_set;
|
||||
camera_dvp_handler = ((dvp_callback == NULL) ? (type_default_callback) : (dvp_callback));
|
||||
camera_uart_handler = ((uart_callback == NULL) ? (type_default_callback) : (uart_callback));
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 设置无线模块类型
|
||||
// 参数说明 type_set 选定的无线模块类型
|
||||
// 参数说明 uart_callback 设备的串口回调函数
|
||||
// 返回参数 void
|
||||
// 使用示例 set_wireless_type(WIRELESS_UART, uart_callback);
|
||||
// 备注信息 一般由各摄像头初始化内部调用
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
void set_wireless_type (wireless_type_enum type_set, callback_function uart_callback)
|
||||
{
|
||||
wireless_type = type_set;
|
||||
wireless_module_uart_handler = ((uart_callback == NULL) ? (type_default_callback) : (uart_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));
|
||||
}
|
||||
83
libraries/zf_device/zf_device_type.h
Normal file
83
libraries/zf_device/zf_device_type.h
Normal file
@@ -0,0 +1,83 @@
|
||||
/*********************************************************************************************************************
|
||||
* CH32V307VCT6 Opensourec Library 即(CH32V307VCT6 开源库)是一个基于官方 SDK 接口的第三方开源库
|
||||
* Copyright (c) 2022 SEEKFREE 逐飞科技
|
||||
*
|
||||
* 本文件是CH32V307VCT6 开源库的一部分
|
||||
*
|
||||
* CH32V307VCT6 开源库 是免费软件
|
||||
* 您可以根据自由软件基金会发布的 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 文件 版本说明
|
||||
* 开发环境 MounRiver Studio V1.8.1
|
||||
* 适用平台 CH32V307VCT6
|
||||
* 店铺链接 https://seekfree.taobao.com/
|
||||
*
|
||||
* 修改记录
|
||||
* 日期 作者 备注
|
||||
* 2022-09-15 大W first version
|
||||
********************************************************************************************************************/
|
||||
#ifndef _zf_device_type_h_
|
||||
#define _zf_device_type_h_
|
||||
|
||||
#include "zf_common_typedef.h"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
NO_CAMERE = 0, // 无摄像头
|
||||
CAMERA_BIN_IIC, // 小钻风 IIC 版本
|
||||
CAMERA_BIN_UART, // 小钻风 UART 版本
|
||||
CAMERA_GRAYSCALE, // 总钻风
|
||||
CAMERA_COLOR, // 凌瞳
|
||||
}camera_type_enum;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
NO_WIRELESS = 0, // 无设备
|
||||
WIRELESS_UART, // 无线串口
|
||||
BLUETOOTH_CH9141, // 蓝牙 CH9141
|
||||
WIFI_UART, // Wi-Fi 串口
|
||||
WIRELESS_CH573,
|
||||
WIFI_SPI, // Wi-Fi SPI
|
||||
}wireless_type_enum;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
NO_TOF = 0, // 无设备
|
||||
TOF_DL1A, // DL1A
|
||||
TOF_DL1B, // DL1B
|
||||
}tof_type_enum;
|
||||
|
||||
typedef void (*callback_function)(void);
|
||||
|
||||
extern camera_type_enum camera_type;
|
||||
extern wireless_type_enum wireless_type;
|
||||
extern tof_type_enum tof_type;
|
||||
|
||||
extern callback_function camera_uart_handler;
|
||||
extern callback_function camera_dvp_handler;
|
||||
extern callback_function wireless_module_uart_handler;
|
||||
extern callback_function tof_module_exti_handler;
|
||||
|
||||
|
||||
void set_camera_type (camera_type_enum type_set, callback_function uart_callback, callback_function dvp_callback);
|
||||
void set_wireless_type (wireless_type_enum type_set, callback_function uart_callback);
|
||||
void set_tof_type (tof_type_enum type_set, callback_function exti_callback);
|
||||
|
||||
|
||||
#endif
|
||||
98
libraries/zf_device/zf_device_virtual_oscilloscope.c
Normal file
98
libraries/zf_device/zf_device_virtual_oscilloscope.c
Normal file
@@ -0,0 +1,98 @@
|
||||
/*********************************************************************************************************************
|
||||
* CH32V307VCT6 Opensourec Library 即(CH32V307VCT6 开源库)是一个基于官方 SDK 接口的第三方开源库
|
||||
* Copyright (c) 2022 SEEKFREE 逐飞科技
|
||||
*
|
||||
* 本文件是CH32V307VCT6 开源库的一部分
|
||||
*
|
||||
* CH32V307VCT6 开源库 是免费软件
|
||||
* 您可以根据自由软件基金会发布的 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 文件 版本说明
|
||||
* 开发环境 MounRiver Studio V1.8.1
|
||||
* 适用平台 CH32V307VCT6
|
||||
* 店铺链接 https://seekfree.taobao.com/
|
||||
*
|
||||
* 修改记录
|
||||
* 日期 作者 备注
|
||||
* 2022-09-15 大W first version
|
||||
********************************************************************************************************************/
|
||||
|
||||
#include "zf_device_virtual_oscilloscope.h"
|
||||
|
||||
uint8_t virtual_oscilloscope_data[10];
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// @brief CRC 校验 内部使用 用户无需关心
|
||||
// @param buff 需要进行 CRC 计算的数据地址
|
||||
// @param crc_cnt 需要进行 CRC 计算的数据个数
|
||||
// @return uint16 CRC 校验结果
|
||||
// Sample usage:
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
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;j<8;j++)
|
||||
{
|
||||
if (crc_temp & 0x01)
|
||||
crc_temp = (crc_temp >>1) ^ 0xa001;
|
||||
else
|
||||
crc_temp = crc_temp >> 1;
|
||||
}
|
||||
}
|
||||
return(crc_temp);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// @brief 虚拟示波器数据转换函数
|
||||
// @param data1 要发送的第一个数据
|
||||
// @param data2 要发送的第二个数据
|
||||
// @param data3 要发送的第三个数据
|
||||
// @param data4 要发送的第四个数据
|
||||
// @param *dat 转换之后存放数据的地址
|
||||
// @return void
|
||||
// 使用示例 uint8_t 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);
|
||||
}
|
||||
45
libraries/zf_device/zf_device_virtual_oscilloscope.h
Normal file
45
libraries/zf_device/zf_device_virtual_oscilloscope.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/*********************************************************************************************************************
|
||||
* CH32V307VCT6 Opensourec Library 即(CH32V307VCT6 开源库)是一个基于官方 SDK 接口的第三方开源库
|
||||
* Copyright (c) 2022 SEEKFREE 逐飞科技
|
||||
*
|
||||
* 本文件是CH32V307VCT6 开源库的一部分
|
||||
*
|
||||
* CH32V307VCT6 开源库 是免费软件
|
||||
* 您可以根据自由软件基金会发布的 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 文件 版本说明
|
||||
* 开发环境 MounRiver Studio V1.8.1
|
||||
* 适用平台 CH32V307VCT6
|
||||
* 店铺链接 https://seekfree.taobao.com/
|
||||
*
|
||||
* 修改记录
|
||||
* 日期 作者 备注
|
||||
* 2022-09-15 大W first version
|
||||
********************************************************************************************************************/
|
||||
|
||||
#ifndef _zf_device_virtual_oscilloscope_h_
|
||||
#define _zf_device_virtual_oscilloscope_h_
|
||||
|
||||
#include "zf_common_typedef.h"
|
||||
|
||||
extern uint8_t virtual_oscilloscope_data[10];
|
||||
|
||||
void virtual_oscilloscope_data_conversion (const int16 data1, const int16 data2, const int16 data3, const int16 data4);
|
||||
|
||||
#endif
|
||||
401
libraries/zf_device/zf_device_w25q32.c
Normal file
401
libraries/zf_device/zf_device_w25q32.c
Normal file
@@ -0,0 +1,401 @@
|
||||
/*********************************************************************************************************************
|
||||
* CH32V307VCT6 Opensourec Library 即(CH32V307VCT6 开源库)是一个基于官方 SDK 接口的第三方开源库
|
||||
* Copyright (c) 2022 SEEKFREE 逐飞科技
|
||||
*
|
||||
* 本文件是CH32V307VCT6 开源库的一部分
|
||||
*
|
||||
* CH32V307VCT6 开源库 是免费软件
|
||||
* 您可以根据自由软件基金会发布的 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_w25q32
|
||||
* 公司名称 成都逐飞科技有限公司
|
||||
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
|
||||
* 开发环境 MounRiver Studio V1.8.1
|
||||
* 适用平台 CH32V307VCT6
|
||||
* 店铺链接 https://seekfree.taobao.com/
|
||||
*
|
||||
* 修改记录
|
||||
* 日期 作者 备注
|
||||
* 2022-09-15 大W first version
|
||||
********************************************************************************************************************/
|
||||
/*********************************************************************************************************************
|
||||
* 接线定义:
|
||||
* ------------------------------------
|
||||
* 模块管脚 单片机管脚
|
||||
* //------------------硬件 SPI 引脚------------------//
|
||||
* SPC 查看 zf_device_w25q32.h 中 W25Q32_SPC_PIN 宏定义
|
||||
* SDI 查看 zf_device_w25q32.h 中 W25Q32_SDI_PIN 宏定义
|
||||
* SDO 查看 zf_device_w25q32.h 中 W25Q32_SDO_PIN 宏定义
|
||||
* CS 查看 zf_device_w25q32.h 中 W25Q32_CS_PIN 宏定义
|
||||
* //------------------硬件 SPI 引脚------------------//
|
||||
* 电源引脚
|
||||
* VCC 3.3V电源
|
||||
* GND 电源地
|
||||
* ------------------------------------
|
||||
********************************************************************************************************************/
|
||||
|
||||
#include "zf_device_w25q32.h"
|
||||
|
||||
|
||||
static uint8 w25q32_read_dat()
|
||||
{
|
||||
// W25Q32_CS(0);
|
||||
uint8 dat = spi_read_8bit(W25Q32_SPI);
|
||||
// W25Q32_CS(1);
|
||||
return dat;
|
||||
}
|
||||
|
||||
static void w25q32_read_dats(uint8 *dat, uint32 len)
|
||||
{
|
||||
// W25Q32_CS(0);
|
||||
spi_read_8bit_array(W25Q32_SPI, dat, len);
|
||||
// W25Q32_CS(1);
|
||||
}
|
||||
|
||||
static void w25q32_write_dat(uint8 dat)
|
||||
{
|
||||
// W25Q32_CS(0);
|
||||
spi_write_8bit(W25Q32_SPI, dat);
|
||||
// W25Q32_CS(1);
|
||||
}
|
||||
|
||||
|
||||
static void w25q32_write_dats(uint8 *dat, uint32 len)
|
||||
{
|
||||
// W25Q32_CS(0);
|
||||
spi_write_8bit_array(W25Q32_SPI, dat, len);
|
||||
// W25Q32_CS(1);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 写使能 内部调用
|
||||
// 参数说明 void
|
||||
// 返回参数 void
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
static void w25q32_write_enable(void)
|
||||
{
|
||||
W25Q32_CS(0);
|
||||
w25q32_write_dat(W25Q32_WRITE_ENABLE); //发送写使能
|
||||
W25Q32_CS(1);
|
||||
}
|
||||
|
||||
////-------------------------------------------------------------------------------------------------------------------
|
||||
//// @brief 写失能 内部调用
|
||||
//// @param void
|
||||
//// @return void
|
||||
////-------------------------------------------------------------------------------------------------------------------
|
||||
//static void w25q32_write_disable(void)
|
||||
//{
|
||||
// W25Q32_CS(0);
|
||||
// w25q32_write_dat(W25Q32_WRITE_DISABLE); //发送写禁止指令
|
||||
// W25Q32_CS(1);
|
||||
//}
|
||||
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 读取状态 内部调用
|
||||
// 参数说明 void
|
||||
// 返回参数 uint8 寄存器状态值
|
||||
// BIT7 6 5 4 3 2 1 0
|
||||
// SPR RV TB BP2 BP1 BP0 WEL BUSY
|
||||
// Sample usage:
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
static uint8 w25q32_read_state(void)
|
||||
{
|
||||
uint8 byte=0;
|
||||
W25Q32_CS(0);
|
||||
//发送读取状态寄存器命令
|
||||
//读取一个字节
|
||||
w25q32_write_dat(W25Q32_READ_STATUS_REG_1); // 发送读取命令
|
||||
byte = w25q32_read_dat(); // 读取一个字节
|
||||
W25Q32_CS(1);
|
||||
return byte;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 等待不忙 内部调用
|
||||
// 参数说明 void
|
||||
// 返回参数 void
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
static void w25q32_wait_busy(void)
|
||||
{
|
||||
while ((w25q32_read_state()&0x01)==0x01); // 等待BUSY复位
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 读芯片id 内部调用
|
||||
// 参数说明 void
|
||||
// 返回参数 uint16 ID值
|
||||
// Sample usage:
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
static uint16 w25q32_read_device_id(void)
|
||||
{
|
||||
uint8 send_dat[4] = {W25Q32_DEVICE_ID, 0x00, 0x00, 0x00};
|
||||
uint8 read_dat[2] = {0};
|
||||
W25Q32_CS(0);
|
||||
w25q32_write_dats(send_dat, 4);
|
||||
w25q32_read_dats(read_dat, 2);
|
||||
W25Q32_CS(1);
|
||||
|
||||
return read_dat[0] << 8 | read_dat[1];
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 擦除W25Q32所有区域(需要等待20秒)
|
||||
// 参数说明 void
|
||||
// 返回参数 void
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
void w25q32_erase_chip(void)
|
||||
{
|
||||
w25q32_wait_busy();
|
||||
W25Q32_CS(0); //使能器件
|
||||
w25q32_write_dat(W25Q32_CHIP_ERASE); //发送片擦除命令
|
||||
W25Q32_CS(1); //取消片选
|
||||
w25q32_wait_busy(); //等待芯片擦除结束
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 读取一个字节 内部调用
|
||||
// 参数说明 uint32 读取地址24bit
|
||||
// 返回参数 uint8 读取到的值
|
||||
// @since v1.0
|
||||
// 使用示例 w25q32_read_byte(0x000001);
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
static uint8 w25q32_read_byte(uint32 addr)
|
||||
{
|
||||
uint8 temp;
|
||||
W25Q32_CS(0);
|
||||
|
||||
w25q32_write_dat(W25Q32_READ_DATA); // 发送读取命令
|
||||
w25q32_write_dat((uint8)((addr)>>16)); // 发送24bit地址
|
||||
w25q32_write_dat((uint8)((addr)>>8));
|
||||
w25q32_write_dat((uint8)addr);
|
||||
temp = w25q32_read_dat(); // 读取一个字节
|
||||
|
||||
W25Q32_CS(1);
|
||||
return temp;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 校验w25q32是否有数据
|
||||
// 参数说明 block_num 需要写入的扇区编号 参数范围 W25Q32_BLOCK_00 - W25Q32_BLOCK_63
|
||||
// 参数说明 sector_num 需要写入的扇区编号 参数范围 W25Q32_SECTION_00 - W25Q32_SECTION_15
|
||||
// 参数说明 page_num 当前扇区页的编号 参数范围 W25Q32_PAGE_00 - W25Q32_PAGE_15
|
||||
// 返回参数 返回1有数据,返回0没有数据,如果需要对有数据的区域写入新的数据则应该对所在扇区进行擦除操作
|
||||
// @since v1.0
|
||||
// 使用示例 w25q32_check(W25Q32_BLOCK_63, W25Q32_SECTION_15, W25Q32_PAGE_00);
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
uint8 w25q32_check (w25q32_block_enum block_num, w25q32_section_enum sector_num, w25q32_page_enum page_num)
|
||||
{
|
||||
uint16 temp_loop;
|
||||
uint32 addr = (W25Q32_BASE_ADDR +
|
||||
W25Q32_BLOCK_SIZE*block_num +
|
||||
W25Q32_SECTION_SIZE*sector_num +
|
||||
W25Q32_PAGE_SIZE*page_num); // 提取当前地址
|
||||
|
||||
for(temp_loop = 0; temp_loop < W25Q32_PAGE_SIZE; temp_loop++) // 循环读取 Flash 的值
|
||||
{
|
||||
if( w25q32_read_byte(addr + temp_loop) != 0xff ) // 如果不是 0xff 那就是有值
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 擦除一个扇区
|
||||
// 参数说明 block_num 需要写入的扇区编号 参数范围 W25Q32_BLOCK_00 - W25Q32_BLOCK_63
|
||||
// 参数说明 sector_num 需要写入的扇区编号 参数范围 W25Q32_SECTION_00 - W25Q32_SECTION_15
|
||||
// 返回参数
|
||||
// @since v1.0
|
||||
// 使用示例 w25q32_erase_sector(W25Q32_BLOCK_63, W25Q32_SECTION_15);
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
uint8 w25q32_erase_sector(w25q32_block_enum block_num, w25q32_section_enum sector_num)
|
||||
{
|
||||
uint32 addr = (W25Q32_BASE_ADDR +
|
||||
W25Q32_BLOCK_SIZE*block_num +
|
||||
W25Q32_SECTION_SIZE*sector_num +
|
||||
W25Q32_PAGE_SIZE*0); // 提取当前地址
|
||||
|
||||
W25Q32_CS(0);
|
||||
|
||||
w25q32_write_dat(W25Q32_SECTOR_ERASE); // 发送擦除扇区命令
|
||||
w25q32_write_dat((uint8)((addr)>>16)); // 发送24bit地址
|
||||
w25q32_write_dat((uint8)((addr)>>8));
|
||||
w25q32_write_dat((uint8)addr);
|
||||
|
||||
W25Q32_CS(1);
|
||||
w25q32_wait_busy(); // 等待擦除完成
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 从该地址开始读取数据 内部使用
|
||||
// 参数说明 addr 开始读取的地址24bit
|
||||
// 参数说明 buff 数据存储区
|
||||
// 参数说明 len 要读取的长度(最大65535)
|
||||
// 返回参数
|
||||
// @since v1.0
|
||||
// 使用示例 w25q32_erase_sector(0x000001, buf, 16);
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
static void w25q32_read_addr_dats(uint32 addr, uint8 *buff, uint16 len)
|
||||
{
|
||||
W25Q32_CS(0);
|
||||
w25q32_write_dat(W25Q32_FAST_READ); // 发送读取命令
|
||||
w25q32_write_dat((uint8)((addr)>>16)); // 发送24bit地址
|
||||
w25q32_write_dat((uint8)((addr)>>8));
|
||||
w25q32_write_dat((uint8)addr);
|
||||
w25q32_read_dat(); // 快速读取要求第一个字节为空字节。
|
||||
w25q32_read_dats(buff, len);
|
||||
|
||||
W25Q32_CS(1);//取消片选
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 从该地址开始写入数据 内部使用
|
||||
// 参数说明 addr 开始写入的地址24bit
|
||||
// 参数说明 buff 数据存储区
|
||||
// 参数说明 len 要写入的长度(最大256,且len不能超过该页剩余的字节数)
|
||||
// 返回参数
|
||||
// @since v1.0
|
||||
// 使用示例 w25q32_write_addr_dats(0x000001, buf, 16);
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
static void w25q32_write_addr_dats(uint32 addr, uint8 *buff, uint16 len)
|
||||
{
|
||||
|
||||
W25Q32_CS(0);
|
||||
|
||||
w25q32_write_dat(W25Q32_PAGE_PROGRAM); // 发送写页命令
|
||||
w25q32_write_dat((uint8)((addr)>>16)); // 发送24bit地址
|
||||
w25q32_write_dat((uint8)((addr)>>8));
|
||||
w25q32_write_dat((uint8)addr);
|
||||
w25q32_write_dats(buff, len);
|
||||
W25Q32_CS(1);
|
||||
w25q32_wait_busy(); // 等待写入结束
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 读取一页
|
||||
// 参数说明 block_num 需要读取的扇区编号 参数范围 W25Q32_BLOCK_00 - W25Q32_BLOCK_63
|
||||
// 参数说明 sector_num 需要读取的扇区编号 参数范围 W25Q32_SECTION_00 - W25Q32_SECTION_15
|
||||
// 参数说明 page_num 需要读取的页编号 参数范围 W25Q32_PAGE_00 - W25Q32_PAGE_15
|
||||
// 参数说明 buf 需要读取的数据地址 传入的数组类型必须为uint8 *
|
||||
// 参数说明 len 需要读取的数据长度 参数范围 1-256
|
||||
// 返回参数 NULL
|
||||
// @since v1.0
|
||||
// 备注信息
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
void w25q32_read_page(w25q32_block_enum block_num, w25q32_section_enum sector_num, w25q32_page_enum page_num,
|
||||
uint8 *buf, uint16 len)
|
||||
{
|
||||
uint32 addr = (W25Q32_BASE_ADDR +
|
||||
W25Q32_BLOCK_SIZE*block_num +
|
||||
W25Q32_SECTION_SIZE*sector_num +
|
||||
W25Q32_PAGE_SIZE*page_num); // 提取当前 Flash 地址
|
||||
|
||||
w25q32_read_addr_dats(addr, buf, len);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 写入一页
|
||||
// 参数说明 block_num 需要读取的扇区编号 参数范围 W25Q32_BLOCK_00 - W25Q32_BLOCK_63
|
||||
// 参数说明 sector_num 需要读取的扇区编号 参数范围 W25Q32_SECTION_00 - W25Q32_SECTION_15
|
||||
// 参数说明 page_num 需要读取的页编号 参数范围 W25Q32_PAGE_00 - W25Q32_PAGE_15
|
||||
// 参数说明 buf 需要读取的数据地址 传入的数组类型必须为uint8 *
|
||||
// 参数说明 len 需要读取的数据长度 参数范围 1-256
|
||||
// 返回参数 NULL
|
||||
// @since v1.0
|
||||
// 备注信息
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
void w25q32_write_page(w25q32_block_enum block_num, w25q32_section_enum sector_num, w25q32_page_enum page_num,
|
||||
uint8 *buf, uint16 len)
|
||||
{
|
||||
uint32 flash_addr = (W25Q32_BASE_ADDR +
|
||||
W25Q32_BLOCK_SIZE*block_num +
|
||||
W25Q32_SECTION_SIZE*sector_num +
|
||||
W25Q32_PAGE_SIZE*page_num); // 提取当前 Flash 地址
|
||||
|
||||
w25q32_write_addr_dats(flash_addr, buf, len);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 自检 内部调用
|
||||
// 参数说明 void
|
||||
// 返回参数 void
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
static uint8 w25q32_self_check(void)
|
||||
{
|
||||
uint8 ret = 0;
|
||||
uint16 dat = 0;
|
||||
volatile int16 timeout_count = W25Q32_TIMEOUT_COUNT;
|
||||
|
||||
///* Winbond SPIFalsh ID */
|
||||
//#define W25Q80 0XEF13
|
||||
//#define W25Q16 0XEF14
|
||||
//#define W25Q32 0XEF15
|
||||
//#define W25Q64 0XEF16
|
||||
//#define W25Q128 0XEF17
|
||||
|
||||
while(((dat & 0xEF10) != 0xEF10) && timeout_count) // 判断 ID 是否正确
|
||||
{
|
||||
timeout_count--;
|
||||
|
||||
dat = w25q32_read_device_id();
|
||||
|
||||
system_delay_ms(1);
|
||||
}
|
||||
|
||||
if(timeout_count < 0)
|
||||
{
|
||||
ret = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 初始化 W25Q32
|
||||
// 参数说明 void
|
||||
// 返回参数 uint8 1-初始化失败 0-初始化成功
|
||||
// Sample usage:
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
uint8 w25q32_init(void)
|
||||
{
|
||||
spi_init(W25Q32_SPI, SPI_MODE0, W25Q32_SPI_SPEED, W25Q32_SPC_PIN, W25Q32_SDI_PIN, W25Q32_SDO_PIN, W25Q32_CS_PIN);
|
||||
|
||||
if( w25q32_self_check() )
|
||||
{
|
||||
zf_log(0, "W25Q32 self check error.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
w25q32_write_enable(); // 写使能
|
||||
return 0;
|
||||
}
|
||||
242
libraries/zf_device/zf_device_w25q32.h
Normal file
242
libraries/zf_device/zf_device_w25q32.h
Normal file
@@ -0,0 +1,242 @@
|
||||
/*********************************************************************************************************************
|
||||
* CH32V307VCT6 Opensourec Library 即(CH32V307VCT6 开源库)是一个基于官方 SDK 接口的第三方开源库
|
||||
* Copyright (c) 2022 SEEKFREE 逐飞科技
|
||||
*
|
||||
* 本文件是CH32V307VCT6 开源库的一部分
|
||||
*
|
||||
* CH32V307VCT6 开源库 是免费软件
|
||||
* 您可以根据自由软件基金会发布的 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_w25q32
|
||||
* 公司名称 成都逐飞科技有限公司
|
||||
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
|
||||
* 开发环境 MounRiver Studio V1.8.1
|
||||
* 适用平台 CH32V307VCT6
|
||||
* 店铺链接 https://seekfree.taobao.com/
|
||||
*
|
||||
* 修改记录
|
||||
* 日期 作者 备注
|
||||
* 2022-09-15 大W first version
|
||||
********************************************************************************************************************/
|
||||
/*********************************************************************************************************************
|
||||
* 接线定义:
|
||||
* ------------------------------------
|
||||
* 模块管脚 单片机管脚
|
||||
* //------------------硬件 SPI 引脚------------------//
|
||||
* SPC 查看 zf_device_w25q32.h 中 W25Q32_SPC_PIN 宏定义
|
||||
* SDI 查看 zf_device_w25q32.h 中 W25Q32_SDI_PIN 宏定义
|
||||
* SDO 查看 zf_device_w25q32.h 中 W25Q32_SDO_PIN 宏定义
|
||||
* CS 查看 zf_device_w25q32.h 中 W25Q32_CS_PIN 宏定义
|
||||
* //------------------硬件 SPI 引脚------------------//
|
||||
* 电源引脚
|
||||
* VCC 3.3V电源
|
||||
* GND 电源地
|
||||
* ------------------------------------
|
||||
********************************************************************************************************************/
|
||||
|
||||
#ifndef _zf_device_w25q32_h_
|
||||
#define _zf_device_w25q32_h_
|
||||
|
||||
#include "zf_common_clock.h"
|
||||
#include "zf_common_debug.h"
|
||||
|
||||
#include "zf_driver_delay.h"
|
||||
#include "zf_driver_spi.h"
|
||||
#include "zf_driver_soft_iic.h"
|
||||
|
||||
|
||||
#define W25Q32_BASE_ADDR (0x00000000) // W25Q32FALSH首地址
|
||||
#define W25Q32_PAGE_SIZE (0x00000100) // 256 byte
|
||||
#define W25Q32_SECTION_SIZE (W25Q32_PAGE_SIZE *16) // 4K byte
|
||||
#define W25Q32_BLOCK_SIZE (W25Q32_SECTION_SIZE *16) // 64K byte
|
||||
|
||||
//W25Q32有64个块儿,共64*65536 = 4194304 Byte;4194304/1024/1024 = 4MB,寻址空间:0x000000~0x3FFFFF;
|
||||
|
||||
//所有W25QXX系列FLASH相同点
|
||||
//不同型号的flash有不同数量的块儿,W25Q16有32块儿,W25Q32有64块儿,以此类推;详细见本文“
|
||||
//3.2、W25QXX系列FLASH芯片不同型号的相同点和区别是啥?”
|
||||
//1块儿 = 16扇区
|
||||
//1块儿 = 16 * 16 * 256字节(Byte)= 65536Byte = 64KB(65536Byte/1024=64KB)
|
||||
//1扇区 = 16页
|
||||
//1扇区 = 16 * 256(Byte)= 4096Byte = 4KB
|
||||
//1页 = 256字节
|
||||
|
||||
|
||||
// 枚举 Flash 块区 此枚举定义不允许用户修改
|
||||
typedef enum
|
||||
{
|
||||
W25Q32_BLOCK_00,
|
||||
W25Q32_BLOCK_01,
|
||||
W25Q32_BLOCK_02,
|
||||
W25Q32_BLOCK_03,
|
||||
W25Q32_BLOCK_04,
|
||||
W25Q32_BLOCK_05,
|
||||
W25Q32_BLOCK_06,
|
||||
W25Q32_BLOCK_07,
|
||||
W25Q32_BLOCK_08,
|
||||
W25Q32_BLOCK_09,
|
||||
W25Q32_BLOCK_10,
|
||||
W25Q32_BLOCK_11,
|
||||
W25Q32_BLOCK_12,
|
||||
W25Q32_BLOCK_13,
|
||||
W25Q32_BLOCK_14,
|
||||
W25Q32_BLOCK_15,
|
||||
W25Q32_BLOCK_16,
|
||||
W25Q32_BLOCK_17,
|
||||
W25Q32_BLOCK_18,
|
||||
W25Q32_BLOCK_19,
|
||||
W25Q32_BLOCK_20,
|
||||
W25Q32_BLOCK_21,
|
||||
W25Q32_BLOCK_22,
|
||||
W25Q32_BLOCK_23,
|
||||
W25Q32_BLOCK_24,
|
||||
W25Q32_BLOCK_25,
|
||||
W25Q32_BLOCK_26,
|
||||
W25Q32_BLOCK_27,
|
||||
W25Q32_BLOCK_28,
|
||||
W25Q32_BLOCK_29,
|
||||
W25Q32_BLOCK_30,
|
||||
W25Q32_BLOCK_31,
|
||||
W25Q32_BLOCK_32,
|
||||
W25Q32_BLOCK_33,
|
||||
W25Q32_BLOCK_34,
|
||||
W25Q32_BLOCK_35,
|
||||
W25Q32_BLOCK_36,
|
||||
W25Q32_BLOCK_37,
|
||||
W25Q32_BLOCK_38,
|
||||
W25Q32_BLOCK_39,
|
||||
W25Q32_BLOCK_40,
|
||||
W25Q32_BLOCK_41,
|
||||
W25Q32_BLOCK_42,
|
||||
W25Q32_BLOCK_43,
|
||||
W25Q32_BLOCK_44,
|
||||
W25Q32_BLOCK_45,
|
||||
W25Q32_BLOCK_46,
|
||||
W25Q32_BLOCK_47,
|
||||
W25Q32_BLOCK_48,
|
||||
W25Q32_BLOCK_49,
|
||||
W25Q32_BLOCK_50,
|
||||
W25Q32_BLOCK_51,
|
||||
W25Q32_BLOCK_52,
|
||||
W25Q32_BLOCK_53,
|
||||
W25Q32_BLOCK_54,
|
||||
W25Q32_BLOCK_55,
|
||||
W25Q32_BLOCK_56,
|
||||
W25Q32_BLOCK_57,
|
||||
W25Q32_BLOCK_58,
|
||||
W25Q32_BLOCK_59,
|
||||
W25Q32_BLOCK_60,
|
||||
W25Q32_BLOCK_61,
|
||||
W25Q32_BLOCK_62,
|
||||
W25Q32_BLOCK_63
|
||||
}w25q32_block_enum;
|
||||
|
||||
// 枚举 Flash 扇区 此枚举定义不允许用户修改
|
||||
typedef enum
|
||||
{
|
||||
W25Q32_SECTION_00,
|
||||
W25Q32_SECTION_01,
|
||||
W25Q32_SECTION_02,
|
||||
W25Q32_SECTION_03,
|
||||
W25Q32_SECTION_04,
|
||||
W25Q32_SECTION_05,
|
||||
W25Q32_SECTION_06,
|
||||
W25Q32_SECTION_07,
|
||||
W25Q32_SECTION_08,
|
||||
W25Q32_SECTION_09,
|
||||
W25Q32_SECTION_10,
|
||||
W25Q32_SECTION_11,
|
||||
W25Q32_SECTION_12,
|
||||
W25Q32_SECTION_13,
|
||||
W25Q32_SECTION_14,
|
||||
W25Q32_SECTION_15,
|
||||
}w25q32_section_enum;
|
||||
|
||||
// 枚举 Flash 页索引 此枚举定义不允许用户修改
|
||||
typedef enum
|
||||
{
|
||||
W25Q32_PAGE_00,
|
||||
W25Q32_PAGE_01,
|
||||
W25Q32_PAGE_02,
|
||||
W25Q32_PAGE_03,
|
||||
W25Q32_PAGE_04,
|
||||
W25Q32_PAGE_05,
|
||||
W25Q32_PAGE_06,
|
||||
W25Q32_PAGE_07,
|
||||
W25Q32_PAGE_08,
|
||||
W25Q32_PAGE_09,
|
||||
W25Q32_PAGE_10,
|
||||
W25Q32_PAGE_11,
|
||||
W25Q32_PAGE_12,
|
||||
W25Q32_PAGE_13,
|
||||
W25Q32_PAGE_14,
|
||||
W25Q32_PAGE_15,
|
||||
}w25q32_page_enum;
|
||||
|
||||
//====================================================硬件 SPI 驱动====================================================
|
||||
#define W25Q32_SPI_SPEED system_clock/8 // 硬件 SPI 速率
|
||||
#define W25Q32_SPI SPI_3 // 硬件 SPI 号
|
||||
#define W25Q32_SPC_PIN SPI1_MAP1_SCK_B3 // 硬件 SPI SCK 引脚
|
||||
#define W25Q32_SDI_PIN SPI1_MAP1_MISO_B4 // 硬件 SPI MOSI 引脚
|
||||
#define W25Q32_SDO_PIN SPI1_MAP1_MOSI_B5 // 硬件 SPI MISO 引脚
|
||||
//====================================================硬件 SPI 驱动====================================================
|
||||
#define W25Q32_CS_PIN A15 // CS 片选引脚
|
||||
#define W25Q32_CS(x) (x? (gpio_high(W25Q32_CS_PIN)): (gpio_low(W25Q32_CS_PIN)))
|
||||
|
||||
#define W25Q32_TIMEOUT_COUNT 0x00FF
|
||||
|
||||
//================================================定义 ICM20602 内部地址================================================
|
||||
#define W25Q32_WRITE_ENABLE 0x06
|
||||
#define W25Q32_WRITE_DISABLE 0x04
|
||||
|
||||
#define W25Q32_READ_STATUS_REG_1 0x05
|
||||
#define W25Q32_READ_STATUS_REG_2 0x35
|
||||
#define W25Q32_READ_STATUS_REG_3 0x15
|
||||
#define W25Q32_WRITE_STATUS_REG_1 0x01
|
||||
#define W25Q32_WRITE_STATUS_REG_2 0x31
|
||||
#define W25Q32_WRITE_STATUS_REG_3 0x11
|
||||
#define W25Q32_PAGE_PROGRAM 0x02
|
||||
#define W25Q32_READ_DATA 0x03
|
||||
#define W25Q32_FAST_READ 0x0B
|
||||
#define W25Q32_SECTOR_ERASE 0x20
|
||||
#define W25Q32_32KB_BLOCK_ERASE 0x52
|
||||
#define W25Q32_64KB_BLOCK_ERASE 0xD8
|
||||
#define W25Q32_CHIP_ERASE 0xC7
|
||||
#define W25Q32_SUSPEND 0x75
|
||||
#define W25Q32_RESUME 0x7A
|
||||
#define W25Q32_READ_UID 0x4B
|
||||
#define W25Q32_JEDEC_ID 0x9F // W25Q32 返回0xEF40
|
||||
#define W25Q32_DEVICE_ID 0x90 // W25Q32 返回0xEF15
|
||||
#define W25Q32_RESET_ENABLE 0x66
|
||||
#define W25Q32_RESET_DEVICE 0x99
|
||||
//================================================定义 ICM20602 内部地址================================================
|
||||
|
||||
|
||||
void w25q32_erase_chip(void);
|
||||
uint8 w25q32_check (w25q32_block_enum block_num, w25q32_section_enum sector_num, w25q32_page_enum page_num);
|
||||
uint8 w25q32_erase_sector (w25q32_block_enum block_num, w25q32_section_enum sector_num);
|
||||
|
||||
void w25q32_read_page (w25q32_block_enum block_num, w25q32_section_enum sector_num, w25q32_page_enum page_num,
|
||||
uint8 *buf, uint16 len);
|
||||
|
||||
void w25q32_write_page (w25q32_block_enum block_num, w25q32_section_enum sector_num, w25q32_page_enum page_num,
|
||||
uint8 *buf, uint16 len);
|
||||
uint8 w25q32_init();
|
||||
|
||||
//SPI_FLASH写使能
|
||||
|
||||
#endif
|
||||
1381
libraries/zf_device/zf_device_wifi_spi.c
Normal file
1381
libraries/zf_device/zf_device_wifi_spi.c
Normal file
File diff suppressed because it is too large
Load Diff
182
libraries/zf_device/zf_device_wifi_spi.h
Normal file
182
libraries/zf_device/zf_device_wifi_spi.h
Normal file
@@ -0,0 +1,182 @@
|
||||
/*********************************************************************************************************************
|
||||
* CH32V307VCT6 Opensourec Library 即(CH32V307VCT6 开源库)是一个基于官方 SDK 接口的第三方开源库
|
||||
* Copyright (c) 2022 SEEKFREE 逐飞科技
|
||||
*
|
||||
* 本文件是CH32V307VCT6 开源库的一部分
|
||||
*
|
||||
* CH32V307VCT6 开源库 是免费软件
|
||||
* 您可以根据自由软件基金会发布的 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 文件 版本说明
|
||||
* 开发环境 MounRiver Studio V1.8.1
|
||||
* 适用平台 CH32V307VCT6
|
||||
* 店铺链接 https://seekfree.taobao.com/
|
||||
*
|
||||
* 修改记录
|
||||
* 日期 作者 备注
|
||||
* 2023-05-25 大W 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_2 ) // 定义使用的SPI号
|
||||
#define WIFI_SPI_SPEED ( 20 * 1000 * 1000) // 硬件 SPI 速率
|
||||
#define WIFI_SPI_SCK_PIN ( SPI2_MAP0_SCK_B13 ) // 定义SPI_SCK引脚
|
||||
#define WIFI_SPI_MOSI_PIN ( SPI2_MAP0_MOSI_B15 ) // 定义SPI_MOSI引脚
|
||||
#define WIFI_SPI_MISO_PIN ( SPI2_MAP0_MISO_B14 ) // 定义SPI_MISO引脚 IPS没有MISO引脚,但是这里任然需要定义,在spi的初始化时需要使用
|
||||
#define WIFI_SPI_CS_PIN ( C0 ) // 定义SPI_CS引脚 采用软件CS引脚
|
||||
#define WIFI_SPI_INT_PIN ( C1 ) // 定义中断引脚
|
||||
#define WIFI_SPI_RST_PIN ( A7 ) // 定义复位引脚
|
||||
|
||||
|
||||
#define WIFI_SPI_BUFFER_SIZE ( 1024 ) // 定义SPI接收的缓冲区大小
|
||||
|
||||
#define WIFI_SPI_AUTO_CONNECT ( 0 ) // 定义是否初始化时建立TCP或者UDP连接 0-不连接 1-自动连接TCP服务器并进入透传模式 2-自动连接UDP服务器并进入透传模式 3:自动建立TCP服务器
|
||||
|
||||
#if (WIFI_SPI_AUTO_CONNECT > 2)
|
||||
#error "WIFI_SPI_AUTO_CONNECT 的值只能为 [0,1,2]"
|
||||
#else
|
||||
#define WIFI_SPI_TARGET_IP "192.168.2.52" // 连接目标的 IP
|
||||
#define WIFI_SPI_TARGET_PORT "8080" // 连接目标的端口
|
||||
#define WIFI_SPI_LOCAL_PORT "8080" // 本机端口
|
||||
#endif
|
||||
|
||||
#define WIFI_SPI_MAX_MULTI ( 8 ) // 多地址发送,最大8个地址
|
||||
|
||||
typedef enum
|
||||
{
|
||||
BUFFER_IDLE, // 模块的缓冲区是空闲的
|
||||
BUFFER_READ, // 模块的缓冲区有数据需要读取
|
||||
BUFFER_WRITE, // 模块的缓冲区是可写的
|
||||
}wifi_spi_buffer_state_enum;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TRANSMIT_IDLE, // 当前没有传输
|
||||
TRANSMIT_WRITE_REQUEST, // 给模块发送了一个传输请求
|
||||
TRANSMIT_READ_STATE, // 读取模块状态
|
||||
TRANSMIT_READ, // 正在读取模块内部数据
|
||||
TRANSMIT_WRITE, // 正在往模块写入数据
|
||||
}wifi_spi_transmit_state_enum;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
WIFI_SPI_STATION, // 设备模式
|
||||
WIFI_SPI_SOFTAP, // AP模式
|
||||
}wifi_spi_mode_enum;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
WIFI_SPI_COMMAND, // 使用命令的方式发送数据
|
||||
WIFI_SPI_SERIANET, // 使用透传的方式发送数据
|
||||
}wifi_spi_transfer_mode_enum;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
WIFI_SPI_TCP_CLIENT, // 模块连接TCP服务器
|
||||
WIFI_SPI_TCP_SERVER, // 模块作为TCP服务器
|
||||
WIFI_SPI_UDP_CLIENT, // 模块启用UDP连接
|
||||
}wifi_spi_connect_mode_enum;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
WIFI_SPI_SERVER_OFF, // 模块未连接服务器
|
||||
WIFI_SPI_SERVER_ON, // 模块已经连接服务器
|
||||
}wifi_spi_connect_state_enum;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
WIFI_SPI_LINK_0, // 模块当前链接 0
|
||||
WIFI_SPI_LINK_1, // 模块当前链接 1
|
||||
WIFI_SPI_LINK_2, // 模块当前链接 2
|
||||
WIFI_SPI_LINK_3, // 模块当前链接 3
|
||||
WIFI_SPI_LINK_4, // 模块当前链接 4
|
||||
}wifi_spi_link_id_enum;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8 reserve;
|
||||
uint8 cmd;
|
||||
uint8 addr;
|
||||
uint8 dummy;
|
||||
uint8 magic;
|
||||
uint8 sequence;
|
||||
uint16 length;
|
||||
}wifi_spi_buffer_struct;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8 version[12]; // 固件版本 字符串形式
|
||||
uint8 mac[20]; // 本机 MAC 地址 字符串形式
|
||||
uint8 local_ip[17]; // 本机 IP 地址 字符串形式
|
||||
uint8 local_port[10]; // 本机端口号 字符串形式
|
||||
uint8 remote_ip[5][17]; // 远端 IP 地址 字符串形式
|
||||
wifi_spi_mode_enum mode; // WIFI 模式
|
||||
wifi_spi_transfer_mode_enum transfer_mode; // 当前传输模式
|
||||
wifi_spi_connect_mode_enum connect_mode; // 网络连接模式
|
||||
wifi_spi_connect_state_enum connect_state; // 服务器连接情况
|
||||
}wifi_spi_information_struct;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8 *source[WIFI_SPI_MAX_MULTI];
|
||||
uint16 length[WIFI_SPI_MAX_MULTI];
|
||||
}wifi_spi_send_multi_struct;
|
||||
|
||||
extern wifi_spi_information_struct wifi_spi_information;
|
||||
|
||||
|
||||
uint8 wifi_spi_disconnected_wifi (void); // 断开 WIFI 连接
|
||||
uint8 wifi_spi_entry_serianet (void); // 打开透传模式
|
||||
uint8 wifi_spi_exit_serianet (void); // 关闭透传模式
|
||||
|
||||
uint8 wifi_spi_connect_tcp_servers (char *ip, char *port, wifi_spi_transfer_mode_enum mode); // 建立 TCP 连接
|
||||
uint8 wifi_spi_connect_udp_client (char *ip, char *port, char *local_port, wifi_spi_transfer_mode_enum mode); // 建立 UDP 传输
|
||||
uint8 wifi_spi_disconnect_link (void); // 断开连接 TCP Server 使用本接口将会断开所有连接
|
||||
|
||||
|
||||
uint32 wifi_spi_send_byte (uint8 data); // WIFI 模块发送字节函数
|
||||
uint32 wifi_spi_send_buffer (const uint8 *buff, uint32 length); // WIFI 模块发送缓冲区函数
|
||||
uint32 wifi_spi_send_buffer_multi (wifi_spi_send_multi_struct *multi_buffer); // WIFI 模块发送多缓冲区函数
|
||||
uint32 wifi_spi_send_string (const char *str); // WIFI 模块发送字符串函数
|
||||
|
||||
uint32 wifi_spi_read_buffer (uint8 *buff, uint32 len); // WIFI 模块数据接收函数
|
||||
|
||||
uint8 wifi_spi_init (char *wifi_ssid, char *pass_word, wifi_spi_mode_enum wifi_mode); // WIFI 模块初始化函数
|
||||
|
||||
#endif
|
||||
|
||||
1213
libraries/zf_device/zf_device_wifi_uart.c
Normal file
1213
libraries/zf_device/zf_device_wifi_uart.c
Normal file
File diff suppressed because it is too large
Load Diff
147
libraries/zf_device/zf_device_wifi_uart.h
Normal file
147
libraries/zf_device/zf_device_wifi_uart.h
Normal file
@@ -0,0 +1,147 @@
|
||||
/*********************************************************************************************************************
|
||||
* CH32V307VCT6 Opensourec Library 即(CH32V307VCT6 开源库)是一个基于官方 SDK 接口的第三方开源库
|
||||
* Copyright (c) 2022 SEEKFREE 逐飞科技
|
||||
*
|
||||
* 本文件是CH32V307VCT6 开源库的一部分
|
||||
*
|
||||
* CH32V307VCT6 开源库 是免费软件
|
||||
* 您可以根据自由软件基金会发布的 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 文件 版本说明
|
||||
* 开发环境 MounRiver Studio V1.8.1
|
||||
* 适用平台 CH32V307VCT6
|
||||
* 店铺链接 https://seekfree.taobao.com/
|
||||
*
|
||||
* 修改记录
|
||||
* 日期 作者 备注
|
||||
* 2022-09-15 大W first version
|
||||
********************************************************************************************************************/
|
||||
/*********************************************************************************************************************
|
||||
* 接线定义:
|
||||
* ------------------------------------
|
||||
* 模块管脚 单片机管脚
|
||||
* RX 查看 zf_device_wifi_uart.h 中 WIFI_UART_RX_PIN 宏定义
|
||||
* TX 查看 zf_device_wifi_uart.h 中 WIFI_UART_TX_PIN 宏定义
|
||||
* RTS 查看 zf_device_wifi_uart.h 中 WIFI_UART_RTS_PIN 宏定义
|
||||
* RST 查看 zf_device_wifi_uart.h 中 WIFI_UART_RST_PIN 宏定义
|
||||
* VCC 5V 电源
|
||||
* GND 电源地
|
||||
* 其余引脚悬空
|
||||
* ------------------------------------
|
||||
*********************************************************************************************************************/
|
||||
#ifndef _zf_device_wifi_uart_h_
|
||||
#define _zf_device_wifi_uart_h_
|
||||
|
||||
#include "zf_common_typedef.h"
|
||||
|
||||
#define WIFI_UART_INDEX (UART_7) // WIFI 模块 所使用到的串口
|
||||
#define WIFI_UART_RX_PIN (UART7_MAP3_TX_E12) // 连接 WIFI 模块 RX
|
||||
#define WIFI_UART_TX_PIN (UART7_MAP3_RX_E13) // 连接 WIFI 模块 TX
|
||||
#define WIFI_UART_BAUD (115200) // 模块工作波特率
|
||||
|
||||
#define WIFI_UART_RTS_PIN (E8) // 定义流控位引脚 指示当前模块是否可以接受数据 0-可以继续接收 1-不可以继续接收
|
||||
#define WIFI_UART_HARDWARE_RST (0) // 定义是否使用硬件复位引脚 0-使用软件复位 1-使用硬件 RST
|
||||
#if WIFI_UART_HARDWARE_RST // 建议使用硬件复位引脚 否则容易出现单片机复位后无法正常初始化模块
|
||||
#define WIFI_UART_RST_PIN (D10) // 定义硬件复位引脚
|
||||
#endif
|
||||
|
||||
#define WIFI_UART_BUFFER_SIZE (256) // 定义接收缓存区大小
|
||||
|
||||
#define WIFI_UART_AUTO_CONNECT (0) // 定义是否初始化时建立TCP或者UDP连接 0-不连接 1-自动连接TCP服务器 2-自动连接UDP服务器 3:自动建立TCP服务器
|
||||
|
||||
#if (WIFI_UART_AUTO_CONNECT > 3)
|
||||
#error "WIFI_UART_AUTO_CONNECT 的值只能为 [0,1,2,3]"
|
||||
#else
|
||||
#define WIFI_UART_TARGET_IP "192.168.2.32" // 连接目标的 IP
|
||||
#define WIFI_UART_TARGET_PORT "8080" // 连接目标的端口
|
||||
#define WIFI_UART_LOCAL_PORT "8080" // 本机端口
|
||||
#endif
|
||||
|
||||
typedef enum
|
||||
{
|
||||
WIFI_UART_STATION, // 设备模式
|
||||
WIFI_UART_SOFTAP, // AP模式
|
||||
}wifi_uart_mode_enum;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
WIFI_UART_COMMAND, // 使用命令的方式发送数据
|
||||
WIFI_UART_SERIANET, // 使用透传的方式发送数据
|
||||
}wifi_uart_transfer_mode_enum;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
WIFI_UART_TCP_CLIENT, // 模块连接TCP服务器
|
||||
WIFI_UART_TCP_SERVER, // 模块作为TCP服务器
|
||||
WIFI_UART_UDP_CLIENT, // 模块启用UDP连接
|
||||
}wifi_uart_connect_mode_enum;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
WIFI_UART_SERVER_OFF, // 模块未连接服务器
|
||||
WIFI_UART_SERVER_ON, // 模块已经连接服务器
|
||||
}wifi_uart_connect_state_enum;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
WIFI_UART_LINK_0, // 模块当前链接 0
|
||||
WIFI_UART_LINK_1, // 模块当前链接 1
|
||||
WIFI_UART_LINK_2, // 模块当前链接 2
|
||||
WIFI_UART_LINK_3, // 模块当前链接 3
|
||||
WIFI_UART_LINK_4, // 模块当前链接 4
|
||||
}wifi_uart_link_id_enum;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8 wifi_uart_version[12]; // 固件版本 字符串形式
|
||||
uint8 wifi_uart_mac[20]; // 本机 MAC 地址 字符串形式
|
||||
uint8 wifi_uart_local_ip[17]; // 本机 IP 地址 字符串形式
|
||||
uint8 wifi_uart_local_port[10]; // 本机端口号 字符串形式
|
||||
uint8 wifi_uart_remote_ip[5][15]; // 远端 IP 地址 字符串形式
|
||||
wifi_uart_mode_enum wifi_uart_mode; // WIFI 模式
|
||||
wifi_uart_transfer_mode_enum wifi_uart_transfer_mode; // 当前传输模式
|
||||
wifi_uart_connect_mode_enum wifi_uart_connect_mode; // 网络连接模式
|
||||
wifi_uart_connect_state_enum wifi_uart_connect_state; // 服务器连接情况
|
||||
}wifi_uart_information_struct;
|
||||
|
||||
extern wifi_uart_information_struct wifi_uart_information;
|
||||
|
||||
|
||||
uint8 wifi_uart_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 *buffer, uint32 len); // WIFI 模块数据发送函数
|
||||
uint32 wifi_uart_tcp_servers_send_buffer (uint8 *buff, uint32 len, wifi_uart_link_id_enum id); // WIFI 模块作为 TCP Server 指定目标设备发送函数
|
||||
uint32 wifi_uart_read_buffer (uint8 *buffer, uint32 len); // WIFI 模块数据接收函数
|
||||
|
||||
void wifi_uart_callback (void); // WIFI 模块串口回调函数
|
||||
uint8 wifi_uart_init (char *wifi_ssid, char *pass_word, wifi_uart_mode_enum wifi_mode); // WIFI 模块初始化函数
|
||||
|
||||
|
||||
#endif
|
||||
181
libraries/zf_device/zf_device_wireless_ch573.c
Normal file
181
libraries/zf_device/zf_device_wireless_ch573.c
Normal file
@@ -0,0 +1,181 @@
|
||||
/*********************************************************************************************************************
|
||||
* CH32V307VCT6 Opensourec Library 即(CH32V307VCT6 开源库)是一个基于官方 SDK 接口的第三方开源库
|
||||
* Copyright (c) 2022 SEEKFREE 逐飞科技
|
||||
*
|
||||
* 本文件是CH32V307VCT6 开源库的一部分
|
||||
*
|
||||
* CH32V307VCT6 开源库 是免费软件
|
||||
* 您可以根据自由软件基金会发布的 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_ch573
|
||||
* 公司名称 成都逐飞科技有限公司
|
||||
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
|
||||
* 开发环境 MounRiver Studio V1.8.1
|
||||
* 适用平台 CH32V307VCT6
|
||||
* 店铺链接 https://seekfree.taobao.com/
|
||||
*
|
||||
* 修改记录
|
||||
* 日期 作者 备注
|
||||
* 2022-09-15 大W first version
|
||||
********************************************************************************************************************/
|
||||
/*********************************************************************************************************************
|
||||
* 接线定义:
|
||||
* ------------------------------------
|
||||
* 模块管脚 单片机管脚
|
||||
* RX 查看 zf_device_wireless_ch573.h 中 WIRELESS_CH573_RX_PIN 宏定义
|
||||
* TX 查看 zf_device_wireless_ch573.h 中 WIRELESS_CH573_TX_PIN 宏定义
|
||||
* RTS 查看 zf_device_wireless_ch573.h 中 WIRELESS_CH573_RTS_PIN 宏定义
|
||||
* VCC 5V 电源
|
||||
* GND 电源地
|
||||
* 其余引脚悬空
|
||||
* ------------------------------------
|
||||
*********************************************************************************************************************/
|
||||
|
||||
#include "zf_common_fifo.h"
|
||||
#include "zf_device_type.h"
|
||||
#include "zf_device_wireless_ch573.h"
|
||||
|
||||
static fifo_struct wireless_ch573_fifo;
|
||||
static uint8 wireless_ch573_buffer[WIRELESS_CH573_BUFFER_SIZE]; // 对应第一个 无线串口 数据存放数组
|
||||
|
||||
static uint8 wireless_ch573_data;
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 CH573无线模块中断回调函数
|
||||
// 参数说明 void
|
||||
// 返回参数 void
|
||||
// Sample usage:
|
||||
// @note
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
void wireless_ch573_callback (void)
|
||||
{
|
||||
uart_query_byte(WIRELESS_CH573_INDEX, &wireless_ch573_data);
|
||||
fifo_write_buffer(&wireless_ch573_fifo, &wireless_ch573_data, 1);
|
||||
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 无线转串口模块 发送数据
|
||||
// 参数说明 data 8bit 数据
|
||||
// 返回参数 uint32 剩余发送长度
|
||||
// Sample usage:
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
uint32 wireless_ch573_send_byte (const uint8 data)
|
||||
{
|
||||
uint16 time_count = 0;
|
||||
while(gpio_get_level(WIRELESS_CH573_RTS_PIN)) // 如果RTS为低电平,则继续发送数据
|
||||
{
|
||||
if(time_count++ > WIRELESS_CH573_TIMEOUT_COUNT)
|
||||
return 1; // 模块忙,如果允许当前程序使用while等待 则可以使用后面注释的while等待语句替换本if语句
|
||||
system_delay_ms(1);
|
||||
}
|
||||
uart_write_byte(WIRELESS_CH573_INDEX, data); // 发送最后的数据
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 CH573无线模块 串口发送数据
|
||||
// 参数说明 buff 数据地址
|
||||
// 参数说明 len 数据长度
|
||||
// 返回参数 uint32 提示信息
|
||||
// Sample usage:
|
||||
// @note
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
uint32 wireless_ch573_send_buff (const uint8 *buff, uint32 len)
|
||||
{
|
||||
uint16 time_count = 0;
|
||||
uint8 pack_len = 62;
|
||||
while(len > pack_len)
|
||||
{
|
||||
time_count = 0;
|
||||
while(gpio_get_level(WIRELESS_CH573_RTS_PIN) && time_count++ < WIRELESS_CH573_TIMEOUT_COUNT) // 如果RTS为低电平,则继续发送数据
|
||||
system_delay_ms(1);
|
||||
if(time_count >= WIRELESS_CH573_TIMEOUT_COUNT)
|
||||
return len; // 模块忙,如果允许当前程序使用while等待 则可以使用后面注释的while等待语句替换本if语句
|
||||
uart_write_buffer(WIRELESS_CH573_INDEX, buff, 30);
|
||||
|
||||
buff += pack_len; // 地址偏移
|
||||
len -= pack_len; // 数量
|
||||
}
|
||||
|
||||
time_count = 0;
|
||||
while(gpio_get_level(WIRELESS_CH573_RTS_PIN) && time_count++ < WIRELESS_CH573_TIMEOUT_COUNT) // 如果RTS为低电平,则继续发送数据
|
||||
system_delay_ms(1);
|
||||
if(time_count >= WIRELESS_CH573_TIMEOUT_COUNT)
|
||||
return len; // 模块忙,如果允许当前程序使用while等待 则可以使用后面注释的while等待语句替换本if语句
|
||||
uart_write_buffer(WIRELESS_CH573_INDEX, buff, len); // 发送最后的数据
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 CH573无线模块 串口接收数据
|
||||
// 参数说明 buff 数据地址
|
||||
// 参数说明 len 数据长度
|
||||
// 返回参数 void
|
||||
// Sample usage:
|
||||
// @note
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
uint32 wireless_ch573_read_buff (uint8 *buff, uint32 len)
|
||||
{
|
||||
uint32 data_len = len;
|
||||
fifo_read_buffer(&wireless_ch573_fifo, buff, &data_len, FIFO_READ_AND_CLEAN);
|
||||
return data_len;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 无线转串口模块 发送摄像头图像至上位机查看图像
|
||||
// 参数说明 *image_addr 需要发送的图像地址
|
||||
// 参数说明 image_size 图像的大小
|
||||
// 返回参数 void
|
||||
// 使用示例 wireless_uart_send_image(&mt9v03x_image[0][0], MT9V03X_IMAGE_SIZE);
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
void wireless_ch573_send_image (const uint8 *image_addr, uint32 image_size)
|
||||
{
|
||||
extern uint8 camera_send_image_frame_header[4];
|
||||
wireless_ch573_send_buff(camera_send_image_frame_header, 4);
|
||||
wireless_ch573_send_buff((uint8 *)image_addr, image_size);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 函数简介 CH573无线模块初始化
|
||||
// 参数说明 void
|
||||
// 返回参数 void
|
||||
// Sample usage:
|
||||
// @note
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
uint8 wireless_ch573_init (void)
|
||||
{
|
||||
|
||||
set_wireless_type(WIRELESS_CH573, wireless_ch573_callback);
|
||||
|
||||
|
||||
|
||||
fifo_init(&wireless_ch573_fifo, FIFO_DATA_8BIT, wireless_ch573_buffer, WIRELESS_CH573_BUFFER_SIZE);
|
||||
gpio_init(WIRELESS_CH573_RTS_PIN, GPI, GPIO_HIGH, GPI_PULL_UP);
|
||||
|
||||
uart_init (WIRELESS_CH573_INDEX, WIRELESS_CH573_BUAD_RATE, WIRELESS_CH573_RX_PIN, WIRELESS_CH573_TX_PIN);
|
||||
uart_rx_interrupt(WIRELESS_CH573_INDEX, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
80
libraries/zf_device/zf_device_wireless_ch573.h
Normal file
80
libraries/zf_device/zf_device_wireless_ch573.h
Normal file
@@ -0,0 +1,80 @@
|
||||
/*********************************************************************************************************************
|
||||
* CH32V307VCT6 Opensourec Library 即(CH32V307VCT6 开源库)是一个基于官方 SDK 接口的第三方开源库
|
||||
* Copyright (c) 2022 SEEKFREE 逐飞科技
|
||||
*
|
||||
* 本文件是CH32V307VCT6 开源库的一部分
|
||||
*
|
||||
* CH32V307VCT6 开源库 是免费软件
|
||||
* 您可以根据自由软件基金会发布的 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_ch573
|
||||
* 公司名称 成都逐飞科技有限公司
|
||||
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
|
||||
* 开发环境 MounRiver Studio V1.8.1
|
||||
* 适用平台 CH32V307VCT6
|
||||
* 店铺链接 https://seekfree.taobao.com/
|
||||
*
|
||||
* 修改记录
|
||||
* 日期 作者 备注
|
||||
* 2022-09-15 大W first version
|
||||
********************************************************************************************************************/
|
||||
/*********************************************************************************************************************
|
||||
* 接线定义:
|
||||
* ------------------------------------
|
||||
* 模块管脚 单片机管脚
|
||||
* RX 查看 zf_device_wireless_ch573.h 中 WIRELESS_CH573_RX_PIN 宏定义
|
||||
* TX 查看 zf_device_wireless_ch573.h 中 WIRELESS_CH573_TX_PIN 宏定义
|
||||
* RTS 查看 zf_device_wireless_ch573.h 中 WIRELESS_CH573_RTS_PIN 宏定义
|
||||
* VCC 5V 电源
|
||||
* GND 电源地
|
||||
* 其余引脚悬空
|
||||
* ------------------------------------
|
||||
*********************************************************************************************************************/
|
||||
|
||||
|
||||
#ifndef _zf_device_wireless_ch573_h_
|
||||
#define _zf_device_wireless_ch573_
|
||||
|
||||
|
||||
#include "zf_driver_gpio.h"
|
||||
#include "zf_driver_uart.h"
|
||||
#include "zf_driver_delay.h"
|
||||
|
||||
|
||||
|
||||
#define WIRELESS_CH573_NUMBER 1 // 定义接入的CH573无线模块的数量 默认最大就三个
|
||||
#define WIRELESS_CH573_INDEX UART_2 // CH573无线模块1 对应使用的串口号
|
||||
#define WIRELESS_CH573_BUAD_RATE 115200 // CH573无线模块1 对应使用的串口波特率
|
||||
#define WIRELESS_CH573_TX_PIN UART2_MAP1_RX_D6 // CH573无线模块1 对应模块的 TX 要接到单片机的 RX
|
||||
#define WIRELESS_CH573_RX_PIN UART2_MAP1_TX_D5 // CH573无线模块1 对应模块的 RX 要接到单片机的 TX
|
||||
#define WIRELESS_CH573_RTS_PIN E10 // CH573无线模块1 对应模块的 RTS 引脚
|
||||
|
||||
|
||||
#define WIRELESS_CH573_BUFFER_SIZE 64
|
||||
#define WIRELESS_CH573_TIMEOUT_COUNT 0x64
|
||||
|
||||
|
||||
|
||||
void wireless_ch573_callback (void);
|
||||
uint32 wireless_ch573_send_byte (const uint8 data);
|
||||
uint32 wireless_ch573_send_buff (const uint8 *buff, uint32 len);
|
||||
uint32 wireless_ch573_send_string (const uint8 *str);
|
||||
void wireless_ch573_send_image (const uint8 *image_addr, uint32 image_size);
|
||||
uint32 wireless_ch573_read_buff (uint8 *buff, uint32 len);
|
||||
uint8 wireless_ch573_init (void);
|
||||
|
||||
#endif
|
||||
295
libraries/zf_device/zf_device_wireless_uart.c
Normal file
295
libraries/zf_device/zf_device_wireless_uart.c
Normal file
@@ -0,0 +1,295 @@
|
||||
/*********************************************************************************************************************
|
||||
* CH32V307VCT6 Opensourec Library 即(CH32V307VCT6 开源库)是一个基于官方 SDK 接口的第三方开源库
|
||||
* Copyright (c) 2022 SEEKFREE 逐飞科技
|
||||
*
|
||||
* 本文件是CH32V307VCT6 开源库的一部分
|
||||
*
|
||||
* CH32V307VCT6 开源库 是免费软件
|
||||
* 您可以根据自由软件基金会发布的 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 文件 版本说明
|
||||
* 开发环境 MounRiver Studio V1.8.1
|
||||
* 适用平台 CH32V307VCT6
|
||||
* 店铺链接 https://seekfree.taobao.com/
|
||||
*
|
||||
* 修改记录
|
||||
* 日期 作者 备注
|
||||
* 2022-09-15 大W first version
|
||||
********************************************************************************************************************/
|
||||
/*********************************************************************************************************************
|
||||
* 接线定义:
|
||||
* ------------------------------------
|
||||
* 模块管脚 单片机管脚
|
||||
* RX 查看 zf_device_wireless_uart.h 中 WIRELESS_UART_RX_PIN 宏定义
|
||||
* TX 查看 zf_device_wireless_uart.h 中 WIRELESS_UART_TX_PIN 宏定义
|
||||
* RTS 查看 zf_device_wireless_uart.h 中 WIRELESS_UART_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_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;
|
||||
}
|
||||
100
libraries/zf_device/zf_device_wireless_uart.h
Normal file
100
libraries/zf_device/zf_device_wireless_uart.h
Normal file
@@ -0,0 +1,100 @@
|
||||
/*********************************************************************************************************************
|
||||
* CH32V307VCT6 Opensourec Library 即(CH32V307VCT6 开源库)是一个基于官方 SDK 接口的第三方开源库
|
||||
* Copyright (c) 2022 SEEKFREE 逐飞科技
|
||||
*
|
||||
* 本文件是CH32V307VCT6 开源库的一部分
|
||||
*
|
||||
* CH32V307VCT6 开源库 是免费软件
|
||||
* 您可以根据自由软件基金会发布的 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.h
|
||||
* 公司名称 成都逐飞科技有限公司
|
||||
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
|
||||
* 开发环境 MounRiver Studio V1.8.1
|
||||
* 适用平台 CH32V307VCT6
|
||||
* 店铺链接 https://seekfree.taobao.com/
|
||||
*
|
||||
* 修改记录
|
||||
* 日期 作者 备注
|
||||
* 2022-09-15 大W first version
|
||||
********************************************************************************************************************/
|
||||
/*********************************************************************************************************************
|
||||
* 接线定义:
|
||||
* ------------------------------------
|
||||
* 模块管脚 单片机管脚
|
||||
* RX 查看 zf_device_wireless_uart.h 中 WIRELESS_UART_RX_PIN 宏定义
|
||||
* TX 查看 zf_device_wireless_uart.h 中 WIRELESS_UART_TX_PIN 宏定义
|
||||
* RTS 查看 zf_device_wireless_uart.h 中 WIRELESS_UART_RTS_PIN 宏定义
|
||||
* 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_7 // 无线串口对应使用的串口号
|
||||
#define WIRELESS_UART_BUAD_RATE 115200 // 无线串口对应使用的串口波特率
|
||||
#define WIRELESS_UART_TX_PIN UART7_MAP3_RX_E13 // 无线串口对应模块的 TX 要接到单片机的 RX
|
||||
#define WIRELESS_UART_RX_PIN UART7_MAP3_TX_E12 // 无线串口对应模块的 RX 要接到单片机的 TX
|
||||
#define WIRELESS_UART_RTS_PIN E8 // 无线串口对应模块的 RTS 引脚
|
||||
|
||||
|
||||
// ------------------------------------ 自动波特率 ------------------------------------
|
||||
// 注意事项1:无线转串口模块版本是V2.0以下的是无法开启自动波特率的。
|
||||
// 注意事项2:开启自动波特率务必连接RTS引脚 否则会开启失败。
|
||||
// 注意事项3:模块自动波特率失败的话 可以尝试断电重启
|
||||
|
||||
// 开启自动波特率务必阅读上面两条 注意事项
|
||||
// 开启自动波特率务必阅读上面两条 注意事项
|
||||
// 开启自动波特率务必阅读上面两条 注意事项
|
||||
|
||||
// 0:关闭自动波特率
|
||||
// 1:开启自动波特率 自动波特率的作用是修改 WIRELESS_UART_BAUD 之后不需要对模块进行配置 模块会自动设置为对应的波特率
|
||||
|
||||
#define WIRELESS_UART_AUTO_BAUD_RATE ( 0 )
|
||||
|
||||
#if (1 == WIRELESS_UART_AUTO_BAUD_RATE)
|
||||
typedef enum
|
||||
{
|
||||
WIRELESS_UART_AUTO_BAUD_RATE_SUCCESS,
|
||||
WIRELESS_UART_AUTO_BAUD_RATE_INIT,
|
||||
WIRELESS_UART_AUTO_BAUD_RATE_START,
|
||||
WIRELESS_UART_AUTO_BAUD_RATE_GET_ACK,
|
||||
}wireless_uart_auto_baudrate_state_enum;
|
||||
#endif
|
||||
// ------------------------------------ 自动波特率 ------------------------------------
|
||||
|
||||
#define WIRELESS_UART_BUFFER_SIZE ( 64 )
|
||||
#define WIRELESS_UART_TIMEOUT_COUNT ( 0x64 )
|
||||
|
||||
uint32 wireless_uart_send_byte (const uint8 data);
|
||||
uint32 wireless_uart_send_buffer (const uint8 *buff, uint32 len);
|
||||
uint32 wireless_uart_send_string (const char *str);
|
||||
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
|
||||
Reference in New Issue
Block a user