STM32 sACN接收多个universe的程序代码
时间: 2024-01-08 13:03:12 浏览: 124
下面是一个基于HAL库的STM32接收多个universe的sACN程序的示例代码:
```c
#include "stm32f4xx_hal.h"
#include <string.h>
#define MAX_SACN_PACKET_SIZE 638 // sACN最大数据包大小
#define NUM_UNIVERSES 4 // 接收的universe数量
#define UNIVERSE_SIZE 512 // 每个universe的大小
// 定义存储接收到的sACN数据的缓冲区
uint8_t sacn_buffer[NUM_UNIVERSES * UNIVERSE_SIZE];
// 定义每个universe的起始地址
const uint16_t universe_address[NUM_UNIVERSES] = { 0x0000, 0x0200, 0x0400, 0x0600 };
// 定义每个universe的组播地址
const uint8_t universe_multicast_address[NUM_UNIVERSES][4] = {
{ 239, 255, 0, 1 },
{ 239, 255, 0, 2 },
{ 239, 255, 0, 3 },
{ 239, 255, 0, 4 }
};
// 定义网络模块句柄
ETH_HandleTypeDef heth;
// 定义sACN数据包结构体
typedef struct {
uint8_t preamble[4];
uint16_t postamble;
uint8_t acn_id[12];
uint16_t flags;
uint16_t length;
uint8_t vector;
uint8_t cid[16];
uint8_t data[];
} sacn_packet_t;
// 初始化网络模块
void MX_ETH_Init(void)
{
heth.Instance = ETH;
heth.Init.AutoNegotiation = ETH_AUTONEGOTIATION_ENABLE;
heth.Init.PhyAddress = LAN8742A_PHY_ADDRESS;
heth.Init.MACAddr[0] = 0x00;
heth.Init.MACAddr[1] = 0x80;
heth.Init.MACAddr[2] = 0xE1;
heth.Init.MACAddr[3] = 0x00;
heth.Init.MACAddr[4] = 0x00;
heth.Init.MACAddr[5] = 0x00;
heth.Init.RxMode = ETH_RXINTERRUPT_MODE;
heth.Init.ChecksumMode = ETH_CHECKSUM_BY_HARDWARE;
heth.Init.MediaInterface = ETH_MEDIA_INTERFACE_RMII;
if (HAL_ETH_Init(&heth) != HAL_OK)
{
Error_Handler();
}
}
// 配置网络模块的组播地址
void MX_ETH_ConfigMulticast(void)
{
for (int i = 0; i < NUM_UNIVERSES; i++) {
uint32_t addr = (universe_multicast_address[i][0] << 24)
| (universe_multicast_address[i][1] << 16)
| (universe_multicast_address[i][2] << 8)
| universe_multicast_address[i][3];
HAL_ETH_SetReceiveFilter(&heth, ETH_FILTER_MULTICAST, (uint8_t*)&addr, 1);
}
}
// 接收sACN数据包
void MX_ETH_ReceiveSACN(void)
{
uint32_t length = 0;
HAL_StatusTypeDef status = HAL_ETH_GetReceivedFrame_IT(&heth);
if (status == HAL_OK) {
sacn_packet_t *packet = (sacn_packet_t*)heth.RxFrameInfos.FSRxDesc->Buffer1Addr;
// 检查sACN数据包的前导码和标识符
if (memcmp(packet->preamble, "\x00\x10\x20\x30", 4) == 0 &&
memcmp(packet->acn_id, "ASC-E1.17\0\0\0\0\0\0\0\0", 12) == 0) {
// 获取sACN数据包中包含的universe
uint16_t universe = ((uint16_t)packet->data[0] << 8) | packet->data[1];
// 检查universe是否在我们需要接收的范围内
int index = -1;
for (int i = 0; i < NUM_UNIVERSES; i++) {
if (universe == universe_address[i]) {
index = i;
break;
}
}
if (index >= 0) {
// 将sACN数据包中的数据存储到对应的缓冲区中
memcpy(&sacn_buffer[index * UNIVERSE_SIZE], &packet->data[2], UNIVERSE_SIZE);
}
}
// 释放DMA缓冲区
HAL_ETH_ReleaseRxDescriptor(&heth, heth.RxFrameInfos.FSRxDesc);
}
}
int main(void)
{
HAL_Init();
MX_ETH_Init();
MX_ETH_ConfigMulticast();
while (1) {
MX_ETH_ReceiveSACN();
// 处理缓冲区中的数据
// ...
}
}
```
以上代码仅用于演示,具体实现方法需要根据实际情况进行调整。需要注意的是,sACN协议的具体实现可能因硬件和软件平台而异,因此代码中的一些细节可能需要根据实际情况进行更改。
阅读全文