feat: 完成按键、屏幕和蜂鸣器适配

This commit is contained in:
2024-01-31 17:20:09 +08:00
parent 7181da95de
commit 64e95d278c
31 changed files with 385 additions and 1338 deletions

29
app/by_button.c Normal file
View File

@@ -0,0 +1,29 @@
#include "by_button.h"
#include "zf_common_headfile.h"
button_event_t button_event;
void by_button_init(void)
{
gpio_init(BUTTON_LEFT_PIN, GPI, 1, GPI_PULL_UP);
gpio_init(BUTTON_DOWN_PIN, GPI, 1, GPI_PULL_UP);
gpio_init(BUTTON_UP_PIN, GPI, 1, GPI_PULL_UP);
gpio_init(BUTTON_CENTER_PIN, GPI, 1, GPI_PULL_UP);
gpio_init(BUTTON_RIGHT_PIN, GPI, 1, GPI_PULL_UP);
gpio_init(BUTTON_SIDE_PIN, GPI, 1, GPI_PULL_UP);
exti_init(BUTTON_LEFT_PIN, EXTI_TRIGGER_FALLING);
exti_init(BUTTON_DOWN_PIN, EXTI_TRIGGER_FALLING);
exti_init(BUTTON_UP_PIN, EXTI_TRIGGER_FALLING);
exti_init(BUTTON_CENTER_PIN, EXTI_TRIGGER_BOTH);
exti_init(BUTTON_RIGHT_PIN, EXTI_TRIGGER_FALLING);
exti_init(BUTTON_SIDE_PIN, EXTI_TRIGGER_FALLING);
}
uint8_t by_button_get_status(void)
{
uint8_t temp_s = (uint8_t)button_event;
button_event = button_event_none;
return temp_s;
}

33
app/by_button.h Normal file
View File

@@ -0,0 +1,33 @@
#ifndef _BY_BUTTON_H__
#define _BY_BUTTON_H__
#include <stdio.h>
#include <stdint.h>
#define LONG_PRESS_THRESHOLD_MS (300ULL)
#define LONG_PRESS_THRESHOLD_TICK (LONG_PRESS_THRESHOLD_MS * 18000ULL)
#define BUTTON_UP_PIN E12
#define BUTTON_DOWN_PIN E11
#define BUTTON_LEFT_PIN E10
#define BUTTON_RIGHT_PIN E14
#define BUTTON_CENTER_PIN E13
#define BUTTON_SIDE_PIN E15
typedef enum button_event_t{
button_event_none = 0,
button_event_up,
button_event_down,
button_event_left,
button_event_right,
button_event_center_sp,
button_event_center_lp,
button_event_side,
}button_event_t;
extern button_event_t button_event;
void by_button_init(void);
uint8_t by_button_get_status(void);
#endif

View File

@@ -1,12 +1,13 @@
#include "by_buzzer.h"
#include "by_rt_button.h"
#include "zf_common_headfile.h"
#include <string.h>
#include "zf_common_headfile.h"
#define BUZZER_QUEUE_LENGTH 40
uint16_t queue_long = 0;
uint32_t a[40] = {0};
uint16_t queue_long = 0;
const uint32_t max_long = 40;
uint32_t a[40];
void queue_init(void)
{
memset(a, 0, sizeof(a));
@@ -14,7 +15,7 @@ void queue_init(void)
void queue_add_element(int element)
{
if (queue_long < max_long) {
if (queue_long < BUZZER_QUEUE_LENGTH) {
a[queue_long] = element;
queue_long += 1;
}
@@ -38,5 +39,15 @@ void queue_pop_read(void)
void by_buzzer_init(void)
{
queue_init();
pwm_init(BUZZER_PIN, 2000, 0);
by_buzzer_add(1250);
by_buzzer_add(1500);
by_buzzer_add(1750);
}
void by_buzzer_add(uint16_t tone)
{
queue_add_element(tone);
}

View File

@@ -1,24 +1,23 @@
#ifndef _BY_BUZZER_H__
#define _BY_BUZZER_H__
#include "by_rt_button.h"
#include "stdio.h"
#include "ch32v30x.h"
#include "zf_common_headfile.h"
#define BY_PRESS_SHORT 2000
#define BY_PRESS_LONG 2500
#define BY_FORWARD 1500
#define BY_BACKWARD 1800
#define BUZZER_PIN TIM3_PWM_MAP0_CH2_A7
extern void by_buzzer_init(void);
extern void queue_init(void);
extern void queue_add_element(int element);
extern void queue_pop_element(void);
extern void queue_pop_read(void);
#define BUZZER_PIN TIM4_PWM_MAP1_CH3_D14
extern uint32_t a[40];
extern uint16_t queue_long;
extern const uint32_t max_long;
extern uint8_t queue_flag;
extern void queue_init(void);
extern void queue_add_element(int element);
extern void queue_pop_element(void);
extern void queue_pop_read(void);
extern void by_buzzer_init(void);
extern void by_buzzer_add(uint16_t tone);
#endif

View File

@@ -1,58 +0,0 @@
#include "by_fan_control.h"
#include "zf_common_headfile.h"
#define Fan_pwm_up1 TIM8_PWM_MAP0_CH1_C6
#define Fan_pwm_up2 TIM8_PWM_MAP0_CH2_C7
#define Fan_pwm_power1 TIM4_PWM_MAP1_CH3_D14
#define Fan_pwm_power2 TIM4_PWM_MAP1_CH4_D15
#define Fan_pwm_power3 TIM4_PWM_MAP1_CH2_D13
#define Fan_pwm_power4 TIM4_PWM_MAP1_CH1_D12
uint32_t myclip(uint32_t x, uint32_t low, uint32_t up)
{
return (x > up ? up : x < low ? low
: x);
}
void by_pwm_init(void)
{
pwm_init(Fan_pwm_up1, 50, 500); // 浮力风扇左
pwm_init(Fan_pwm_up2, 50, 500); // 浮力风扇右
pwm_init(Fan_pwm_power1, 50, 500); // 动力风扇左1
pwm_init(Fan_pwm_power2, 50, 500); // 动力风扇右1
pwm_init(Fan_pwm_power3, 50, 500); // 动力风扇左2
pwm_init(Fan_pwm_power4, 50, 500); // 动力风扇右2
// system_delay_ms(3000);
// // pwm_init(Fan_pwm_power1, 50, 1000); // 动力风扇左1
// // pwm_init(Fan_pwm_power2, 50, 1000); // 动力风扇右1
// // pwm_init(Fan_pwm_power3, 50, 1000); // 动力风扇左2
// // pwm_init(Fan_pwm_power4, 50, 1000); // 动力风扇右2
// // system_delay_ms(5000);
// pwm_set_duty(Fan_pwm_power1, 600);
// pwm_set_duty(Fan_pwm_power2, 600);
// pwm_set_duty(Fan_pwm_power3, 600);
// pwm_set_duty(Fan_pwm_power4, 600);
// while(1);
}
void by_pwm_update_duty(uint32_t update_pwm_duty1, uint32_t update_pwm_duty2)
{
update_pwm_duty1=myclip(update_pwm_duty1, 500, 900);
update_pwm_duty2=myclip(update_pwm_duty2, 500, 900);
pwm_set_duty(Fan_pwm_up1, update_pwm_duty1);
pwm_set_duty(Fan_pwm_up2, update_pwm_duty2);
}
void by_pwm_power_duty(uint32_t power_pwm_duty_l1, uint32_t power_pwm_duty_r1, uint32_t power_pwm_duty_l2, uint32_t power_pwm_duty_r2)
{
power_pwm_duty_l1=myclip(power_pwm_duty_l1, 500, 900);
power_pwm_duty_r1=myclip(power_pwm_duty_r1, 500, 900);
power_pwm_duty_l2=myclip(power_pwm_duty_l2, 500, 900);
power_pwm_duty_r2=myclip(power_pwm_duty_r2, 500, 900);
pwm_set_duty(Fan_pwm_power1, power_pwm_duty_l1);
pwm_set_duty(Fan_pwm_power2, power_pwm_duty_r1);
pwm_set_duty(Fan_pwm_power3, power_pwm_duty_l2);
pwm_set_duty(Fan_pwm_power4, power_pwm_duty_r2);
}

View File

@@ -1,11 +0,0 @@
#ifndef _BY_FAN_CONTROL_H_
#define _BY_FAN_CONTROL_H_
#include "stdio.h"
#include "ch32v30x.h"
extern void by_pwm_init(void);
void by_pwm_update_duty(uint32_t update_pwm_duty1,uint32_t update_pwm_duty2);
void by_pwm_power_duty(uint32_t power_pwm_duty_l1, uint32_t power_pwm_duty_r1,uint32_t power_pwm_duty_l2, uint32_t power_pwm_duty_r2);
#endif

View File

@@ -1,192 +0,0 @@
#include "by_imu.h"
#include "zf_common_headfile.h"
#include <math.h>
#define delta_T 0.002f // 2ms 计算一次
float I_ex, I_ey, I_ez; // 误差积分
quater_param_t Q_info = {1, 0, 0}; // 全局四元数
euler_param_t eulerAngle; // 欧拉角
icm_param_t icm_data;
gyro_param_t GyroOffset;
bool GyroOffset_init = 0;
float param_Kp = 0.17f; // 加速度计的收敛速率比例增益 0.17
float param_Ki = 0.004f; // 陀螺仪收敛速率的积分增益 0.004
float fast_sqrt(float x)
{
float halfx = 0.5f * x;
float y = x;
long i = *(long *)&y;
i = 0x5f3759df - (i >> 1);
y = *(float *)&i;
y = y * (1.5f - (halfx * y * y));
return y;
}
void gyroOffset_init(void) /////////陀螺仪零飘初始化
{
float xdata_temp = 0;
float ydata_temp = 0;
float zdata_temp = 0;
imu660ra_get_gyro();
xdata_temp = imu660ra_gyro_x;
ydata_temp = imu660ra_gyro_y;
zdata_temp = imu660ra_gyro_z;
GyroOffset.Xdata = 0;
GyroOffset.Ydata = 0;
GyroOffset.Zdata = 0;
for (uint16_t i = 0; i < 5000; i++) {
imu660ra_get_gyro();
xdata_temp = imu660ra_gyro_x * 0.3f + xdata_temp * 0.7f;
ydata_temp = imu660ra_gyro_y * 0.3f + ydata_temp * 0.7f;
zdata_temp = imu660ra_gyro_z * 0.3f + zdata_temp * 0.7f;
GyroOffset.Xdata += xdata_temp;
GyroOffset.Ydata += ydata_temp;
GyroOffset.Zdata += zdata_temp;
system_delay_ms(5);
}
GyroOffset.Xdata /= 5000.0f;
GyroOffset.Ydata /= 5000.0f;
GyroOffset.Zdata /= 5000.0f;
// GyroOffset.Xdata = -1.034f;
// GyroOffset.Ydata = -2.21f;
// GyroOffset.Zdata = -3.15f;
GyroOffset_init = 1;
}
// 转化为实际物理值
void ICM_getValues()
{
#define alpha 0.2738f
// icm_data.acc_x = imu660ra_acc_x * alpha + icm_data.acc_x * (1 - alpha);
// icm_data.acc_y = imu660ra_acc_y * alpha + icm_data.acc_y * (1 - alpha);
// icm_data.acc_z = imu660ra_acc_z * alpha + icm_data.acc_z * (1 - alpha);
icm_data.acc_x = imu660ra_acc_x;
icm_data.acc_y = imu660ra_acc_y;
icm_data.acc_z = imu660ra_acc_z;
icm_data.gyro_x = icm_data.gyro_x * alpha + ((imu660ra_gyro_x - GyroOffset.Xdata) / 939.65f) * (1 - alpha);
icm_data.gyro_y = icm_data.gyro_y * alpha + ((imu660ra_gyro_y - GyroOffset.Ydata) / 939.65f) * (1 - alpha);
icm_data.gyro_z = icm_data.gyro_z * alpha + ((imu660ra_gyro_z - GyroOffset.Zdata) / 939.65f) * (1 - alpha);
}
// 互补滤波
void ICM_AHRSupdate(float gx, float gy, float gz, float ax, float ay, float az)
{
float halfT = 0.5 * delta_T;
float vx, vy, vz; // 当前的机体坐标系上的重力单位向量
float ex, ey, ez; // 四元数计算值与加速度计测量值的误差
float q0 = Q_info.q0;
float q1 = Q_info.q1;
float q2 = Q_info.q2;
float q3 = Q_info.q3;
float q0q0 = q0 * q0;
float q0q1 = q0 * q1;
float q0q2 = q0 * q2;
// float q0q3 = q0 * q3;
float q1q1 = q1 * q1;
// float q1q2 = q1 * q2;
float q1q3 = q1 * q3;
float q2q2 = q2 * q2;
float q2q3 = q2 * q3;
float q3q3 = q3 * q3;
// float delta_2 = 0;
// 对加速度数据进行归一化 得到单位加速度
float norm = fast_sqrt(ax * ax + ay * ay + az * az);
ax = ax * norm;
ay = ay * norm;
az = az * norm;
// 根据当前四元数的姿态值来估算出各重力分量。用于和加速计实际测量出来的各重力分量进行对比,从而实现对四轴姿态的修正
vx = 2.0f * (q1q3 - q0q2);
vy = 2.0f * (q0q1 + q2q3);
vz = q0q0 - q1q1 - q2q2 + q3q3;
// vz = 1.0f - 2.0f * q1q1 - 2.0f * q2q2;
// vz = (q0*q0-0.5f+q3 * q3) * 2;
// 叉积来计算估算的重力和实际测量的重力这两个重力向量之间的误差。
ex = ay * vz - az * vy;
ey = az * vx - ax * vz;
ez = ax * vy - ay * vx;
// 用叉乘误差来做 PI 修正陀螺零偏,
// 通过调节 param_Kpparam_Ki 两个参数,
// 可以控制加速度计修正陀螺仪积分姿态的速度。
I_ex += halfT * ex; // integral error scaled by Ki
I_ey += halfT * ey;
I_ez += halfT * ez;
gx = gx + param_Kp * ex + param_Ki * I_ex;
gy = gy + param_Kp * ey + param_Ki * I_ey;
gz = gz + param_Kp * ez + param_Ki * I_ez;
/*数据修正完成,下面是四元数微分方程*/
// 四元数微分方程,其中 halfT 为测量周期的 1/2gx gy gz 为陀螺仪角速度,以下都是已知量,这里使用了一阶龙哥库塔求解四元数微分方程
q0 = q0 + (-q1 * gx - q2 * gy - q3 * gz) * halfT;
q1 = q1 + (q0 * gx + q2 * gz - q3 * gy) * halfT;
q2 = q2 + (q0 * gy - q1 * gz + q3 * gx) * halfT;
q3 = q3 + (q0 * gz + q1 * gy - q2 * gx) * halfT;
// delta_2=(2*halfT*gx)*(2*halfT*gx)+(2*halfT*gy)*(2*halfT*gy)+(2*halfT*gz)*(2*halfT*gz);
// 整合四元数率 四元数微分方程 四元数更新算法,二阶毕卡法
// q0 = (1-delta_2/8)*q0 + (-q1*gx - q2*gy - q3*gz)*halfT;
// q1 = (1-delta_2/8)*q1 + (q0*gx + q2*gz - q3*gy)*halfT;
// q2 = (1-delta_2/8)*q2 + (q0*gy - q1*gz + q3*gx)*halfT;
// q3 = (1-delta_2/8)*q3 + (q0*gz + q1*gy - q2*gx)*halfT
// normalise quaternion
norm = fast_sqrt(q0 * q0 + q1 * q1 + q2 * q2 + q3 * q3);
Q_info.q0 = q0 * norm;
Q_info.q1 = q1 * norm;
Q_info.q2 = q2 * norm;
Q_info.q3 = q3 * norm;
}
void ICM_getEulerianAngles(void)
{
// 采集陀螺仪数据
imu660ra_get_acc();
imu660ra_get_gyro();
imu660ra_get_temperature();
ICM_getValues();
ICM_AHRSupdate(icm_data.gyro_x, icm_data.gyro_y, icm_data.gyro_z, icm_data.acc_x, icm_data.acc_y, icm_data.acc_z);
float q0 = Q_info.q0;
float q1 = Q_info.q1;
float q2 = Q_info.q2;
float q3 = Q_info.q3;
// 四元数计算欧拉角
eulerAngle.pitch = asinf(-2 * q1 * q3 + 2 * q0 * q2) * 180.0f / M_PI; // pitch
eulerAngle.roll = atan2f(2 * q2 * q3 + 2 * q0 * q1, -2 * q1 * q1 - 2 * q2 * q2 + 1) * 180.0f / M_PI; // roll
eulerAngle.yaw = atan2f(2 * q1 * q2 + 2 * q0 * q3, -2 * q2 * q2 - 2 * q3 * q3 + 1) * 180.0f / M_PI; // yaw
/* 姿态限制*/
if (eulerAngle.roll > 90 || eulerAngle.roll < -90) {
if (eulerAngle.pitch > 0) {
eulerAngle.pitch = 180 - eulerAngle.pitch;
}
if (eulerAngle.pitch < 0) {
eulerAngle.pitch = -(180 + eulerAngle.pitch);
}
}
if (eulerAngle.yaw > 180) {
eulerAngle.yaw -= 180;
} else if (eulerAngle.yaw < -180) {
eulerAngle.yaw += 180;
}
}

View File

@@ -1,47 +0,0 @@
#ifndef _BY_IMU_H__
#define _BY_IMU_H__
#include <stdio.h>
#include "ch32v30x.h"
typedef struct {
float gyro_x;
float gyro_y;
float gyro_z;
float acc_x;
float acc_y;
float acc_z;
} icm_param_t;
typedef struct {
float q0;
float q1;
float q2;
float q3;
} quater_param_t;
typedef struct {
float pitch; //俯仰角
float roll; //偏航角
float yaw; //翻滚角
} euler_param_t;
typedef struct {
float Xdata;
float Ydata;
float Zdata;
} gyro_param_t;
extern icm_param_t icm_data;
extern euler_param_t eulerAngle;
extern gyro_param_t GyroOffset;
void gyroOffset_init(void);
float fast_sqrt(float x);
void ICM_AHRSupdate(float gx, float gy, float gz, float ax, float ay, float az);
void ICM_getValues();
void ICM_getEulerianAngles(void);
#endif

View File

@@ -1,6 +1,5 @@
#include "by_rt_button.h"
#include "zf_common_headfile.h"
#include "by_imu.h"
uint8_t rotate_button;
void by_gpio_init(void)
@@ -24,35 +23,4 @@ uint8_t by_get_rb_status(void)
uint8_t temp_s = rotate_button;
rotate_button = 0;
return temp_s;
}
void by_ips_show(void)
{
ips200_show_string(0, 0, "button status:");
// ips200_show_uint(104, 0, by_get_rb_status(), 1);
switch (by_get_rb_status()) {
case 1:
ips200_show_string(104, 0, "press");
break;
case 2:
ips200_show_string(104, 0, "up ");
break;
case 3:
ips200_show_string(104, 0, "down ");
break;
default:
ips200_show_string(104, 0, " ");
break;
}
// 按钮
ips200_show_string(0, 16, "imu:");
ips200_show_float(46, 32, eulerAngle.pitch, 3, 2);
ips200_show_float(46, 48, eulerAngle.roll, 3, 2);
ips200_show_float(46, 64, eulerAngle.yaw, 3, 2);
// ips200_show_float(46 , 32, icm_data.gyro_x, 2, 2);
// ips200_show_float(106, 32, icm_data.gyro_y, 2, 2);
// ips200_show_float(166, 32, icm_data.gyro_z, 2, 2);
ips200_show_float(46, 80, imu660ra_temperature, 2, 2);
// printf("%d,%d,%d\n", (int16_t)(icm_data.gyro_x * 10), (int16_t)(icm_data.gyro_y * 10), (int16_t)(icm_data.gyro_z * 10));
}
}

View File

@@ -4,9 +4,6 @@
#include "stdio.h"
#include "ch32v30x.h"
#define LONG_PRESS_THRESHOLD_MS (300ULL)
#define LONG_PRESS_THRESHOLD_TICK (LONG_PRESS_THRESHOLD_MS * 18000ULL)
typedef enum rotate_button_event {
rotate_button_press_short = 1,
rotate_button_press_long = 2,

View File

@@ -35,11 +35,8 @@
#include "zf_common_headfile.h"
#include "by_rt_button.h"
#include "by_imu.h"
#include "jj_blueteeth.h"
#include "by_button.h"
#include "by_buzzer.h"
#include "jj_motion.h"
#include "jj_blueteeth.h"
void NMI_Handler(void) __attribute__((interrupt()));
void HardFault_Handler(void) __attribute__((interrupt()));
@@ -94,8 +91,6 @@ void USART1_IRQHandler(void)
void USART2_IRQHandler(void)
{
if (USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) {
uart_query_byte(UART_2, &bt_buffer);
bt_rx_flag = true;
USART_ClearITPendingBit(USART2, USART_IT_RXNE);
}
}
@@ -201,14 +196,6 @@ void EXTI9_5_IRQHandler(void)
EXTI_ClearITPendingBit(EXTI_Line8);
}
if (SET == EXTI_GetITStatus(EXTI_Line9)) {
if (SET == gpio_get_level(E10)) {
rotate_button = rotate_button_backward;
queue_add_element(BY_BACKWARD);
} else {
rotate_button = rotate_button_forward;
queue_add_element(BY_FORWARD);
}
EXTI_ClearITPendingBit(EXTI_Line9);
}
}
@@ -216,57 +203,63 @@ void EXTI9_5_IRQHandler(void)
void EXTI15_10_IRQHandler(void)
{
if (SET == EXTI_GetITStatus(EXTI_Line10)) {
// <20>˴<EFBFBD><CBB4><EFBFBD>д<EFBFBD>û<EFBFBD><C3BB><EFBFBD><EFBFBD><EFBFBD> (A10/B10..E10) <20><><EFBFBD>Ŵ<EFBFBD><C5B4><EFBFBD>
// <20>˴<EFBFBD><CBB4><EFBFBD>д<EFBFBD>û<EFBFBD><C3BB><EFBFBD><EFBFBD><EFBFBD> (A10/B10..E10) <20><><EFBFBD>Ŵ<EFBFBD><C5B4><EFBFBD>
system_delay_ms(10);
if (RESET == gpio_get_level(BUTTON_LEFT_PIN)) {
button_event = button_event_left;
}
by_buzzer_add(1250);
EXTI_ClearITPendingBit(EXTI_Line10);
}
if (SET == EXTI_GetITStatus(EXTI_Line11)) {
system_delay_ms(10);
if (RESET == gpio_get_level(BUTTON_DOWN_PIN)) {
button_event = button_event_down;
}
by_buzzer_add(1250);
EXTI_ClearITPendingBit(EXTI_Line11);
}
if (SET == EXTI_GetITStatus(EXTI_Line12)) {
system_delay_ms(10);
if (RESET == gpio_get_level(BUTTON_UP_PIN)) {
button_event = button_event_up;
}
by_buzzer_add(1250);
EXTI_ClearITPendingBit(EXTI_Line12);
}
if (SET == EXTI_GetITStatus(EXTI_Line13)) {
static uint64_t time_via = 0;
system_delay_ms(10);
if (RESET == gpio_get_level(E11)) {
if (RESET == gpio_get_level(BUTTON_CENTER_PIN)) {
time_via = system_get_tick();
EXTI_ClearITPendingBit(EXTI_Line11);
} else if (SET == gpio_get_level(E11)) {
} else if (SET == gpio_get_level(BUTTON_CENTER_PIN)) {
time_via = system_get_tick() - time_via;
if (time_via > LONG_PRESS_THRESHOLD_TICK) {
rotate_button = rotate_button_press_long;
queue_add_element(BY_PRESS_LONG);
button_event = button_event_center_lp;
by_buzzer_add(2000);
} else {
rotate_button = rotate_button_press_short;
queue_add_element(BY_PRESS_SHORT);
button_event = button_event_center_sp;
by_buzzer_add(1800);
}
time_via = 0;
EXTI_ClearITPendingBit(EXTI_Line11);
}
if (SET == EXTI_GetITStatus(EXTI_Line12)) {
EXTI_ClearITPendingBit(EXTI_Line12);
EXTI_ClearITPendingBit(EXTI_Line13);
}
if (SET == EXTI_GetITStatus(EXTI_Line14)) {
system_delay_ms(10);
if (RESET == gpio_get_level(BUTTON_RIGHT_PIN)) {
button_event = button_event_right;
by_buzzer_add(1250);
}
if (SET == EXTI_GetITStatus(EXTI_Line13)) {
// -----------------* ToF INT <20><><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD> Ԥ<><D4A4><EFBFBD>жϴ<D0B6><CFB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> *-----------------
tof_module_exti_handler();
// -----------------* ToF INT <20><><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD> Ԥ<><D4A4><EFBFBD>жϴ<D0B6><CFB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> *-----------------
// <20>˴<EFBFBD><CBB4><EFBFBD>д<EFBFBD>û<EFBFBD><C3BB><EFBFBD><EFBFBD><EFBFBD> (A13/B13..E13) <20><><EFBFBD>Ŵ<EFBFBD><C5B4><EFBFBD>
// <20>˴<EFBFBD><CBB4><EFBFBD>д<EFBFBD>û<EFBFBD><C3BB><EFBFBD><EFBFBD><EFBFBD> (A13/B13..E13) <20><><EFBFBD>Ŵ<EFBFBD><C5B4><EFBFBD>
EXTI_ClearITPendingBit(EXTI_Line13);
}
if (SET == EXTI_GetITStatus(EXTI_Line14)) {
// -----------------* DM1XA <20><><EFBFBD>ź<EFBFBD> Ԥ<><D4A4><EFBFBD>жϴ<D0B6><CFB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> *-----------------
dm1xa_light_callback();
// -----------------* DM1XA <20><><EFBFBD>ź<EFBFBD> Ԥ<><D4A4><EFBFBD>жϴ<D0B6><CFB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> *-----------------
EXTI_ClearITPendingBit(EXTI_Line14);
}
if (SET == EXTI_GetITStatus(EXTI_Line15)) {
// -----------------* DM1XA <20><>/<2F><><EFBFBD><EFBFBD><EFBFBD>ź<EFBFBD> Ԥ<><D4A4><EFBFBD>жϴ<D0B6><CFB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> *-----------------
dm1xa_sound_callback();
// -----------------* DM1XA <20><>/<2F><><EFBFBD><EFBFBD><EFBFBD>ź<EFBFBD> Ԥ<><D4A4><EFBFBD>жϴ<D0B6><CFB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> *-----------------
EXTI_ClearITPendingBit(EXTI_Line15);
EXTI_ClearITPendingBit(EXTI_Line14);
}
if (SET == EXTI_GetITStatus(EXTI_Line15)) {
system_delay_ms(10);
if (RESET == gpio_get_level(BUTTON_SIDE_PIN)) {
button_event = button_event_side;
by_buzzer_add(2000);
by_buzzer_add(1500);
}
EXTI_ClearITPendingBit(EXTI_Line15);
}
}
@@ -274,8 +267,6 @@ void TIM1_UP_IRQHandler(void)
{
if (TIM_GetITStatus(TIM1, TIM_IT_Update) != RESET) {
TIM_ClearITPendingBit(TIM1, TIM_IT_Update);
sport_motion2(bt_fly);
}
}
@@ -310,7 +301,6 @@ void TIM5_IRQHandler(void)
void TIM6_IRQHandler(void)
{
if (TIM_GetITStatus(TIM6, TIM_IT_Update) != RESET) {
ICM_getEulerianAngles();
TIM_ClearITPendingBit(TIM6, TIM_IT_Update);
}
}

View File

@@ -1,92 +0,0 @@
#include "jj_blueteeth.h"
#include "jj_motion.h"
#include "by_fan_control.h"
bool bt_rx_flag = false;
uint8 bt_buffer; // 接收字符存入
float bt_angle = 0.0f;
uint32_t bt_run_flag = 0;
uint8_t bt_flow_flag = 0;
uint32_t bt_fly = 0;
uint32_t bt_flow = 0;
enum bt_order {
Start_work = 0x01,
Turn_Left = 0x02,
Turn_Right = 0x03,
Speed_up = 0x04,
Speed_down = 0x05,
Stop_fly = 0x06,
Flow_on = 0x08,
Flow_up = 0x09,
Flow_down = 0x10,
};
/**
* @brief 蓝牙初始化
* @retval 无
*/
void jj_bt_init()
{
uart_init(UART_2, 115200, UART2_MAP1_TX_D5, UART2_MAP1_RX_D6);
// uart_tx_interrupt(UART_2, 1);
uart_rx_interrupt(UART_2, ENABLE);
}
/**
*@brief 蓝牙中断回调函数
*/
void jj_bt_run()
{
if (bt_rx_flag) {
switch (bt_buffer) {
case Start_work:
bt_angle = 0.0f;
break;
case Turn_Left:
bt_angle = 10.0f;
break;
case Turn_Right:
bt_angle = -10.0f;
break;
case Speed_down:
bt_fly -= 10;
break;
case Speed_up:
bt_fly += 10;
break;
case Stop_fly:
bt_run_flag = !bt_run_flag;
break;
case Flow_on:
bt_flow_flag = !bt_flow_flag;
break;
case Flow_up:
bt_flow += 20;
break;
case Flow_down:
bt_flow -= 20;
break;
default:
break;
}
if (bt_flow_flag == 0) {
bt_flow = 0;
}
by_pwm_update_duty(bt_flow + 500, bt_flow + 500);
bt_rx_flag = false;
}
}
void bt_printf(const char *format, ...)
{
char sbuf[40];
va_list args;
va_start(args, format);
vsnprintf(sbuf, 40, format, args);
va_end(args);
for (uint16_t i = 0; i < strlen(sbuf); i++) {
while (USART_GetFlagStatus((USART_TypeDef *)uart_index[UART_2], USART_FLAG_TC) == RESET)
;
USART_SendData((USART_TypeDef *)uart_index[UART_2], sbuf[i]);
}
}

View File

@@ -1,14 +0,0 @@
#ifndef _JJ_BLUETEETH_H_
#define _JJ_BLUETEETH_H_
#include "stdio.h"
#include "zf_driver_uart.h"
extern bool bt_rx_flag;
extern uint8_t bt_buffer;
extern uint32_t bt_fly;
extern uint32_t bt_run_flag;
extern float bt_angle;
void jj_bt_init();
void jj_bt_run();
void bt_printf(const char *format, ...);
#endif

View File

@@ -1,60 +0,0 @@
#include "jj_motion.h"
#include "by_fan_control.h"
#include "by_imu.h"
#include "../3rd-lib/PID-Library/pid.h"
#include "jj_blueteeth.h"
#include "gl_common.h"
PID_TypeDef angle_pid;
PID_TypeDef gyro_z_pid;
PID_TypeDef img_x_pid;
float an_Kp = 8.0f;
float an_Ki = 0.0f;
float an_Kd = 2.0f;
float im_Kp = 1.0f;
float im_Ki = 0.0f;
float im_Kd = 0.0f;
float set_x = 0.0f;
float img_x = 40.0f;
float yaw0 = 0;
float out_M = 0;
float out_yaw;
uint32_t cnt1 = 0;
/**
* @brief
*
* @param fy y轴的加速度
*/
void sport_motion2(uint32_t fy)
{
cnt1++;
yaw0 = imu660ra_gyro_z;
if (cnt1 >= 50) {
PID_Compute(&angle_pid);
cnt1 = 0;
}
PID_Compute(&gyro_z_pid);
if (bt_run_flag == 1) {
by_pwm_power_duty((int32_t)(500 + fy + out_M), (int32_t)(500 + fy - out_M),
(int32_t)(500 + fy + out_M), (int32_t)(500 + fy - out_M));
} else {
by_pwm_power_duty(500, 500, 500, 500);
}
}
/**
* @brief 结构体初始化
*
*/
void sport_pid_init()
{
PID(&angle_pid, &bt_angle, &out_yaw, &set_x, im_Kp, im_Ki, im_Kd, 0, 0);
PID(&gyro_z_pid, &yaw0, &out_M, &out_yaw, an_Kp, an_Ki, an_Kd, 1, 1);
PID_Init(&angle_pid);
PID_Init(&gyro_z_pid);
PID_SetOutputLimits(&angle_pid, -500.0f, 500.0f);
PID_SetOutputLimits(&gyro_z_pid, -400.0f, 400.0f);
PID_SetMode(&gyro_z_pid, 1);
PID_SetMode(&angle_pid, 1);
}

View File

@@ -1,18 +0,0 @@
#ifndef _JJ_MOTION_H_
#define _JJ_MOTION_H_
#include "ch32v30x.h"
#include "../3rd-lib/PID-Library/pid.h"
extern PID_TypeDef angle_pid;
extern PID_TypeDef gyro_z_pid;
extern float an_Kp;
extern float an_Ki;
extern float an_Kd;
extern float im_Kp;
extern float im_Ki;
extern float im_Kd;
extern float out_M;
extern float out_yaw;
extern float yaw0;
void sport_pid_init();
void sport_motion2(uint32_t fy);
#endif

View File

@@ -2,20 +2,19 @@
#include "./page/page_ui_widget.h"
#include "./page/page.h"
#include "zf_common_headfile.h"
#include "jj_motion.h"
PARAM_INFO Param_Data[DATA_NUM];
soft_iic_info_struct eeprom_param;
TYPE_UNION iic_buffer[DATA_IN_FLASH_NUM];
void jj_param_eeprom_init()
{
soft_iic_init(&eeprom_param, K24C02_DEV_ADDR, K24C02_SOFT_IIC_DELAY, K24C02_SCL_PIN, K24C02_SDA_PIN); // eeprom初始化
PARAM_REG(angle_Kp, &an_Kp, EFLOAT, 1, "an_P"); // 注冊
PARAM_REG(angle_Ki, &an_Ki, EFLOAT, 1, "an_I"); // 注冊
PARAM_REG(angle_Kd, &an_Kd, EFLOAT, 1, "an_D"); // 注冊
PARAM_REG(imgax_Kp, &im_Kp, EFLOAT, 1, "im_P"); // 注冊
PARAM_REG(imgax_Ki, &im_Ki, EFLOAT, 1, "im_I"); // 注冊
PARAM_REG(imgax_Kd, &im_Kd, EFLOAT, 1, "im_D"); // 注冊
soft_iic_init(&eeprom_param, K24C02_DEV_ADDR, K24C02_SOFT_IIC_DELAY, K24C02_SCL_PIN, K24C02_SDA_PIN); // eeprom 初始化
// PARAM_REG(angle_Kp, &an_Kp, EFLOAT, 1, "an_P"); // 注冊
// PARAM_REG(angle_Ki, &an_Ki, EFLOAT, 1, "an_I"); // 注冊
// PARAM_REG(angle_Kd, &an_Kd, EFLOAT, 1, "an_D"); // 注冊
// PARAM_REG(imgax_Kp, &im_Kp, EFLOAT, 1, "im_P"); // 注冊
// PARAM_REG(imgax_Ki, &im_Ki, EFLOAT, 1, "im_I"); // 注冊
// PARAM_REG(imgax_Kd, &im_Kd, EFLOAT, 1, "im_D"); // 注冊
for (uint8 i = 0; i < DATA_IN_FLASH_NUM; i++) {

View File

@@ -22,46 +22,34 @@
* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明)
********************************************************************************************************************/
#include "gl_headfile.h"
#include "by_rt_button.h"
#include "by_fan_control.h"
#include "./page/page.h"
#include "jj_blueteeth.h"
#include "jj_param.h"
#include "./page/page_ui_widget.h"
#include "by_buzzer.h"
#include "jj_motion.h"
#include "by_imu.h"
int main(void)
{
clock_init(SYSTEM_CLOCK_120M);
clock_init(SYSTEM_CLOCK_144M);
system_delay_init();
debug_init();
mt9v03x_init();
// mt9v03x_init();
ips200_init(IPS200_TYPE_SPI);
by_gpio_init();
by_exit_init();
by_pwm_init();
jj_bt_init();
usb_cdc_init();
by_buzzer_init();
while (imu660ra_init())
;
jj_param_eeprom_init();
by_button_init();
// while (imu660ra_init())
// ;
// jj_param_eeprom_init();
Page_Init();
sport_pid_init();
pit_ms_init(TIM6_PIT, 2);
pit_ms_init(TIM1_PIT, 2);
// gyroOffset_init();
while (1) {
Page_Run();
jj_bt_run();
queue_pop_read();
bt_printf("hello:%f,%f\n",out_M,out_yaw);
if (mt9v03x_finish_flag) {
// 该操作消耗大概 1970 个 tick折合约 110us
memcpy(mt9v03x_image_copy[0], mt9v03x_image[0], (sizeof(mt9v03x_image_copy) / sizeof(uint8_t)));
//adaptiveThreshold((uint8_t*)mt9v03x_image_copy, (uint8_t*)mt9v03x_image_copy, 188, 120, 7, 17);
//ips200_show_gray_image(0, 0, mt9v03x_image_copy[0], MT9V03X_W, MT9V03X_H, MT9V03X_W, MT9V03X_H, 0);
// adaptiveThreshold((uint8_t*)mt9v03x_image_copy, (uint8_t*)mt9v03x_image_copy, 188, 120, 7, 17);
// ips200_show_gray_image(0, 0, mt9v03x_image_copy[0], MT9V03X_W, MT9V03X_H, MT9V03X_W, MT9V03X_H, 0);
mt9v03x_finish_flag = 0;
state_type = COMMON_STATE;
@@ -72,27 +60,25 @@ int main(void)
ElementJudge();
ElementRun();
MidLineTrack();
}
}
}
void adaptiveThreshold(uint8_t* img_data, uint8_t* output_data, int width, int height, int block, uint8_t clip_value){
int half_block = block / 2;
for(int y=half_block; y<height-half_block; y++){
for(int x=half_block; x<width-half_block; x++){
// 计算局部阈值
int thres = 0;
for(int dy=-half_block; dy<=half_block; dy++){
for(int dx=-half_block; dx<=half_block; dx++){
thres += img_data[(x+dx)+(y+dy)*width];
void adaptiveThreshold(uint8_t *img_data, uint8_t *output_data, int width, int height, int block, uint8_t clip_value)
{
int half_block = block / 2;
for (int y = half_block; y < height - half_block; y++) {
for (int x = half_block; x < width - half_block; x++) {
// 计算局部阈值
int thres = 0;
for (int dy = -half_block; dy <= half_block; dy++) {
for (int dx = -half_block; dx <= half_block; dx++) {
thres += img_data[(x + dx) + (y + dy) * width];
}
}
thres = thres / (block * block) - clip_value;
// 进行二值化
output_data[x + y * width] = img_data[x + y * width] > thres ? 255 : 0;
}
}
thres = thres / (block * block) - clip_value;
// 进行二值化
output_data[x+y*width] = img_data[x+y*width]>thres ? 255 : 0;
}
}
}

View File

@@ -1,6 +1,6 @@
#include "page.h"
#include "by_rt_button.h"
#include "by_button.h"
PAGE_LIST pagelist[page_max];
static uint8_t page_busy = 0;
@@ -89,8 +89,8 @@ uint8_t Page_GetStatus(void)
*/
void Page_Run(void)
{
uint8_t temp_status = by_get_rb_status(); // 轮询旋钮状态
if(temp_status){
uint8_t temp_status = by_button_get_status(); // 轮询旋钮状态
if (temp_status) {
pagelist[now_page].EventCallback(temp_status);
}
@@ -118,7 +118,7 @@ void Page_Run(void)
}
/**
* @brief 页面初始化(注册,构建) ATTENTION 在此处添加新加入的页面
* @brief 页面初始化注册构建ATTENTION 在此处添加新加入的页面
*
*/
void Page_Init(void)

View File

@@ -13,7 +13,7 @@
#include "zf_common_headfile.h"
#include "by_rt_button.h"
#include "by_button.h"
enum PageID {
PAGE_NULL = -1,
@@ -28,11 +28,11 @@ enum PageID {
page_max,
};
typedef enum page_event{
page_event_forward = rotate_button_forward,
page_event_backward = rotate_button_backward,
page_event_press_short = rotate_button_press_short,
page_event_press_long = rotate_button_press_long,
typedef enum page_event {
page_event_forward = button_event_up,
page_event_backward = button_event_down,
page_event_press_short = button_event_center_sp,
page_event_press_long = button_event_center_lp,
} page_event;
typedef void (*CallbackFunction_t)(void);
@@ -45,16 +45,16 @@ typedef struct {
EventFunction_t EventCallback;
} PAGE_LIST;
//页面注册函数
#define PAGE_REG(name)\
do{\
extern void PageRegister_##name(unsigned char pageID);\
PageRegister_##name(name);\
}while(0)
// 页面注册函数
#define PAGE_REG(name) \
do { \
extern void PageRegister_##name(unsigned char pageID); \
PageRegister_##name(name); \
} while (0)
void Page_Register(uint8_t pageID, char *pageText,
CallbackFunction_t setupCallback, CallbackFunction_t loopCallback,
CallbackFunction_t exitCallback, EventFunction_t eventCallback);
CallbackFunction_t setupCallback, CallbackFunction_t loopCallback,
CallbackFunction_t exitCallback, EventFunction_t eventCallback);
void Page_EventTransmit(unsigned char event);
void Page_Shift(unsigned char pageID);

View File

@@ -1,11 +1,10 @@
#include "jj_param.h"
#include "page_ui_widget.h"
#include "jj_motion.h"
#include "page.h"
#define LINE_HEAD 0
#define LINE_END DATA_NUM - 2
static char Text[] = "RealTime Param";
static char Text[] = "Param";
int event_flag = 0;
int32_t index_power = 0;
static int8_t Curser = LINE_HEAD; // 定义光标位置
@@ -75,7 +74,6 @@ static void Event(page_event event)
return;
} else if (page_event_press_long == event) {
jj_param_update();
sport_pid_init();
Page_Shift(page_menu);
return;
}