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 s | A1 01 seq_L seq_H uptime_0..3;板号 A1、协议版本 1、序号、运行时间 ms。 |
0x102 | 输入电压 | 板卡发送,每 500 ms | uint16,单位 mV。例如 90 2F = 0x2F90 = 12176 mV = 12.176 V。 |
0x103 | 四路频率 | 板卡发送,每 500 ms | 4 个 uint16,单位 Hz;依次为 PA0、PA2、PA6、PB14。 |
0x321 | DAC 设置 | 外部发送给板卡 | [DAC 编号][mV_L][mV_H],编号仅允许 1 或 2。 |
0x322 | DAC 应答 | 板卡发送,设置后 | [结果][DAC 编号][mV_L][mV_H];结果 1 成功,0 失败。 |
0x330 | 15 路状态 | 板卡发送,上电或状态变化 | 状态 uint16、变化掩码 uint16、时间戳 uint32 ms。 |
0x6A0 | 心跳 | 板卡发送,每 1 s | A1 01 seq_L seq_H uptime_0..3;板号 A1、协议版本 1、序号、运行时间 ms。 |
0x6A1 | 输入电压 | 板卡发送,每 500 ms | uint16,单位 mV。例如 90 2F = 0x2F90 = 12176 mV = 12.176 V。 |
0x6A2 | 四路频率 | 板卡发送,每 500 ms | 4 个 uint16,单位 Hz;依次为 PA0、PA2、PA6、PB14。 |
0x6A3 | DAC 设置 | 外部发送给板卡 | [DAC 编号][mV_L][mV_H],编号仅允许 1 或 2。 |
0x6A4 | DAC 应答 | 板卡发送,设置后 | [结果][DAC 编号][mV_L][mV_H];结果 1 成功,0 失败。 |
0x6A5 | ASSI RGB 灯控 | 外部发送给板卡 | byte0:0=关、1=黄常亮、2=黄闪、3=蓝闪、4=蓝常亮。 |
0x6A6 | 15 路状态 | 板卡发送,上电或状态变化 | 状态 uint16、变化掩码 uint16、时间戳 uint32 ms。 |
电压 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
DAC1 1.234 DAC2 2500 D1 2.5V-
命令不区分大小写,支持伏特小数或毫伏整数。设置完成后串口会回显结果,CAN1/CAN2 同时发送 0x322 应答。
命令不区分大小写,支持伏特小数或毫伏整数。设置完成后串口会回显结果,CAN1/CAN2 同时发送 0x6A4 应答。
频率使用相邻上升沿时间差计算;连续 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]