DM9051 SPI 接口以太网模块 + NuTinyM051 + uIP实现web server
2016-01-18 21:26
756 查看
最近在某個论坛裡,看到这篇STM32F103+DM9051_UIP_SPI to 以太网,透过該版主拿到了DM9051NP
以太网卡,刚好手上有Nuvoton NuTiny M051 和 M451,就先用M051拿来做一个简单的web server,透过web server 来控制开发板上的LED灯亮灭。
模式來传输,以实现资料传送快速。DM9051NP通过1个中断引脚和SPI介面來进行与主控制器/MCU单片机的通信,资料传输规格为10/100 M。相關介紹可以參考STM32F103+DM9051_UIP_SPI to 以太网。以下是DM9051NP 以太網卡特點:
• Package:32支接脚封装,QFN.
• IEEE 802.3az Energy Efficient Ethernet (EEE)
• Built-in integrated 3.3V to 1.8V regulator
• 远端唤醒 (WOL)
• 平行线/交叉线自动切换 HP Auto-MDIX
• Support 光口介面
• 具有16KB SRAM静态随机存取记忆
• EMI (Class B) and HBM ESD Rating 8KV
• 工业温度规范: –40℃ to +85℃
• 功率:(100/10 M) => 429/561 mW
• 连续工作温度<60℃
![](http://img.blog.csdn.net/20160118212903307?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
上图是聯傑國際(D***ICOM) DM9051NP 以太网路卡SPI Pin的排列。
NuTinyM051使用的是SPI1与DM9051NP SPI脚位的硬体连接如下:
![](http://img.blog.csdn.net/20160118212942683?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
上图为M051 + DM9051硬体连接示意图。
DM9051_Write_Reg(), DM9051_Read_Mem(), DM9051_Writer_Mem() , 修改如下:
(1) 首先配置M0516 SPI1 相关设定
控制 LED function,新增web_led.c 和web_led.h 如下:
最后在网址列输入IP 192.168.XXX.XXX进入 uip web server控制LED,因为uip 有开DHCP 也可设定为固定IP ,看使用者设定输入正确的IP位址
![](http://img.blog.csdn.net/20160118213916078?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
就可以透过web 控制LED,如下可以看到MCU + DM9051相关讯息,最下面可以看到控制LED 选单,
按下on 、off 、Flash后网址后面会分别显示XXX.XXX.XXX.XXX / LED0、1、2让使用者可以知道目前设定
![](http://img.blog.csdn.net/20160118215615165?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
以上完成后就是一个简单webserver 控制LED应用了,最後附上程序:
DM9051网卡 + NuTinyM051 + uIP实现web server
以太网卡,刚好手上有Nuvoton NuTiny M051 和 M451,就先用M051拿来做一个简单的web server,透过web server 来控制开发板上的LED灯亮灭。
1. DM9051NP硬体相关描述
DM9051NP SPI介面网卡芯片是聯傑國際(D***ICOM)为了方便MCU单片机系统进行乙太网通信而开发出的解决方案。DM9051NP晶片是带有行业标准串列外设介面(Serial Peripheral Interface,SPI)的独立乙太网控制器。DM9051NP符合IEEE 802.3 规范,它还支援以DMA模式來传输,以实现资料传送快速。DM9051NP通过1个中断引脚和SPI介面來进行与主控制器/MCU单片机的通信,资料传输规格为10/100 M。相關介紹可以參考STM32F103+DM9051_UIP_SPI to 以太网。以下是DM9051NP 以太網卡特點:
• Package:32支接脚封装,QFN.
• IEEE 802.3az Energy Efficient Ethernet (EEE)
• Built-in integrated 3.3V to 1.8V regulator
• 远端唤醒 (WOL)
• 平行线/交叉线自动切换 HP Auto-MDIX
• Support 光口介面
• 具有16KB SRAM静态随机存取记忆
• EMI (Class B) and HBM ESD Rating 8KV
• 工业温度规范: –40℃ to +85℃
• 功率:(100/10 M) => 429/561 mW
• 连续工作温度<60℃
上图是聯傑國際(D***ICOM) DM9051NP 以太网路卡SPI Pin的排列。
NuTinyM051使用的是SPI1与DM9051NP SPI脚位的硬体连接如下:
M0516 | DM9051 |
P0.7(Pin32) | CLK (Pin07) |
P0.6(Pin33) | MISO (Pin05) |
P0.5(Pin34) | MOSI (Pin03) |
P0.4(Pin35) | CSS (Pin01) |
上图为M051 + DM9051硬体连接示意图。
2.DM9051网卡驱动
SPI 设定和 R/W data 参考M0516 Library SPI_Loopback sample code 可到nuvoton 官网下载M0516 Library, 再参考STM32F103+DM9051_UIP_SPI to 以太网附件中的驱动,将DM9051_Configuration() SPI设定改为M0516 SPI1 Pin Group 设定和修改DM9051_Read_Reg(),DM9051_Write_Reg(), DM9051_Read_Mem(), DM9051_Writer_Mem() , 修改如下:
(1) 首先配置M0516 SPI1 相关设定
void DM9051_Configuration(void) { /* Enable SPI1 peripheral clock */ CLK_EnableModuleClock(SPI1_MODULE); /* Select HCLK as the clock source of SPI1 */ CLK_SetModuleClock(SPI1_MODULE, CLK_CLKSEL1_SPI1_S_HCLK, MODULE_NoMsk); /* Reset IP */ SYS_ResetModule(SPI1_RST); /* Setup SPI1 multi-function pins */ SYS->P0_MFP = SYS_MFP_P04_SPISS1 | SYS_MFP_P05_MOSI_1 | SYS_MFP_P06_MISO_1 | SYS_MFP_P07_SPICLK1; /*---------------------------------------------------------------------------------------------------------*/ /* Init SPI */ /*---------------------------------------------------------------------------------------------------------*/ /* Configure SPI1 as a master, SPI clock rate 200 KHz, clock idle low, 32-bit transaction, drive output on falling clock edge and latch input on rising edge. */ SPI_Open(SPI1, SPI_MASTER, SPI_MODE_0, 8, 25000000); /* Disable the automatic hardware slave selection function. Select the SPI1_SS pin and configure as low-active. */ SPI_DisableAutoSS(SPI1); SPI_EnableFIFO(SPI1, 3, 3); }
(2) 透过read cmd 读出register
/*------------------------------------------------------*/ /* DM9051_Read_Reg() */ /* SPI read command: bit7 = 0, */ /* bit[6:0] = Reg. offset addr */ /* Disable auto SPI slave chip select. */ /*------------------------------------------------------*/ uint8_t DM9051_Read_Reg(uint8_t Reg_Off) { SPI_SET_SS_LOW(SPI1); /* SPI transfer DM9051 Read-Command and Reg. offset. */ //SPI_WRITE_TX0(SPI1, (uint32_t)Reg_Off); //Read command + Register offset address while(SPI_GET_TX_FIFO_FULL_FLAG(SPI1)); SPI_WRITE_TX0(SPI1, Reg_Off); //Read command + Register offset address while(SPI_IS_BUSY(SPI1)); SPI_WRITE_TX0(SPI1, 0x0); //Dummy for read register value. while(SPI_IS_BUSY(SPI1)); SPI_READ_RX0(SPI1); // dummy read, jump 1st byte. SPI_SET_SS_HIGH(SPI1); return (SPI_READ_RX0(SPI1) & 0xFF); }
(3)透过write cmd 写入register
/*------------------------------------------------------*/ /* DM9051_Write_Reg() */ /* SPI write command: bit7 = 1, */ /* bit[6:0] = Reg. offset addr */ /* Disable auto SPI slave chip select. */ /*------------------------------------------------------*/ void DM9051_Write_Reg(uint8_t Reg_Off, uint8_t spi_data) { uint32_t cmdaddr; cmdaddr = (Reg_Off | 0x80); SPI_SET_SS_LOW(SPI1); /* SPI transfer DM9051 Read-Command and Reg. offset. */ SPI_WRITE_TX0(SPI1, cmdaddr); //Read command + Register offset address while(SPI_IS_BUSY(SPI1)); SPI_WRITE_TX0(SPI1, (uint32_t)spi_data); while(SPI_IS_BUSY(SPI1)); /*Clear SPI TX FIFO*/ SPI_ClearRxFIFO(SPI1); SPI_SET_SS_HIGH(SPI1); return; }
(4) 连续读出 data 从spi array
/*------------------------------------------------------*/ /* DM9051_Read_Mem() */ /* */ /* DM9051 burst read command: SPI_RD_BURST = 0x72 */ /* Disable auto SPI slave chip select. */ /*------------------------------------------------------*/ void DM9051_Read_Mem(uint8_t* pu8data, uint32_t datalen) { uint32_t i; // Read SPI_Data_Array back from the slave uint8_t burstcmd = SPI_RD_BURST; SPI_SET_SS_LOW(SPI1); SPI_WRITE_TX0(SPI1, (uint32_t)burstcmd); while(SPI_IS_BUSY(SPI1)); SPI_READ_RX0(SPI1); for(i = 0 ; i < datalen; i++){ pu8data[i] = SPI_WRITE_TX0(SPI1, (uint32_t )0x0); while(SPI_GET_RX_FIFO_EMPTY_FLAG(SPI1)); pu8data[i] = (uint8_t)SPI_READ_RX0(SPI1); } while(SPI_IS_BUSY(SPI1)); /*Clear SPI TX FIFO*/ SPI_ClearTxFIFO(SPI1); SPI_SET_SS_HIGH(SPI1); }
(5) 连续写入data到spi array
/*------------------------------------------------------*/ /* DM9051_Write_Mem() */ /* */ /* DM9051 burst write command: SPI_WR_BURST = 0xF8 */ /* Disable auto SPI slave chip select. */ /*------------------------------------------------------*/ void DM9051_Write_Mem(uint8_t* pu8data, uint32_t datalen) { uint32_t i; uint8_t burstcmd = SPI_WR_BURST; /* Send the array to the slave*/ SPI_SET_SS_LOW(SPI1); SPI_WRITE_TX0(SPI1, (uint32_t)burstcmd); while(SPI_IS_BUSY(SPI1)); SPI_READ_RX0(SPI1); for(i = 0; i < datalen; i++){ while(SPI_GET_TX_FIFO_FULL_FLAG(SPI1)); SPI_WRITE_TX0(SPI1, (uint32_t)pu8data[i]); } while(SPI_IS_BUSY(SPI1)); /*Clear SPI RX FIFO*/ SPI_ClearRxFIFO(SPI1); SPI_SET_SS_HIGH(SPI1); }
3. 简单的web server 控制 LED
uIP就不多介绍了,网路上有许多相关资料可以参考,在上一部份将驱动设置好后,將tapdev_init()、tapdev_read()、tapdev_send()對應到DM9051_init()、DM9051_rx()、DM9051_tx() function即可附件可參考,在main()中加入在 http_init(); 然后在http.c 在handle_input中天加控制 LED function,新增web_led.c 和web_led.h 如下:
(1)首先先在 http.c handle_input()新增判斷:
static PT_THREAD(handle_input(struct httpd_state *s)) { PSOCK_BEGIN(&s->sin); PSOCK_READTO(&s->sin, ISO_space); if(strncmp(s->inputbuf, http_get, 4) != 0) { PSOCK_CLOSE_EXIT(&s->sin); } PSOCK_READTO(&s->sin, ISO_space); if(s->inputbuf[0] != ISO_slash) { PSOCK_CLOSE_EXIT(&s->sin); } if(s->inputbuf[1] == ISO_space) { //strncpy(s->filename, http_index_html, sizeof(s->filename)); strncpy(s->filename, http_webMain_html, sizeof(s->filename)); } #if 1 //web control led /* Control led, 0 = OFF, 1 = ON, 2 = Flash */ else if (s->inputbuf[3] == 'L','E','D' && ((s->inputbuf[4] == '0') || (s->inputbuf[4] == '1') || (s->inputbuf[4] == '2'))){ Set_LED_mode(s->inputbuf[4]); s->inputbuf[4]= 0; //strncpy(s->filename, "/home.html", 10); strncpy(s->filename, http_webMain_html, sizeof(s->filename)); } #endif else { s->inputbuf[PSOCK_DATALEN(&s->sin) - 1] = 0; strncpy(s->filename, &s->inputbuf[0], sizeof(s->filename)); } /* httpd_log_file(uip_conn->ripaddr, s->filename);*/ s->state = STATE_OUTPUT; while(1) { PSOCK_READTO(&s->sin, ISO_nl); if(strncmp(s->inputbuf, http_referer, 8) == 0) { s->inputbuf[PSOCK_DATALEN(&s->sin) - 2] = 0; /* httpd_log(&s->inputbuf[9]);*/ } } PSOCK_END(&s->sin); }
(2)LED 设定和控制判断代码如下:
void Set_LED_mode(char lkkcode) { //int i; GPIO_SetMode(P3, BIT6, GPIO_PMD_OUTPUT); if(lkkcode == ('0')) // LED off { P36 = 1; }else if (lkkcode == '1'){ // LED on P36 = 0; }else if(lkkcode == '2') // LED Flash { //for(i = 0 ; i< 30 ; ++i) { P36 = 0; Delay(25); P36 = 1; Delay(25); } } }
最后在网址列输入IP 192.168.XXX.XXX进入 uip web server控制LED,因为uip 有开DHCP 也可设定为固定IP ,看使用者设定输入正确的IP位址
就可以透过web 控制LED,如下可以看到MCU + DM9051相关讯息,最下面可以看到控制LED 选单,
按下on 、off 、Flash后网址后面会分别显示XXX.XXX.XXX.XXX / LED0、1、2让使用者可以知道目前设定
以上完成后就是一个简单webserver 控制LED应用了,最後附上程序:
DM9051网卡 + NuTinyM051 + uIP实现web server
相关文章推荐
- UICollectionView的使用方法及demo
- iOS开发之指定UIView的某几个角为圆角
- REG QUERY命令参数(注册表)
- hdu 1387 Team Queue (链表)
- [问题记录]AutoLayout下UIScrollView 布局错位及解决方法
- java基础学习总结——GUI编程(一)
- java基础学习总结——GUI编程(二)
- UGUI中ScrollView滑动适应问题解决办法
- Android java.exe finished with non-zero exit value 1
- serialVersionUID的作用
- Uncaught InvalidStateError: Failed to set the 'value' property on 'HTMLInputElement': This input element accepts a filename, which may only be programmatically set to the empty string.
- Git---通过一个具体实例详解Git常用命令以及提交pr(pull request)
- LeetCode题解——Longest Consecutive Sequence
- LeetCode Permutation Sequence
- UI课程(tableView)
- UVA 11404 Palindromic Subsequence 刘汝佳的动归练习
- jd-gui报错INTERNAL ERROR 解决办法
- hdu 1159 Common Subsequence 最大公共子串
- hdu1423 Greatest Common Increasing Subsequence
- 【Elasticsearch】query_string的各种用法