diff --git a/A11_F407_SDC_ACQ_DAC_CubeMX/A11_F407_SDC_ACQ_DAC.ioc b/A11_F407_SDC_ACQ_DAC_CubeMX/A11_F407_SDC_ACQ_DAC.ioc index eb50f98..cfa50b1 100644 --- a/A11_F407_SDC_ACQ_DAC_CubeMX/A11_F407_SDC_ACQ_DAC.ioc +++ b/A11_F407_SDC_ACQ_DAC_CubeMX/A11_F407_SDC_ACQ_DAC.ioc @@ -68,14 +68,17 @@ Mcu.Pin28=PB9 Mcu.Pin29=PE0 Mcu.Pin3=PB0 Mcu.Pin30=PE1 -Mcu.Pin31=VP_SYS_VS_Systick +Mcu.Pin31=PE9 +Mcu.Pin32=PE10 +Mcu.Pin33=PE11 +Mcu.Pin34=VP_SYS_VS_Systick Mcu.Pin4=PB10 Mcu.Pin5=PB11 Mcu.Pin6=PB14 Mcu.Pin7=PD8 Mcu.Pin8=PD9 Mcu.Pin9=PD10 -Mcu.PinsNb=32 +Mcu.PinsNb=35 Mcu.ThirdPartyNb=0 Mcu.UserConstants= Mcu.UserName=STM32F407VETx @@ -139,6 +142,9 @@ PD8.Signal=GPXTI8 PD9.Signal=GPXTI9 PE0.Signal=GPIO_Output PE1.Signal=GPIO_Output +PE9.Signal=GPIO_Output +PE10.Signal=GPIO_Output +PE11.Signal=GPIO_Output PinOutPanel.RotationAngle=0 ProjectManager.AskForMigrate=true ProjectManager.BackupPrevious=false diff --git a/A11_F407_SDC_ACQ_DAC_CubeMX/Src/main.c b/A11_F407_SDC_ACQ_DAC_CubeMX/Src/main.c index 6bf5195..63fa698 100644 --- a/A11_F407_SDC_ACQ_DAC_CubeMX/Src/main.c +++ b/A11_F407_SDC_ACQ_DAC_CubeMX/Src/main.c @@ -66,12 +66,20 @@ typedef struct #define CAN_HEARTBEAT_PERIOD_MS 1000U #define PWM_TIMEOUT_MS 1000U -#define CAN_HEARTBEAT_STD_ID 0x100U -#define CAN_GPIO_REPORT_STD_ID 0x330U -#define CAN_ADC_REPORT_STD_ID 0x102U -#define CAN_PWM_REPORT_STD_ID 0x103U -#define CAN_DAC_CMD_STD_ID 0x321U -#define CAN_DAC_ACK_STD_ID 0x322U +#define CAN_HEARTBEAT_STD_ID 0x6A0U +#define CAN_ADC_REPORT_STD_ID 0x6A1U +#define CAN_PWM_REPORT_STD_ID 0x6A2U +#define CAN_DAC_CMD_STD_ID 0x6A3U +#define CAN_DAC_ACK_STD_ID 0x6A4U +#define CAN_ASSI_LAMP_CMD_STD_ID 0x6A5U +#define CAN_GPIO_REPORT_STD_ID 0x6A6U + +#define ASSI_LAMP_FLASH_HALF_PERIOD_MS 250U +#define ASSI_STATE_OFF 0U +#define ASSI_STATE_READY 1U +#define ASSI_STATE_DRIVING 2U +#define ASSI_STATE_EMERGENCY 3U +#define ASSI_STATE_FINISHED 4U /* USER CODE END PD */ @@ -110,7 +118,8 @@ static uint32_t adc_filter_sum; static uint8_t adc_filter_count; static uint8_t adc_filter_index; static char uart_line[UART_LINE_SIZE]; -static uint8_t uart_line_len; +static uint8_t uart_line_len; +static uint8_t assi_lamp_state; /* USER CODE END PV */ @@ -133,8 +142,10 @@ static void PollCanBus(CAN_HandleTypeDef *hcan, const char *name); static void PollCaptureChannels(void); static void PollGpioChanges(void); static void SendPeriodicReport(void); -static void ServiceHeartbeat(void); -static void SendCanHeartbeat(void); +static void ServiceHeartbeat(void); +static void ServiceAssiLamp(void); +static void SendCanHeartbeat(void); +static void HandleAssiLampSetRequest(const char *source, uint8_t state); static void HandleTextCommand(const char *source, const char *line); static void HandleDacSetRequest(const char *source, uint8_t dac_id, uint16_t millivolts); static void UartWrite(const char *text); @@ -221,9 +232,10 @@ int main(void) /* USER CODE BEGIN 3 */ PollUart(); - PollCanBus(&hcan1, "CAN1"); - PollCanBus(&hcan2, "CAN2"); - PollCaptureChannels(); + PollCanBus(&hcan1, "CAN1"); + PollCanBus(&hcan2, "CAN2"); + ServiceAssiLamp(); + PollCaptureChannels(); PollGpioChanges(); SendPeriodicReport(); ServiceHeartbeat(); @@ -666,7 +678,7 @@ static void MX_GPIO_Init(void) HAL_GPIO_WritePin(GPIOA, GPIO_PIN_11, GPIO_PIN_RESET); /*Configure GPIO pin Output Level */ - HAL_GPIO_WritePin(GPIOE, GPIO_PIN_0|GPIO_PIN_1, GPIO_PIN_RESET); + HAL_GPIO_WritePin(GPIOE, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11, GPIO_PIN_RESET); /*Configure GPIO pins : PD8 PD9 PD10 PD11 PD12 PD13 PD14 PD0 @@ -687,8 +699,8 @@ static void MX_GPIO_Init(void) GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); - /*Configure GPIO pins : PE0 PE1 */ - GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1; + /*Configure GPIO pins : PE0 PE1 PE9 PE10 PE11 */ + GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; @@ -753,14 +765,16 @@ static void AppInit(void) adc_filter_sum = 0U; adc_filter_count = 0U; adc_filter_index = 0U; - uart_line_len = 0U; + uart_line_len = 0U; + assi_lamp_state = ASSI_STATE_OFF; (void)DacSetMillivolts(1U, 0U); (void)DacSetMillivolts(2U, 0U); UartWrite("\r\nA11 F407 monitor ready\r\n"); UartWrite("UART: DAC1 1.234 or DAC2 2500\r\n"); - UartWrite("CAN cmd 0x321: [dac_id][mV_L][mV_H] or ASCII text\r\n"); + UartWrite("CAN cmd 0x6A3: [dac_id][mV_L][mV_H] or ASCII text\r\n"); + UartWrite("CAN cmd 0x6A5: [ASSI state 0=OFF,1=READY,2=DRIVING,3=EMERGENCY,4=FINISHED]\r\n"); BroadcastGpioReport(0U, gpio_last_state); } @@ -810,7 +824,7 @@ static void PollCanBus(CAN_HandleTypeDef *hcan, const char *name) continue; } - if (rx_header.StdId == CAN_DAC_CMD_STD_ID) + if (rx_header.StdId == CAN_DAC_CMD_STD_ID) { if ((rx_header.DLC >= 3U) && (rx_data[0] >= 1U) && (rx_data[0] <= 2U)) { @@ -825,8 +839,15 @@ static void PollCanBus(CAN_HandleTypeDef *hcan, const char *name) memcpy(line, rx_data, length); line[length] = '\0'; HandleTextCommand(name, line); - } - } + } + } + else if (rx_header.StdId == CAN_ASSI_LAMP_CMD_STD_ID) + { + if ((rx_header.DLC >= 1U) && (rx_data[0] <= ASSI_STATE_FINISHED)) + { + HandleAssiLampSetRequest(name, rx_data[0]); + } + } } } @@ -918,7 +939,7 @@ static void SendPeriodicReport(void) } } -static void ServiceHeartbeat(void) +static void ServiceHeartbeat(void) { uint32_t now = HAL_GetTick(); @@ -927,7 +948,53 @@ static void ServiceHeartbeat(void) last_heartbeat_ms = now; HAL_GPIO_TogglePin(GPIOE, GPIO_PIN_0); } -} +} + +static void ServiceAssiLamp(void) +{ + GPIO_PinState red = GPIO_PIN_RESET; + GPIO_PinState green = GPIO_PIN_RESET; + GPIO_PinState blue = GPIO_PIN_RESET; + bool flash_on = ((HAL_GetTick() / ASSI_LAMP_FLASH_HALF_PERIOD_MS) & 1U) == 0U; + + switch (assi_lamp_state) + { + case ASSI_STATE_READY: + red = GPIO_PIN_SET; + green = GPIO_PIN_SET; + break; + + case ASSI_STATE_DRIVING: + red = flash_on ? GPIO_PIN_SET : GPIO_PIN_RESET; + green = flash_on ? GPIO_PIN_SET : GPIO_PIN_RESET; + break; + + case ASSI_STATE_EMERGENCY: + blue = flash_on ? GPIO_PIN_SET : GPIO_PIN_RESET; + break; + + case ASSI_STATE_FINISHED: + blue = GPIO_PIN_SET; + break; + + case ASSI_STATE_OFF: + default: + break; + } + + HAL_GPIO_WritePin(GPIOE, GPIO_PIN_9, red); + HAL_GPIO_WritePin(GPIOE, GPIO_PIN_10, green); + HAL_GPIO_WritePin(GPIOE, GPIO_PIN_11, blue); +} + +static void HandleAssiLampSetRequest(const char *source, uint8_t state) +{ + char reply[64]; + + assi_lamp_state = state; + snprintf(reply, sizeof(reply), "OK %s ASSI state=%u\r\n", source, (unsigned int)state); + UartWrite(reply); +} static void SendCanHeartbeat(void) { @@ -945,7 +1012,7 @@ static void SendCanHeartbeat(void) can_heartbeat_sequence++; gpio_state = ReadGpioInputState(); - /* CAN ID 0x100, sent independently on CAN1 and CAN2: + /* CAN ID 0x6A0, sent independently on CAN1 and CAN2: * [0] 0xA1 board identifier; [1] firmware protocol version 1; * [2..3] sequence counter, little-endian; [4..7] uptime in ms, little-endian. */ diff --git a/SDC-ACQ_DAC_固件交付说明.html b/SDC-ACQ_DAC_固件交付说明.html index b6b3c74..86b8f2c 100644 --- a/SDC-ACQ_DAC_固件交付说明.html +++ b/SDC-ACQ_DAC_固件交付说明.html @@ -99,20 +99,21 @@

所有字段均为小端序(低字节在前)。板卡主动上报的帧会分别发到 CAN1 和 CAN2。

- - - - - - + + + + + + +
CAN ID名称方向 / 时机数据定义
0x100心跳板卡发送,每 1 sA1 01 seq_L seq_H uptime_0..3;板号 A1、协议版本 1、序号、运行时间 ms。
0x102输入电压板卡发送,每 500 msuint16,单位 mV。例如 90 2F = 0x2F90 = 12176 mV = 12.176 V。
0x103四路频率板卡发送,每 500 ms4 个 uint16,单位 Hz;依次为 PA0、PA2、PA6、PB14。
0x321DAC 设置外部发送给板卡[DAC 编号][mV_L][mV_H],编号仅允许 1 或 2。
0x322DAC 应答板卡发送,设置后[结果][DAC 编号][mV_L][mV_H];结果 1 成功,0 失败。
0x33015 路状态板卡发送,上电或状态变化状态 uint16、变化掩码 uint16、时间戳 uint32 ms。
0x6A0心跳板卡发送,每 1 sA1 01 seq_L seq_H uptime_0..3;板号 A1、协议版本 1、序号、运行时间 ms。
0x6A1输入电压板卡发送,每 500 msuint16,单位 mV。例如 90 2F = 0x2F90 = 12176 mV = 12.176 V。
0x6A2四路频率板卡发送,每 500 ms4 个 uint16,单位 Hz;依次为 PA0、PA2、PA6、PB14。
0x6A3DAC 设置外部发送给板卡[DAC 编号][mV_L][mV_H],编号仅允许 1 或 2。
0x6A4DAC 应答板卡发送,设置后[结果][DAC 编号][mV_L][mV_H];结果 1 成功,0 失败。
0x6A5ASSI RGB 灯控外部发送给板卡byte0:0=关、1=黄常亮、2=黄闪、3=蓝闪、4=蓝常亮。
0x6A615 路状态板卡发送,上电或状态变化状态 uint16、变化掩码 uint16、时间戳 uint32 ms。

DAC 设置示例

电压 V 到 CAN 数据的换算:mV = round(V × 1000),随后拆为低字节和高字节。

-
DAC1 输出 3.000 V:ID = 0x321,DLC = 3,DATA = 01 B8 0B
-DAC2 输出 1.140 V:ID = 0x321,DLC = 3,DATA = 02 74 04
+  
DAC1 输出 3.000 V:ID = 0x6A3,DLC = 3,DATA = 01 B8 0B
+DAC2 输出 1.140 V:ID = 0x6A3,DLC = 3,DATA = 02 74 04
 
-应答示例(DAC1 成功设为 3.000 V):ID = 0x322,DATA = 01 01 B8 0B
+应答示例(DAC1 成功设为 3.000 V):ID = 0x6A4,DATA = 01 01 B8 0B
DAC 输出范围为 0–5000 mV。软件中 DAC1、DAC2 到板级 MC_L、MC_R 的实际对应关系应以实物测量为准。

4. ADC 电压说明

@@ -124,7 +125,7 @@ DAC2 输出 1.140 V:ID = 0x321,DLC = 3,DATA = 02 74 04
DAC1 1.234
 DAC2 2500
 D1 2.5V
-

命令不区分大小写,支持伏特小数或毫伏整数。设置完成后串口会回显结果,CAN1/CAN2 同时发送 0x322 应答。

+

命令不区分大小写,支持伏特小数或毫伏整数。设置完成后串口会回显结果,CAN1/CAN2 同时发送 0x6A4 应答。

6. 频率输入说明

频率使用相邻上升沿时间差计算;连续 1 秒没有新边沿时,该通道输出 0 Hz。当前版本只测频率,不输出占空比。

diff --git a/SDC_ACQ_DAC.dbc b/SDC_ACQ_DAC.dbc index 2c5b54a..58e76e0 100644 --- a/SDC_ACQ_DAC.dbc +++ b/SDC_ACQ_DAC.dbc @@ -34,46 +34,51 @@ BS_: BU_: SDC_ACQ_DAC VehicleController -BO_ 256 SDC_Heartbeat: 8 SDC_ACQ_DAC +BO_ 1696 SDC_Heartbeat: 8 SDC_ACQ_DAC SG_ Board_Identifier : 0|8@1+ (1,0) [0|255] "" VehicleController SG_ Protocol_Version : 8|8@1+ (1,0) [0|255] "" VehicleController SG_ Heartbeat_Sequence : 16|16@1+ (1,0) [0|65535] "" VehicleController SG_ Uptime : 32|32@1+ (0.001,0) [0|4294967.295] "s" VehicleController -BO_ 258 SDC_ADC_InputVoltage: 2 SDC_ACQ_DAC +BO_ 1697 SDC_ADC_InputVoltage: 2 SDC_ACQ_DAC SG_ Input_Voltage : 0|16@1+ (0.001,0) [0|65.535] "V" VehicleController -BO_ 259 SDC_InputFrequencies: 8 SDC_ACQ_DAC +BO_ 1698 SDC_InputFrequencies: 8 SDC_ACQ_DAC SG_ Frequency_PA0 : 0|16@1+ (1,0) [0|65535] "Hz" VehicleController SG_ Frequency_PA2 : 16|16@1+ (1,0) [0|65535] "Hz" VehicleController SG_ Frequency_PA6 : 32|16@1+ (1,0) [0|65535] "Hz" VehicleController SG_ Frequency_PB14 : 48|16@1+ (1,0) [0|65535] "Hz" VehicleController -BO_ 801 SDC_DAC_Set: 3 VehicleController +BO_ 1699 SDC_DAC_Set: 3 VehicleController SG_ DAC_Select : 0|8@1+ (1,0) [1|2] "" SDC_ACQ_DAC SG_ DAC_Command_Voltage : 8|16@1+ (0.001,0) [0|5] "V" SDC_ACQ_DAC -BO_ 802 SDC_DAC_Ack: 4 SDC_ACQ_DAC +BO_ 1700 SDC_DAC_Ack: 4 SDC_ACQ_DAC SG_ DAC_Set_Result : 0|8@1+ (1,0) [0|1] "" VehicleController SG_ DAC_Select : 8|8@1+ (1,0) [1|2] "" VehicleController SG_ DAC_Output_Voltage : 16|16@1+ (0.001,0) [0|5] "V" VehicleController -BO_ 816 SDC_GPIO_Status: 8 SDC_ACQ_DAC +BO_ 1701 ASSI_Lamp_Set: 1 VehicleController + SG_ ASSI_State : 0|8@1+ (1,0) [0|4] "" SDC_ACQ_DAC + +BO_ 1702 SDC_GPIO_Status: 8 SDC_ACQ_DAC SG_ SDC_Input_State : 0|15@1+ (1,0) [0|32767] "" VehicleController SG_ SDC_Changed_Mask : 16|15@1+ (1,0) [0|32767] "" VehicleController SG_ Timestamp : 32|32@1+ (0.001,0) [0|4294967.295] "s" VehicleController -VAL_ 256 Board_Identifier 161 "A11_F407" ; -VAL_ 801 DAC_Select 1 "DAC1" 2 "DAC2" ; -VAL_ 802 DAC_Set_Result 0 "Failed" 1 "OK" ; -VAL_ 802 DAC_Select 1 "DAC1" 2 "DAC2" ; +VAL_ 1696 Board_Identifier 161 "A11_F407" ; +VAL_ 1699 DAC_Select 1 "DAC1" 2 "DAC2" ; +VAL_ 1700 DAC_Set_Result 0 "Failed" 1 "OK" ; +VAL_ 1700 DAC_Select 1 "DAC1" 2 "DAC2" ; +VAL_ 1701 ASSI_State 0 "AS_OFF" 1 "AS_READY" 2 "AS_DRIVING" 3 "AS_EMERGENCY" 4 "AS_FINISHED" ; -CM_ BO_ 256 "Standard ID 0x100. Sent every 1 s on CAN1 and CAN2."; -CM_ BO_ 258 "Standard ID 0x102. Filtered and calibrated physical input voltage before the hardware divider."; -CM_ BO_ 259 "Standard ID 0x103. Sent every 500 ms. Frequency order is PA0, PA2, PA6, PB14."; -CM_ BO_ 801 "Standard ID 0x321. Accepted on CAN1 and CAN2. The on-wire voltage is an unsigned mV value."; -CM_ BO_ 802 "Standard ID 0x322. Sent on CAN1 and CAN2 after a DAC command. Result 0 indicates the I2C write failed."; -CM_ BO_ 816 "Standard ID 0x330. Sent at startup and whenever PD0-PD14 state changes, on CAN1 and CAN2."; +CM_ BO_ 1696 "Standard ID 0x6A0. Sent every 1 s on CAN1 and CAN2."; +CM_ BO_ 1697 "Standard ID 0x6A1. Filtered and calibrated physical input voltage before the hardware divider."; +CM_ BO_ 1698 "Standard ID 0x6A2. Sent every 500 ms. Frequency order is PA0, PA2, PA6, PB14."; +CM_ BO_ 1699 "Standard ID 0x6A3. Accepted on CAN1 and CAN2. The on-wire voltage is an unsigned mV value."; +CM_ BO_ 1700 "Standard ID 0x6A4. Sent on CAN1 and CAN2 after a DAC command. Result 0 indicates the I2C write failed."; +CM_ BO_ 1701 "Standard ID 0x6A5. Accepted on CAN1 and CAN2. Byte 0 selects the latched ASSI RGB lamp state: AS_OFF, AS_READY, AS_DRIVING, AS_EMERGENCY, or AS_FINISHED."; +CM_ BO_ 1702 "Standard ID 0x6A6. Sent at startup and whenever PD0-PD14 state changes, on CAN1 and CAN2."; CM_ SG_ 256 Board_Identifier "Fixed board identifier 0xA1."; CM_ SG_ 259 Frequency_PA0 "TIM5_CH1 input capture on PA0."; CM_ SG_ 259 Frequency_PA2 "TIM9_CH1 input capture on PA2."; diff --git a/output/pdf/CAN报文说明表.pdf b/output/pdf/CAN报文说明表.pdf new file mode 100644 index 0000000..8813947 --- /dev/null +++ b/output/pdf/CAN报文说明表.pdf @@ -0,0 +1,89 @@ +%PDF-1.4 +%“Œ‹ž ReportLab Generated PDF document (opensource) +1 0 obj +<< +/F1 2 0 R /F2 3 0 R +>> +endobj +2 0 obj +<< +/BaseFont /Helvetica /Encoding /WinAnsiEncoding /Name /F1 /Subtype /Type1 /Type /Font +>> +endobj +3 0 obj +<< +/BaseFont /STSong-Light /DescendantFonts [ << +/BaseFont /STSong-Light /CIDSystemInfo << +/Ordering (GB1) /Registry (Adobe) /Supplement 0 +>> /DW 1000 /FontDescriptor << +/Ascent 752 /CapHeight 737 /Descent -271 /Flags 6 /FontBBox [ -25 -254 1000 880 ] /FontName /STSongStd-Light + /ItalicAngle 0 /Leading 148 /MaxWidth 1000 /MissingWidth 500 /StemH 91 /StemV 58 + /Type /FontDescriptor /XHeight 553 +>> /Subtype /CIDFontType0 /Type /Font + /W [ 1 [ 207 270 342 467 462 797 710 239 374 ] 10 [ 374 423 605 238 375 238 334 462 ] 18 26 462 27 28 238 + 29 31 605 32 [ 344 748 684 560 695 739 563 511 729 793 + 318 312 666 526 896 758 772 544 772 628 + 465 607 753 711 972 647 620 607 374 333 + 374 606 500 239 417 503 427 529 415 264 + 444 518 241 230 495 228 793 527 524 ] 81 [ 524 504 338 336 277 517 450 652 466 452 + 407 370 258 370 605 ] ] +>> ] /Encoding /UniGB-UCS2-H /Name /F2 /Subtype /Type0 /Type /Font +>> +endobj +4 0 obj +<< +/Contents 8 0 R /MediaBox [ 0 0 841.8898 595.2756 ] /Parent 7 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +5 0 obj +<< +/PageMode /UseNone /Pages 7 0 R /Type /Catalog +>> +endobj +6 0 obj +<< +/Author (\(anonymous\)) /CreationDate (D:20260918211423+08'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260918211423+08'00') /Producer (ReportLab PDF Library - \(opensource\)) + /Subject (\(unspecified\)) /Title (\376\377\000S\000D\000C\000-\000A\000C\000Q\000_\000D\000A\000C\000 \000C\000A\000N\000 b\245e\207\213\364f\016\210h) /Trapped /False +>> +endobj +7 0 obj +<< +/Count 1 /Kids [ 4 0 R ] /Type /Pages +>> +endobj +8 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 2111 +>> +stream +Gb!;fh/h((&:`#5Tg!Re16%B=ojKYo"7u]ZKS7Mh@60e&L5&MI+XA`F*r+L%P0]Xn:@RY>6o>J'tgP:)LT+A(Q3m9EL\HB2W`gB%u\8fuDbU3Tj?FfSs\;1G4Zm_CuIBs87+oABM-8@C$VN!gkOp&tn%^JB2R.5kNa%$e3En#VgJH:TjN@2-[5o'tP(14:Nj(^qu9Wg[Sd/'e"K0JZok[XO*p/Q&p_]il1Y.p6*\'Z)ptQ1;SYCqTL'>[p#-D%/gT$"pV@H'S%)>a3k5t0Wp*^$6f!\#X!Am/V9WH?^C;IE$d^6K+.;JB6VB&:pOHS65#8u=3(KVIBQXNX\EkHN7'SNa1V@HUsl_gKuW3OumcCL%9A?jUgGN7$r`K38ff_\Y@443J"?mGN[^Y,&JS5J/rTV?2;+fCqW-RYD;g4^Z[)Y+Kf@:Ejc1ojld"%G(^B>u.4hT+7VYO+RlA:6+2sWQ/+NV=t#7VZGQ/)jgX[2o(kGgqB?6H9]%H7D,`*RXe$6)N4i'VKQ#CZohp'$tu';rAl[I;VD6\Q2i`W:ShBuB5OR1FkGI\3M5RfACWtZ48KOp.C1-bWCdGGRcOVN,d7H1f8o3Rspp9"csLseN@+AT_b&X.3;F;;\=^j"2:m[\tHb$5V)PaB%pZ!4+S7M(5MB8]WDR(9f/n9p_4-8Q:ks.`1bk-pN%b0gtkWpYthLA*`']cMhLi_@(NNlc5P(e#6_*W`"gdffuI^ji9_re5)`k7nj*Hds`,O"NWHhUc3YOqk<%;sPph.C!?J+X'<]fR/Q2>]I_2F!%jJmJ+.RsL62'1=T,>)Y&!!C?.[H]-srJY\Ij>rRifSHX"6C"a9d2$=;(!qdI`.bY$j2$?IZh^i]=p/b"CjuIendstream +endobj +xref +0 9 +0000000000 65535 f +0000000061 00000 n +0000000102 00000 n +0000000209 00000 n +0000001142 00000 n +0000001345 00000 n +0000001413 00000 n +0000001796 00000 n +0000001855 00000 n +trailer +<< +/ID +[<0c601b021e0ca62988154610c4965733><0c601b021e0ca62988154610c4965733>] +% ReportLab generated PDF document -- digest (opensource) + +/Info 6 0 R +/Root 5 0 R +/Size 9 +>> +startxref +4057 +%%EOF diff --git a/固件使用说明.md b/固件使用说明.md index f08b2c3..944430d 100644 --- a/固件使用说明.md +++ b/固件使用说明.md @@ -30,6 +30,7 @@ | CAN1 | `PB8` RX、`PB9` TX | 标准帧,500 kbit/s | | CAN2 | `PB5` RX、`PB6` TX | 标准帧,500 kbit/s | | DAC I2C | `PB10` SCL、`PB11` SDA / `I2C2` | 控制两颗 MCP4725,5 V 基准 | +| ASSI RGB 灯 MOS | `PE9` R、`PE10` G、`PE11` B | 推挽输出,高电平使能外部 MOS | | 调试串口 | `PA9` TX、`PA10` RX / `USART1` | 115200、8N1、无流控 | | 运行/故障 LED | `PE0` / `PE1` | 正常心跳 / 故障指示 | @@ -77,27 +78,32 @@ CAN1 和 CAN2 使用相同协议,所有主动上报均分别发送到两条总 | ID | 名称 | 周期/触发 | 数据 | |---:|---|---|---| -| `0x100` | 心跳 | 每 1 s | `A1 01 seq_L seq_H uptime_0..3` | -| `0x102` | ADC 电压 | 每 500 ms | 输入电压 `uint16`,单位 mV | -| `0x103` | 四路频率 | 每 500 ms | 4 个 `uint16`,单位 Hz,顺序 PA0/PA2/PA6/PB14 | -| `0x330` | GPIO 状态 | 上电、任一输入变化 | 状态 `uint16`、变化掩码 `uint16`、时间戳 `uint32 ms` | -| `0x321` | DAC 设置命令 | 接收 | `[DAC 编号][mV_L][mV_H]` | -| `0x322` | DAC 应答 | 每次 DAC 设置后 | `[结果][DAC 编号][mV_L][mV_H]` | +| `0x6A0` | 心跳 | 每 1 s | `A1 01 seq_L seq_H uptime_0..3` | +| `0x6A1` | ADC 电压 | 每 500 ms | 输入电压 `uint16`,单位 mV | +| `0x6A2` | 四路频率 | 每 500 ms | 4 个 `uint16`,单位 Hz,顺序 PA0/PA2/PA6/PB14 | +| `0x6A3` | DAC 设置命令 | 接收 | `[DAC 编号][mV_L][mV_H]` | +| `0x6A4` | DAC 应答 | 每次 DAC 设置后 | `[结果][DAC 编号][mV_L][mV_H]` | +| `0x6A5` | ASSI 灯控 | 接收 | `byte0`:`0=AS_OFF`、`1=AS_READY`、`2=AS_DRIVING`、`3=AS_EMERGENCY`、`4=AS_FINISHED` | +| `0x6A6` | GPIO 状态 | 上电、任一输入变化 | 状态 `uint16`、变化掩码 `uint16`、时间戳 `uint32 ms` | 心跳帧中板号为 `0xA1`、协议版本为 `0x01`,序号与上电时间均为低字节在前。完整信号定义和量纲以 [DBC 文件](SDC_ACQ_DAC.dbc) 为准。 +### ASSI RGB 状态灯 + +`PE9/PE10/PE11` 分别控制外部红、绿、蓝灯 MOS,均为高电平有效。`0x6A5` 可由 CAN1 或 CAN2 接收,状态在下一帧有效灯控报文到达前保持不变;上电默认 `AS_OFF`。`AS_READY` 为红绿常亮(黄),`AS_DRIVING` 为红绿以 2 Hz、50% 占空比闪烁(各 250 ms 亮/灭),`AS_EMERGENCY` 为蓝灯以相同节奏闪烁,`AS_FINISHED` 为蓝灯常亮。`PE0` 运行心跳和 `PE1` 故障指示保持原行为。 + ### DAC CAN 报文示例 将 DAC1 设为 2.500 V: ```text -ID=0x321 DLC=3 DATA=01 C4 09 +ID=0x6A3 DLC=3 DATA=01 C4 09 ``` 成功应答: ```text -ID=0x322 DLC=4 DATA=01 01 C4 09 +ID=0x6A4 DLC=4 DATA=01 01 C4 09 ``` DAC 编号 1 的 I2C 7 位地址为 `0x61`,编号 2 为 `0x60`。两路与板级 `MC_L`、`MC_R` 网络的实际对应关系需要以实物测量确认后再固化到线束文档。 @@ -111,7 +117,7 @@ DAC 编号 1 的 I2C 7 位地址为 `0x61`,编号 2 为 `0x60`。两路与板 ```text A11 F407 monitor ready UART: DAC1 1.234 or DAC2 2500 -CAN cmd 0x321: [dac_id][mV_L][mV_H] or ASCII text +CAN cmd 0x6A3: [dac_id][mV_L][mV_H] or ASCII text ``` 支持的 DAC 命令不区分大小写: @@ -122,7 +128,7 @@ DAC2 2500 D1 2.5V ``` -数值可使用伏特小数或毫伏整数;允许范围为 0 至 5000 mV。命令执行后会回显结果,并在两条 CAN 上发送 `0x322` 应答。 +数值可使用伏特小数或毫伏整数;允许范围为 0 至 5000 mV。命令执行后会回显结果,并在两条 CAN 上发送 `0x6A4` 应答。 ## 8. 编译、生成与下载 @@ -158,6 +164,6 @@ Release 固件为 `build/Release/A11_F407_SDC_ACQ_DAC.bin`。若改动了 `.ioc` - 变更 CubeMX 配置后必须重新生成并重新编译,检查 `main.c` 的用户代码区是否完整保留。 - 修改 CAN 速率时,CAN1 与 CAN2 的波特率及外部分析仪配置必须一致。 -- 修改 ADC 分压、标定或滤波参数时,应使用已知直流电压复测,并确认 CAN `0x102` 与串口数值一致。 +- 修改 ADC 分压、标定或滤波参数时,应使用已知直流电压复测,并确认 CAN `0x6A1` 与串口数值一致。 - 修改 DAC 地址、参考电压或输出范围时,同时更新 DBC、本文和 `DAC*_ADDR7`、`DAC_REFERENCE_MV` 宏。 - 本工程不包含构建目录和 `.bin`、`.elf`、`.hex` 等固件二进制;发布生产固件前应从当前提交重新编译生成。