本帖最后由 黑皮男 于 2015-11-30 15:09 编辑 已经在论坛水了近一年了,兑换了两块开发板,但是一直没有发点有用的帖子,深感抱歉。现在深深的反省一下,把这几天调试DM9000的过程简单分享一下,希望对向我这样刚接触网卡芯片的新手作一个参考。已调通发包收包函数,并可以获取主机的MAC地址。光是模拟IO口接收就已经让我很是头疼了一阵。参考DM9000网卡芯片详细调试过程。这个在百度一搜就有,百度文库里有,这里仅仅介绍一下我自己所遇到的问题。附件直接拿来不能用,需要自己建工程然后添加进去 一、IO口模拟总线。 很多地方是用一个PORT(16bit)来模拟16位的数据总线,但是这样就不能随意配置IO口,这是我不喜欢的地方,于是参考了ST官方例程,把所需的IO口装在数组里,这样便于管理,移植起来也方便。当然,这样肯定会降低读写速度,但是对于我这样的新手来说,并不是很关心速度。 首先在头文件定义各个数据线: #define BUS_BITS 16 #define BSP_IO15_PIN GPIO_PIN_9 #define BSP_IO15_PORT GPIOC #define BSP_IO14_PIN GPIO_PIN_8 #define BSP_IO14_PORT GPIOB #define BSP_IO13_PIN GPIO_PIN_9 #define BSP_IO13_PORT GPIOB #define BSP_IO12_PIN GPIO_PIN_6 #define BSP_IO12_PORT GPIOA #define BSP_IO11_PIN GPIO_PIN_7 #define BSP_IO11_PORT GPIOA #define BSP_IO10_PIN GPIO_PIN_6 #define BSP_IO10_PORT GPIOB #define BSP_IO9_PIN GPIO_PIN_7 #define BSP_IO9_PORT GPIOC #define BSP_IO8_PIN GPIO_PIN_9 #define BSP_IO8_PORT GPIOA #define BSP_IO7_PIN GPIO_PIN_8 #define BSP_IO7_PORT GPIOA #define BSP_IO6_PIN GPIO_PIN_10 #define BSP_IO6_PORT GPIOB #define BSP_IO5_PIN GPIO_PIN_4 #define BSP_IO5_PORT GPIOB #define BSP_IO4_PIN GPIO_PIN_5 #define BSP_IO4_PORT GPIOB #define BSP_IO3_PIN GPIO_PIN_11 #define BSP_IO3_PORT GPIOC #define BSP_IO2_PIN GPIO_PIN_10 #define BSP_IO2_PORT GPIOA #define BSP_IO1_PIN GPIO_PIN_2 #define BSP_IO1_PORT GPIOC #define BSP_IO0_PIN GPIO_PIN_3 #define BSP_IO0_PORT GPIOC 在C文件中定义总线数组: GPIO_TypeDef * BUS_PORT[BUS_BITS]={BSP_IO0_PORT, BSP_IO1_PORT, BSP_IO2_PORT, BSP_IO3_PORT, BSP_IO4_PORT, BSP_IO5_PORT, BSP_IO6_PORT, BSP_IO7_PORT, BSP_IO8_PORT, BSP_IO9_PORT, BSP_IO10_PORT, BSP_IO11_PORT, BSP_IO12_PORT, BSP_IO13_PORT, BSP_IO14_PORT, BSP_IO15_PORT}; const uint16_t BUS_PIN[BUS_BITS]={BSP_IO0_PIN, BSP_IO1_PIN, BSP_IO2_PIN, BSP_IO3_PIN, BSP_IO4_PIN, BSP_IO5_PIN, BSP_IO6_PIN, BSP_IO7_PIN, BSP_IO8_PIN, BSP_IO9_PIN, BSP_IO10_PIN, BSP_IO11_PIN, BSP_IO12_PIN, BSP_IO13_PIN, BSP_IO14_PIN, BSP_IO15_PIN}; IO初始化等略去,后面会附上源文件。 对总线写操作: void BSP_BUS_Write16Bit(uint16_t data){ uint8_t i; for(i = 16;i>0;i--){ if(data&0x8000) SET_BIT(BUS_PORT[i-1]->ODR, BUS_PIN[i-1]); else CLEAR_BIT(BUS_PORT[i-1]->ODR, BUS_PIN[i-1]); data=data<<1; } } 对总线读操作(此处有误,注意READ_BIT内对IO的读取时按数组脚标读的,论坛的编辑器吧变量i给漏掉了,添加不上): uint16_t BSP_BUS_Read16Bit(void){ uint8_t i; uint16_t res=0x00; for(i=0;i<16;i++){ if(READ_BIT(BUS_PORT->IDR , BUS_PIN )) res =res|(1<<i); } return res; } 总线的读写操作就到此,还需要配置IO的输入输出模式,以便随时更改IO模式,使用了两个函数进行实现,请参考附件。 二、DM9000驱动程序(使用DM9000A) 以下关于DM9000的读写是按照时序来写的,开始的时候参照别人模拟时序,怎么都调不通, 后来仔细看了数据手册开发现读时序有问题。 DM9000 写命令: uint16_t DM_ReadData(void) { uint16_t res; DM9000_CMD_HIGH; DM9000_CS_LOW; DM9000_RD_LOW; res = DM_READ_DATA(); //此句一定要放在DM9000_RD_HIGH之前 DM9000_RD_HIGH; DM9000_CS_HIGH; return res; } 关于其他的读写函数请参照附件(时序都差不多) 收发包的过程函数,就请大家查看百度文库中有关的详细说明。 arp数据包结构的定义一定要按照顺序定义结构体中的每一个变量,并且要注意按照ARP数据帧结构定义每一个结构体中的变量(这涉及到数据类型对齐的问题),这个结构体会映射到一个收发缓冲数组中。 请注意arp数据包中op选项应该为: 1:arp request 2:: arp response 3:rarp request 4: rarp response 我看有人写的是0:arp request , 1: arp response.但是在TCP/IP详解卷I中是按 1:arp request 2: arp response 3:rarp request 4: rarp response定义的。 void BSP_Arp_Request(void) { arpbuf=(ARP_HDR *)Buffer; memcpy(arpbuf->ethhdr.d_mac, host_mac_addr, 6); memcpy(arpbuf->ethhdr.s_mac, mac_addr, 6); arpbuf->ethhdr.type = HON(0x0806); //arp request/response type arpbuf->hwtype = HON(1); //ethernet type arpbuf->protocol = HON(0x0800); arpbuf->hwlen = 6; arpbuf->protolen = 4; //arpbuf->opcode = HON(1); arpbuf->opcode = HON(1); // 1:arp request 2:: arp response 3:rarp request 4: rarp response memcpy(arpbuf->s_mac, mac_addr, 6); memcpy(arpbuf->s_ipaddr, ip_addr, 4); memcpy(arpbuf->d_ipaddr, host_ip_addr, 4); packet_len = 42; memcpy(TxBuffer, Buffer, 42); DM_SendPacket(Buffer, packet_len); } |
STM32F303.zip
下载22.82 KB, 下载次数: 57, 下载积分: ST金币 -1
【STM32F303开发】开发学习笔记、教程集合贴
【合集】STM32F303开发教程
【STM32F303开发】+ 使用片内的CCMRAM缩短代码执行时间
【STM32F303开发】(五)TIM定时器PWM的输出与捕获
【STM32F303开发】+ 内部Flash模拟EEPROM
【STM32F303开发】+如何解析GPS数据
【STM32F303开发】+使用fromelf反汇编keil生成的AXF文件
使用STM32F303VBT6的SPI驱动TM1629A
【STM32F303开发】+ 使用SWO输出调试信息到Debug Viewer窗口
【STM32F303开发】基础:工程模板+LED+USART+常用文档+按键中断
仅供学习使用而已,项目中这样干肯定不行。
不能白拿了免费的开发板,总得出点力