网络MAC地址从哪里获得?可以获取mcu的CPU ID,然后从CPU ID获取MAC地址
unsigned char _eth_phy_mac[6] = {0x8, 0x2e,0,0,0,0};
void Eth_GenMAC(){
/*
SerialID[0] = *(unsigned int*)(0x1FFFF7E8);
SerialID[1] = *(unsigned int*)(0x1FFFF7EC);
SerialID[2] = *(unsigned int*)(0x1FFFF7F0);
*/
unsigned char *cpu_id = (unsigned char *)0x1FFFF7E8;
unsigned int crc32_value;
crc32_value = https://www.it610.com/article/crc32(cpu_id, 12);
_eth_phy_mac[2] = (char)(crc32_value >> 0);
_eth_phy_mac[3] = (char)(crc32_value >> 8);
_eth_phy_mac[4] = (char)(crc32_value >> 16);
_eth_phy_mac[5] = (char)(crc32_value >> 24);
};
stm32的ethernet 初始化,主要是PHY的驱动,
void stm32f107_eth_init(void)
{
RCC_ClocksTypeDef RCC_Clocks;
Eth_GenMAC();
eth_phy_clk_init();
eth_phy_gpio_init();
eth_phy_nvic_init();
eth_phy_mco_init();
eth_phy_confugration();
RCC_GetClocksFreq(&RCC_Clocks);
SysTick_Config(RCC_Clocks.SYSCLK_Frequency / 100);
NVIC_SetPriority (SysTick_IRQn, 1);
}
然后Lwip初始化操作
int Eth_LwipRegisterWithDHCP(){
struct ip_addr ipaddr;
struct ip_addr netmask;
struct ip_addr gw;
setIsDHCP();
mem_init();
memp_init();
ipaddr.addr = 0;
netmask.addr = 0;
gw.addr = 0;
Set_MAC_Address(_eth_phy_mac);
netif_add(ð_phy_netif, &ipaddr, &netmask, &gw, NULL, ðernetif_init, ðernet_input);
netif_set_default(ð_phy_netif);
dhcp_start(ð_phy_netif);
netif_set_up(ð_phy_netif);
return 0;
}
【阅读STM32F107的lwip移植后的一个项目工程】移植LWIP到stm32上无操作系统时,注意不同的phy芯片,网卡驱动不同,所以,第一步应该是网卡驱动的改写,然后时候网络数据收发使用DMA的两个描述符,收和发,采用环形链表的数据结构。DMA的描述符结构如下:
typedef struct{
__IO uint32_tStatus;
/*!< Status */
uint32_tControlBufferSize;
/*!< Control and Buffer1, Buffer2 lengths */
uint32_tBuffer1Addr;
/*!< Buffer1 address pointer */
uint32_tBuffer2NextDescAddr;
/*!< Buffer2 or next descriptor address pointer */
/* Enhanced ETHERNET DMA PTP Descriptors */
#ifdef USE_ENHANCED_DMA_DESCRIPTORS
uint32_tExtendedStatus;
/* Extended status for PTP receive descriptor */
uint32_tReserved1;
/* Reserved */
uint32_tTimeStampLow;
/* Time Stamp Low value for transmit and receive */
uint32_tTimeStampHigh;
/* Time Stamp High value for transmit and receive */
#endif /* USE_ENHANCED_DMA_DESCRIPTORS */
} ETH_DMADESCTypeDef;
如果定义的是接收结构体数组类型可以使用函数ETH_DMARxDescChainInit()ETH_DMATxDescChainInit()完成链表的构成。
使用结构体指针完成对两个TX和RX的描述符跟踪
__IO ETH_DMADESCTypeDef*DMATxDescToSet;
__IO ETH_DMADESCTypeDef*DMARxDescToGet;
注意对收发数据的内存管理,通常使用动态的分配内容空间,并且接收数据是使用中断接收的方式处理
void ETH_IRQHandler(void)
{
while(ETH_GetRxPktSize(DMARxDescToGet)!=0)//?ì2aê?·?ê?μ?êy?Y°ü
{
lwip_pkt_handle();
}
ETH_DMAClearITPendingBit(ETH_DMA_IT_R);
ETH_DMAClearITPendingBit(ETH_DMA_IT_NIS);
}
推荐阅读
- KEIL下载键变灰色,ST-link无法下载程序
- MCU|【PIC32MZ】Usart串口通讯
- 在STM32F103C8T6上移植UCOS系统
- MCU|【PIC32MZ】按键中断
- MCU|【PIC32MZ】开发环境的搭建
- 7路PWM产生程序阅读
- 硬件|单片机mcu—time定时器详解
- stm32影子寄存器、预装载寄存器,TIM_OC1PreloadConfig和TIM_ARRPreloadConfig的作用
- Keil逻辑分析仪的使用