关于DSP2812控制W5500的程序解读

核磁项目3月22日@TOC

CMD文件的解读

在这里插入图片描述将此引脚置为低电平,表示为微计算机模式,向量表指向Boot Rom。

	ROM     		 : origin = 0x3FF000, length = 0x000FC0     /* boot ROM available if MP/MCn=0 */

程序从这儿开始。
再看看存储器映像。
在这里插入图片描述分配程序空间

PRAMH0     : origin = 0x3f8000, length = 0x003000boot ROM available if MP/MCn=0 */

但是存在一个问题,就是我占用了保留的空间,因为CMD命令显示程序空间不够,很可能会出问题。如果出问题了,第一个解决办法是,将程序空间放到外扩RAM Zone2中,因为上传的数据花不了那么空间;第二个办法就是换芯片,换个RAM空间多一点的芯片。

PAGE 1 就是分配数据空间,注意要对应起来,外设和一些C的数据空间,一般模板是两个CMD文件,我只用了一个文件。

如果说 MEMORY 命令是定义每个东西的位置。那么SECTION命令就是,将所有相关的程序,数据分配到固定位置。

main函数的解读

一些加头文件等等的操作不在赘述。包括对文件夹的设置,什么文件怎么放等等。

首先定义一些网络相关的变量

uint8 server_ip[4]={192,168,1,101};
uint16 server_port=5000;
uint16 local_port=6000;
uint16 len=0;
uint8 buffer[2048];
boot ROM available if MP/MCn=0 */

网络客户端端口网络客户端ip本地端口
len代表socket缓存里面还剩余的空间,buffer数组存的是从W5500里面读取到的数据。这个下文再分析

对系统的初始化

关看门狗;

void DisableDog(void)
{
    EALLOW;
    SysCtrlRegs.WDCR= 0x0068;
    EDIS;
}

初始化锁相环,定义时钟;

      EALLOW;
      SysCtrlRegs.PLLCR.bit.DIV = val;
      EDIS;

在这里插入图片描述 Val 就是一个数,4-bit PLL Select。时钟=外部时钟*Val/2

初始化外设时钟

     SysCtrlRegs.HISPCP.all = 0x0000;
     SysCtrlRegs.LOSPCP.all = 0x0002;
     SysCtrlRegs.PCLKCR.bit.EVAENCLK=1;
     SysCtrlRegs.PCLKCR.bit.EVBENCLK=1;
     SysCtrlRegs.PCLKCR.bit.SPIENCLK=1;

这些外设时钟一般都是默认的高速还是低速时钟,高速和低速时钟是通过主频分频而来。如上代码所示,高速不分频,低速分两次,就是除以4.本项目晶振为10M,主频50M,高速50M,低速12,5M.事件A,B都是高速。spi为低速。此处存在一个问题,中断的时钟开不开。

对SPI的GPIO口的初始化

在这里插入图片描述硬件如图。四个接口分别为F1,F2,F3,F4

	void InitSpiaGpio(void)
	{

	   EALLOW;
	   GpioMuxRegs.GPFMUX.bit.SPISIMOA_GPIOF0=1;
	   GpioMuxRegs.GPFMUX.bit.SPISOMIA_GPIOF1=1;
	   GpioMuxRegs.GPFMUX.bit.SPICLKA_GPIOF2=1;
	   GpioMuxRegs.GPFMUX.bit.SPISTEA_GPIOF3=1;
	   EDIS;
	}

程序直接如图,2812貌似不用设置方向和上拉什么的,只需要配置为SPI的接口,这个存疑。也就是他的复用。配置为普通IO的话,寄存器写0,复用外设则写1。

对SPI的复位IO口的初始化

在这里插入图片描述存在疑惑,它的中断需不需要用上,由图,gpioa9,配置他的io和方向,是一个输出。代码如图

void gpio_config(void)
{
	 EALLOW;
	 GpioMuxRegs.GPAMUX.bit.CAP2Q2_GPIOA9=0;//GPA9 RSTn,设置为i/o
	 GpioMuxRegs.GPADIR.bit.GPIOA9= 1;//方向输出;1:输出;0:输入
	 EDIS;
}

然后是一些关中断的操作

对SPI本身的初始化

void spi_init()
{

	SpiaRegs.SPICCR.bit.SPISWRESET = 0;//复位SPI
	SpiaRegs.SPICCR.all = 0x000F;		//0000  0000  0000 1111
												//0~3,字节控制为16位;4,禁止SPI回送;5,保留;6,上升输出,下降输入;7,复位
	SpiaRegs.SPICTL.all = 0x0006;		// 00000000 0000 0110   中断无效,使能发送引脚,主机模式  无相位延时 禁止中断
//	Enable master mode, normal phase, // enable talk, and SPI int disabled.
	SpiaRegs.SPISTS.all = 0x0000;		//溢出中断,禁止SPI中断; 复位系统
	SpiaRegs.SPIBRR = 0x0009;			//SPI波特率=12.5M/10=1.25MHZ;0000 1001
	SpiaRegs.SPIPRI.bit.FREE = 1;		//Set so breakpoints don't disturb xmission
	SpiaRegs.SPICCR.bit.SPISWRESET = 1;
}

这儿就需要查寄存器进行一个修改了,DSP做主机,W5500做从机
波特率设置
在这里插入图片描述SPICCR寄存器:此寄存器0~3位决定在一个移送序列中,作为单个字符被移动的位的数量这里我们设置为16位。
此寄存器的第6位代表的时钟极性,通过两个位才能确定SPI发送和接收的方式。一个是SPICCR.CLKPOLARITY,一个是SPCTL.CLK_PHASE。共有四种方式。但是W5500只支持两种,0和3。问题来了,主机和从机的模式是否一致,还是只需要设置主机的模式。我认为应该只用设计主机的模式,所以我设置为模式0。上升沿发送,下降沿接收,无延时
SPIPRI 这个设置为x 1 ,忽略了中断,可能会有问题。

复位W5500

void Reset_W5500(void)//reset
{
	GpioDataRegs.GPADAT.bit.GPIOA9 = 0;
	delay_loop();
	GpioDataRegs.GPADAT.bit.GPIOA9 = 1;
	delay_loop();
}

设置默认网络相关的变量

void set_default(void)									// 设置默认MAC、IP、GW、SUB、DNS
{  
  uint8 mac[6]={0x00,0x08,0xdc,0x11,0x11,0x11};
  uint8 lip[4]={192,168,1,88};
  uint8 sub[4]={255,255,255,0};
  uint8 gw[4]={192,168,1,1};
  uint8 dns[4]={8,8,8,8};
  memcpy(ConfigMsg.lip, lip, 4);
  //printf("lip: %d.%d.%d.%d\r\n",lip[0],lip[1],lip[2],lip[3]);
  memcpy(ConfigMsg.sub, sub, 4);
  //printf("sub: %d.%d.%d.%d\r\n",sub[0],sub[1],sub[2],sub[3]);
  memcpy(ConfigMsg.gw,  gw, 4);
  //printf("gw: %d.%d.%d.%d\r\n",gw[0],gw[1],gw[2],gw[3]);
  memcpy(ConfigMsg.mac, mac,6);

  memcpy(ConfigMsg.dns,dns,4);
  //printf("dns: %d.%d.%d.%d\r\n",dns[0],dns[1],dns[2],dns[3]);

  ConfigMsg.dhcp=0;
  ConfigMsg.debug=1;
  ConfigMsg.fw_len=0;
  
  ConfigMsg.state=NORMAL_STATE;
  ConfigMsg.sw_ver[0]=FW_VER_HIGH;
  ConfigMsg.sw_ver[1]=FW_VER_LOW;
}

调试网络的时候肯定得改一些IP地址什么的。

设置网络,

W5500写入什么东西,mac,sub,gw	lip。
值得关注的是对Socket的初始化,将他的Socket 0 调成16K
代码:
uint8 txsize[MAX_SOCK_NUM] = {16,0,0,0,0,0,0,0};		// 选择8个Socket每个Socket发送缓存的大小,在w5500.c的void sysinit()有设置过程
uint8 rxsize[MAX_SOCK_NUM] = {16,0,0,0,0,0,0,0};		// 选择8个Socket每个Socket接收缓存的大小,在w5500.c的void sysinit()有设置过程

while1程序

首先是一个Switch
去读取Sn_SR寄存器的值,看他是否为0x13
在这里插入图片描述代表为TCP工作模式。然后根据端口和IP连接。

			case SOCK_INIT:
					connect(0, server_ip,server_port);

然后再读,是否为0x17
在这里插入图片描述代表连接成功,进行下一步。
在这里插入图片描述读取该位,Sn_IR_CON,表示建立连接。
读取Sn_RX_RSR,len=getSn_RX_RSR(0);看他还有多少空间
Sn_RX_RSR 显示了 Socket n 接收缓存中已接收和保存的数据大小。
len不为0,

					if(len>0)
					{
						//memset(buffer,'0',strlen(buffer));
						recv(0,buffer,len);
						send(0,buffer,len);

					}

这样就把w5500里面的数据,存到了buffer数组里面,然后在sendbuffer里面的数据到W5500.就完成了一个LOOPback的回环。

  • 0
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值