W5300驱动说明

        W5300是一款带有硬件协议栈的网络芯片,内部拥有128K的缓存,最大支持8路socket通信,与MCU之间通过16位数据总线通信,通信速度远超W5500之类以SPI作为通信接口的网络芯片,特别适合对高速网络传输有需求的应用。

        本次使用STM32F205ZET6作为主控MCU,通过FSMC接口与W5300连接,主机在完成配置后,就可以像访问SRAM一样轻松操作W5300。以下为W5300引脚介绍及参考电路

        除FSMC接口外,还需要额外的芯片复位脚和中断脚。芯片上电复位不太可靠,因此一般需要通过操作复位引脚来进行可靠复位,这个特性在W5500上也有,需要注意。中断脚的话不是必须的,也可以通过查询方式来获取中断信息,但这里我们还是使用了。

        除此以外,硬件上还有一些配置,可以对照上面的电路图

        硬件连接没有问题后就开始软件编程了,首先是初始化。初始化这部分分两块,一个是对于FSMC的引脚初始化,另一部分是对于芯片的初始化。

        FSMC初始化(在这里不包括复位和中断脚的初始化,这两个脚可以使用普通IO,而FSMC的引脚是固定的),根据接线不同,FSMC_NORSRAMInitStructure.FSMC_Bank和FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth参数也不同,具体的可以查看STM32的手册。

void Config_FSMC(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
  
    FSMC_NORSRAMInitTypeDef  FSMC_NORSRAMInitStructure;
    FSMC_NORSRAMTimingInitTypeDef  p;
  
    FSMC_NORSRAMDeInit(FSMC_Bank1_NORSRAM1);
  
    /* AHB3 Peripheral Clock configuration -------------------------------------*/
    /* FSMC clock enable */
    RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FSMC , ENABLE); 
  
    /* Enable GPIOs clock */
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOE | RCC_AHB1Periph_GPIOF |
                            RCC_AHB1Periph_GPIOG, ENABLE);
    
  /*-- GPIOs Configuration -----------------------------------------------------*/
  /*
   +-------------------+--------------------+------------------+------------------+
   | PD0  <-> FSMC_D2  | PE0  <-> FSMC_NBL0 | PF0 <-> FSMC_A0  | PG0 <-> FSMC_A10 |
   | PD1  <-> FSMC_D3  | PE1  <-> FSMC_NBL1 | PF1 <-> FSMC_A1  | PG1 <-> FSMC_A11 |
   | PD4  <-> FSMC_NOE | PE2  <-> FSMC_A23  | PF2 <-> FSMC_A2  | PG2 <-> FSMC_A12 |
   | PD5  <-> FSMC_NWE | PE3  <-> FSMC_A19  | PF3 <-> FSMC_A3  | PG3 <-> FSMC_A13 |
   | PD8  <-> FSMC_D13 | PE4  <-> FSMC_A20  | PF4 <-> FSMC_A4  | PG4 <-> FSMC_A14 |
   | PD9  <-> FSMC_D14 | PE5  <-> FSMC_A21  | PF5 <-> FSMC_A5  | PG5 <-> FSMC_A15 |
   | PD10 <-> FSMC_D15 | PE6  <-> FSMC_A22  | PF12 <-> FSMC_A6 | PG9 <-> FSMC_NE2 |
   | PD11 <-> FSMC_A16 | PE7  <-> FSMC_D4   | PF13 <-> FSMC_A7 |------------------+
   | PD12 <-> FSMC_A17 | PE8  <-> FSMC_D5   | PF14 <-> FSMC_A8 |
   | PD13 <-> FSMC_A18 | PE9  <-> FSMC_D6   | PF15 <-> FSMC_A9 |
   | PD14 <-> FSMC_D0  | PE10 <-> FSMC_D7   |------------------+
   | PD15 <-> FSMC_D1  | PE11 <-> FSMC_D8   |
   +-------------------| PE12 <-> FSMC_D9   |
                       | PE13 <-> FSMC_D10  |
                       | PE14 <-> FSMC_D11  |
                       | PE15 <-> FSMC_D12  |
                       +--------------------+
  */
  
    /* GPIOD configuration */
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource0, GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource1, GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource4, GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource5, GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource8, GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource9, GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource10, GPIO_AF_FSMC);
    //GPIO_PinAFConfig(GPIOD, GPIO_PinSource11, GPIO_AF_FSMC); 
    //GPIO_PinAFConfig(GPIOD, GPIO_PinSource12, GPIO_AF_FSMC);
    //GPIO_PinAFConfig(GPIOD, GPIO_PinSource13, GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource14, GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource15, GPIO_AF_FSMC);
  
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0  | GPIO_Pin_1  | GPIO_Pin_4  | GPIO_Pin_5  | 
                                  GPIO_Pin_8  | GPIO_Pin_9  | GPIO_Pin_10 | GPIO_Pin_14 | 
                                  GPIO_Pin_15;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
  
    GPIO_Init(GPIOD, &GPIO_InitStructure);
    
    /* GPIOE configuration */
    //GPIO_PinAFConfig(GPIOE, GPIO_PinSource0 , GPIO_AF_FSMC);
    //GPIO_PinAFConfig(GPIOE, GPIO_PinSource1 , GPIO_AF_FSMC);
    //GPIO_PinAFConfig(GPIOE, GPIO_PinSource2 , GPIO_AF_FSMC);
    //GPIO_PinAFConfig(GPIOE, GPIO_PinSource3 , GPIO_AF_FSMC);
    //GPIO_PinAFConfig(GPIOE, GPIO_PinSource4 , GPIO_AF_FSMC);
    //GPIO_PinAFConfig(GPIOE, GPIO_PinSource5 , GPIO_AF_FSMC);
    //GPIO_PinAFConfig(GPIOE, GPIO_PinSource6 , GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOE, GPIO_PinSource7 , GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOE, GPIO_PinSource8 , GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOE, GPIO_PinSource9 , GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOE, GPIO_PinSource10 , GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOE, GPIO_PinSource11 , GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOE, GPIO_PinSource12 , GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOE, GPIO_PinSource13 , GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOE, GPIO_PinSource14 , GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOE, GPIO_PinSource15 , GPIO_AF_FSMC);
  
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7  | GPIO_Pin_8  | GPIO_Pin_9  | GPIO_Pin_10 | 
                                  GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | 
                                  GPIO_Pin_15;
  
    GPIO_Init(GPIOE, &GPIO_InitStructure);
   
    /* GPIOF configuration */
    GPIO_PinAFConfig(GPIOF, GPIO_PinSource0 , GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOF, GPIO_PinSource1 , GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOF, GPIO_PinSource2 , GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOF, GPIO_PinSource3 , GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOF, GPIO_PinSource4 , GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOF, GPIO_PinSource5 , GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOF, GPIO_PinSource12 , GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOF, GPIO_PinSource13 , GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOF, GPIO_PinSource14 , GPIO_AF_FSMC);
    //GPIO_PinAFConfig(GPIOF, GPIO_PinSource15 , GPIO_AF_FSMC);
  
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0  | GPIO_Pin_1  | GPIO_Pin_2  | GPIO_Pin_3  | 
                                  GPIO_Pin_4  | GPIO_Pin_5  | GPIO_Pin_12 | GPIO_Pin_13 |
                                  GPIO_Pin_14 ;      
  
    GPIO_Init(GPIOF, &GPIO_InitStructure);
  
  
    //-- FSMC Configuration ------------------------------------------------------
    p.FSMC_AddressSetupTime      = 0;
    p.FSMC_AddressHoldTime       = 0;
    p.FSMC_DataSetupTime         = 5; //2
    p.FSMC_BusTurnAroundDuration = 1; //0
    p.FSMC_CLKDivision           = 0;
    p.FSMC_DataLatency           = 0;
    p.FSMC_AccessMode            = FSMC_AccessMode_A;
	
    FSMC_NORSRAMInitStructure.FSMC_Bank 		       = FSMC_Bank1_NORSRAM1;
    FSMC_NORSRAMInitStructure.FSMC_DataAddressMux        = FSMC_DataAddressMux_Disable;
    FSMC_NORSRAMInitStructure.FSMC_MemoryType            = FSMC_MemoryType_SRAM;
    FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth       = FSMC_MemoryDataWidth_16b;
    FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode       = FSMC_BurstAccessMode_Disable;
    FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity    = FSMC_WaitSignalPolarity_Low;
    FSMC_NORSRAMInitStructure.FSMC_WrapMode              = FSMC_WrapMode_Disable;
    FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive      = FSMC_WaitSignalActive_BeforeWaitState;
    FSMC_NORSRAMInitStructure.FSMC_WriteOperation        = FSMC_WriteOperation_Enable;
    FSMC_NORSRAMInitStructure.FSMC_WaitSignal 	       = FSMC_WaitSignal_Disable;
    FSMC_NORSRAMInitStructure.FSMC_ExtendedMode 	       = FSMC_ExtendedMode_Disable;
    //FSMC_NORSRAMInitStructure.FSMC_AsyncWait 		= FSMC_AsyncWait_Disable; //
    FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait      = FSMC_AsynchronousWait_Disable; 
    FSMC_NORSRAMInitStructure.FSMC_WriteBurst 	       = FSMC_WriteBurst_Disable;
    FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p;
    FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct     = &p;
	
    FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure); 
	
    /* Enable FSMC Bank1_SRAM Bank */
    FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM1, ENABLE);  

}

        接下来就是对于芯片的初始化,前面说过对于芯片的访问如同SRAM一样,具体到W5300上,就是寄存器地址好比SRAM存储地址,操作寄存器就是往不同的地址写数据。W5300的寄存器地址都是厂商给定的相对地址,而基地址则跟FSMC接线有关。

        W5300的寄存器分为模式寄存器,间接模式寄存器,通用寄存器和SOCKET寄存器。不同的寄存器分管不同的功能,具体的可以查阅官方手册,这里不作列举了。

        W5300的初始化分为3个步骤

  1. 设置主机接口(数据总线宽度,接口模式,时序)
  2. 设置网络信息(MAC,本地IP,网关,子网掩码,重发间隔次数等)
  3. 分配SOCKET内部TX/RX存储空间

        示例代码如下

u8 W5300_Init(void)
{
	u16 i;
	u16 Tsum=0,Rsum=0;
	u16 val;
	u8  rMac[6];
	
	vdTimeDelay(0x00800000);
    // 设置主机接口:8位/直接访问
	_SetMR(MR_RST);
	vdTimeDelay(0x02000000);
   	//setMR(getMR()|MR_FS);
    // 设置主机中断:IP冲突 | 目标端口无法到达 // | Socket0~3 
	_SetIMR(IR_IPCF | IR_DPUR  | 0x03);// 
    // 设置网络参数
	_SetSHAR((u8 *)&(SysInfo.bMAC[0]));
	_SetGAR((u8 *)&(SysInfo.bGW[0]));
	_SetSUBR((u8 *)&(SysInfo.bSUB[0]));
	_SetSIPR((u8 *)&(SysInfo.bIP[0]));

	_GetSHAR((u8 *)rMac);
	for(i = 0;i<6;i++)
	{
		if(SysInfo.bMAC[i] != rMac[i]) break;
	}
	if(i < 6) return 0;

    // 配置重复发送超时周期的值,RTR的标准单位是 100us
	_SetRTR(2000);
    // 配置重复发送的次数。当重复发送的次数达到 RCR+1时,将产生超时中断(Sn_IR 的TIMEOUT?位置1)
	_SetRCR(7);
    
    // 分配Socket内存
	for(i=0; i < MAX_SOCKET_NUM; i++)
	{
		if(TxMemSize[i] > 64)	return 0;
		if(RxMemSize[i] > 64)	return 0;
		Tsum += (u16)TxMemSize[i];
		Rsum += (u16)RxMemSize[i];
		dwTMSsum[i] = ((u32)TxMemSize[i]) << 10;
		dwRMSsum[i] = ((u32)RxMemSize[i]) << 10;
	}
	if( (Tsum % 8) || ((Tsum + Rsum) != 128)) return 0;
   
   	for(i = 0;i<8;i++)
	{
		_SetTMSR(i,TxMemSize[i]);
		_SetRMSR(i,RxMemSize[i]);
	}
	val = 0;
	for(i=0; i < Tsum/8; i++)
	{
		val <<= 1;
		val  |= 1;
	}
	_SetMTYPER(val);
	return 1;
}

        之后就可以根据实际应用进行socket编程了,根据配置选择TCP或UDP通信等,每个socket可以独立配置互不影响。

        当网络接收到数据时,触发中断,通过读取IR寄存器获知中断类型,然后进相应的处理函数去处理。

void ISR_W5300(void)
{
	u16 wPendInt;
// Close Global Interrupt
	wPendInt = _GetIR();
// IP地址冲突
	if(wPendInt & IR_IPCF)    // check the IP conflict interrupt
	{
		_SetIR(IR_IPCF);
	}
// 目标IP无法到达
	if(wPendInt & IR_DPUR)    // check the unreachable destination interrupt
	{
		_SetIR(IR_DPUR);
	}
	if (wPendInt & 0x0001) ISR_Socket0();
	if (wPendInt & 0x0002) ISR_Socket1();
    if (wPendInt & 0x0004) ISR_Socket2();
// Open Global Interrupt
}

        如果要进行发送,则操作相应的SOCKET寄存器即可

void _WrSxBuffer(u8 Sx,u8* buf,u32 len)
{
	u32 z,tLen;
	pSOCKET Sn;
	Sn = (pSOCKET)(SOCKET0_BASE + SOCKET_REG_SIZE * Sx);
	tLen = len + (len & 0x01);
   
    for(z = 0; z < tLen; z += 2)
    {
        Sn->TX_FIFOR = (u16)(*(buf + z)<< 8) | (u16)(*(buf+z+1));
    }
}

        代码太多不便展示,具体可参考

        https://download.csdn.net/download/u011436603/88902967?spm=1001.2014.3001.5503

  • 27
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以太网W5300芯片是一款用于实现以太网通信的专用集成电路芯片。在使用W5300芯片进行驱动时,需要进行以下几个步骤。 首先,我们需要准备一个W5300芯片的驱动程序。这个驱动程序可以从官方网站或者其他可信的资源中获取。下载后,我们需要将其解压并保存到一个合适的位置。 接下来,我们需要将W5300芯片连接到我们的目标设备上。这包括将芯片插入到适当的插槽中,并连接相应的引脚,如电源和通讯接口等。 一旦W5300芯片与设备连接好,我们就可以开始加载驱动程序了。这通常需要在操作系统中进行设置。具体的设置方法可以在驱动程序提供的文档中找到。 一旦驱动程序加载成功,我们就可以开始使用W5300芯片进行以太网通信了。这包括发送和接收数据包,建立和维护连接等操作。我们可以使用编程语言中的相关库或者API来进行这些操作。 在使用W5300芯片进行驱动时,我们还需要注意一些常见的问题。例如,需要确保设备的硬件连接正确,驱动程序的版本与芯片兼容等。此外,我们还需要遵循相关的网络协议和程式设计规范,以确保通信的正确性和稳定性。 总之,驱动以太网W5300芯片需要准备合适的驱动程序,连接芯片到设备,加载驱动程序,使用相关的库或API进行通信操作,同时注意常见问题和规范。这样一来,我们就可以成功地使用W5300芯片实现以太网通信了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

慕诗客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值