(实验55)单片机,STM32F4学习笔记,代码讲解【网络通信实验】【正点原子】【原创】

文章目录

  • 其它文章链接,独家吐血整理
  • 实验现象
  • 主程序
  • LWIP初始化程序
  • 代码讲解


其它文章链接,独家吐血整理

(实验3)单片机,STM32F4学习笔记,代码讲解【按键输入实验】【正点原子】【原创】
(实验4)单片机,STM32F4学习笔记,代码讲解【串口实验】【正点原子】【原创】
(实验5)单片机,STM32F4学习笔记,代码讲解【外部中断实验】【正点原子】【原创】
(实验6,实验7)单片机,STM32F4学习笔记,代码讲解【看门狗实验】【正点原子】【原创】
(实验8)单片机,STM32F4学习笔记,代码讲解【定时器实验】【正点原子】【原创】
(实验9)单片机,STM32F4学习笔记,代码讲解【PWM输出实验】【正点原子】【原创】
(实验10)单片机,STM32F4学习笔记,代码讲解【输入捕获实验】【正点原子】【原创】
(实验11)单片机,STM32F4学习笔记,代码讲解【电容触摸按键实验】【正点原子】【原创】
(实验12)单片机,STM32F4学习笔记,代码讲解【OLED显示实验】【正点原子】【原创】
(实验13)单片机,STM32F4学习笔记,代码讲解【TFTLCD彩屏显示实验】【正点原子】【原创】
(实验15)单片机,STM32F4学习笔记,代码讲解【RTC实时时钟实验】【正点原子】【原创】
(实验17)单片机,STM32F4学习笔记,代码讲解【待机唤醒实验】【正点原子】【原创】
(实验23)单片机,STM32F4学习笔记,代码讲解【DMA实验】【正点原子】【原创】
(实验25)单片机,STM32F4学习笔记,代码讲解【SPI实验】【正点原子】【原创】
(实验34)单片机,STM32F4学习笔记,代码讲解【FLASH模拟EEPROM实验】【正点原子】【原创】
(实验36)单片机,STM32F4学习笔记,代码讲解【外部SRAM实验】【正点原子】【原创】
(实验37)单片机,STM32F4学习笔记,代码讲解【内存管理实验】【正点原子】【原创】
(实验38)单片机,STM32F4学习笔记,代码讲解【SD卡实验】【正点原子】【原创】
(实验39)单片机,STM32F4学习笔记,代码讲解【FATFS实验】【正点原子】【原创】
(实验46)单片机,STM32F4学习笔记,代码讲解【FPU测试实验】【正点原子】【原创】
(实验47)单片机,STM32F4学习笔记,代码讲解【DSP-FFT测试实验】【正点原子】【原创】
(实验50)单片机,STM32F4学习笔记,代码讲解【串口IAP实验】【正点原子】【原创】
(实验50)单片机,STM32F4学习笔记,代码讲解【串口IAP实验-RTC时钟实验】【正点原子】【原创】
(实验55)单片机,STM32F4学习笔记,代码讲解【网络通信实验】【正点原子】【原创】

实验现象

    本实验开机后,程序初始化LWIP,包括:初始化LAN8720A、申请内存、开启DHCP服务、添加并打开
	网卡,然后等待DHCP获取IP成功,当DHCP获取成功后,将在LCD屏幕上显示DHCP得到的IP地址,如
	果DHCP获取失败,那么将使用静态IP(固定为:192.168.1.30),然后开启Web Server服务,并
	进入主循环,等待按键输入选择需要测试的功能:
    KEY0按键,用于选择TCP Server测试功能。
    KEY1按键,用于选择TCP Client测试功能
    KEY2按键,用于选择UDP测试功能
   
    TCP Server测试的时候,直接使用DHCP获取到的IP(DHCP失败,则使用静态IP)作为服务器地址,
	端口号固定为:8088。在电脑端,可以使用网络调试助手(TCP Client模式)连接开发板,连接成
	功后,屏幕显示连接上的Client的IP地址,此时便可以互相发送数据了。按KEY0发送数据给电脑,
	电脑端发送过来的数据将会显示在LCD屏幕上。按KEY_UP可以退出TCP Server测试。
    
    TCP Client测试的时候,先通过KEY0/KEY2来设置远端IP地址(Server的IP),端口号固定为:
	8087。设置好之后哦,通过KEY_UP确认,随后,开发板会不断尝试连接到所设置的远端IP地址
	(端口:8087),此时我们需要在电脑端使用网络调试助手(TCP Server模式),设置端口为:
	8087,开启TCP Server服务,等待开发板连接。当连接成功后,测试方法同TCP Server测试的
	方法一样。
 
    UDP测试的时候,同TCP Client测试几乎一模一样,先通过KEY0/KEY2设置远端IP地址(电脑端的
	IP),端口号固定为:8089,然后按KEY_UP确认。电脑端使用网络调试助手(UDP模式),设置端
	口为:8089,开启UDP服务。不过对于UDP通信,我们得先按开发板KEY0,发送一次数据给电脑,随
	后才可以电脑发送数据给开发板,实现数据互发。按KEY_UP可以退出UDP测试。

    Web Server的测试相对简单,只需要在浏览器端输入开发板的IP地址(DHCP获取到的IP地址或者
	DHCP失败时使用的静态IP地址),即可登录一个Web界面,在Web界面,可以实现对DS1(LED1)的控
	制、蜂鸣器的控制、查看ADC1通道5的值、内部温度传感器温度值以及查看RTC时间和日期等。
	DS0用于提示程序正在运行。

主程序

int main(void)
{
	u8 t;
	u8 key;
	delay_init(168);       	//延时初始化
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
	uart_init(115200);   	//串口波特率设置
	usmart_dev.init(84); 	//初始化USMART
	LED_Init();  			//LED初始化
	KEY_Init();  			//按键初始化
	LCD_Init(); 			//LCD初始化
	FSMC_SRAM_Init();		//初始化外部SRAM  
	BEEP_Init();			//蜂鸣器初始化
	My_RTC_Init();  		//RTC初始化
	Adc_Init();  			//ADC初始化 
	Adc_Temperate_Init(); 	//内部温度传感器初始化
	TIM3_Int_Init(999,839); //100khz的频率,计数1000为10ms
	mymem_init(SRAMIN);		//初始化内部内存池
	mymem_init(SRAMEX);		//初始化外部内存池
	mymem_init(SRAMCCM);	//初始化CCM内存池
	POINT_COLOR = RED; 		//红色字体
	lwip_test_ui(1);		//加载前半部分UI
	
	//先初始化lwIP(包括LAN8720初始化),此时必须插上网线,否则初始化会失败!! 
	LCD_ShowString(30,110,200,16,16,"lwIP Initing...");
	while(lwip_comm_init()!=0)
	{
		LCD_ShowString(30,110,200,16,16,"lwIP Init failed!");
		delay_ms(1200);
		LCD_Fill(30,110,230,110+16,WHITE);//清除显示
		LCD_ShowString(30,110,200,16,16,"Retrying...");  
	}
	LCD_ShowString(30,110,200,16,16,"lwIP Init Successed");
	//等待DHCP获取 
 	LCD_ShowString(30,130,200,16,16,"DHCP IP configing...");
	while((lwipdev.dhcpstatus!=2)&&(lwipdev.dhcpstatus!=0XFF))//等待DHCP获取成功/超时溢出
	{
		lwip_periodic_handle();
	}
	lwip_test_ui(2);//加载后半部分UI 
	httpd_init();	//HTTP初始化(默认开启websever)
	while(1)
	{
		key=KEY_Scan(0);
		switch(key)
		{
			case KEY0_PRES://TCP Server模式
				tcp_server_test();
				lwip_test_ui(3);//重新加载UI
				break;
			case KEY1_PRES://TCP Client模式
				tcp_client_test();
				lwip_test_ui(3);//重新加载UI
				break; 
			case KEY2_PRES://UDP模式
				udp_demo_test();
				lwip_test_ui(3);//重新加载UI
				break; 
		}
		lwip_periodic_handle();
		delay_ms(2);
		t++;
		if(t==100)LCD_ShowString(30,230,200,16,16,"Please choose a mode!");
		if(t==200)
		{ 
			t=0;
			LCD_Fill(30,230,230,230+16,WHITE);//清除显示
			LED0=!LED0;
		} 
	}
}

LWIP初始化程序

extern void Adc_Temperate_Init(void);	//声明内部温度传感器初始化函数
//加载UI
//mode:
//bit0:0,不加载;1,加载前半部分UI
//bit1:0,不加载;1,加载后半部分UI
void lwip_test_ui(u8 mode)
{
	u8 speed;
	u8 buf[30]; 
	POINT_COLOR=RED;
	if(mode&1<<0)//0000 0001
	{
		LCD_Fill(30,30,lcddev.width,110,WHITE);	//清除显示
		LCD_ShowString(30,30,200,16,16,"Explorer STM32F4");
		LCD_ShowString(30,50,200,16,16,"Ethernet lwIP Test");
		LCD_ShowString(30,70,200,16,16,"ATOM@ALIENTEK");
		LCD_ShowString(30,90,200,16,16,"2014/8/15"); 	
	}
	if(mode&1<<1)//0000 0010
	{
		LCD_Fill(30,110,lcddev.width,lcddev.height,WHITE);	//清除显示
		LCD_ShowString(30,110,200,16,16,"lwIP Init Successed");
		if(lwipdev.dhcpstatus==2)sprintf((char*)buf,"DHCP IP:%d.%d.%d.%d",lwipdev.ip[0],lwipdev.ip[1],lwipdev.ip[2],lwipdev.ip[3]);//打印动态IP地址
		else sprintf((char*)buf,"Static IP:%d.%d.%d.%d",lwipdev.ip[0],lwipdev.ip[1],lwipdev.ip[2],lwipdev.ip[3]);//打印静态IP地址
		LCD_ShowString(30,130,210,16,16,buf); 
		speed=LAN8720_Get_Speed();//得到网速
		if(speed&1<<1)LCD_ShowString(30,150,200,16,16,"Ethernet Speed:100M");
		else LCD_ShowString(30,150,200,16,16,"Ethernet Speed:10M");
		LCD_ShowString(30,170,200,16,16,"KEY0:TCP Server Test");
		LCD_ShowString(30,190,200,16,16,"KEY1:TCP Client Test");
		LCD_ShowString(30,210,200,16,16,"KEY2:UDP Test");
	}
}

代码讲解

//F407自带以太网模块=MAC控制器(支持DMA)+MII介质接口+RMII简化介质接口+SMI用于外部PHY通信
//F407必须外接PHY芯片,才支持以太网通信,芯片通过MII/RMII接口与F407内部MAC连接,也支持SMI配置PHY芯片
//SMI接口=站管理接口=该接口通过两条线(时钟+数据),访问控制PHY寄存器,支持访问32个PHY
//然后,从所选择的PHY中的32个寄存器中,选择出一个寄存器,用于PHY与MAC之间收发数据
//MII接口=介质独立接口=用于MAC层与PHY层进行数据传输
//RMII接口=精简介质独立接口,和上面功能一样,只是需要引脚数减少为7个,必须外接时钟源=有源晶振

//TCP/IP协议=网络通讯协议=TCP协议+IP协议,由网络接口层,网络层,传输层,应用层构成
//在OSI模型中,将上述分为七个层级(具体看开发指南)
//PHY芯片相当于物理层,MAC相当于数据链路层,LWIP相当于网络层,传输层,应用层就是具体功能实现

//LWIP=协议栈,用来实现TCP/IP网络信息传输,它的优点是,占用RAM和ROM资源都很小

//C语言中,1=0000 0001,所以1<<1=0000 0010,1< //也就是说,mode&1<<0=mode&(1<<0),所以if(mode&1<<1)这句话相当于mode是否等于2的1次幂,也就是为1和2了
//0000 0010&mode中,除了mode中bit1位会保持原样,其余位全部清0,也就是2^bit1次幂
//也就是只要mode中bit1位为1,不管mode实际为多少值都可以进入这个函数,这也就是这个代码好处
//比如当mode位3=0000 0011时,两个if语句都可以进入,这种思路不可谓不巧妙,当然也可用其它方式实现

//涉及到网络代码的知识,我已经枯了,算了算了,以后有机会再碰它,现在差不多先这样吧

你可能感兴趣的:(学校-32单片机,单片机,经验分享,学习)