用户工具

站点工具


icore3_arm_hal_23

差别

这里会显示出您选择的修订版和当前版本之间的差别。

到此差别页面的链接

后一修订版
前一修订版
icore3_arm_hal_23 [2020/08/01 18:03]
fmj 创建
icore3_arm_hal_23 [2022/03/18 15:11] (当前版本)
sean
行 2: 行 2:
 |技术支持电话|**0379-69926675-801** ​ ||| |技术支持电话|**0379-69926675-801** ​ |||
 |技术支持邮件|Gingko@vip.163.com ​ ||| |技术支持邮件|Gingko@vip.163.com ​ |||
-|技术论坛|http://​www.eeschool.org ​ ||| 
 ^  版本 ​ ^  日期 ​ ^  作者 ​ ^  修改内容 ​ ^ ^  版本 ​ ^  日期 ​ ^  作者 ​ ^  修改内容 ​ ^
 |  V1.0  |  2020-08-01 ​ |  gingko ​ |  初次建立 ​ | |  V1.0  |  2020-08-01 ​ |  gingko ​ |  初次建立 ​ |
行 10: 行 9:
 \\ \\
 \\ \\
 +
  
 ===== STM32CubeMX教程二十三——LAN_TCPC实验 ===== ===== STM32CubeMX教程二十三——LAN_TCPC实验 =====
行 126: 行 126:
 {{ :​icore3:​icore3_arm_hal_23_10.png?​direct |}} {{ :​icore3:​icore3_arm_hal_23_10.png?​direct |}}
     * Sn_DPORT (Socket n 目标端口寄存器) [R/W] [0x0010-0x0011] [0x00]     * Sn_DPORT (Socket n 目标端口寄存器) [R/W] [0x0010-0x0011] [0x00]
-      * Sn_DPORT 配置或指示了 Socket n 的目标主机端口号,在 TCP/UDP 模式下生 +      * Sn_DPORT 配置或指示了 Socket n 的目标主机端口号,在 TCP/UDP 模式下生效。在 TCP 客户端模式下,在 CONNET 配置命令前,该寄存器配置了 TCP Server监听的端口号。例如: Socket 0 的目标端口号 = 5000(0x1388) ,配置应如下:
-效。在 TCP 客户端模式下,在 CONNET 配置命令前,该寄存器配置了 TCP Server +
-监听的端口号。例如: Socket 0 的目标端口号 = 5000(0x1388) ,配置应如下:+
 {{ :​icore3:​icore3_arm_hal_23_11.png?​direct |}} {{ :​icore3:​icore3_arm_hal_23_11.png?​direct |}}
 === 3、TCPC简介 ===  ​ === 3、TCPC简介 ===  ​
行 135: 行 133:
 {{ :​icore3:​icore3_arm_hal_23_12.png?​direct |}} {{ :​icore3:​icore3_arm_hal_23_12.png?​direct |}}
   * 客户端与服务器在使用TCP传输协议时要先建立一个“通道”,在传输完毕之后又要关闭这“通道”,前者可以被形象地成为“三次握手”,而后者则可以被称为“四次挥手”。   * 客户端与服务器在使用TCP传输协议时要先建立一个“通道”,在传输完毕之后又要关闭这“通道”,前者可以被形象地成为“三次握手”,而后者则可以被称为“四次挥手”。
 +
   * 通道的建立——三次握手:   * 通道的建立——三次握手:
   - 在建立通道时,客户端首先要向服务端发送一个SYN同步信号。   - 在建立通道时,客户端首先要向服务端发送一个SYN同步信号。
行 145: 行 144:
   - 客户端在收到这个信号之后会回复一个确认信号,在服务端接收到这个信号之后,服务端与客户端的通道也就关闭了   - 客户端在收到这个信号之后会回复一个确认信号,在服务端接收到这个信号之后,服务端与客户端的通道也就关闭了
  
-==== 四、 实验程序 ==== +==== 四、 实验原理 ==== 
- +  * iCore3带有W5500嵌入式以太网控制器,本实验实现TCP客户端功能。以PC作为服务器,iCore3作为客户端,PC的IP地址192.168.0.2,端口号为60001,iCore3的IP地址为192.168.0.10,端口随机。当客户端连接到服务器,TCP建立成功即可进行数据信息传输。以下为实验原理图。 
-=== 1. 函数 ===+{{ :​icore3:​icore3_arm_hal_23_13.png?​direct |}} 
 +==== 五、 实验程序 ==== 
 +=== 1. main()函数中建立的客户端程序 ​===
 <code c> <code c>
-int main(void  + ​while ​(1
-  ​ +  
-  ​HAL_Init();  ​ + //处理TCP client信息 
-  ​SystemClock_Config();   + switch(getSn_SR(0))    /​*获取socket0的状态*/​ 
-  ​MX_GPIO_Init();  ​ +
-  ​MX_USB_DEVICE_Init();   + case SOCK_INIT: ​                  /​*socket初始化完成*/​ 
-  ​MX_SDIO_SD_Init();   + connect(0, remote_ip ,60001);  ​/​*在TCP模式下向服务器发送连接请求*/ ​ 
-  ​while ​(1  + break; 
-    + case SOCK_ESTABLISHED: ​         /​*socket连接建立*/​ 
-        ​LED_RED_ON  + if(getSn_IR(0) & Sn_IR_CON
-        ​LED_GREEN_OFF  +
-        ​LED_BLUE_OFF;  ​ + setSn_IR(0, Sn_IR_CON);   /​*Sn_IR的第0位置1*/​ 
-        ​HAL_Delay(500);   +
-        ​LED_RED_OFF;  ​ + receive_length = getSn_RX_RSR(0); /​*len为已接收数据的大小*/​ 
-        ​LED_GREEN_ON  + if(receive_length > 0
-        ​LED_BLUE_OFF;  ​ +
-        ​HAL_Delay(500);   + memset(receive_buffer,​0,​sizeof(receive_buffer))
-        ​LED_RED_OFF  + recv(0,​receive_buffer,​receive_length)
-        ​LED_GREEN_OFF;  ​ +/​*W5500接收来自Sever的数据*/​ 
-        ​LED_BLUE_ON  + send(0,​receive_buffer,​receive_length); 
-        ​HAL_Delay(500);   ​ + }   ​ 
-   + break
 + case SOCK_CLOSE_WAIT: ​         /​*socket等待关闭状态*/​ 
 + disconnect(0); 
 + break
 + case SOCK_CLOSED: ​             /​*socket关闭*/​ 
 + local_port = rand() % 10000 + 50000
 + socket(0,​Sn_MR_TCP,​local_port,​Sn_MR_ND);       
 +/​*打开socket0的一个端口*/​ 
 + break; 
 + }
 } }
 +
 </​code>​ </​code>​
-  * Main函数中对SDIO与USB分别进行了初始化,在while循环中用三色灯循环点亮表明程序正在运行。 +  
-=== 2. 初始化函数 ​===+=== 2. SPI初始化配置 ​=== 
 +  * 初始化SPI 主要是对SPI要使用到的引脚以及SPI通信协议中时钟相位和极性进行设置 
 <code c> <code c>
-void MX_SDIO_SD_Init(void) {   +void MX_SPI1_Init(void) 
-  hsd.Instance = SDIO  +
-  hsd.Init.ClockEdge ​SDIO_CLOCK_EDGE_RISING  +hspi1.Instance = SPI1;  
-  hsd.Init.ClockBypass ​SDIO_CLOCK_BYPASS_DISABLE  +hspi1.Init.Mode SPI_MODE_MASTER; //​SPI主模式 
-  hsd.Init.ClockPowerSave=SDIO_CLOCK_POWER_SAVE_DISABLE+hspi1.Init.Direction ​SPI_DIRECTION_2LINES; //​全双工模式 
-  hsd.Init.BusWide ​SDIO_BUS_WIDE_1B  +hspi1.Init.DataSize ​SPI_DATASIZE_8BIT; //​数据位为8位 
-  hsd.Init.HardwareFlowControl ​SDIO_HARDWARE_FLOW_CONTROL_ENABLE  +hspi1.Init.CLKPolarity ​SPI_POLARITY_LOW; //CPOL = 0 
-  hsd.Init.ClockDiv ​0  +hspi1.Init.CLKPhase ​SPI_PHASE_1EDGE; //​CPHA为数据线的第一个变化沿 
-  if (HAL_SD_Init(&​hsd) !HAL_OK) ​  ​{ ​ +hspi1.Init.NSS SPI_NSS_SOFT; //​软件控制NSS 
- Error_Handler()  +hspi1.Init.BaudRatePrescaler ​SPI_BAUDRATEPRESCALER_2;//​2分频 
- }  ​ +hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; //​最高位先发送 
-  if (HAL_SD_ConfigWideBusOperation(&hsd, SDIO_BUS_WIDE_4B) != HAL_OK) ​   +hspi1.Init.TIMode = SPI_TIMODE_DISABLE;​ //​TIMODE模式关闭 
-     ​Error_Handler(); ​  +hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;//​CRC关闭 
-    +hspi1.Init.CRCPolynomial = 10;//​默认值,无效 
- +if (HAL_SPI_Init(&hspi1) != HAL_OK)//​初始化 
 +
 +Error_Handler();​ 
 +
 +}
  
 </​code>​ </​code>​
-=== 3. 接口函数 ===  +=== 3. SPI读写函数配置 ​===  
-  * 在usbd_storage_if.c文件中是USB_MSC初始化与读写相关函数。需要在这文件下编相关写SDIO的相关函数,分别STORAGE_GetCapacity_HS获取容量信息函数STORAGE_Read_HSSDIO函数与STORAGE_Write_HSSDIO函数。分别引入SD卡的接口函数。HAL_SD_GetCardInfo获取SD卡信息函数,HAL_SD_ReadBlocks取SD卡函数,HAL_SD_WriteBlocksSD卡函数以及HAL_SD_GetCardState获取SD卡状态信息函数 +  * HAL_SPI_TransmitReceive()为SPI的HAL库读写函数,一次操作一字节,数据同时入同时出。send_data()函数为单字节读写函数,write()函数为多字节读写函数,可实现多字节数据的读写。
-  * 获取容量信息函数+
 <code c> <code c>
-int8_t STORAGE_GetCapacity_HS(uint8_t lun, uint32_t *block_num, uint16_t *block_size  +static unsigned char send_data(unsigned char data)//​SPI读写字节函数 
-  +
-  /* USER CODE BEGIN 10 */  ​ +unsigned char receive_data;​ 
-  ​HAL_SD_GetCardInfo(&hsd,&SDCardInfo);   +HAL_SPI_TransmitReceive(&hspi1,&data,&​receive_data,​1,​1000);//​接收发送函数 
- +return receive_data;//​返回接收到的值 
-  *block_num ​ = STORAGE_BLK_NBR  +
-  ​*block_size ​STORAGE_BLK_SIZ  +static int write(int number, unsigned char buf) //​SPI读写多字节函数 
-  ​return ​(USBD_OK);   +
-  /* USER CODE END 10 *  +int i
-+SPI1_CS_OFF; ​                      //​拉低CS引脚 
 +for (i 0i < number; i++){ 
 +buf[i] = send_data(buf[i]);   //​调用send_data()函数 
 +
 +SPI1_CS_ON;​   ​//拉高CS引脚 
 +return 0; 
 +}
 </​code>​ </​code>​
-  *  读SDIO函数+  
 +=== 4. W5500.c中的寄存器函数 ​=== 
 <code c> <code c>
-int8_t STORAGE_Read_HS(uint8_t lunuint8_t *buf+//​定义本设备IP地址、默认网关、MAC地址、子网掩码 
- uint32_t blk_addruint16_t blk_len)  +W5500_T w5500={ 
-  + .initialize=initialize, 
-  /* USER CODE BEGIN 13 *  + .mac = {0x00,​0x98,​0xdc,​0x42,​0x61,​0x11}
-uint32_t timeout = 10000;  ​+ .ip = {192,168,​0,​10},​ 
 + .sub = {255,​255,​255,​0},​ 
 + .gw = {192,​168,​0,​1}  
 +}; 
 +//​W5500写函数 
 +void IINCHIP_WRITE (unsigned long int addrbsb, unsigned char data)  
 +
 +SPI1_CS_OFF;​ 
 +spi1.send_data( (addrbsb & 0x00FF0000)>>​16); ​     ​// Address byte 1 
 +spi1.send_data( (addrbsb & 0x0000FF00)>>​ 8);      // Address byte 2 
 +spi1.send_data( (addrbsb & 0x000000F8) + 4);  ​ 
 +// Data write command and Write data length 1 
 +spi1.send_data(data); ​              // Data write (write 1byte data) 
 +SPI1_CS_ON 
 +}
  
-    if(HAL_SD_ReadBlocks(&​hsd,​buf,​blk_addr,​(uint32_t)blk_len, timeout== USBD_OK){  ​ +//​W5500读函数 
-            while(HAL_SD_GetCardState(hsd)!= HAL_OK  +unsigned char IINCHIP_READ ​(unsigned long int addrbsb) // Address byte 1 
-            ​{ ​  +
-                if (timeout-- == 0  + ​unsigned char data = 0; 
-                {  ​ + ​SPI1_CS_OFF;​ 
-                    ​return -1;   + ​spi1.send_data( (addrbsb & 0x00FF0000)>>16);      // Address byte 1 
-                }  ​ + spi1.send_data( (addrbsb & 0x0000FF00)>> 8);      // Address byte 2 
-            ​} ​  + spi1.send_data(addrbsb & 0x000000F8))    ;                                
-    }      +// Data read command and Read data length ​
-  return ​(USBD_OK);   + data = spi1.send_data(0x00);          // Data read (read 1byte data) 
-  ​/* USER CODE END 13 */  ​+ ​SPI1_CS_ON;​ 
 + ​return data;  
 } }
  
 </​code>​ </​code>​
-  * 写SDIO函数 +==== 、 实验步骤 ====
-<code c> +
-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 */   +
-+
-</​code>​ +
-==== 五、 实验步骤 ====+
   - 把仿真器与iCore3的SWD调试口相连(直接相连或者通过转接器相连);   - 把仿真器与iCore3的SWD调试口相连(直接相连或者通过转接器相连);
-  - 将跳线帽插在USB OTG; 
-  - 将Micro SD卡插入TF卡座里面; 
   - 把iCore3(USB OTG)通过Micro USB线与计算机相连,为iCore3供电;   - 把iCore3(USB OTG)通过Micro USB线与计算机相连,为iCore3供电;
 +  - 把iCore3网口通过网线与计算机网口相连;
 +  - 设置本机电脑IP;(方法见附录1)
   - 打开Keil MDK 开发环境,并打开本实验工程;   - 打开Keil MDK 开发环境,并打开本实验工程;
 +  - 打开TCP&​UDP测试工具;(安装及使用方法见附录2)
   - 烧写程序到iCore3上;   - 烧写程序到iCore3上;
-  - 在电脑上操作磁盘。 +  - 以进入Debug 模式,单步运行或设置断点程序逻辑
- +
-==== 六、 实现象 ==== +
-  * 下载程序到iCore3上之后,可以从设备管理器内查看到USB大容量存储设备。同时可以看到设备和驱动器里面多了一个磁盘。可以对该磁盘进行操作,即可读写Micro SD卡 +
-{{ :​icore3:​icore3_arm_hal_22_2.png?​direct |}} +
  
 +==== 七、 实验现象 ====
 +  * 在发送区编辑完要发送的数据信息后,点击发送即可收到发送的数据包。如图所示
 +{{ :​icore3:​icore3_arm_hal_23_14.png?​direct |}}
  
 +==== 附录1 ====
 +1、打开控制面板网络和Internet网络和共享中心更改适配器设置以太网属性
 +{{ :​icore3:​icore3_arm_hal_23_14.png?​direct |}}
 +2、Internet协议版本选择使用下面的IP地址(如下图所示),然后更改IP地址和默认网关
 +{{ :​icore3:​icore3_arm_hal_23_14.png?​direct |}}
 +==== 附录2 ====
 +1、TCP&​UDP测试工具安装
 +双击TCPUDPDebug102_Setup.exe,点击下一步,在这里安装路径我们默认即可,点击安装,然后Finish。
 +2、TCP&​UDP测试工具的使用
 +(1)打开测试工具,界面如下。点击创建服务器,弹出了设置端口的窗口,端口设置为60001。
 +{{ :​icore3:​icore3_arm_hal_23_14.png?​direct |}}
 +(2)服务器已经创建完成(如下图),点击启动服务器
 +{{ :​icore3:​icore3_arm_hal_23_14.png?​direct |}}
 +(3)iCore3客户端自动连接服务器,即可进行通信。(若连接不上请关闭电脑防火墙)
  
icore3_arm_hal_23.1596276232.txt.gz · 最后更改: 2020/08/01 18:03 由 fmj