#include "MAIN.H" //can消息 UnInfCan UnInfCan_1 = {0}; UnSwSample UnSwSample_1 = {0}; UnSwOut UnSwOut_1 = {0}; UnRemoteControlOutput UnRemoteControlOutput_1 = {0,0,0,0,0,0,0,0};//遥控器数据发送 UnRemoteControlOutput UnRemoteControlOutput_2 = {0,0,0,0,0,0,0,0};//遥控器数据发送 SBusData sbus_data; //CAN发送计数 uword CntCan_1 = 0; bit FlgCan_1 = 0; //第一次采集数据有效标志 bit FlgOneTime = 0; ubyte uart2RxFlag = 0; uword RgCanPerid = 50; ubyte can_error_cnt = 0; ubyte can_error_flg = 0; ubyte RestartDataFlg1 _at_ 0xF5E7; ubyte RestartDataFlg2 _at_ 0xF600; //PWM 20181227 ubyte PwmH[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; //----------------------------------------------------------------------- //RTC定时器 //----------------------------------------------------------------------- void RTCProcess(void) { //************************************************************************ //////CAN发送计数 if(FlgCan_1){CntCan_1++;if(CntCan_1 >= RgCanPerid){FlgCan_1=0; CntCan_1=0;}}else{CntCan_1=0;} //************************************************************************ } // SBus 数据解析函数 SBusData* parseSBusData(const uint8_t *input_data) { // 解析16个通道的数据,每个通道为11位 sbus_data.channels[0] = (input_data[1] | input_data[2] << 8) & 0x07FF; sbus_data.channels[1] = (input_data[2] >> 3 | input_data[3] << 5) & 0x07FF; sbus_data.channels[2] = (input_data[3] >> 6 | input_data[4] << 2 | input_data[5] << 10) & 0x07FF; sbus_data.channels[3] = (input_data[5] >> 1 | input_data[6] << 7) & 0x07FF; sbus_data.channels[4] = (input_data[6] >> 4 | input_data[7] << 4) & 0x07FF; sbus_data.channels[5] = (input_data[7] >> 7 | input_data[8] << 1 | input_data[9] << 9) & 0x07FF; sbus_data.channels[6] = (input_data[9] >> 2 | input_data[10] << 6) & 0x07FF; sbus_data.channels[7] = (input_data[10] >> 5 | input_data[11] << 3) & 0x07FF; sbus_data.channels[8] = (input_data[12] | input_data[13] << 8) & 0x07FF; sbus_data.channels[9] = (input_data[13] >> 3 | input_data[14] << 5) & 0x07FF; sbus_data.channels[10] = (input_data[14] >> 6 | input_data[15] << 2 | input_data[15] << 10) & 0x07FF; sbus_data.channels[11] = (input_data[16] >> 1 | input_data[17] << 7) & 0x07FF; sbus_data.channels[12] = (input_data[17] >> 4 | input_data[18] << 4) & 0x07FF; sbus_data.channels[13] = (input_data[18] >> 7 | input_data[19] << 1 | input_data[20] << 9) & 0x07FF; sbus_data.channels[14] = (input_data[20] >> 2 | input_data[21] << 6) & 0x07FF; sbus_data.channels[15] = (input_data[21] >> 5 | input_data[22] << 3) & 0x07FF; // 解析标志字节 sbus_data.flags = input_data[23]; uart2RxFlag = 1; return &sbus_data; } //can错误处理 void CanErrorProcess(void) { ubyte ubNSRL; ubyte ubNSRH; ubyte ubResetLEC = 0x3F; //------------------------------------------- EA = 0; CAN_pushAMRegs(); // push the CAN Access Mediator Registers SFR_PAGE(_su0, SST0); // switch to page 0 CAN_vWriteCANAddress(CAN_NSR0); CAN_vReadEN(); ubNSRL = CAN_DATA0; ubNSRH = CAN_DATA1; if (ubNSRL & 0x20) // if ALERT { CAN_vInit(); } if (ubNSRL & 0x07) // if LEC { ubResetLEC = 0x38; } //// Reset LEC, TXOK, RXOK, ALERT, EWRN, BOFF, LLE, LOE (if set) CAN_vWriteCANAddress(CAN_NSR0); // Addressing CAN_NSR0 CAN_DATA0 = ~(ubNSRL & ubResetLEC); // load CAN_NSR0 status register[7-0] CAN_DATA1 = ~(ubNSRH); // load CAN_NSR0 status register[15-8] CAN_vWriteEN(D0_VALID+D1_VALID); // Data0 and Data1 are Valid for SFR_PAGE(_su0, RST0); // restore the old SCU page CAN_popAMRegs(); // restore the CAN Access Mediator Registers EA = 1; } void CanTransmit(ubyte index,ubyte *buf) { ubyte CanTransmitbuf[8] = {0,0,0,0,0,0,0,0}; //----------------- -------- CanTransmitbuf[2] = buf[0]; CanTransmitbuf[3] = buf[1]; CanTransmitbuf[0] = buf[2]; CanTransmitbuf[1] = buf[3]; CanTransmitbuf[6] = buf[4]; CanTransmitbuf[7] = buf[5]; CanTransmitbuf[4] = buf[6]; CanTransmitbuf[5] = buf[7]; CAN_waitTransmit(index);//发送前等待上一帧发送完,不然会丢帧 CAN_vLoadData(index, (ulong *)CanTransmitbuf);// 装载数据 CAN_vTransmit(index); } typedef enum { STT_INIT_LIGHT, // 进入保持的初始状态 STT_STABLE, // 稳定态 STT_BLINK_CHECK, // 闪烁检测 STT_BLINKING // 闪烁确认 } BlinkState; typedef struct { BlinkState current_state; uint8_t last_input; uint16_t unified_timer; // 统一定时器 uint8_t trans_count; // 翻转次数需要记录 uint8_t stable_type; } BlinkDetector; BlinkDetector blink_detector = {0}; /* LED状态检测函数(状态机+统一定时器优化版) * 参数: * ctx - 状态机上下文指针(需保证非空) * current_input- 当前输入电平(0:低 1:高) * output - 输出状态指示(0:无效 1:稳定高 2:稳定低 3:闪烁) * 原理: * 1. 统一定时器替代原多计时器 * 2. 简化状态转移逻辑 * 3. 状态迁移原子操作 */ void detectLedState(BlinkDetector* ctx, uint8_t current_input, uint8_t* output) { *output = 0; switch(ctx->current_state) { /* 关键初始状态:确保首次状态正确建立 */ case STT_INIT_LIGHT: { ctx->last_input = current_input; // 强制记录初始值 ctx->stable_type = current_input ? 1 : 2; ctx->current_state = STT_STABLE; // 进入稳定状态 ctx->unified_timer = 0; // 初始化计时器 *output = 0; break; } case STT_STABLE: { if(current_input != ctx->last_input) { ctx->current_state = STT_BLINK_CHECK; ctx->trans_count = 1; ctx->unified_timer = 0; ctx->last_input = current_input; ctx->stable_type = current_input ? 1 : 2; // 同步状态变量 } else if(ctx->unified_timer >= STABLE_CONFIRM_TIME) { *output = ctx->stable_type; ctx->unified_timer = 0; ctx->stable_type = current_input ? 1 : 2; // 确认状态 } else { ctx->unified_timer++; *output = ctx->stable_type; } break; } /* 闪烁状态:时间窗口内统计电平翻转次数 */ case STT_BLINK_CHECK: { if(ctx->unified_timer >= BLINK_WINDOW) // 到达检测窗口时间 { if(ctx->trans_count >= MIN_BLINKS) // 达到最小闪烁次数 { ctx->current_state = STT_BLINKING;// 进入闪烁确认状态 ctx->unified_timer = 0; // 重置超时计时 } else // 未达闪烁阈值 { ctx->current_state = STT_STABLE; // 返回稳定状态 ctx->unified_timer = 0; // 重置状态计时器 } } else // 检测期内 { ctx->unified_timer++; // 统一计时累计 if(current_input != ctx->last_input) { ctx->trans_count++; // 翻转次数累计 ctx->last_input = current_input; // 更新最后检测值 } } break; } /* 闪烁确认状态:维持闪烁活动判断 */ case STT_BLINKING: { // 检测电平变化计数 if(current_input != ctx->last_input) { ctx->unified_timer = 0; // 重置超时计时 ctx->last_input = current_input; *output = 3; // 输出当前闪烁状态 } else if(ctx->unified_timer >= BLINK_TIMEOUT) { ctx->current_state = STT_STABLE; ctx->stable_type = current_input ? 1 : 2; // 更新当前稳定状态变量 ctx->unified_timer = 0; } else { ctx->unified_timer ++; // 维持当前稳定时间累计计时 *output = 3; // 输出当前闪烁状态 } break; } default:break; } } //SBUS转CAN数据解析 void sbusCanDecode(void) { float SBUS2CANdecodeTemp = 0.0; //---------------------------------------------- if(uart2RxFlag == 1) { uart2RxFlag = 0; //通道0 - 直接发送原始值 DF_Curvature = (int16_t)sbus_data.channels[0]; //通道1 - 直接发送原始值 DF_Speed = (int16_t)sbus_data.channels[1]; //通道7 - 直接发送原始值 DF_Reserve = (int16_t)sbus_data.channels[7]; //SwA if(sbus_data.channels[1] >= 1700)//高位 { DF_SwA = 1; } else { DF_SwA = 0; } //SwB if(sbus_data.channels[6] >= 1700)//第三档 { DF_SwB = 2; } else if(sbus_data.channels[6] <= 250)//第二档 { DF_SwB = 0; } else//第一档 { DF_SwB = 1; } //SwC if(sbus_data.channels[4] >= 1700)//第三档 { DF_SwC = 2; } else if(sbus_data.channels[4] <= 250)//第二档 { DF_SwC = 0; } else//第一档 { DF_SwC = 1; } //SwD if(sbus_data.channels[5] >= 1700)//高位 { DF_SwD = 1; } else { DF_SwD = 0; } if(0 == sbus_data.flags)//23通道状态 为0标志位表示遥控器 { DF_RCHSta = 1;//遥控器在线 } else { DF_RCHSta = 0;//遥控器离线 } SBUS2CANdecodeTemp = (float)(sbus_data.channels[2]); UnRemoteControlOutput_2.bit_data.speed = (int16_t)SBUS2CANdecodeTemp;//数据 SBUS2CANdecodeTemp = (float)(sbus_data.channels[3]); UnRemoteControlOutput_2.bit_data.curvature = (int16_t)SBUS2CANdecodeTemp;//数据 } UnRemoteControlOutput_2.bit_data.switch_a = P1_2;// UnRemoteControlOutput_2.bit_data.switch_d = P1_3;// } //CAN发送接收 void CanRXTX(void) { stCAN_SWObj StrCanRx = {0}; uword tmp = 0; ubyte i = 0,j = 0; ubyte sbus_temp[2] = {0,0}; static ubyte match_freq_sta = 0; static uword match_freq_cnt = 0; static uword match_freq_time = 0; //------------------------------------ if(CAN_ubNewData(DF_SwRx)) { CAN_vGetMsgObj(DF_SwRx, &StrCanRx); UnInfCan_1.ArrData.ArrRX[0][3] = StrCanRx.ulDATAL.ubDB[0]; UnInfCan_1.ArrData.ArrRX[0][2] = StrCanRx.ulDATAL.ubDB[1]; UnInfCan_1.ArrData.ArrRX[0][1] = StrCanRx.ulDATAL.ubDB[2]; UnInfCan_1.ArrData.ArrRX[0][0] = StrCanRx.ulDATAL.ubDB[3]; UnInfCan_1.ArrData.ArrRX[0][7] = StrCanRx.ulDATAH.ubDB[0]; UnInfCan_1.ArrData.ArrRX[0][6] = StrCanRx.ulDATAH.ubDB[1]; UnInfCan_1.ArrData.ArrRX[0][5] = StrCanRx.ulDATAH.ubDB[2]; UnInfCan_1.ArrData.ArrRX[0][4] = StrCanRx.ulDATAH.ubDB[3]; CAN_vReleaseObj(DF_SwRx); } if(CAN_ubNewData(DF_SwRxPwm)) { // CAN_vGetMsgObj(DF_SwRxPwm, &StrCanRx); // UnInfCan_1.ArrData.ArrRX[1][2] = StrCanRx.ulDATAL.ubDB[0]; // UnInfCan_1.ArrData.ArrRX[1][3] = StrCanRx.ulDATAL.ubDB[1]; // UnInfCan_1.ArrData.ArrRX[1][0] = StrCanRx.ulDATAL.ubDB[2]; // UnInfCan_1.ArrData.ArrRX[1][1] = StrCanRx.ulDATAL.ubDB[3]; // UnInfCan_1.ArrData.ArrRX[1][6] = StrCanRx.ulDATAH.ubDB[0]; // UnInfCan_1.ArrData.ArrRX[1][7] = StrCanRx.ulDATAH.ubDB[1]; // UnInfCan_1.ArrData.ArrRX[1][4] = StrCanRx.ulDATAH.ubDB[2]; // UnInfCan_1.ArrData.ArrRX[1][5] = StrCanRx.ulDATAH.ubDB[3]; // CAN_vReleaseObj(DF_SwRxPwm); //// //接收到的数据保存到PWM数据结构体20181227 //// PwmH[0 ] = (ubyte)UnInfCan_1.BitData.Pwm_01; //// PwmH[1 ] = (ubyte)UnInfCan_1.BitData.Pwm_02; //// PwmH[2 ] = (ubyte)UnInfCan_1.BitData.Pwm_03; //// PwmH[3 ] = (ubyte)UnInfCan_1.BitData.Pwm_04; //// PwmH[4 ] = (ubyte)UnInfCan_1.BitData.Pwm_05; //// PwmH[5 ] = (ubyte)UnInfCan_1.BitData.Pwm_06; //// PwmH[6 ] = (ubyte)UnInfCan_1.BitData.Pwm_07; //// PwmH[7 ] = (ubyte)UnInfCan_1.BitData.Pwm_08; //// PwmH[8 ] = (ubyte)UnInfCan_1.BitData.Pwm_09; //// PwmH[9 ] = (ubyte)UnInfCan_1.BitData.Pwm_10; //// PwmH[10] = (ubyte)UnInfCan_1.BitData.Pwm_11; //// PwmH[11] = (ubyte)UnInfCan_1.BitData.Pwm_12; //// PwmH[12] = (ubyte)UnInfCan_1.BitData.Pwm_13; //// PwmH[13] = (ubyte)UnInfCan_1.BitData.Pwm_14; //// PwmH[14] = (ubyte)UnInfCan_1.BitData.Pwm_15; //// PwmH[15] = (ubyte)UnInfCan_1.BitData.Pwm_16; } //50ms发送一帧 if(!FlgCan_1) { FlgCan_1 = 1; sbus_temp[0] = P1_3; // sbus_temp[1] = 3; detectLedState(&blink_detector, sbus_temp[0], &sbus_temp[1]); // UnRemoteControlOutput_2.bit_data.enable = blink_detector.current_state;// // UnRemoteControlOutput_2.bit_data.reserve1 = sbus_temp[1]; if( (MATCH_CMD == UnInfCan_1.ArrData.ArrRX[0][0]) || (CHANGE_CMD == UnInfCan_1.ArrData.ArrRX[0][0]) )//对频命令或切换 { if(MATCH_CMD == UnInfCan_1.ArrData.ArrRX[0][0])//对频 { match_freq_time = MATCH_TIME; } else { match_freq_time = CHANGE_TIME; } switch(match_freq_sta) { case 0: if(match_freq_cnt >= match_freq_time)//时间到了就发送确认 { SwOut01 = 0;//取消对频 match_freq_sta = 1; match_freq_cnt = 0; } else { SwOut01 = 1;//对频指令 match_freq_sta = 0; match_freq_cnt ++; } break; case 1: if(match_freq_cnt >= MATCH_WAIT_TIME)// { SwOut01 = 0;//取消对频 match_freq_sta = 0; match_freq_cnt = 0; UnInfCan_1.ArrData.ArrRX[0][0] = 0; } else { SwOut01 = 0;//对频指令 match_freq_sta = 1; match_freq_cnt ++; } break; default:; } } CanTransmit(DF_SwTx,(ubyte *)&UnRemoteControlOutput_1.arr[0]); CanTransmit(DF_SwTx1,(ubyte *)&UnRemoteControlOutput_2.arr[0]); } if( (0x40 == can_error_cnt) || (0x80 == can_error_cnt) )//20250625判断是否发生总线错误 { can_error_flg = can_error_cnt; CAN_vInit(); can_error_cnt = 0; } }