热度 26
2015-6-1 17:14
920 次阅读|
0 个评论
转载自:http://www.embed-net.com/thread-55-1-1.html 官方提供了W5500的最新驱动库,下载地址如下: http://wizwiki.net/wiki/doku.php?id=products:w5500:driver 下面简单介绍下如何使用这套库 首先下载库源码,文件目录如下所示: 我们主要用到Ethernet文件夹下面的文件,将这些文件加入到自己的工程中,然后编译,若编译出现类似于如下错误 ..\User\Ethernet\wizchip_conf.c(113): error: #29: expected an expression .id = _WIZCHIP_ID_, ..\User\Ethernet\wizchip_conf.c(114): error: #29: expected an expression .if_mode = _WIZCHIP_IO_MODE_, ..\User\Ethernet\wizchip_conf.c(115): error: #29: expected an expression .CRIS._enter = wizchip_cris_enter, ..\User\Ethernet\wizchip_conf.c(116): error: #29: expected an expression .CRIS._exit = wizchip_cris_exit, ..\User\Ethernet\wizchip_conf.c(117): error: #29: expected an expression .CS._select = wizchip_cs_select, ..\User\Ethernet\wizchip_conf.c(118): error: #29: expected an expression .CS._deselect = wizchip_cs_deselect, ..\User\Ethernet\wizchip_conf.c(119): error: #29: expected an expression .IF.BUS._read_byte = wizchip_bus_readbyte, ..\User\Ethernet\wizchip_conf.c(120): error: #29: expected an expression .IF.BUS._write_byte = wizchip_bus_writebyte ..\User\Ethernet\wizchip_conf.c(123): warning: #12-D: parsing restarts here after previous syntax error }; ..\User\Ethernet\wizchip_conf.c: 1 warning, 8 errors 则需要根据自己的编译器做下设置,keil MDK设置如下所示: 主要原因是Keil MDK默认设置不支持按照结构体名称初始化结构体的原因导致。 W5500和MCU是通过SPI接口通信的,库是利用如下结构体中的相关函数指针实现SPI通信和其他功能。 _WIZCHIP WIZCHIP = { .id = _WIZCHIP_ID_, .if_mode = _WIZCHIP_IO_MODE_, .CRIS._enter = wizchip_cris_enter, .CRIS._exit = wizchip_cris_exit, .CS._select = wizchip_cs_select, .CS._deselect = wizchip_cs_deselect, .IF.BUS._read_byte = wizchip_bus_readbyte, .IF.BUS._write_byte = wizchip_bus_writebyte // .IF.SPI._read_byte = wizchip_spi_readbyte, // .IF.SPI._write_byte = wizchip_spi_writebyte }; 根据函数名字和库中的注释,我们这里也对要实现的函数做个简单的说明 wizchip_cris_enter :进入临界区的函数,可以不管 wizchip_cris_exit :退出临界区的函数,也可以不管 wizchip_cs_select :输出有效片选信号的函数,也就是控制CS输出低电平的函数,必须实现 wizchip_cs_deselect :控制CS输出高电平的函数,必须实现 wizchip_bus_readbyte :SPI总线读取一字节数据函数,必须实现 wizchip_bus_writebyte :SPI总线写一字节数据函数,必须实现根据以上可知,只要实现了SPI的基本操作,移植基本完成,是不是很简单 下面我们就新建一个spi.c的文件来实现这几个函数,当然这些函数名字可以不和这个结构体里面的函数名字一样,到时候可以调用相关的函数注册下即可 /** ****************************************************************************** * @file spi.c * $Author: 飞鸿踏雪 $ * $Revision: 17 $ * $Date:: 2014-10-25 11:16:48 +0800 #$ * @brief SPI驱动函数实现. ****************************************************************************** * @attention * *h3center© Copyright 2009-2012, EmbedNet/center *center http://www.embed-net.com /center *centerAll Rights Reserved/center/h3 * ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ #include "main.h" /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ /* Private function prototypes -----------------------------------------------*/ /* Private functions ---------------------------------------------------------*/ /** * @brief 使能SPI时钟 * @retval None */ static void SPI_RCC_Configuration( void ) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_SPI1,ENABLE); } /** * @brief 配置指定SPI的引脚 * @retval None */ static void SPI_GPIO_Configuration( void ) { GPIO_InitTypeDef GPIO_InitStruct; //PA4-CS,PA5-SCK,PA6-MISO,PA7-MOSI GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6|GPIO_Pin_7; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOA, GPIO_InitStruct); //初始化片选输出引脚 GPIO_InitStruct.GPIO_Pin = GPIO_Pin_4; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOA, GPIO_InitStruct); GPIO_SetBits(GPIOA,GPIO_Pin_4); } /** * @brief 根据外部SPI设备配置SPI相关参数 * @retval None */ void SPI_Configuration( void ) { SPI_InitTypeDef SPI_InitStruct; SPI_RCC_Configuration(); SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2; SPI_InitStruct.SPI_Direction= SPI_Direction_2Lines_FullDuplex; SPI_InitStruct.SPI_Mode = SPI_Mode_Master; SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b; SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low; SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge; SPI_InitStruct.SPI_NSS = SPI_NSS_Soft; SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB; SPI_InitStruct.SPI_CRCPolynomial = 7; SPI_Init(SPI1,SPI_InitStruct); SPI_GPIO_Configuration(); SPI_SSOutputCmd(SPI1, ENABLE); SPI_Cmd(SPI1, ENABLE); } /** * @brief 写1字节数据到SPI总线 * @param TxData 写到总线的数据 * @retval None */ void SPI_WriteByte(uint8_t TxData) { while ((SPI1-SRSPI_I2S_FLAG_TXE)==0); //等待发送区空 SPI1-DR=TxData; //发送一个byte while ((SPI1-SRSPI_I2S_FLAG_RXNE)==0); //等待接收完一个byte SPI1-DR; } /** * @brief 从SPI总线读取1字节数据 * @retval 读到的数据 */ uint8_t SPI_ReadByte( void ) { while ((SPI1-SRSPI_I2S_FLAG_TXE)==0); //等待发送区空 SPI1-DR=0xFF; //发送一个空数据产生输入数据的时钟 while ((SPI1-SRSPI_I2S_FLAG_RXNE)==0); //等待接收完一个byte return SPI1-DR; } /** * @brief 进入临界区 * @retval None */ void SPI_CrisEnter( void ) { __set_PRIMASK(1); } /** * @brief 退出临界区 * @retval None */ void SPI_CrisExit( void ) { __set_PRIMASK(0); } /** * @brief 片选信号输出低电平 * @retval None */ void SPI_CS_Select( void ) { GPIO_ResetBits(GPIOA,GPIO_Pin_4); } /** * @brief 片选信号输出高电平 * @retval None */ void SPI_CS_Deselect( void ) { GPIO_SetBits(GPIOA,GPIO_Pin_4); } /*********************************END OF FILE**********************************/ 到这里,移植基本上完成。 但是这些SPI的接口函数如何跟这套库衔接呢?不用怕,库提供有这样的函数来注册,只要在主函数中调用下就可以了,具体程序如下 // First of all, Should register SPI callback functions implemented by user for accessing WIZCHIP /* Critical section callback */ reg_wizchip_cris_cbfunc(SPI_CrisEnter, SPI_CrisExit); //注册临界区函数 /* Chip selection call back */ #if _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_VDM_ reg_wizchip_cs_cbfunc(SPI_CS_Select, SPI_CS_Deselect); //注册SPI片选信号函数 #elif _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_FDM_ reg_wizchip_cs_cbfunc(SPI_CS_Select, SPI_CS_Deselect); // CS must be tried with LOW. #else #if (_WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SIP_) != _WIZCHIP_IO_MODE_SIP_ #error "Unknown _WIZCHIP_IO_MODE_" #else reg_wizchip_cs_cbfunc(wizchip_select, wizchip_deselect); #endif #endif /* SPI Read Write callback function */ reg_wizchip_spi_cbfunc(SPI_ReadByte, SPI_WriteByte); //注册读写函数 到这里,移植工程基本完成,下面我们就将官方提供的一个loopback的测试程序移植到我们自己的工程中来,基本上也没做什么修改,下面是测试工程用到的几个测试函数 继续阅读:http://www.embed-net.com/thread-55-1-1.html