搜索
bottom↓
回复: 72

[关注]老外的Mega88做的Web网页服务器(翻译版)

[复制链接]

出0入296汤圆

发表于 2006-12-4 22:44:29 | 显示全部楼层 |阅读模式
好久没有发原创文章了,实在对不起大家。

拿个翻译的东西凑数。







使用ATMega88实现HTTP/TCP(AVR Web服务器)

HTTP/TCP with an atmega88 microcontroller (AVR web server)



Abstract:

摘要



This is a continuation of the article An AVR microcontroller based Ethernet device. The hardware is still the same (ENC28J60 + atmega88). The software is now updated to provide also a a web-server.

本文是之前《基于AVR的以太网设备》的续篇。硬件还和之前一样(ENC28j60+ATMega88)。片内软件现在已经升级到能够支持做一个Web服务器了。



That is: instead of using a command line application and send UDP packets to the Ethernet device we can just point our web browser to it. .... and even better: we add only the web server and all the UDP based functionality is still there. Now you can use both!

升级的部分是:使用web浏览器取代之前的命令行发送UDR数据报的方式来访问我们的以太网设备……之前的UDP基本功能仍然保留。现在,这两种功能你都可以使用了!

The code is written in C and there is even a lot of space left on the atmega88 microcontroller.

即便代码是使用C编写的,(编译以后)ATMeg88存储器中仍然有相当的剩余。



All hardware components are available from shop.tuxgraphics.org.



The software and circuit diagrams are available for free (GPL V2 license).



代码和电路都是免费可用的。



Introduction



A UDP command interface is sufficient for most applications but an integrated web-server is much more universal and easier to use. How to build a web server into an atmega88 chip?

对于大部分应用场合,UDP命令行的方式已经足够了,但是,对于一个简单通用的综合性Web服务器来说,却远远不够。怎样在一个ATMega88中建立一个Web服务器呢?



Before starting this Ethernet project I did of course some prototyping and then I noticed already that UDP was not a problem with lots of space left on the atmega88. Therefore I was quite confident that TCP + HTTP will work. TCP/IP was invented more than 25 years ago. Todays microcontrollers provide almost the computing power a standard computer had at that time. No java or xml was used at that time. Things were done in smart and efficient ways.

在我开始做这个以太网项目的之前,我做了一些原型机,在这个过程中,我注意到,即便实现了UDP协议以后,ATMega88中仍然有大量的空间剩余。因此,我对于实现TCP+HTTP非常有信心。TCP/IP协议已经诞生了将近25年。当今的微控制器提供了一个几乎和从前标准计算机相同的计算能力。而从前,没有java和xml。今天,同样的事情通过一种更加小巧有效的方法完成。

So here is a real web-server on an atmega88 AVR microcontroller.

所以今天,我们将在这里通过ATMega88实现一个真正的Web网络服务器。





TCP is a state machine

TCP 是一个状态机



TCP is a protocol where one establishes a connection. For this a number of packets are first exchanged and both sides of the connection go through several states [see tcp state machine from rfc793]. Once the connection is established a number of data packets can be sent. More than one packet, large amounts of data can be sent. Counters and the state machine ensure that the actual user data arrives in correct order and without data loss.

TCP是一个建立网络连接的协议。通过该协议,在连接建立之前,连接双方通过交换一些IP数据报实现在一些状态间进行切换[请参照RFC793标准中TCP状态机的相关内容]。一旦连接建立成功,包含数据的IP数据报将被传送——实现海量数据的传输。通过计数器和状态机我们可以确认数据被按照正确的顺序传送,并且没有发生丢失。



Large web pages will need to send many data packets. Small pages less. How many do we need to send???

大的网页需要发送大量的数据包,当然,小的网页需要传送的数据包就要少些(数据包就是包含实际数据的IP数据报),那么,我们究竟需要发送多少呢?



Let’s take a look at the application introduced in the first article [June 2006, article060601]. In this first article we just switch on and off something. It can be done with a simple web page which might look like this:

让我们回顾一下本文的前篇中提到过的那个程序。在前文中,我们只是(用UDP协议实现)将一些开关打开(Switch on)或者关闭(Switch off),同样的功能可以通过下面的简单网页来实现:



Output is: ON

Switch off



Figure 1: The web page needed for the Ethernet Remote Device circuit.

Figure 1:使用网页来配置远处的以太网设备



Other applications might be measurement of temperature or air pressure. Those are all small web

pages with is very little data. In other words we will send less than 100 bytes including all the html

tags. How many IP packets with data will be sent for such a page?

Just one!

在其他的应用中,可能是(用UDP协议)来采集温度或者气压。这些都是小的网页,只需要很少少的信息量。换句话说,我们只需要发送不到100个字节的信息就可以包含所有的HTML网页信息了。那么,这种情况下究竟需要多少IP数据包来发送这样的页面呢?

The whole point of using TCP is that one can send more than one packet of data but we don’t need

that functionality. We need TCP only because HTTP is based on it and we want HTTP in order to





use our web browser.

使用TCP协议的要点是:虽然发送者可以发送多个数据包,但我们并不需要这样能够的功能。我们是用TCP协议,只是因为我们网页浏览器使用的HTTP协议是建立在TCP基础之上的。



Under the assumption that you will never need to send more than one packet with data the whole TCP protocol and state handling can be simplified a lot. We can e.g send the FIN immediately together with the data. This makes the state handling for the closing of the connection very simple.

假设我们永远也不需要发送多于一个的数据包,那么整个TCP协议以及其状态处理可以大大的简化。例如,我们可以在发送完数据以后立即发送FIN(申请断开连接的请求信号)。这样,关闭连接的状态处理就变得非常简单了(因为状态少了)。



Under this assumption it possible to implement a web-server in a atmega88 and have just under 50% of the chip’s memory still free for the actual application.



在这个假设下,就有可能在ATmega88中实现Web服务器,甚至我们还有将近50%的片内存储空间留下用来执行其他实际(功能)的应用程序。



The Ethernet remote device with build-in web server: switching something on and off

内建Web服务器的以太网远程设备:



开关的控制



The application that the eth_rem_dev_tcp-2.X software implements is a simple switch. You can

switch on or off something. A simple password mechanism provides very basic protection to avoid

that unauthorized users toggle the switch.

Here is a screen shot of the web-page that the eth_rem_dev_tcp-2.X displays:

代码:eth_rem_dev_tcp-2.X实现一个简单的开关控制。你可以通过这个实例来控制(远程以太网设备的某些)开关量。同时,通过一个简单的密码检测提供最基本的保护,防止未经授权的用户来攫取开关的控制权。

下面的图片是这个例程的一个截屏:



Figure 2: The atmega88 based web-server, screenshot with mozilla firefox

Figure 2:基于ATMega88的Web服务器的网页截图

A Single Data Packet TCP/HTTP web-server on a microcontroller

使用微控制器实现的单数据包的TCP/HTTP网页服务器



The code is available at the end of the article and I will explain it a bit. That way you will hopefully be able to modify it and adapt it also to other applications. The Single Data Packet web-server will go through the following TCP states:

文章结尾处的代码是可以直接使用的,当然我会适当作一些解释。这样你就可以通过修改代码来适应其他应用的要求。单数据包Web服务器将经过以下(简化过的)状态(实现一次数据传输):

1        receive SYN

2        send SYN,ACK

3        receive ACK (the connection is now established)

4        receive ACK with HTTP GET command

5        send ACK

6        send FIN,ACK with HTTP data (e.g 200 OK)

7        receive FIN,ACK

8        send ACK



1        接收“从对方到己方”的连接请求信号(SYN)

2        发送“从己方到对方”的连接请求(SYN),并应答前面的对方的连接请求(ACK)

3        接收对方回应的应答信号(现在,已经建立了一个连接)

4        接收HTTP GET 指令的应答信号(ACK)

5        发送应答信号

6        发送HTTP数据包(比方说,200个字节的数据),同时请求终止“从己方到对方”连接(FIN),并直接应答(ACK)

7        接收对方请求终止“从对方到己方”连接的信号(FIN)以及对刚才发送出去的终止请求的应答信号(ACK)

8        发送应答信号,告知对方它终止连接的请求已经被响应(ACK)



As you can see this is a quite simple command and action sequence. I have implemented the needed functions for this the file ip_arp_udp_tcp.c The file main.c is where the receive loop for the data is implemented. main.c has in this loop a number of if statements in order to decide what action to take. Here you will also see that the code branches between udp and tcp with port 80 (=web-server). If you want to implement your own application (e.g read temperatures, air pressure, whatever...) the you just need to modify the code above the call to the function print_webpage and modify the function print_webpage in order to print your own webpage. All this is in the file main.c The file enc28j60.c implements the driver to the Ethernet chip. You don’t have to worry about the enc28j60.c.

就像你上面看到的那样,这一过程非常简单。我已经在ip_arp_udp_tcp.c文件中完成了所需的基本函数。主文件main.c中有一个查询式的数据接收循环。上面描述的状态以及状态的处理程序都在这个循环中得到实现。例程中,你会发现用于分别处理UDP和TCP(Web服务器通常使用80端口)的程序分支。如果你想实现一个你自己的功能(比方说,读取温度、气压或者其他什么东东……)你只需要修改所生成网页的内容以及之前的一些代码就可以了。所有的这些都在main.c中,而文件enc28j60.c是以太网芯片的驱动函数库,你可以不必理它。



The URL format

URL格式

In order to build an interactive web page the HTML code provides "点击此处打开armok01137143.pdf




-----此内容被Gorgon Meducer于2006-12-04,22:45:44编辑过

出0入296汤圆

 楼主| 发表于 2006-12-4 22:50:19 | 显示全部楼层
相关程序代码



点击此处下载armok01137146.rar

出0入0汤圆

发表于 2006-12-4 23:26:36 | 显示全部楼层
好东西,谢谢楼主,另外不知这个文章出自哪里?想去作者网站看看还有什么好东东。

出0入0汤圆

发表于 2006-12-4 23:31:32 | 显示全部楼层
http://www.tuxgraphics.org/electronics/

出0入0汤圆

发表于 2006-12-4 23:37:04 | 显示全部楼层
有点害怕,这么小的芯片能完成这么大的功能吗。

出0入0汤圆

发表于 2006-12-4 23:48:50 | 显示全部楼层
谢谢楼主,正需要!

出0入0汤圆

发表于 2006-12-5 00:17:59 | 显示全部楼层
AVR的web服务器早有了呀.粗略的看了一下,没什么实用价值,价格高且只能显示几个文字,多几个设置就麻烦了

多谢提供,还是不错的参考
-----此内容被donkey于2006-12-05,00:22:45编辑过

出0入0汤圆

发表于 2006-12-5 08:29:39 | 显示全部楼层
兄弟,强啊,英文水平高!谢谢了。

出0入0汤圆

发表于 2007-5-14 09:59:41 | 显示全部楼层
看看这个webserver的实现……

出0入0汤圆

发表于 2007-5-14 11:50:18 | 显示全部楼层
好东西,谢谢楼主,翻译这么好,辛苦了

出0入0汤圆

发表于 2007-5-14 12:18:26 | 显示全部楼层
这样的贴 好贴 顶起来 感谢楼主的贡献

出0入0汤圆

发表于 2007-5-14 14:28:02 | 显示全部楼层
我已经把它移植到S64上了,对于S64这么小的ROM来说,效果还算可以~~

出10入95汤圆

发表于 2007-5-15 12:52:47 | 显示全部楼层
好贴,顶!!

出0入0汤圆

发表于 2008-4-2 14:23:20 | 显示全部楼层
mark

出0入0汤圆

发表于 2008-4-3 14:53:57 | 显示全部楼层
1 问题:没有实现大于一个IP数据包容量的数据传送的状态机处理,仅能处理一个IP数据包(无状态的),
2 问题:如果多个客户端同时访问,也会出现问题

请傻孩子老师,谈谈数据容量超过IP数据包最大携带数据容量的数据传送方法,也就是状态的处理

出0入0汤圆

发表于 2008-4-3 15:34:00 | 显示全部楼层
好,顶

出0入0汤圆

发表于 2008-4-3 15:50:13 | 显示全部楼层
1 问题:没有实现大于一个IP数据包容量的数据传送的状态机处理,仅能处理一个IP数据包(无状态的),
2 问题:如果多个客户端同时访问,也会出现问题
  
请傻孩子老师,谈谈数据容量超过IP数据包最大携带数据容量的数据传送方法,也就是状态的处理

出0入0汤圆

发表于 2008-4-3 16:17:45 | 显示全部楼层
谢谢,收藏

出0入0汤圆

发表于 2008-4-3 16:39:11 | 显示全部楼层
会英文就是好啊。哈哈

出0入296汤圆

 楼主| 发表于 2008-4-3 18:19:28 | 显示全部楼层
to 【16楼】 zjybest 绝对痴迷

    您这样尊称我,我更加不好意思了。这篇稿件是我学习TCP/IP时翻译的,但是我并没有在TCP/IP上有所发展。所以,对于你说的问题我很遗憾……不过我觉得,也许就是分包处理吧……我这里有一个状态机,用于在串口缓冲区小于数据包的情况下,发送大量数据,至少在思路上有所帮助吧:



/***********************************************************
*   函数说明:  数据包发送函数                             *
*   输入:      数据包序列号,要发送数据的大小,数据缓冲区 *
*               工作模式                                   *
*   输出:      状态机是否继续运行                         *
*   调用函数:  无                                         *
* -------------------------------------------------------- *
*  [ 说 明 ]    该函数仅适用于大数据包的发送。             *
***********************************************************/
BOOL AT_MF_Send_MSG(UINT8 chModel,AT_MF_SEQUENCE_NUMBER_TYPE SEQNumber,
                    AT_MF_MESSAGE_SIZE_TYPE MSGSize,
                    void *pMSGBody)
{
    static UINT8 s_chActionFlag = NULL;
    static UINT8 n = 0;
    static BYTE *p = NULL;
    static AT_MF_MESSAGE_SIZE_TYPE s_MessageSize = 0;
    #if defined(AT_MF_USE_CRC_CHECK)
    static UINT16 wCRC = 0;
    #elif defined(AT_MF_USE_XOR_CHECK)
    static UINT8 chXOR = 0;
    #endif

    if (chModel == 0xFF)
    {
        AMSM_STOP_ALL_ACTIONS
        return FALSE;
    }
   
    if (s_chActionFlag == NULL)
    {
        AMSM_START = TRUE;
    }
   
    if (AMSM_START)
    {
        s_MessageSize = MSGSize;
        if ((pMSGBody == NULL) || (MSGSize == 0))
        {
            //强壮性检测,不需要发送任何东西
            AMSM_STOP_ALL_ACTIONS
            return FALSE;
        }
        
        #if defined(AT_MF_USE_CRC_CHECK)
        wCRC = 0;
        #elif defined(AT_MF_USE_XOR_CHECK)
        chXOR = 0;
        #endif
        
        AMSM_START = FALSE;
        AMSM_SEND_HEAD = TRUE;
    }
   
    if (AMSM_SEND_HEAD)
    {
        if (SERIAL_OUT(AT_MF_MESSAGE_START))
        {
            //发送成功
            n = 0;

            AMSM_SEND_SEQUENCE_NUM = TRUE;
            AMSM_SEND_HEAD = FALSE;
        }
        else
        {
            REFRESH_SERIAL_BUFFER
        }
    }
   
    if (AMSM_SEND_SEQUENCE_NUM)
    {
        p = (BYTE *)&SEQNumber;
        
        while(TRUE)
        {
            if (SERIAL_OUT(p[n]))
            {
                //发送成功
                n++;
                if (n == sizeof(AT_MF_SEQUENCE_NUMBER_TYPE))
                {
                    //发送数据完成
                    n = 0;
               
                    AMSM_SEND_MESSAGE_SIZE = TRUE;
                    AMSM_SEND_SEQUENCE_NUM = FALSE;
                    break;

                }

            }
            else
            {
                REFRESH_SERIAL_BUFFER
                break;
            }
        }
    }
   
    if (AMSM_SEND_MESSAGE_SIZE)
    {
        p = (BYTE *)&MSGSize;
        
        while(TRUE)
        {
            if (SERIAL_OUT(p[n]))
            {
                //发送成功
                n++;
                if (n == sizeof(AT_MF_MESSAGE_SIZE_TYPE))
                {
                    //发送数据完成
                    
                    AMSM_SEND_TOKEN = TRUE;
                    AMSM_SEND_MESSAGE_SIZE = FALSE;
                    break;
                }
            }
            else
            {
                REFRESH_SERIAL_BUFFER
                break;
            }
        }
    }
   
    if (AMSM_SEND_TOKEN)
    {
        if (SERIAL_OUT(AT_MF_TOKEN))
        {
            //发送成功
            n = 0;
            
            AMSM_SEND_DATA = TRUE;
            AMSM_SEND_TOKEN = FALSE;
        }
    }
   
    if (AMSM_SEND_DATA)
    {
        
        p = (BYTE *)pMSGBody;
        
        while(TRUE)
        {
            UINT8 chTempData = 0;
            if (chModel)
            {
                //单字节模式
                chTempData = *p;
            }
            else
            {
                chTempData = p[n];
            }
            if (SERIAL_OUT(chTempData))
            {
                //发送成功
                #if defined(AT_MF_USE_CRC_CHECK)
                CRC(wCRC,chTempData)                        //计算CRC16
                #elif defined(AT_MF_USE_XOR_CHECK)
                chXOR ^= chTempData;                        //计算XOR
                #endif
            
                n++;
                if (n == s_MessageSize)
                {
                    //发送完成
                    n = 0;
               
                    AMSM_SEND_CHECK = TRUE;
                    AMSM_SEND_DATA = FALSE;
                    break;
                }
                else
                {
                    if (chModel)
                    {
                        //单字节工作模式
                        return FALSE;
                    }
                }
            }
            else
            {
                REFRESH_SERIAL_BUFFER
                break;
            }
        }
    }

    if (AMSM_SEND_CHECK)
    {
        #if defined(AT_MF_USE_CRC_CHECK)
        p = (BYTE *)&wCRC;
        #elif defined(AT_MF_USE_XOR_CHECK)
        p = (BYTE *)&chXOR;
        #endif
        
        while(TRUE)
        {
            if (SERIAL_OUT(p[n]))
            {
                //发送成功
                n++;
                #if defined(AT_MF_USE_CRC_CHECK)
                if (n == 2)
                #elif defined(AT_MF_USE_XOR_CHECK)
                if (n == 1)
                #endif
                {
                    
                    //整个数据包发送完成
                    if (chModel)
                    {
                        //单字节工作模式
                        AMSM_SEND_CHECK = FALSE;
                        AMSM_IDEL = TRUE;
                        
                        return FALSE;
                    }
                    else
                    {

                        AMSM_STOP_ALL_ACTIONS;
                        return FALSE;
                    }
                    
                }
            }
            else
            {
                REFRESH_SERIAL_BUFFER
                break;
            }
        }
    }
   
    if (AMSM_IDEL)
    {
        return FALSE;
    }
   
    return TRUE;
}

出0入0汤圆

发表于 2008-4-3 18:40:01 | 显示全部楼层
非常强悍,不得不佩服老外。
这次也可以把armok那里买的M32的以太网板子拿出来学习了

出0入0汤圆

发表于 2008-4-3 22:38:59 | 显示全部楼层
收藏了

出0入0汤圆

发表于 2008-4-4 09:18:39 | 显示全部楼层
Gorgon Meducer 傻孩子,谢谢你的回答,代码非常好。
  我认为:这个方法可以对待一个客户端访问WEB服务器,但是多个客户端就成为问题,应该每个客户端都有状态,而且应该有一种机制保证函数的可重入性的调用。所以,个人认为,上面的代码,本质来说不适合商业化,我需要商业化的设计方法学习。

出0入0汤圆

发表于 2008-4-4 09:46:39 | 显示全部楼层
不错收了

出0入296汤圆

 楼主| 发表于 2008-4-22 17:13:37 | 显示全部楼层
to 【22楼】 zjybest 绝对痴迷
     我提供的代码是mkII下载器协议的……不是TCP/IP的……所以你说的是否商业化的问题……其实……那个……

出0入0汤圆

发表于 2008-4-23 08:48:53 | 显示全部楼层
Gorgon Meducer 傻孩子 ;
   我说的是TCP/IP 基于多用户,状态机,多数据包(传输数据》一个TCP包容量)的处理的技术

出0入0汤圆

发表于 2008-4-23 08:57:59 | 显示全部楼层
========================
【25楼】 zjybest 绝对痴迷
积分:106
派别:
等级:------
来自:湖北省黄石
        Gorgon Meducer 傻孩子 ;
   我说的是TCP/IP 基于多用户,状态机,多数据包(传输数据》一个TCP包容量)的处理的技术
========================
拜托你至少还是用ARM7吧……AT91SAM7X256,内置以太网控制器、CAN控制器、64KRAM可在55MHz下全速工作,256KFLASH可在30MHz下全速工作,你所要的全都能做到

出0入0汤圆

发表于 2008-11-19 22:29:27 | 显示全部楼层
真的是好东西,记号

出0入0汤圆

发表于 2008-11-19 23:39:27 | 显示全部楼层
太牛了,老外都是外星人来的吗?

出0入0汤圆

发表于 2008-11-20 09:09:18 | 显示全部楼层
不错!

出0入0汤圆

发表于 2008-11-20 09:16:08 | 显示全部楼层
好东西

出0入0汤圆

发表于 2008-12-4 21:05:56 | 显示全部楼层
强悍,原文好像在http://tuxgraphics.org/electronics/200611/embedded-webserver.shtml,谢谢你的翻译

出0入0汤圆

发表于 2008-12-4 23:08:06 | 显示全部楼层
mark

出0入0汤圆

发表于 2008-12-5 08:47:09 | 显示全部楼层
感谢了

出0入0汤圆

发表于 2008-12-5 10:45:23 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-8-5 11:35:24 | 显示全部楼层
想要做......

出0入0汤圆

发表于 2009-8-5 12:00:22 | 显示全部楼层
学习

出0入0汤圆

发表于 2009-8-5 14:33:59 | 显示全部楼层
好贴。请你们都是什么职业的工程师?还是在校的读研的研究生?发觉你们太厉害了。

出0入0汤圆

发表于 2009-10-27 20:01:00 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-10-28 12:25:31 | 显示全部楼层
太强大了

出0入46汤圆

发表于 2009-10-28 12:57:58 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-10-28 16:29:29 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-10-28 17:08:26 | 显示全部楼层
学习

出0入0汤圆

发表于 2010-5-9 12:04:17 | 显示全部楼层
好东西.mark!

出0入0汤圆

发表于 2010-5-11 13:00:16 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-8-15 13:33:54 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-8-15 13:46:26 | 显示全部楼层
好东西

出0入0汤圆

发表于 2010-12-11 12:53:48 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-12-28 23:19:19 | 显示全部楼层
MARK

出0入0汤圆

发表于 2010-12-29 13:09:16 | 显示全部楼层
老帖焕发

出0入0汤圆

发表于 2011-1-31 13:39:21 | 显示全部楼层
make~谢谢分享

出0入0汤圆

发表于 2011-1-31 14:11:40 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-1-31 23:57:47 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-2-1 11:04:50 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-2-1 11:16:28 | 显示全部楼层
mark tcpip

出0入0汤圆

发表于 2011-2-1 11:17:11 | 显示全部楼层
回复【楼主位】Gorgon Meducer 傻孩子
-----------------------------------------------------------------------

mark tcpip

出0入0汤圆

发表于 2011-2-1 19:10:16 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-2-21 00:48:28 | 显示全部楼层
牛 tcpip

出0入0汤圆

发表于 2011-6-12 18:17:16 | 显示全部楼层
怎么MARK啊

出0入0汤圆

发表于 2011-6-27 22:16:13 | 显示全部楼层
来学习来了。。。

出0入0汤圆

发表于 2011-9-23 11:57:52 | 显示全部楼层
傻孩子老师,有没有自动获取IP的方法啊?

出0入0汤圆

发表于 2011-9-23 12:37:57 | 显示全部楼层
回复【61楼】zend  
-----------------------------------------------------------------------

你可以参考下 ethernut 的源码。

出0入0汤圆

发表于 2012-3-28 19:45:24 | 显示全部楼层
bao qiang ya

出0入0汤圆

发表于 2012-3-28 19:51:23 来自手机 | 显示全部楼层
Gorgon_Meducer 发表于 2006-12-4 22:50
相关程序代码



点击此处下载armok01137146.rar

非常感谢分享'有用

出0入0汤圆

发表于 2012-3-28 20:10:26 | 显示全部楼层
感觉好像美国大学康奈尔有门课都是用ATMEL的 每学期都有很多项目挂在网上 不知道这个是不是的

话说这帖子06年的都被翻出来了...

出0入0汤圆

发表于 2012-3-28 20:55:13 | 显示全部楼层
谢谢,收藏

出0入0汤圆

发表于 2012-5-4 11:41:44 | 显示全部楼层
mark                        

出0入0汤圆

发表于 2012-9-6 09:24:12 | 显示全部楼层
哪一个open source 的 web server 有能力做到 "动态网页" 的功能?
只能做到 "静态网页" 的 服务器, 实用价值实在不高.

出0入0汤圆

发表于 2012-9-6 10:13:58 | 显示全部楼层
谢谢分享

出0入0汤圆

发表于 2013-6-25 23:18:54 | 显示全部楼层
学习一下。。谢谢
Gorgon Meducer 傻孩子

出0入0汤圆

发表于 2013-12-15 16:47:03 | 显示全部楼层
可能有用,赞一个

出0入0汤圆

发表于 2014-6-1 20:47:43 | 显示全部楼层
mark随时可能会游泳哦
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-29 14:29

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表