打印

STM32F107&407开发板科星F107源码笔记以太网篇-申请置酷 给力

[复制链接]
11029|35
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 网络转接 于 2013-9-27 17:26 编辑

                     
                     
      软件平台  IAR5.40&MDK4.22
      硬件平台 科星F107开发板
      淘宝平台   
corxstm32.taobao.com
           
沙发
ren0zhe| | 2013-9-27 10:22 | 只看该作者
沙发!

使用特权

评论回复
板凳
网络转接|  楼主 | 2013-9-27 10:23 | 只看该作者
本帖最后由 网络转接 于 2013-9-27 11:36 编辑

这里是以太网部分的学习笔记 所有的笔记将会在这里共享给大家

基础接口的笔记IAR6.40版本在
https://bbs.21ic.com/icview-619245-1-3.html
基础接口笔记IAR5.40和MDK4.22(已经写好的)会专开帖子整理。
所有资料不久将会共享完成,在此之前购买开发板的网络将会得到优惠 198的板子==158元提供给网友。

使用特权

评论回复
地板
网络转接|  楼主 | 2013-9-27 10:47 | 只看该作者
本帖最后由 网络转接 于 2013-9-27 10:49 编辑

  网络部分已经完成的程序列表  主芯片 STM32F107VCT6  PHY  DP83848
            科星F107开发板网络应用篇之TCP服务器--与上位机通信
            科星F107开发板网络应用篇之TCP客户端--与上位机通信
            科星F107开发板网络应用篇之TCP服务器-控制LED灯
            科星F107开发板网络应用篇之TCP客户端-控制LED灯
            科星F107开发板网络应用篇之UDP通信---与上位机通信
            科星F107开发板网络应用篇之UDP模式修改IP
            科星F107开发板网络应用篇之DHCP自动获取功能--获取IP 更改ip
            科星F107开发板网络应用篇之综合功能测试一------DHCP自动获取IP 扫描IP 连接开发板 通信 控制功能的实现
            科星F107开发板网络应用篇之WEB功能的实现----------简单web的实现
            。。。。。。。。后续的正在完善 慢慢添加  

     上位机 VB编程  持续完善 赠送源码
            
            

               

使用特权

评论回复
5
网络转接|  楼主 | 2013-9-27 11:05 | 只看该作者
本帖最后由 网络转接 于 2013-9-27 11:07 编辑

第一篇       TCP服务器模式简单数据收发
             ----控制开发板LED
概要
  通过TCP 服务器模式简单的建立和数据收发,我们能大概了解一下LWIP的进程流程,具体的函数说明和更详细的讲解,可以参考LWIP讲解的专业文档,这里我们主要以应用为主,不对lwip内核进行讨论,笔者也不是懂得太多,还希望大家一起讨论,指出和更正作者的错误,一起进步。使用静态设置ip的方式。
打开工程《科星F107开发板网络应用篇之TCP服务器》
   打开MAIN.C主文件
    int main(void)
{
  
        System_Setup();  底层硬件驱动初始化 时钟 IO  PHY  NVIC
        LwIP_Init();     LwIP协议栈初始化,包括IP初始化和物理地址初始化,可进入进行相应的修改
        HelloWorld_init();建立一个TCP端口
while (1)
           {   
                LwIP_Periodic_Handle(LocalTime); 协议任务循环调用 暂时不需要更改 这里我们不对他进行讲解
           }
}
  System_Setup();
主要是初始化和STM32F107有关的IO和时钟 学习过我们前面的笔记 应该都比较了解了
    LwIP_Init();
    初始化一个协议栈的堆栈,以便存储我们TCP建立和通信的一些参数信息或者是回调函数,同时这里设置了网络端口最主要的MAC地址和IP信息。
进入函数内部查看:
void LwIP_Init(void)
{
  struct ip_addr ipaddr;
  struct ip_addr netmask;
  struct ip_addr gw;
uint8_t macaddress[6]={0,0,0,0,0,1};
  mem_init();主要是告知内存堆的起止地址,以及初始化空闲表,由lwip 初始化时自己调用,该接口为内部私有接口,不对用户层开放
   memp_init();将全局memp_memory按照固定块大小进行分割,并用memp_tab 进行串接
上面两个函数 完成了协议栈运行时的对栈和内存的初始化和链接,我们在这里暂且认为他处理的已经很好了 后面程序用到后 会具体理解它具体做了什么
  IP4_ADDR(&ipaddr, 192, 168, 0, 8);
  IP4_ADDR(&netmask, 255, 255, 255, 0);
  IP4_ADDR(&gw, 192, 168, 0, 1); 设置ip信息
Set_MAC_Address(macaddress); 设置MAC地址 只是把mac存入全局变量 还未真正初始化到我们的网络接口
  netif_add(&netif, &ipaddr, &netmask, &gw, NULL, ðernetif_init, ðernet_input); //创建一个网络接口
  netif_set_default(&netif);//初始化缺省网络接口,把前面的netif设置为缺省网络接口。
netif_set_up(&netif);//使能网络接口 建立网络接口通道
}
这里我们还有看一下一个重要的函数
netif_add(&netif, &ipaddr, &netmask, &gw, NULL, ðernetif_init, ðernet_input); //创建一个网络接口
进入子函数  
   这里面有很多#if xxx
  #endif
没有定义的 是很多用不上的 可以删掉 这里因为全局变量已经定义 我们可以不必去掉 只看我们关心的几个赋值 下面我一一注释:
  struct netif *
netif_add(struct netif *netif, struct ip_addr *ipaddr, struct ip_addr *netmask,
  struct ip_addr *gw,
  void *state,
  err_t (* init)(struct netif *netif), 我们自己写的初始化函数
  err_t (* input)(struct pbuf *p, struct netif *netif))数据接收到后的递交IP层的函数
{
  static u8_t netifnum = 0;
  /* reset new interface configuration state */
  netif->ip_addr.addr = 0;
  netif->netmask.addr = 0;
  netif->gw.addr = 0;
  netif->flags = 0;
#if LWIP_DHCP
  /* netif not under DHCP control by default */
  netif->dhcp = NULL;
#endif /* LWIP_DHCP */
#if LWIP_AUTOIP
  /* netif not under AutoIP control by default */
  netif->autoip = NULL;
#endif /* LWIP_AUTOIP */
#if LWIP_NETIF_STATUS_CALLBACK
  netif->status_callback = NULL;
#endif /* LWIP_NETIF_STATUS_CALLBACK */
#if LWIP_NETIF_LINK_CALLBACK
  netif->link_callback = NULL;
#endif /* LWIP_NETIF_LINK_CALLBACK */
#if LWIP_IGMP
  netif->igmp_mac_filter = NULL;
#endif /* LWIP_IGMP */
#if ENABLE_LOOPBACK
  netif->loop_first = NULL;
  netif->loop_last = NULL;
#endif /* ENABLE_LOOPBACK */
  /* remember netif specific state information data */
  netif->state = state;
  netif->num = netifnum++;
  netif->input = input;  把最后一个参数函数给了INPUT 接收数据处理的
#if LWIP_NETIF_HWADDRHINT
  netif->addr_hint = NULL;
#endif /* LWIP_NETIF_HWADDRHINT*/
#if ENABLE_LOOPBACK && LWIP_LOOPBACK_MAX_PBUFS
  netif->loop_cnt_current = 0;
#endif /* ENABLE_LOOPBACK && LWIP_LOOPBACK_MAX_PBUFS */
  netif_set_addr(netif, ipaddr, netmask, gw);设置IP等参数
  /* call user specified initialization function for netif */
  if (init(netif) != ERR_OK) { 执行底层初始化函数  主要是底层的数据传输函数和初始化 和硬件相关驱动 完成返回OK 说明硬件可以正常收发数据了
他调用的函数就是这个函数的参数ethernetif_init 这个函数的作用就是把底层 也就是硬件收发函数 打包成子函数传递给上层 也就是我们现在定义的网络接口 供更上层调用 主要几个函数是 进入这个函数查看
netif->output = etharp_output; IP层数据包发送函数
  netif->linkoutput = low_level_output;ERP数据包发送函数
  ethernetif->ethaddr = (struct eth_addr *)&(netif->hwaddr[0]);
  low_level_init(netif);初始化硬件
上面三个函数才是真正的和硬件相关的 到此硬件初始化 就算完成了
    return NULL;
  }
  /* add this netif to the list */
  netif->next = netif_list; 把我们设置的网络接口插入链路表
  netif_list = netif;
  snmp_inc_iflist();
#if LWIP_IGMP
  /* start IGMP processing */
  if (netif->flags & NETIF_FLAG_IGMP) {
    igmp_start( netif);
  }
#endif /* LWIP_IGMP */
  LWIP_DEBUGF(NETIF_DEBUG, ("netif: added interface %c%c IP addr ",
    netif->name[0], netif->name[1]));
  ip_addr_debug_print(NETIF_DEBUG, ipaddr);
  LWIP_DEBUGF(NETIF_DEBUG, (" netmask "));
  ip_addr_debug_print(NETIF_DEBUG, netmask);
  LWIP_DEBUGF(NETIF_DEBUG, (" gw "));
  ip_addr_debug_print(NETIF_DEBUG, gw);
  LWIP_DEBUGF(NETIF_DEBUG, ("\n"));
  return netif;
}
这里或许应该还有很多疑问和不解 先不纠缠 我们就认为网卡初始化就结束了,能正常收发数据了。也就是说LwIP_Init 完成了网卡初始化 可以正常接收数据了 这里如果我们下载进去程序到开发板 给他ip发数据就能接收到底层arp数据了 这里我们就可以ping通我们的开发板了。

使用特权

评论回复
6
网络转接|  楼主 | 2013-9-27 11:11 | 只看该作者
那么怎么建立连接 接收数据 并且返回数据呢?
看一下底层接受和发送函数
  发送 前面刚提到过low_level_output
  接受low_level_input(netif); 为什么是这个呢?
我们看一下中断函数里面”stm32f10x_it.c”
找到void LwIP_Pkt_Handle(void)
{
  /* 接受网络数据包 并且返回数据 握手和数据传输 */
  ethernetif_input(&netif);
}
进入ethernetif_input(&netif);函数里面
  ethernetif_input(struct netif *netif)
{
  err_t err;
  struct pbuf *p;
  /* move received packet into a new pbuf */
  p = low_level_input(netif);底层硬件接受函数 就在这里了。这就是接受数据然后存到指针内存P中。 接受了数据就要送给上层去处理 他在那里?看后面  P这个存了数据的参数 就肯定找到了。
  /* no packet could be read, silently ignore this */
  if (p == NULL) return ERR_MEM;
  err = netif->input(p, netif);//这就是处理数据的传递函数 这个函数去哪里了呢?看一下前面讲到的netif_add 函数 他实际是指向了函数ethernet_input 这里就是分析数据的了,它主要就是判断这个包是IP 还是ERP 还是。。然后再往上传递。。一直到应用层 比如是数据还是握手之类的 分了很多 具体的我们后面有单节具体说 这里就认为数据正确的给到了处理函数出。
  if (err != ERR_OK)
  {
    LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n"));
    pbuf_free(p);
    p = NULL;
  }
  return err;
}
前面的操作已经建立了网络底层 可以ping通了,下一步我们就是建立一个具体的端口号,这样我们就能和开发板通过IP和端口号去建立连接和收发数据了。
接着看主程序下面的函数
HelloWorld_init();
void HelloWorld_init(void)
{
  struct tcp_pcb *pcb;                           
  
  pcb = tcp_new();     分配一个新的tcp_pcb结构 里面只是调用了tcp_alloc(TCP_PRIO_NORMAL); TCP_PRIO_NORMAL正常优先级的TCP协议块                             
  tcp_bind(pcb, IP_ADDR_ANY, 23);绑定连接到一个本地端口号和IP地址.
参数ipaddr如果为IP_ADDR_ANY,表示绑定到任何本地地址,那么IP_ADDR_ANY是什么呢?lwip-1.3.0/src/include/ipv4/lwip/ip_addr.h中定义了:
#define IP_ADDR_ANY         ((struct ip_addr *)&ip_addr_any)
ip_addr_any是一个ip_addr型变量,lwip-1.3.0/src/core/ipv4/ip_addr.c中有如下声明:
                   #define IP_ADDR_ANY_VALUE 0x00000000UL
const struct ip_addr ip_addr_any = { IP_ADDR_ANY_VALUE };
所以, IP_ADDR_ANY是等于0x00000000UL. IP地址上规定  0.0.0.0为广播地址,也就是任意地址的意思.
  pcb = tcp_listen(pcb);  进入监听状态 函数原型tcp_listen_with_backlog
:这个函数从原理上看也比较简单,首先是做一些必要的检查,判断原始pcb是否已经处于连接状态,如果没有则申请一块tcp_pcb类型的内存,将原始的必要的pcb内容复制到新的pcb中,设置新的pcb状态为LISTEN,释放原始的pcb,并将新pcb连接放入已监听队列.                 
tcp_accept(pcb, HelloWorld_accept); 指定处于监听状态的连接接通后将要调用的回调函数
客户端连接成功后,会进入这个函数HelloWorld_accept 怎么进入的?就是数据分析一步步分析过来的 进入这个函数 就说明连接建立了 然后就可以收发数据了。
   看一下这个函数
     static err_t HelloWorld_accept(void *arg, struct tcp_pcb *pcb, err_t err)
{     
  
   
  tcp_arg(pcb, mem_calloc(sizeof(struct name), 1));  //告诉他们 已经建立连接
  tcp_err(pcb, HelloWorld_conn_err); //错误回调函数
  tcp_write(pcb, GREETING, strlen(GREETING), 0); //输出Hello.连接已经建立!欢迎来到科星F107开发板网络学习!  告诉连接已经建立
  tcp_recv(pcb, HelloWorld_recv);//指定接收到数据后的回调函数 这里就是连接建立后的接受数据的函数。客户端来的数据将会到这个函数去处理
   看一下在这里我们是怎么写的
     static err_t HelloWorld_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
{
  struct pbuf *q;
  struct name *name = (struct name *)arg;
  if (p != NULL)
  {        
    tcp_recved(pcb, p->tot_len);
    if(!name)
      {
      pbuf_free(p);
      return ERR_ARG;
      }
     q=p;
     tcp_write(pcb, HELLO, strlen(HELLO), 1);//输出数据给客户端
     tcp_write(pcb,q->payload, q->len, 1);
     tcp_write(pcb, END, strlen(END), 1);
     pbuf_free(p);
  }  
  else if (err == ERR_OK)
  {
    /* When the pbuf is NULL and the err is ERR_OK, the remote end is closing the connection. */
    /* We free the allocated memory and we close the connection */
    mem_free(name);
    return tcp_close(pcb);
  }
  return ERR_OK;
}
  return ERR_OK;
}
   
}
tcp_receive(struct tcp_pcb *pcb) 笔记存储 和程序无关
测试操作
下载程序到F107科星开发板 打开上位机
按照我们的界面填写IP和远程端口号 也就是开发板的IP和端口号


      

截图10.jpg (38 KB )

截图10.jpg

使用特权

评论回复
7
网络转接|  楼主 | 2013-9-27 11:21 | 只看该作者
第一篇                   TCP客户端模式简单数据收发
             ----控制开发板LED
概要
建立LWIP客户端模式,科星F107开发板做为客户端去连接PC测试软件模拟的服务器,实现简单的数据收发,通过上位机控制板子的LED
打开工程《科星F107开发板网络应用篇之TCP客户端》
   打开MAIN.C主文件
int main(void)
{
  
  
  System_Setup();
  LwIP_Init();
  //Client_init();
while (1)
  {   
      
     LwIP_Periodic_Handle(LocalTime);
  }
}
上面和前面讲到的服务器模式,区别只在于Client_init();函数,别的和前面都一样,这里不再讲解,我们主要看一下Client_init();函数里的内容 看看客户端和服务器的区别。
void Client_init(void)
{
  struct tcp_pcb *pcb;     
  struct ip_addr ipaddr;
  IP4_ADDR(&ipaddr,192,168,0,22); 远程服务器IP 写进全局变量
  
  pcb = tcp_new();      建立一个新的tcp 链接                                
  tcp_bind(pcb, IP_ADDR_ANY, 23);   绑定开发板IP和端口号 这里端口号可以是0 也就是随机,因为是客户端 不必知道端口号。   
  tcp_connect(pcb, &ipaddr, PEER_PORT, tcp_Client_connected);  主要是这里和服务器不太一样,服务器模式是监听listen,客户端的话 就要主动去连接服务器 我们看一下 参数的含义
PCB 就是我们前面建立的tcp端口
IPADDR 要连接的远程服务器IP 这里设置的是测试的电脑的IP
         这里设置的是IP4_ADDR(&ipaddr,192,168,0,22);
PEER_PORT 远程端口号 我们要连接的端口号 这里我们设置的是5000
#define PEER_PORT    5000
看一下我们测试软件和电脑的设置截图 主要是电脑的IP和上位机的本地端口号 别的没用

使用特权

评论回复
8
网络转接|  楼主 | 2013-9-27 11:22 | 只看该作者
tcp_Client_connected 连接到远程服务器成功后的回调函数 连接成功后会调用这个函数,我们看一下这个过程是怎么到这个函数的
进入函数:        tcp_connect(pcb,&ipaddr, PEER_PORT, tcp_Client_connected);
  下面第四个参数* connected就是回调函数 在程序里找到这个
err_t
tcp_connect(struct tcp_pcb *pcb, struct ip_addr *ipaddr, u16_t port,
      err_t (* connected)(void *arg, struct tcp_pcb *tpcb, err_t err))
{
  err_t ret;
  u32_t iss;

  LWIP_ERROR("tcp_connect: can only connected from state CLOSED", pcb->state == CLOSED, return ERR_ISCONN);

  LWIP_DEBUGF(TCP_DEBUG, ("tcp_connect to port %"U16_F"\n", port));
  if (ipaddr != NULL) {
    pcb->remote_ip = *ipaddr; 远程IP
  } else {
    return ERR_VAL;
  }
  pcb->remote_port = port; 端口号
  if (pcb->local_port == 0) {
    pcb->local_port = tcp_new_port(); 本地端口号
  }
  iss = tcp_next_iss();
  pcb->rcv_nxt = 0;
  pcb->snd_nxt = iss;
  pcb->lastack = iss - 1;
  pcb->snd_lbb = iss - 1;
  pcb->rcv_wnd = TCP_WND;
  pcb->rcv_ann_wnd = TCP_WND;
  pcb->rcv_ann_right_edge = pcb->rcv_nxt;
  pcb->snd_wnd = TCP_WND;
  /* As initial send MSS, we use TCP_MSS but limit it to 536.
     The send MSS is updated when an MSS option is received. */
  pcb->mss = (TCP_MSS > 536) ? 536 : TCP_MSS;
#if TCP_CALCULATE_EFF_SEND_MSS
  pcb->mss = tcp_eff_send_mss(pcb->mss, ipaddr);
#endif /* TCP_CALCULATE_EFF_SEND_MSS */
  pcb->cwnd = 1;
  pcb->ssthresh = pcb->mss * 10;
  pcb->state = SYN_SENT;
#if LWIP_CALLBACK_API  
  pcb->connected = connected; 回调函数传递给我们网络端口connected
   既然是连接成功后回调这个函数 那么在哪里检测是不是连接成功呢?
  如果调用的话肯定是调用pcb->connected 因为他就是回调函数 我们刚才已经传递给他了
这里如果对LWIP不熟的话 可能就搜不到了,我们直接告诉大家 在TCP.h中
  #define TCP_EVENT_CONNECTED(pcb,err,ret)                         \
  do {                                                           \
    if((pcb)->connected != NULL)                                 \
      (ret) = (pcb)->connected((pcb)->callback_arg,(pcb),(err)); \
    else (ret) = ERR_OK;                                         \
  } while (0)
所以我们搜索TCP_EVENT_CONNECTED就能找到连接远程服务器成功后 程序到了哪里 并且调用了我们的回调函数。搜一下:
  在tcp_process(struct tcp_pcb *pcb)函数中 果然 这个就是tcp进程的函数,我们看在哪里调用了?
switch (pcb->state) {
  case SYN_SENT:
    LWIP_DEBUGF(TCP_INPUT_DEBUG, ("SYN-SENT: ackno %"U32_F" pcb->snd_nxt %"U32_F" unacked %"U32_F"\n", ackno,
     pcb->snd_nxt, ntohl(pcb->unacked->tcphdr->seqno)));
    /* received SYN ACK with expected sequence number? */
    if ((flags & TCP_ACK) && (flags & TCP_SYN)
        && ackno == ntohl(pcb->unacked->tcphdr->seqno) + 1) {
      pcb->snd_buf++;
      pcb->rcv_nxt = seqno + 1;
      pcb->rcv_ann_right_edge = pcb->rcv_nxt;
      pcb->lastack = ackno;
      pcb->snd_wnd = tcphdr->wnd;
      pcb->snd_wl1 = seqno - 1; /* initialise to seqno - 1 to force window update */
      pcb->state = ESTABLISHED;

#if TCP_CALCULATE_EFF_SEND_MSS
      pcb->mss = tcp_eff_send_mss(pcb->mss, &(pcb->remote_ip));
#endif /* TCP_CALCULATE_EFF_SEND_MSS */

      /* Set ssthresh again after changing pcb->mss (already set in tcp_connect
       * but for the default value of pcb->mss) */
      pcb->ssthresh = pcb->mss * 10;

      pcb->cwnd = ((pcb->cwnd == 1) ? (pcb->mss * 2) : pcb->mss);
      LWIP_ASSERT("pcb->snd_queuelen > 0", (pcb->snd_queuelen > 0));
      --pcb->snd_queuelen;
      LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_process: SYN-SENT --queuelen %"U16_F"\n", (u16_t)pcb->snd_queuelen));
      rseg = pcb->unacked;
      pcb->unacked = rseg->next;

      /* If there's nothing left to acknowledge, stop the retransmit
         timer, otherwise reset it to start again */
      if(pcb->unacked == NULL)
        pcb->rtime = -1;
      else {
        pcb->rtime = 0;
        pcb->nrtx = 0;
      }

      tcp_seg_free(rseg);

      /* Call the user specified function to call when sucessfully
       * connected. */
      TCP_EVENT_CONNECTED(pcb, ERR_OK, err);就是这里 接收到服务器的回应 具体是怎么到这里的 这个就得靠大家去看lwip函数讲解了 这里就不多说了 大致的流程已经和大家说了。
      tcp_ack_now(pcb);
    }

#endif /* LWIP_CALLBACK_API */
  TCP_RMV(&tcp_bound_pcbs, pcb);
  TCP_REG(&tcp_active_pcbs, pcb);

  snmp_inc_tcpactiveopens();
  
  ret = tcp_enqueue(pcb, NULL, 0, TCP_SYN, 0, TF_SEG_OPTS_MSS
#if LWIP_TCP_TIMESTAMPS
                    | TF_SEG_OPTS_TS
#endif
                    );
  if (ret == ERR_OK) {
    tcp_output(pcb);
  }
  return ret;
}
               
                                                }

OK 这样连接建立后就进入了回调函数tcp_Client_connected 进入函数后

err_t tcp_Client_connected(void *arg, struct tcp_pcb *pcb, err_t err)
{
   tcp_write(pcb, GREETING, strlen(GREETING), 0); //输出hello
   tcp_recv(pcb, HelloWorld_recv);//指定接收到数据后的回调函数
  return ERR_OK;
}
我们看到这里和服务器又一样了。连接成功后发送数据给上位机
#define GREETING "Hello.连接已经建立!欢迎来到科星F107开发板网络学习!\r\n"
然后TCP_RECV指定了接受数据的回调函数 这里我们直接调用了服务器模式时候的函数。
这样客户端模式的通信 就完成了。
注:
  因为客户端的连接,每次都是有固定的流程和时间,也许上电开始服务器并没有准备好,或者是通信过程中由于某些原因连接断开了,那就需要我们能够保证这种情况下也能连接,那么我们就得在没有连上的时候,一直去尝试连接,才能做到从连,所以我们实际应用中把客户端连接的函数Client_init();放到了主循环中。

测试流程
下载程序到开发板,打开上位机 电脑和上位机的配置按照上面的截图
点击“开始监听” 等待开发板客户端的连接 连上后如图

使用特权

评论回复
9
网络转接|  楼主 | 2013-9-27 11:27 | 只看该作者

使用特权

评论回复
10
fengchao989| | 2013-9-28 17:10 | 只看该作者
:hug:
太棒了!顶!
V5~~~

使用特权

评论回复
11
fengchao989| | 2013-9-28 18:35 | 只看该作者
嗯 没有LED如何控制呢,静静期待。

使用特权

评论回复
12
fengchao989| | 2013-9-29 15:29 | 只看该作者
自己稀里糊涂捣鼓了一天,加了这么一行程序
  if(strcmp((p->payload),"ledon")==0)
                                {        GPIO_SetBits(GPIOH,GPIO_Pin_2);
                                        tcp_write(tpcb,DATA2,strlen(DATA2),1);       
                                }
居然能控制LED了~~~但是不明白怎么回事:lol

使用特权

评论回复
13
网络转接|  楼主 | 2013-9-29 20:11 | 只看该作者
static err_t HelloWorld_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
{
  struct pbuf *q;
  struct name *name = (struct name *)arg;
  char *c;
  if (p != NULL)
  {        
    tcp_recved(pcb, p->tot_len);
    if(!name)
      {
      pbuf_free(p);
      return ERR_ARG;
      }
   
     q=p;
     c=q->payload;
      if(c[0]==1)
      {
        if(c[1]==1)
           GPIO_SetBits(GPIOA,GPIO_Pin_4);  
        if(c[1]==0)
           GPIO_ResetBits(GPIOA,GPIO_Pin_4);  
      }
      if(c[0]==2)
      {
        if(c[1]==1)
           GPIO_SetBits(GPIOA,GPIO_Pin_5);  
        if(c[1]==0)
           GPIO_ResetBits(GPIOA,GPIO_Pin_5);  
      }
      if(c[0]==3)
      {
        if(c[1]==1)
           GPIO_SetBits(GPIOA,GPIO_Pin_7);  
        if(c[1]==0)
           GPIO_ResetBits(GPIOA,GPIO_Pin_7);  
      }
      if(c[0]==4)
      {
        if(c[1]==1)
           GPIO_SetBits(GPIOA,GPIO_Pin_6);  
        if(c[1]==0)
           GPIO_ResetBits(GPIOA,GPIO_Pin_6);  
      }
      if(c[0]==5)
      {
        if(c[1]==5)
        {
            GPIO_ResetBits(GPIOD,GPIO_Pin_3);
        Delay(100);
            GPIO_SetBits(GPIOD,GPIO_Pin_3);
        }
      }
     tcp_write(pcb, HELLO, strlen(HELLO), 1);
     tcp_write(pcb,q->payload, q->len, 1);
     tcp_write(pcb, END, strlen(END), 1);
     pbuf_free(p);
  }  
  else if (err == ERR_OK)
  {
    /* When the pbuf is NULL and the err is ERR_OK, the remote end is closing the connection. */
    /* We free the allocated memory and we close the connection */
    mem_free(name);
    return tcp_close(pcb);
  }
  return ERR_OK;
}

使用特权

评论回复
14
网络转接|  楼主 | 2013-9-29 20:12 | 只看该作者
在这里 等国庆之后 整理好了 一起上传源码

使用特权

评论回复
15
mmbs| | 2013-9-29 20:56 | 只看该作者
等待中******

使用特权

评论回复
16
shenpingbing| | 2013-9-30 10:42 | 只看该作者
又一个卖板子的

使用特权

评论回复
17
地瓜patch| | 2013-9-30 11:45 | 只看该作者
给力,顶一个

使用特权

评论回复
18
网络转接|  楼主 | 2013-10-3 19:29 | 只看该作者
shenpingbing 发表于 2013-9-30 10:42
又一个卖板子的

买板子的怎么了? 我觉得那些用心做开发板的既能自己挣很多钱 还能分享知识给网友 我觉得很好

使用特权

评论回复
19
wfmartin28| | 2013-10-4 10:58 | 只看该作者
源码呢??

使用特权

评论回复
20
fengchao989| | 2013-10-8 12:43 | 只看该作者
上传源码和笔记吧~~等了一个国庆节~~天天盼啊

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:stm家园 http://corxstm32.taobao.com/ 专业 诚信  stm家园

19

主题

503

帖子

6

粉丝