/**************************************************************
 * blade_control.h  —  轨道风机叶片控制 公共定义
 * 目标：STC89C52 / 12MHz / 12T   TB6600 / DM542 驱动器
 * 轴1 = 叶面角（绕竖轴）  轴2 = 叶轴角（绕展向轴）
 * 传动：叶面角 蜗杆1:蜗轮65          → 1:65
 *       叶轴角 蜗杆→蜗轮65→内齿52→丝杆齿轮20→丝杆Tr8×4→螺母→连片25→叶片杆25
 *              蜗杆:丝杆 = 25:1
 **************************************************************/
#ifndef __BLADE_CONTROL_H__
#define __BLADE_CONTROL_H__

#include <reg52.h>
#include <intrins.h>

/* ---------- 细分与机械常数 ---------- */
#define MICRO_FACE      1600      /* 叶面角细分（原 6400，改 1600 提速 4 倍）*/
#define MICRO_AXIS      1600      /* 叶轴角细分 */
#define Z_WORMWHEEL     65
#define Z_INT           52
#define Z_SCREWGEAR     20
#define SCREW_PITCH     4.0f      /* mm，已由 2 改为 4 */
#define LEVER_L         25.0f     /* 叶片杆 L */
#define LINK_L          25.0f     /* 连片 l  */
#define AXIS_D          17.0f     /* 丝杆轴—叶片轴间距 D */

/* 每脉冲位移/角度 */
/* 叶面角：360/(65*MICRO_FACE) = 0.0034615 度/脉冲 */
#define DEG_PER_PULSE_FACE   (360.0f / (Z_WORMWHEEL * MICRO_FACE))
/* 叶轴角：每蜗杆圈螺母 0.16mm（=SCREW_PITCH*Z_INT/Z_SCREWGEAR/Z_WORMWHEEL */
#define MM_PER_PULSE_AXIS    (SCREW_PITCH * (float)Z_INT / (float)Z_SCREWGEAR \
                              / (float)Z_WORMWHEEL / MICRO_AXIS)   /* 0.0001 mm */

/* ---------- 脉冲发生器 ---------- */
#define F_PULSE_MAX     30000UL   /* 30 kHz */
#define F_PULSE_START    2000UL   /* 2  kHz 起步 */
#define T0_RELOAD_FAST  (65536UL - (12000000UL/12UL/F_PULSE_MAX))  /* ≈33  */
#define T0_RELOAD_SLOW  (65536UL - (12000000UL/12UL/F_PULSE_START))/* =500  */
#define ACC_STEP_US     20        /* 20ms 线性升速（每 1ms 调一次重装值）*/

/* 状态机 */
#define ST_INIT   0
#define ST_RUN    1
#define ST_MAINT  2
#define ST_STOP   3
#define ST_DANCE  4
#define ST_PROT   5

/* 限位（软限位） */
#define FACE_MIN_DEG  (-90.0f)
#define FACE_MAX_DEG  (135.0f)
#define AXIS_MIN_DEG  (0.0f)
#define AXIS_MAX_DEG  (15.0f)

/* ---------- 引脚（按实际硬件修改） ---------- */
sbit STEP_FACE = P1^0;
sbit DIR_FACE  = P1^1;
sbit STEP_AXIS = P1^2;
sbit DIR_AXIS  = P1^3;
sbit RS485_DE  = P1^4;      /* 485 收发切换：1=发 */
sbit BUZZER    = P1^5;
sbit LED_RUN   = P1^6;
sbit KEY_MODE  = P3^2;      /* 外部中断0，切换运行/检修/停止 */

/* ---------- 叶轴角映射表（细分1600、螺距4mm；0.5° 间隔，31 点）---------- */
/* 由 s(α)=L·sinα+√(l²−(D−L·cosα)²) 计算，s0 = 23.685mm */
extern const unsigned long code AXIS_MAP[31];

/* ---------- 通信帧 ---------- */
#define FRM_HEAD   0xAA
#define FRM_TAIL   0x55
#define FRM_LEN    9
#define CMD_OPER   0x01
#define CMD_MODF   0x02
#define CMD_STOP   0x03
#define CMD_DANC   0x04
#define CMD_PROT   0x05
#define CMD_QUERY  0x06

typedef struct {
    unsigned char id;
    float face_deg;     /* 叶面角目标 */
    float axis_deg;     /* 叶轴角目标 */
    unsigned char mode;
} ctrl_t;

extern ctrl_t g_ctrl;

/* ---------- 接口 ---------- */
void  timer_init(void);
void  uart_init(unsigned int baud);      /* 9600 @11.0592MHz 或 4800 @12MHz */
void  rs485_send_frame(unsigned char id, float face, float axis, unsigned char mode);
unsigned char crc8(const unsigned char *buf, unsigned char len);
float calc_leaf_surface_angle(float wind_angle, float slider_angle);
float calc_leaf_axis_angle(float slider_angle);
void  set_face_target(float deg);
void  set_axis_target(float deg);
unsigned long axis_deg_to_pulses(float deg);
float axis_pulses_to_deg(unsigned long n);
void  pulse_service(void);
void  lcd_show(unsigned char line, const char *s);

#endif
