这是本文档旧的修订版!
	
		| 银杏科技有限公司旗下技术文档发布平台 | 
	
		| 技术支持电话 | 0379-69926675-801 | 
	
		| 技术支持邮件 | Gingko@vip.163.com | 
	
		| 技术论坛 | http://www.eeschool.org | 
	
		| 版本 | 日期 | 作者 | 修改内容 | 
	
		| V1.0 | 2020-08-01 | gingko | 初次建立 | 
STM32CubeMX教程二十三——LAN_TCPC实验
1. 新建工程:在主界面选择File–>New Project   或者直接点击ACCEE TO MCU SELECTOR  
 2. 出现芯片型号选择,搜索自己芯片的型号,双击型号,或者点击Start Project进入配置
在搜索栏的下面,提供的各种查找方式,可以选择芯片内核、型号等等,可以帮助你查找芯片。本实验选取的芯片型号为:STM32F407IGTx。
2. 出现芯片型号选择,搜索自己芯片的型号,双击型号,或者点击Start Project进入配置
在搜索栏的下面,提供的各种查找方式,可以选择芯片内核、型号等等,可以帮助你查找芯片。本实验选取的芯片型号为:STM32F407IGTx。
 3. 配置RCC,使用外部时钟源
3. 配置RCC,使用外部时钟源
 4. 配置调试引脚
4. 配置调试引脚
 5. 将LED对应的3个引脚(PI5,PI6,PI7)设置为GPIO_Output
5. 将LED对应的3个引脚(PI5,PI6,PI7)设置为GPIO_Output
 6. 引脚模式配置
6. 引脚模式配置
 7. 配置SPI
7. 配置SPI
 选用PA15引脚作为SPI1_CS
选用PA15引脚作为SPI1_CS
 8. 时钟源设置,选择外部高速时钟源,配置为最大主频
8. 时钟源设置,选择外部高速时钟源,配置为最大主频
 
9. 工程文件的设置, 这里就是工程的各种配置 我们只用到有限几个,其他的默认即可  IDE我们使用的是 MDK5
 10. 点击Code Generator,进行进一步配置
10. 点击Code Generator,进行进一步配置
 
-  Copy all used libraries into the project folder 
-  将HAL库的所有.C和.H都复制到所建工程中 
-  Copy only the necessary library files 
-  只复制所需要的.C和.H(推荐) 
-  Add necessary library files as reference in the toolchain project configuration file 
-  不复制文件,直接从软件包存放位置导入.C和.H 
自行选择方式即可
11. 然后点击GENERATE CODE  创建工程
 创建成功,打开工程。
创建成功,打开工程。
 
实验二十三:LAN_TCPC实验——以太网数据传输
一、 实验目的与意义
-  了解STM32的SPI和W5500的TCPC结构 
-  了解STM32的SPI和W5500的TCPC特征 
-  掌握SPI和TCPC的使用方法 
-  掌握STM32 HAL库中SPI和TCPC的配置方法 
-  掌握KEIL  MDK集成开发环境使用方法 
 
二、 实验设备及平台
- 
- 
-  Micro USB线缆。 
-  网线 
-  Keil MDK 开发平台。 
-  STM32CubeMX开发平台。 
-  装有WIN XP(及更高版本)系统的计算机。 
 
三、 实验原理
1、SPI简介
-  SPI是串行外围设备接口,全称Serial Peripheral interface,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线。主要应用在 EEPROM,FLASH,实时时钟,AD转换器,还有数字信号处理器和数字信号解码器之间。 
-  SPI 主要特点有: - 
-  可以同时发出和接收串行数据; 
-  可以当作主机或从机工作; 
-  提供频率可编程时钟; 
-  发送结束中断标志; 
-  写冲突保护; 
-  总线竞争保护等; 
 
-  SPI的通信原理很简单,它以主从方式工作,这种模式通常有一个主设备和一个或多个从设备,需要至少4根线,它们是MISO(主设备数据输入)、MOSI(主设备数据输出)、SCLK(时钟)、CS(片选)。 - 
-  MISO 主设备数据输入,从设备数据输出。 
-  MOSI 主设备数据输出,从设备数据输入。 
-  SCLK时钟信号,由主设备产生。 
-  CS从设备片选信号,由主设备控制。当有多个从设备的时候,因为每个从设备上都有一个片选引脚接入到主设备机中,当我们的主设备和某个从设备通信时将需要将从设备对应的片选引脚电平拉低或者是拉高。 
 
 
-  在一个SPI时钟周期内,会完成如下操作: - 
-  主设备通过MOSI线发送1位数据,从设备通过该线读取这1位数据; 
-  从设备通过MISO线发送1位数据,主设备通过该线读取这1位数据。 
 
-  这是通过移位寄存器来实现的。主机和从机都有一个串行移位寄存器,随着时钟脉冲,数据按照从高位到低位的方式依次移出主设备寄存器和从机寄存器,并且依次移入从设备寄存器和主设备寄存器。当寄存器中的内容全部移出时,相当于完成了两个寄存器内容的交换。  
-  主机通过向它的SPI串行寄存器写入一个字节来发起一次传输。寄存器通过MOSI信号线将字节传送给主机,从机也将自己的移位寄存器中的内容通过MISO信号线返回给主机,这样两个移位寄存器中的内容就被交换,外设的写操作和读操作是同时进行的。如果只进行写操作,主机只需忽略接收到的字节;反之,若主机要读取从机的一个字节,就必须发送一个空字节来引发从机的传输。 
 
 
 
 
 
2、W5500简介
-  W5500是一款全硬件TCP/IP嵌入式以太网控制器,为嵌入式系统提供了更加简易的互联网连接方案。W5500集成了TCP/IP协议栈,10/100M以太网数据链路层(MAC)及物理层(PHY),使得用户使用单芯片就能够在他们的应用中拓展网络连接。久经市场考验的WIZnet全硬件TCP/IP协议栈支持TCP,UDP,IPv4,ICMP,ARP,IGMP 以及PPPoE协议。W5500内嵌32K字节片上缓存以供以太网包处理。如果你使用W5500,你只需要一些简单的Socket编程就能实现以太网应用。这将会比其他嵌入式以太网方案更加快捷、简便。用户可以同时使用8个硬件Socket独立通讯。W5500提供了SPI(外设串行接口)从而能够更加容易与外设MCU整合。而且,W5500使用了新的高效SPI协议支持80MHz速率,从而能够更好的实现高速网络通讯。 
-  W5500 有 1 个通用寄存器, 8 个 Socket 寄存器区,以及对应每个 Socket 的收发缓存区。每个区域均通过 SPI 数据帧的区域选择位(BSB[4:0])来选取。 
-  (1)通用寄存器区配置了 W5500 的基本信息。  
-  GAR (网关 IP 地址寄存器) [R/W] [0x0001 – 0x0004] [0x00] 
 
 
 
 
-  (2)Socket 端口寄存器 - 
-  Socket寄存器用于建立socket通信。TCP是一种连接的通信。两个socket连接之前,必定要有一个Socket处在监听状态,而另一个socket启动连接,处于监听状态的就是服务器,启动连接的Socket就是客户端。启动TCP连接之前,必须正确设置Socket的目标IP和目的端口号。以下为配置目标IP地址和目的端口号的Socket寄存器。 
-  Sn_DIPR (Socket 目标 IP 地址寄存器) [R/W] [0x000C-0x000F] [0x00000000] 
 
 
效。在 TCP 客户端模式下,在 CONNET 配置命令前,该寄存器配置了 TCP Server
监听的端口号。例如: Socket 0 的目标端口号 = 5000(0x1388) ,配置应如下:
 
 
3、TCPC简介
-  TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议,由IETF的RFC 793定义。在简化的计算机网络OSI模型中,它完成第四层传输层所指定的功能,用户数据报协议(UDP)是同一层内[1]  另一个重要的传输协议。在因特网协议族(Internet protocol suite)中,TCP层是位于IP层之上,应用层之下的中间层。不同主机的应用层之间经常需要可靠的、像管道一样的连接,但是IP层不提供这样的流机制,而是提供不可靠的包交换。 
-  基于TCP/IP协议的服务器和客户端程序的一般流程,如下图所示: 
 
-  在建立通道时,客户端首先要向服务端发送一个SYN同步信号。 
-  服务端在接收到这个信号之后会向客户端发出SYN同步信号和ACK确认信号。 
-  当服务端的ACK和SYN到达客户端后,客户端与服务端之间的这个“通道”就会被建立起来 
-  在数据传输完毕之后,客户端会向服务端发出一个FIN终止信号 
-  服务端在收到这个信号之后会向客户端发出一个ACK确认信号 
-  如果服务端此后也没有数据发给客户端时服务端会向客户端发送一个FIN终止信号 
-  客户端在收到这个信号之后会回复一个确认信号,在服务端接收到这个信号之后,服务端与客户端的通道也就关闭了 
 
四、 实验程序
1. 主函数
int main(void)  
{   
  HAL_Init();  
  SystemClock_Config();  
  MX_GPIO_Init();  
  MX_USB_DEVICE_Init();  
  MX_SDIO_SD_Init();  
  while (1)  
  {  
        LED_RED_ON;  
        LED_GREEN_OFF;  
        LED_BLUE_OFF;  
        HAL_Delay(500);  
        LED_RED_OFF;  
        LED_GREEN_ON;  
        LED_BLUE_OFF;  
        HAL_Delay(500);  
        LED_RED_OFF;  
        LED_GREEN_OFF;  
        LED_BLUE_ON;  
        HAL_Delay(500);   
  }  
}
 
2. 初始化函数
void MX_SDIO_SD_Init(void) {  
  hsd.Instance = SDIO;  
  hsd.Init.ClockEdge = SDIO_CLOCK_EDGE_RISING;  
  hsd.Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE;  
  hsd.Init.ClockPowerSave=SDIO_CLOCK_POWER_SAVE_DISABLE;
  hsd.Init.BusWide = SDIO_BUS_WIDE_1B;  
  hsd.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_ENABLE;  
  hsd.Init.ClockDiv = 0;  
  if (HAL_SD_Init(&hsd) != HAL_OK)   { 
 Error_Handler();  
 }  
  if (HAL_SD_ConfigWideBusOperation(&hsd, SDIO_BUS_WIDE_4B) != HAL_OK)  {  
     Error_Handler();  
  }  
}
 
3. 接口函数
int8_t STORAGE_GetCapacity_HS(uint8_t lun, uint32_t *block_num, uint16_t *block_size)  
{  
  /* USER CODE BEGIN 10 */  
  HAL_SD_GetCardInfo(&hsd,&SDCardInfo);  
 
  *block_num  = STORAGE_BLK_NBR;  
  *block_size = STORAGE_BLK_SIZ;  
  return (USBD_OK);  
  /* USER CODE END 10 */  
} 
int8_t STORAGE_Read_HS(uint8_t lun, uint8_t *buf,
 uint32_t blk_addr, uint16_t blk_len) 
{  
  /* USER CODE BEGIN 13 */  
uint32_t timeout = 10000;  
 
    if(HAL_SD_ReadBlocks(&hsd,buf,blk_addr,(uint32_t)blk_len, timeout) == USBD_OK){  
            while(HAL_SD_GetCardState(hsd)!= HAL_OK)  
            {  
                if (timeout-- == 0)  
                {  
                    return -1;  
                }  
            }  
    }     
  return (USBD_OK);  
  /* USER CODE END 13 */  
}
int8_t STORAGE_Write_HS(uint8_t lun, uint8_t *buf, 
uint32_t blk_addr, uint16_t blk_len)  
{  
  /* USER CODE BEGIN 14 */  
    uint32_t timeout = 10000;  
 
    if(HAL_SD_WriteBlocks(hsd,buf, blk_addr, blk_len, timeout) == USBD_OK){  
            while(HAL_SD_GetCardState(hsd)!= HAL_OK)  
            {  
                if (timeout-- == 0)  
                {  
                    return -1;  
                }  
            }  
    }     
  return (USBD_OK);  
  /* USER CODE END 14 */  
}
 
五、 实验步骤
-  把仿真器与iCore3的SWD调试口相连(直接相连或者通过转接器相连); 
-  将跳线帽插在USB OTG; 
-  将Micro SD卡插入TF卡座里面; 
-  把iCore3(USB OTG)通过Micro USB线与计算机相连,为iCore3供电; 
-  打开Keil MDK 开发环境,并打开本实验工程; 
-  烧写程序到iCore3上; 
-  即可在电脑上操作磁盘。 
 
六、 实验现象