前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >调通STM32F103RCT6 与W5500网卡芯片的PING程序

调通STM32F103RCT6 与W5500网卡芯片的PING程序

作者头像
呱牛笔记
发布2023-05-02 15:36:34
6120
发布2023-05-02 15:36:34
举报
文章被收录于专栏:呱牛笔记呱牛笔记

接到一个任务,验证硬件同事的一块板子上网卡芯片W5500的功能是否正常,MCU使用的是STM32F103RCT6 ,从了解到的信息看,W5500和MCU之间使用SPI接口进行通信,跟最近调了好久的DW1000的使用方法相同,驱动是厂家提供的,也就是只需要调通SPI通信,基本上就能驱动W5500工作!

标准库版本:STM32F10x_StdPeriph_Lib_V3.5.0

W5500与STM32F103RCT6 的引脚关系如下,使用的是STM32F103RCT6 芯片的SPI2:

代码语言:javascript
复制
    PA8 -> W5500_RST
    PB12 -> W5500_SCS
    PB13 -> W5500_SCK
    PB14 -> W5500_MISO
    PB15 -> W5500_MOSI
    PA15 -> W5500_INT

关键的第一个点是GPIO的初始化(参考CSDN的文档实现):

代码语言:javascript
复制
    GPIO_InitTypeDef GPIO_InitStructure;
    SPI_InitTypeDef   	SPI_InitStructure;
    /*使能GPIOA的rcc时钟*/ 
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); 
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); 
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);  
     
    
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);


    
    /*配置GPIO引脚*/
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_15| GPIO_Pin_3;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
    GPIO_Init(GPIOA, &GPIO_InitStructure); 
    
     /* Configure SPI1 pins: SCK, MISO and MOSI -------------*/
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
    GPIO_InitStructure.GPIO_Mode =  GPIO_Mode_IPU;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    /* Set Chip Select pin */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_12;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
    GPIO_SetBits(GPIOB, GPIO_Pin_12);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    GPIO_ResetBits(GPIOA, GPIO_Pin_8);//RST
         
     
    /*配置GPIO引脚*/
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
       
    /*初始化GPIO*/
    GPIO_Init(GPIOC, &GPIO_InitStructure);    
    
    /* Set SPI interface */
    SPI_InitStructure.SPI_Direction=SPI_Direction_2Lines_FullDuplex;
    SPI_InitStructure.SPI_Mode=SPI_Mode_Master;
    SPI_InitStructure.SPI_DataSize=SPI_DataSize_8b;
    SPI_InitStructure.SPI_CPOL=SPI_CPOL_Low;
    SPI_InitStructure.SPI_CPHA=SPI_CPHA_1Edge;
    SPI_InitStructure.SPI_NSS=SPI_NSS_Soft;
    SPI_InitStructure.SPI_BaudRatePrescaler=SPI_BaudRatePrescaler_2;
    SPI_InitStructure.SPI_FirstBit=SPI_FirstBit_MSB;
    SPI_InitStructure.SPI_CRCPolynomial=7;

    SPI_Init(SPI2,&SPI_InitStructure);
    SPI_Cmd(SPI2,ENABLE);
    
    SPI_I2S_ClearFlag(SPI2, SPI_I2S_FLAG_TXE);
    SPI_I2S_ClearFlag(SPI2, SPI_I2S_FLAG_RXNE);

W5500的上电,根据W5500的驱动文档,需要把W5500的RST引脚拉低超过500us

代码语言:javascript
复制
void func_w5500_reset(void)
{ 
  GPIO_ResetBits(W5500_RST_GPIO_PORT, W5500_RST_PIN); 
  delay_ms(2);
  GPIO_SetBits(W5500_RST_GPIO_PORT, W5500_RST_PIN); 
  delay_ms(1600);
}

SPI读写:

代码语言:javascript
复制
/* NSS pin is SW controllable */
#define port_SPIx_set_chip_select()     GPIO_SetBits(W5500_SPI2_CS_GPIO_PORT, W5500_SPI2_CS_PIN)
#define port_SPIx_clear_chip_select()   GPIO_ResetBits(W5500_SPI2_CS_GPIO_PORT, W5500_SPI2_CS_PIN)
 
 
uint8_t func_spi_write_a_byte(uint8_t byte)
{ 
	//port_SPIx_set_chip_select();
 
        /* Wait until TXE flag is set to send data */
	while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET)
        {
        }
        
        //SPI_I2S_SendData(SPI2, byte);
        SPI2->DR = byte; /* set output to 0 (MOSI), this is necessary for
        e.g. when waking up DW1000 from DEEPSLEEP via dwt_spicswakeup() function.
        */

        /* Wait until RXNE flag is set to read data */
	while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET)
        {
        }
        
        //return SPI_I2S_ReceiveData(SPI2);
        uint8_t byte_read = SPI2->DR;  //copy data read form (MISO) 
 
	//port_SPIx_clear_chip_select(); 
	
	return byte_read; 
}  

void func_spi_cs_select(void)
{
  port_SPIx_clear_chip_select();
}

void func_spi_cs_deselect(void)
{
  port_SPIx_set_chip_select();
}

测试程序

代码语言:javascript
复制
#include "SEGGER_RTT.h"
#define logD(...) SEGGER_RTT_printf(0, __VA_ARGS__)  


int main(void)
{  
    reset_w5500();
    
    config_eth();
    uint8_t test_0 = 0;
    uint8_t test_1 = 1;
    while(1)
    {
        int i;
       
           
        SEGGER_RTT_printf(0, "times:%d\r\n",  times++);
 
        test_eth(); 
        delay_ms(500); 
     }                 
}
typedef  uint8_t uint8;

static uint8 test_ip[8] = {'\0'}; 
static char print_str[1024] = "\0";
void test_eth(){  
        int index = 0;
	  
	memset(test_ip, 0x00, 8);
	memset(print_str, 0x00, 1024);
	getGAR(test_ip);
	index = 0;
	for(int i=0; i<4; i++){
		sprintf(print_str + index, "%d.", test_ip[i]);
		index = strlen(print_str);
	}
	logD("gateway:%s\r\n", print_str);
	
	memset(test_ip, 0x00, 8);
	memset(print_str, 0x00, 1024);
	getSIPR(test_ip);
	index = 0;
	for(int i=0; i<4; i++){
		sprintf(print_str + index, "%d.", test_ip[i]);
		index = strlen(print_str);
	}
	logD("ip:%s\r\n", print_str);
	
}
void config_eth(){ 
	uint8 mac[6]={0, };
	uint8 lip[4]={192,168,86,197};
	uint8 sub[4]={255,255,255,0};
	uint8 gw[4]={192,168,86,1};//根据网络所在的IP地址段和网关信息修改
	
	char print_str[1024] = "\0";
	memset(print_str, 0x00, 1024);
	memset(mac, 0x00, 6);
        getMacByLockCode(mac);
	
	int index = 0;
	for(int i=0; i<6; i++){
		sprintf(print_str + index, "%d.", mac[i]);
		index = strlen(print_str);
	}
	logD("mac:%s\r\n", print_str);
	 
	
	uint8 test_ip[8] = {'\0'};
	memset(test_ip, 0x00, 8);
	memset(print_str, 0x00, 1024);
	getSIPR(test_ip);
	index = 0;
	for(int i=0; i<4; i++){
		sprintf(print_str + index, "%d.", test_ip[i]);
		index = strlen(print_str);
	}
	logD("old ip:%s\r\n", print_str);
	
	setSHAR(mac);
	
	
	memset(test_ip, 0x00, 8);
	memset(print_str, 0x00, 1024);
	getSHAR(test_ip);
	index = 0;
	for(int i=0; i<6; i++){
		sprintf(print_str + index, "%d.", test_ip[i]);
		index = strlen(print_str);
	}
	logD("new mac:%s\r\n", print_str);
	
        setSUBR(sub);
        setGAR(gw);
        setSIPR(lip);
	
	memset(test_ip, 0x00, 8);
	memset(print_str, 0x00, 1024);
	getGAR(test_ip);
	index = 0;
	for(int i=0; i<4; i++){
		sprintf(print_str + index, "%d.", test_ip[i]);
		index = strlen(print_str);
	}
	logD("gateway:%s\r\n", print_str);
	
	memset(test_ip, 0x00, 8);
	memset(print_str, 0x00, 1024);
	getSIPR(test_ip);
	index = 0;
	for(int i=0; i<4; i++){
		sprintf(print_str + index, "%d.", test_ip[i]);
		index = strlen(print_str);
	}
	logD("ip:%s\r\n", print_str);
	
}

使用参考连接中提供的下载iolibarary,修改了基本的方法后,调通了ping程序

遗留问题:

STM32 CubeMX生成基于Hal库的工程,在SPI口配置为输出时,拉低和拉高均不生效;

呱牛笔记
呱牛笔记
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-02-23 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档