#include "clock-arch.h" #include "stm32f10x.h" extern __IO int32_t g_RunTime; /*---------------------------------------------------------------------------*/ clock_time_t clock_time(void) { return g_RunTime; } /*---------------------------------------------------------------------------*/ 使用stm32 滴答定时器中断代码: User/stm32f10x_it.c __IO int32_t g_RunTime = 0; void SysTick_Handler(void) { static uint8_t s_count = 0; if (++s_count >= 10) { s_count = 0; g_RunTime++; /* 全局运行时间每10ms增1 */ if (g_RunTime == 0x80000000) { g_RunTime = 0; } } } 3.uipopt.h/uip-conf.h 是配置文件,用来设置本地的IP 地址、网关地址、MAC 地址、全局缓冲区的大小、支持的最大连接数、侦听数、ARP 表大小等。可以根据需要配置。 #define UIP_FIXEDADDR 1 决定uIP是否使用一个固定的IP地址。 如果uIP使用一个固定的IP地址,应该置位(set)这些uipopt.h中的选项。如果不的话,则应该使用宏uip_sethostaddr(),uip_setdraddr() 和 uip_setnetmask()。 #define UIP_PINGADDRCONF 0 Ping IP地址赋值。 #define UIP_FIXEDETHADDR 0 指明uIP ARP模块是否在编译时使用一个固定的以太网MAC地址。 #define UIP_TTL 255 uIP发送的IP packets的IP TTL (time to live)。 #define UIP_REASSEMBLY 0 uIP支持IP packets的分片和重组。 #define UIP_REASS_MAXAGE 40 一个IP fragment在被丢弃之前可以在重组缓冲区中存在的最大时间。 #define UIP_UDP 0 是否编译UDP的开关。 #define UIP_ACTIVE_OPEN 1 决定是否支持uIP打开一个连接。 #define UIP_CONNS 10 同时可以打开的TCP连接的最大数目。由于TCP连接是静态分配的,减小这个数目将占用更少的RAM。每一个TCP连接需要大约30字节的内存。 #define UIP_LISTENPORTS 10 同时监听的TCP端口的最大数目。每一个TCP监听端口需要2个字节的内存。 #define UIP_RECEIVE_WINDOW 32768 建议的接收窗口的大小。如果应用程序处理到来的数据比较慢,那么应该设置的小一点(即,相对与uip_buf缓冲区的大小来说),相反如果应用程序处理数据很快,可以设置的大一点(32768字节)。 #define UIP_URGDATA 1 决定是否支持TCP urgent data notification。 #define UIP_RTO 3 The initial retransmission timeout counted in timer pulses.不要改变 #define UIP_MAXRTX 8 在中止连接之前,应该重发一个段的最大次数。不要改变 #define UIP_TCP_MSS (UIP_BUFSIZE – UIP_LLH_LEN – 40) TCP段的最大长度。它不能大于UIP_BUFSIZE – UIP_LLH_LEN – 40. #define UIP_TIME_WAIT_TIMEOUT 120 一个连接应该在TIME_WAIT状态等待多长。不要改变 #define UIP_ARPTAB_SIZE 8 ARP表的大小。如果本地网络中有许多到这个uIP节点的连接,那么这个选项应该设置为一个比较大的值。 #define UIP_BUFSIZE 1500 uIP packet缓冲区不能小于60字节,但也不必大于1500字节。 #define UIP_STATISTICS 1 决定是否支持统计数字。统计数字对调试很有帮助,并展示给用户。 #define UIP_LOGGING 0 输出uIP登陆信息。 #define UIP_LLH_LEN 14 链接层头部长度。对于SLIP,应该设置成0。 uip-conf.h 中增加几个主要结构体定义,不include任何应用 #define UIP_CONF_LOGGING 0 //logging off typedef int uip_tcp_appstate_t; //出错可注释 typedef int uip_udp_appstate_t; //出错可注释 /*#include "smtp.h"*/ /*#include "hello-world.h"*/ /*#include "telnetd.h"*/ /*#include "webserver.h"*/ /*#include "dhcpc.h"*/ /*#include "resolv.h"*/ /*#include "webclient.h"*/ #include "app_call.h" //加入一个Uip的数据接口文件 uIP 在接受到底层传来的数据包后,调用UIP_APPCALL( ),将数据送到上层应用程序处理。 User/app_call.c #include "stm32f10x.h" #ifndef UIP_APPCALL #define UIP_APPCALL Uip_Appcall #endif #ifndef UIP_UDP_APPCALL #define UIP_UDP_APPCALL Udp_Appcall #endif void Uip_Appcall(void); void Udp_Appcall(void); void Uip_Appcall(void) { } void Udp_Appcall(void) { } 4.加入uIP 的的主循环代码架构 User/main.c #include "stm32f10x.h" #include "stdio.h" #include "string.h" #include "uip.h" #include "uip_arp.h" #include "tapdev.h" #include "timer.h" #include "ENC28J60.h" #include "SPI.h" #define PRINTF_ON 1 #define BUF ((struct uip_eth_hdr *)&uip_buf[0]) #ifndef NULL #define NULL (void *)0 #endif /* NULL */ static unsigned char mymac[6] = {0x04,0x02,0x35,0x00,0x00,0x01}; void RCC_Configuration(void); void GPIO_Configuration(void); void USART_Configuration(void); int main(void) { int i; uip_ipaddr_t ipaddr; struct timer periodic_timer, arp_timer; RCC_Configuration(); GPIO_Configuration(); USART_Configuration(); SPInet_Init(); timer_set(&periodic_timer, CLOCK_SECOND / 2); timer_set(&arp_timer, CLOCK_SECOND * 10); SysTick_Config(72000); //配置滴答计时器 //以太网控制器驱动初始化 tapdev_init(mymac); //Uip 协议栈初始化 uip_init(); uip_ipaddr(ipaddr, 192, 168, 1, 15); //配置Ip uip_sethostaddr(ipaddr); uip_ipaddr(ipaddr, 192, 168, 1, 1); //配置网关 uip_setdraddr(ipaddr); uip_ipaddr(ipaddr, 255, 255, 255, 0); //配置子网掩码 uip_setnetmask(ipaddr); while(1){ uip_len = tapdev_read(); //从网卡读取数据 if(uip_len > 0) { //如果数据存在则按协议处理 if(BUF->type == htons(UIP_ETHTYPE_IP)) { //如果收到的是IP数据,调用uip_input()处理 uip_arp_ipin(); uip_input(); /* If the above function invocation resulted in data that should be sent out on the network, the global variable uip_len is set to a value > 0. */ if(uip_len > 0) { uip_arp_out(); tapdev_send(); } }else if(BUF->type == htons(UIP_ETHTYPE_ARP)){ //如果收到的是ARP数据,调用uip_arp_arpin处理 uip_arp_arpin(); /* If the above function invocation resulted in data that should be sent out on the network, the global variable uip_len is set to a value > 0. */ if(uip_len > 0) { tapdev_send(); } } }else if(timer_expired(&periodic_timer)){ //查看0.5s是否到了,调用uip_periodic处理TCP超时程序 timer_reset(&periodic_timer); for(i = 0; i < UIP_CONNS; i++) { uip_periodic(i); /* If the above function invocation resulted in data that should be sent out on the network, the global variable uip_len is set to a value > 0. */ if(uip_len > 0) { uip_arp_out(); tapdev_send(); } } for(i = 0; i < UIP_UDP_CONNS; i++) { uip_udp_periodic(i); //处理udp超时程序 /* If the above function invocation resulted in data that should be sent out on the network, the global variable uip_len is set to a value > 0. */ if(uip_len > 0) { uip_arp_out(); tapdev_send(); } } /* Call the ARP timer function every 10 seconds. */ //10s到了就处理ARP if(timer_expired(&arp_timer)) { timer_reset(&arp_timer); uip_arp_timer(); } } } } /*******************************Stm32 Set***************************************/ void GPIO_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOA , &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA , &GPIO_InitStructure); } void RCC_Configuration(void) { /* 定义枚举类型变量 HSEStartUpStatus */ ErrorStatus HSEStartUpStatus; /* 复位系统时钟设置*/ RCC_DeInit(); /* 开启HSE*/ RCC_HSEConfig(RCC_HSE_ON); /* 等待HSE起振并稳定*/ HSEStartUpStatus = RCC_WaitForHSEStartUp(); /* 判断HSE起是否振成功,是则进入if()内部 */ if(HSEStartUpStatus == SUCCESS) { /* 选择HCLK(AHB)时钟源为SYSCLK 1分频 */ RCC_HCLKConfig(RCC_SYSCLK_Div1); /* 选择PCLK2时钟源为 HCLK(AHB) 1分频 */ RCC_PCLK2Config(RCC_HCLK_Div1); /* 选择PCLK1时钟源为 HCLK(AHB) 2分频 */ RCC_PCLK1Config(RCC_HCLK_Div2); /* 设置FLASH延时周期数为2 */ FLASH_SetLatency(FLASH_Latency_2); /* 使能FLASH预取缓存 */ FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); /* 选择锁相环(PLL)时钟源为HSE 1分频,倍频数为9,则PLL输出频率为 8MHz * 9 = 72MHz */ RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); /* 使能PLL */ RCC_PLLCmd(ENABLE); /* 等待PLL输出稳定 */ while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); /* 选择SYSCLK时钟源为PLL */ RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); /* 等待PLL成为SYSCLK时钟源 */ while(RCC_GetSYSCLKSource() != 0x08); } /* 打开APB2总线上的GPIOA时钟*/ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1, ENABLE); } void USART_Configuration(void) { USART_InitTypeDef USART_InitStructure; USART_ClockInitTypeDef USART_ClockInitStructure; USART_ClockInitStructure.USART_Clock = USART_Clock_Disable; USART_ClockInitStructure.USART_CPOL = USART_CPOL_Low; USART_ClockInitStructure.USART_CPHA = USART_CPHA_2Edge; USART_ClockInitStructure.USART_LastBit = USART_LastBit_Disable; USART_ClockInit(USART1 , &USART_ClockInitStructure); USART_InitStructure.USART_BaudRate = 9600; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx|USART_Mode_Tx; USART_Init(USART1,&USART_InitStructure); USART_Cmd(USART1,ENABLE); } #if PRINTF_ON int fputc(int ch,FILE *f) { USART_SendData(USART1,(u8) ch); while(USART_GetFlagStatus(USART1,USART_FLAG_TC) == RESET); return ch; } #endif 5.解决编译过程中的错误。归总如下:
//resolv_conn = uip_udp_new(dnsserver, HTONS(53)); resolv_conn = uip_udp_new((uip_ipaddr_t*)dnsserver, HTONS(53)); 解决完所有问题后,编译成功后下载到stm32,ping 测试。。
|
|