国民技术
直播中

donatello1996

8年用户 687经验值
擅长:MEMS/传感技术
私信 关注
[经验]

【国民技术N32项目移植】半小时移植完成SPI1驱动代码&使用W5500模块进行UDP通信,十分甚至九分好用

      得益于N32标准库参考ST标准库,就连SPI1的数据寄存器和状态寄存器相应位的功能不能说大同小异,也可以说是完全一致的:
4.jpg 3.jpg

跟GPIO操作一样,N32的SPI驱动库函数也就是改了下拼写,配置方式与ST完全相同,配置SPI1八位数据传输,CPOL为低,CPHA为第一个时钟沿开始传输,高字节在前,波特率分频为APB2总线的64分频:
  1. void SPI1_Init()

    {

            GPIO_InitType GPIO_InitStructure = {0};

            SPI_InitType  SPI_InitStructure = {0};

           

            RCC_ConfigPclk2(RCC_HCLK_DIV2);


  2.   RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOA | RCC_APB2_PERIPH_SPI1 , ENABLE);

           

            //GPIO_ConfigPinRemap


  3.         RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_AFIO, ENABLE );


  4.         GPIO_InitStructure.Pin = GPIO_PIN_5;

            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

            GPIO_InitPeripheral(GPIOA, &GPIO_InitStructure);


  5.         GPIO_InitStructure.Pin = GPIO_PIN_6;

            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOAtiNG;

            GPIO_InitPeripheral(GPIOA, &GPIO_InitStructure);


  6.         GPIO_InitStructure.Pin = GPIO_PIN_7;

            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

            GPIO_InitPeripheral(GPIOA, &GPIO_InitStructure);

           

            SPI_InitStructure.DataDirection = SPI_DIR_DOUBLELINE_FULLDUPLEX;

            SPI_InitStructure.SpiMode       = SPI_MODE_MASTER;

            SPI_InitStructure.DataLen       = SPI_DATA_SIZE_8BITS;

            SPI_InitStructure.CLKPOL        = SPI_CLKPOL_LOW;

            SPI_InitStructure.CLKPHA        = SPI_CLKPHA_FIRST_EDGE;

            SPI_InitStructure.NSS           = SPI_NSS_SOFT;

            SPI_InitStructure.BaudRatePres  = SPI_BR_PRESCALER_64;

            SPI_InitStructure.FirstBit      = SPI_FB_MSB;

            SPI_InitStructure.CRCPoly       = 7;

            SPI_Init(SPI1, &SPI_InitStructure);

            SPI_Enable(SPI1, ENABLE);


  7. }



N32的STS寄存器的最后两位代表TE和RNE,也就是发送缓冲区清零状态和接收缓冲区清零状态:
  1. uint8_t SPI1_ReadWriteByte(uint8_t data)

    {               

            uint8_t retry = 0;                                       

            while ((SPI1->STS & SPI_I2S_TE_FLAG) == RESET)

            {

                    retry ++;

                    if(retry > 200)return 0;

            }                          

            SPI1->DAT = data;

            retry=0;


  2.         while ((SPI1->STS & SPI_I2S_RNE_FLAG) == RESET)

            {

                    retry ++;

                    if(retry > 200)return 0;

        }

            return SPI1->DAT;

    }


W5500初始化代码稍微有些内容,这里简单节选方便帖子展示,若主办方需要,可以直接找我要完整代码:
  1. void W5500_SetEthernet(void)

    {

            char tdata[20];

            uint8_t i;

            uint8_t w5500_get_ip[4] = {0};

            uint8_t w5500_get_mask[4] = {0};

            uint8_t w5500_get_gateway[4] = {0};


  2.         memcpy(tdata,(char*)(0X1FFFF7E8),12);

            memcpy(MAC, tdata, 6);

            for(i = 0; i < 6; i++)

            {

                    if(MAC[i] == 0XFF)  MAC[i] = 0X90 + i;

            }

            MAC[0] = 40;

            MAC[1] = 150;

           

            printf("MAC = %xh %xh %xh %xh %xh %xhn" , MAC[0], MAC[1], MAC[2], MAC[3], MAC[4], MAC[5]);


  3.         W5500_Set_Mac(MAC);

            W5500_Set_IP(Local_IP);

            W5500_Get_IP(&w5500_get_ip);

           

            printf("W5500 w5500_get_ip = %d %d %d %dn" , w5500_get_ip[0] , w5500_get_ip[1] , w5500_get_ip[2] , w5500_get_ip[3]);

           

            W5500_Set_Mask(Mask);

            W5500_Get_Mask(&w5500_get_mask);

            printf("W5500 w5500_get_mask = %d %d %d %dn" , w5500_get_mask[0] , w5500_get_mask[1] , w5500_get_mask[2] , w5500_get_mask[3]);

           

            W5500_Set_Gateway(Gateway);

            W5500_Get_Gateway(&w5500_get_gateway);

            printf("W5500 w5500_get_gateway = %d %d %d %dn" , w5500_get_gateway[0] , w5500_get_gateway[1] , w5500_get_gateway[2] , w5500_get_gateway[3]);

           

            W5500_SocketInit(txsize , rxsize);

           

            if(socketopen & 0x01) W5500_Socket_Mode_Init(0 , socketType[0]);

            if(socketopen & 0x02) W5500_Socket_Mode_Init(1 , socketType[1]);

            W5500_Socket_Mode_Init(2 , socketType[2]);

            W5500_Socket_Mode_Init(3 , socketType[3]);

            //Enable socket(channel) 0 and 1 , set socket 0 and 1 for UDP mode/unicast

    }


  4. void W5500_Init()

    {

            GPIO_InitType GPIO_InitStructure = {0};


  5.         RCC_EnableAPB2PeriphClk(W5500_CS_GPIOEN | W5500_RST_GPIOEN | W5500_INT_GPIOEN , ENABLE);


  6.         GPIO_InitStructure.Pin = W5500_CS_PIN;

            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

            GPIO_InitPeripheral(W5500_CS_GPIO , &GPIO_InitStructure);


  7.         GPIO_InitStructure.Pin = W5500_RST_PIN;

            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

            GPIO_InitPeripheral(W5500_RST_GPIO , &GPIO_InitStructure);


  8.         GPIO_InitStructure.Pin = W5500_INT_PIN;

            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;

            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

            GPIO_InitPeripheral(W5500_INT_GPIO , &GPIO_InitStructure);


  9.         W5500_RST_GPIO->PBC |= W5500_RST_PIN;

            Delay_ms(100);

            W5500_RST_GPIO->PBSC |= W5500_RST_PIN;

            Delay_ms(100);


  10.         SPI1_Init();


  11.         W5500_SetEthernet();


  12.         W5500_ReconnectTimeout(2000);

            W5500_ReconnectCount(3);

            W5500_InterruptMask(socketopen | 0x10);

            W5500_Set_INTLEVEL(0x0008);

    }


  13. void W5500_Send_UDP_Buffer_Specify_IP_port(uint8_t s, uint8_t buffer[] , uint16_t len ,

            uint8_t specify_ip[] , int specify_port)

    //W5500 send udp buffer

    {

            uint8_t temp[4];

            uint32_t writeAddr;

            IINCHIP_ISR_DISABLE();

            //disable W5500 IRQ

           

            W5500_Write_Buffer(Sn_DIPR0(s), specify_ip , 4);

            W5500_WriteByte(Sn_DPORT0(s), specify_port >> 8);

            W5500_WriteByte(Sn_DPORT1(s), specify_port);

            W5500_Read_Buffer(Sn_TX_WR0(s), temp, 2);


  14.         writeAddr = ((uint32_t)temp[0] << 16) | ((uint32_t)temp[1] << 8) | 0x10 | (s << 5);

            W5500_Write_Buffer(writeAddr, (uint8_t *)buffer, len);

            writeAddr >>= 8;

            writeAddr += len;

            temp[0] = writeAddr >> 8;

            temp[1] = writeAddr;


  15.         W5500_Write_Buffer(Sn_TX_WR0(s), temp, 2);

            W5500_WriteByte(Sn_CR(s), Sn_CR_SEND);


  16.         IINCHIP_ISR_ENABLE();

            //enable W5500 IRQ

    }


演示效果,开发板连接的W5500模块地址为192.168.0.200,电脑地址为192.168.0.106,每一秒发送一个UDP包:
5.jpg 7.jpg 6.jpg

更多回帖

发帖
×
20
完善资料,
赚取积分