file-type

详解浮动IP创建与工作原理

下载需积分: 0 | 730KB | 更新于2024-08-04 | 19 浏览量 | 0 下载量 举报 收藏
download 立即下载
本篇教程将详细介绍如何在OpenStack环境中创建并使用浮动IP(Floating IP),以便从外部网络直接访问虚拟机实例。浮动IP是一种网络服务,它在云计算中扮演着关键角色,尤其对于多租户架构,确保了租户间的网络隔离和外部访问的灵活性。 首先,回顾基础知识:当一个租户网络通过Neutron路由器连接到互联网时,路由器通常是其默认网关。当数据包从实例(instance)发送到外部网络时,路由器执行源NAT(Source Network Address Translation),将数据包的源地址替换为其自身的外网IP,确保包能到达外部网络,并且返回时能找到正确的实例。这种技术使得内部网络保持私密性,而外部用户则可以通过指定的浮动IP进行访问。 浮动IP的核心概念包括: 1. **静态NAT**:浮动IP提供了一种一对一的映射关系,即每个外部访问的IP(浮动IP)对应一个内部实例的私有IP。这允许外部用户直接通过浮动IP访问实例,而无需知道其内部的私有IP。 2. **位置**:浮动IP不是绑定在实例上,而是配置在为项目提供网关的路由器的外网接口上。这意味着浮动IP是独立于实例存在的,但由路由器控制其路由和NAT规则。 3. **路由规则**:路由器根据数据包的来源和目的地自动调整其源或目标地址。当数据包从外部返回时,路由器会识别出浮动IP并将其转换回正确的实例IP。 接下来的步骤演示了浮动IP的分配过程: - 在OpenStack管理界面中,进入Project -> Compute -> Access & Security菜单,选择FloatingIPs标签页。 - 分配浮动IP:点击"Allocate IP To Project",选择浮动IP池ext_net,然后点击"Allocate IP",获取一个新的IP地址,例如10.10.10.3。 - 分配给实例:将刚分配的浮动IP10.10.10.3与实例cirros-vm3关联起来,通过点击"Associate"按钮,将其映射到实例的私有IP172.16.101.3。 在下一章节,我们将深入探讨浮动IP在底层网络架构中的具体作用,以及如何跟踪和理解数据包在分配和关联浮动IP后的路由、NAT和安全策略。理解浮动IP的工作原理有助于管理员更好地管理和优化云网络环境,确保服务的可靠性和性能。

相关推荐

filetype

carbon@carbon-R5300-G4X:/$ openstack --debug token issue # 启用调试模式查看详细过程 START with options: ['--debug', 'token', 'issue'] options: Namespace(access_key='', access_secret='***', access_token='***', access_token_endpoint='', access_token_type='', auth_type='', auth_url='', authorization_code='', cacert=None, cert='', client_id='', client_secret='***', cloud='', consumer_key='', consumer_secret='***', debug=True, default_domain='default', default_domain_id='', default_domain_name='', deferred_help=False, discovery_endpoint='', domain_id='', domain_name='', endpoint='', identity_provider='', identity_provider_url='', insecure=None, interface='', key='', log_file=None, openid_scope='', os_beta_command=False, os_compute_api_version='', os_identity_api_version='3', os_image_api_version='', os_network_api_version='', os_object_api_version='', os_project_id=None, os_project_name=None, os_volume_api_version='', passcode='', password='***', project_domain_id='', project_domain_name='Default', project_id='', project_name='admin', protocol='', redirect_uri='', region_name='', timing=False, token='***', trust_id='', url='http://controller:35357/v3', user_domain_id='', user_domain_name='Default', user_id='', username='admin', verbose_level=3, verify=None) Auth plugin token_endpoint selected auth_config_hook(): {'dns_api_version': '2', 'api_timeout': None, 'secgroup_source': 'neutron', 'interface': None, 'default_domain': 'default', 'url': 'http://controller:35357/v3', 'deferred_help': False, 'object_store_api_version': '1', 'identity_api_version': '3', 'network_api_version': '2', 'networks': [], 'region_name': '', 'database_api_version': '1.0', 'volume_api_version': '2', 'container_api_version': '1', 'verbose_level': 3, 'disable_vendor_agent': {}, 'image_format': 'qcow2', 'image_api_version': '2', 'floating_ip_source': 'neutron', 'verify': True, 'compute_api_version': '2', 'username': 'admin', 'password': 'Hbis@123', 'auth_type': 'token_endpoint', 'baremetal_api_version': '1', 'beta_command': False, 'cert': None, 'cacert': None, 'debug': True, 'auth': {'project_domain_name': 'Default', 'project_name': 'admin', 'user_domain_name': 'Default', 'token': '4dfca0e2d881e685109d'}, 'orchestration_api_version': '1', 'image_api_use_tasks': False, 'metering_api_version': '2', 'key': None, 'key_manager_api_version': 'v1', 'timing': False} defaults: {'dns_api_version': '2', 'api_timeout': None, 'object_store_api_version': '1', 'interface': None, 'verify': True, 'container_api_version': '1', 'identity_api_version': '2.0', 'network_api_version': '2', 'volume_api_version': '2', 'secgroup_source': 'neutron', 'database_api_version': '1.0', 'disable_vendor_agent': {}, 'image_format': 'qcow2', 'image_api_version': '2', 'compute_api_version': '2', 'cert': None, 'auth_type': 'token_endpoint', 'baremetal_api_version': '1', 'cacert': None, 'orchestration_api_version': '1', 'image_api_use_tasks': False, 'metering_api_version': '2', 'key': None, 'key_manager_api_version': 'v1', 'floating_ip_source': 'neutron'} cloud cfg: {'dns_api_version': '2', 'api_timeout': None, 'secgroup_source': 'neutron', 'interface': None, 'default_domain': 'default', 'object_store_api_version': '1', 'url': 'http://controller:35357/v3', 'deferred_help': False, 'container_api_version': '1', 'identity_api_version': '3', 'network_api_version': '2', 'networks': [], 'region_name': '', 'database_api_version': '1.0', 'volume_api_version': '2', 'verbose_level': 3, 'disable_vendor_agent': {}, 'image_format': 'qcow2', 'image_api_version': '2', 'verify': True, 'compute_api_version': '2', 'cert': None, 'username': 'admin', 'password': '***', 'auth_type': 'token_endpoint', 'timing': False, 'beta_command': False, 'baremetal_api_version': '1', 'floating_ip_source': 'neutron', 'debug': True, 'auth': {'url': 'http://controller:35357/v3', 'project_name': 'admin', 'user_domain_name': 'Default', 'project_domain_name': 'Default', 'token': '***'}, 'orchestration_api_version': '1', 'image_api_use_tasks': False, 'metering_api_version': '2', 'key': None, 'key_manager_api_version': 'v1', 'cacert': None} object_store API version 1, cmd group openstack.object_store.v1 identity API version 3, cmd group openstack.identity.v3 network API version 2, cmd group openstack.network.v2 volume API version 2, cmd group openstack.volume.v2 compute API version 2, cmd group openstack.compute.v2 image API version 2, cmd group openstack.image.v2 neutronclient API version 2, cmd group openstack.neutronclient.v2 Auth plugin token_endpoint selected auth_config_hook(): {'dns_api_version': '2', 'api_timeout': None, 'secgroup_source': 'neutron', 'interface': None, 'default_domain': 'default', 'url': 'http://controller:35357/v3', 'deferred_help': False, 'object_store_api_version': '1', 'identity_api_version': '3', 'network_api_version': '2', 'networks': [], 'region_name': '', 'database_api_version': '1.0', 'volume_api_version': '2', 'container_api_version': '1', 'verbose_level': 3, 'disable_vendor_agent': {}, 'image_format': 'qcow2', 'image_api_version': '2', 'floating_ip_source': 'neutron', 'verify': True, 'compute_api_version': '2', 'username': 'admin', 'password': 'Hbis@123', 'auth_type': 'token_endpoint', 'baremetal_api_version': '1', 'beta_command': False, 'cert': None, 'cacert': None, 'debug': True, 'auth': {'project_domain_name': 'Default', 'project_name': 'admin', 'user_domain_name': 'Default', 'token': '4dfca0e2d881e685109d'}, 'orchestration_api_version': '1', 'image_api_use_tasks': False, 'metering_api_version': '2', 'key': None, 'key_manager_api_version': 'v1', 'timing': False} command: token issue -> openstackclient.identity.v3.token.IssueToken Using auth plugin: token_endpoint Using parameters {'url': 'http://controller:35357/v3', 'project_name': 'admin', 'user_domain_name': 'Default', 'project_domain_name': 'Default', 'token': '***'} Get auth_ref run(Namespace(columns=[], formatter='table', max_width=0, noindent=False, prefix='', variables=[])) Get auth_ref Only an authorized user may issue a new token. Traceback (most recent call last): File "/usr/lib/python3/dist-packages/cliff/app.py", line 387, in run_subcommand result = cmd.run(parsed_args) File "/usr/lib/python3/dist-packages/osc_lib/command/command.py", line 41, in run return super(Command, self).run(parsed_args) File "/usr/lib/python3/dist-packages/cliff/display.py", line 100, in run column_names, data = self.take_action(parsed_args) File "/usr/lib/python3/dist-packages/openstackclient/identity/v3/token.py", line 180, in take_action _("Only an authorized user may issue a new token.")) osc_lib.exceptions.AuthorizationFailure: Only an authorized user may issue a new token. clean_up IssueToken: Only an authorized user may issue a new token. Traceback (most recent call last): File "/usr/lib/python3/dist-packages/osc_lib/shell.py", line 135, in run ret_val = super(OpenStackShell, self).run(argv) File "/usr/lib/python3/dist-packages/cliff/app.py", line 267, in run result = self.run_subcommand(remainder) File "/usr/lib/python3/dist-packages/osc_lib/shell.py", line 180, in run_subcommand ret_value = super(OpenStackShell, self).run_subcommand(argv) File "/usr/lib/python3/dist-packages/cliff/app.py", line 387, in run_subcommand result = cmd.run(parsed_args) File "/usr/lib/python3/dist-packages/osc_lib/command/command.py", line 41, in run return super(Command, self).run(parsed_args) File "/usr/lib/python3/dist-packages/cliff/display.py", line 100, in run column_names, data = self.take_action(parsed_args) File "/usr/lib/python3/dist-packages/openstackclient/identity/v3/token.py", line 180, in take_action _("Only an authorized user may issue a new token.")) osc_lib.exceptions.AuthorizationFailure: Only an authorized user may issue a new token. END return value: 1

filetype

一、介绍 ESP8266是一款嵌入式系统级芯片,它集成了Wi-Fi功能和微控制器能力于一身,常用于物联网(IoT)项目中。这款芯片支持TCP/IP协议栈,能够连接到WiFi网络,并通过AT命令或者更高级的API与主控设备进行通信。它的低功耗特性使得它可以长时间运行在电池供电下,广泛应用于智能家居、智能门锁、无线传感器网络等应用中。 以下是ESP8266-01S模块的参数: 型号 ESP8266-01S 使用电压 3.0~3.6V WIFI模式 STATION/AP/STATION+AP 通信距离 100M 天线 PCB板载天线 SPI FLASH 1MB 天线标准 802.11B/G/N 哔哩哔哩视频链接: ESP8266模块(WIFI STM32) (资料分享见文末) 二、传感器原理 1.原理图 2.引脚描述 引脚名称 描述 GND GND IO2 通用IO内部已上拉 IO0 工作模式选择 RXD 串口接收 3V3 电源正极3.3V RST 复位 EN 使能 TX 串口发送 3.ESP8266基础AT指令介绍 4.ESP8266基础工作模式 ESP8266WIFI 模式有两种,一种叫 AP 模式,一种叫 Station 模式,AP 就是我们平时所说的热点,如 WIFI 路由器,开了热点的手机,或者是公共热点等,这些 AP 设备可以允许其他设备(如手机,笔记本电脑等)输入热点名和密码(也可不设置密码)后接入,Station 则是前面说的连接 AP 的设备,如:手机,笔记本电脑等,ESP8266 还有第三种模式:AP+Station,即:将 AP 和 Station 的功能合二为一,但是应用的场景不多,这里不做展示。 三、程序设计 使用STM32F103C8T6通过网络调试助手(APP)控制LED亮灭。 ESP8266_TX PA3 ESP8266_RX PA2 LED PA0 串口 串口1 main.c文件 #include "stm32f10x.h" #include "led.h" #include "usart.h" #include "delay.h" #include "esp8266.h" /*****************辰哥单片机设计****************** STM32 * 项目 : ESP8266模块通信实验 * 版本 : V1.0 * 日期 : 2024.9.30 * MCU : STM32F103C8T6 * 接口 : 参看usart2.h * BILIBILI : 辰哥单片机设计 * CSDN : 辰哥单片机设计 * 作者 : 辰哥 **********************BEGIN***********************/ uint8_t flag; int main(void) { SystemInit();//配置系统时钟为72M delay_init(72); LED_Init(); LED_On(); USART_Config(); ESP8266_Init (); //初始化WiFi模块使用的接口和外设(使用串口2) ESP8266_StaTcpClient ();//WiFi模块设置 printf("Start \n"); delay_ms(1000); while (1) { switch(flag) { case 'a': LED_On();break;//开灯 case 'c': LED_Off();break;//关灯 } } } esp8266.h文件 #ifndef __ESP8266_H #define __ESP8266_H #include "stm32f10x.h" #include "common.h" #include <stdio.h> #include <stdbool.h> /*****************辰哥单片机设计****************** STM32 * 项目 : ESP8266模块通信实验 * 版本 : V1.0 * 日期 : 2024.9.30 * MCU : STM32F103C8T6 * 接口 : 串口2 * BILIBILI : 辰哥单片机设计 * CSDN : 辰哥单片机设计 * 作者 : 辰哥 **********************BEGIN***********************/ #if defined ( __CC_ARM ) #pragma anon_unions #endif /******************************* ESP8266 数据类型定义 ***************************/ typedef enum{ STA, AP, STA_AP } ENUM_Net_ModeTypeDef; typedef enum{ enumTCP, enumUDP, } ENUM_NetPro_TypeDef; typedef enum{ Multiple_ID_0 = 0, Multiple_ID_1 = 1, Multiple_ID_2 = 2, Multiple_ID_3 = 3, Multiple_ID_4 = 4, Single_ID_0 = 5, } ENUM_ID_NO_TypeDef; typedef enum{ OPEN = 0, WEP = 1, WPA_PSK = 2, WPA2_PSK = 3, WPA_WPA2_PSK = 4, } ENUM_AP_PsdMode_TypeDef; /******************************* ESP8266 外部全局变量声明 ***************************/ #define RX_BUF_MAX_LEN 1024 //最大接收缓存字节数 extern struct STRUCT_USARTx_Fram //串口数据帧的处理结构体 { char Data_RX_BUF [ RX_BUF_MAX_LEN ]; union { __IO u16 InfAll; struct { __IO u16 FramLength :15; // 14:0 __IO u16 FramFinishFlag :1; // 15 } InfBit; }; } strEsp8266_Fram_Record; /******************************** ESP8266 连接引脚定义 ***********************************/ #define macESP8266_CH_PD_APBxClock_FUN RCC_APB2PeriphClockCmd #define macESP8266_CH_PD_CLK RCC_APB2Periph_GPIOA #define macESP8266_CH_PD_PORT GPIOA #define macESP8266_CH_PD_PIN GPIO_Pin_5 #define macESP8266_RST_APBxClock_FUN RCC_APB2PeriphClockCmd #define macESP8266_RST_CLK RCC_APB2Periph_GPIOA #define macESP8266_RST_PORT GPIOA #define macESP8266_RST_PIN GPIO_Pin_6 #define macESP8266_USART_BAUD_RATE 115200 #define macESP8266_USARTx USART2 #define macESP8266_USART_APBxClock_FUN RCC_APB1PeriphClockCmd #define macESP8266_USART_CLK RCC_APB1Periph_USART2 #define macESP8266_USART_GPIO_APBxClock_FUN RCC_APB2PeriphClockCmd #define macESP8266_USART_GPIO_CLK RCC_APB2Periph_GPIOA #define macESP8266_USART_TX_PORT GPIOA #define macESP8266_USART_TX_PIN GPIO_Pin_2 #define macESP8266_USART_RX_PORT GPIOA #define macESP8266_USART_RX_PIN GPIO_Pin_3 #define macESP8266_USART_IRQ USART2_IRQn #define macESP8266_USART_INT_FUN USART2_IRQHandler /*********************************************** ESP8266 函数宏定义 *******************************************/ #define macESP8266_Usart( fmt, ... ) USART_printf ( macESP8266_USARTx, fmt, ##__VA_ARGS__ ) #define macPC_Usart( fmt, ... ) printf ( fmt, ##__VA_ARGS__ ) //#define macPC_Usart( fmt, ... ) #define macESP8266_CH_ENABLE() GPIO_SetBits ( macESP8266_CH_PD_PORT, macESP8266_CH_PD_PIN ) #define macESP8266_CH_DISABLE() GPIO_ResetBits ( macESP8266_CH_PD_PORT, macESP8266_CH_PD_PIN ) #define macESP8266_RST_HIGH_LEVEL() GPIO_SetBits ( macESP8266_RST_PORT, macESP8266_RST_PIN ) #define macESP8266_RST_LOW_LEVEL() GPIO_ResetBits ( macESP8266_RST_PORT, macESP8266_RST_PIN ) /****************************************** ESP8266 函数声明 ***********************************************/ void ESP8266_Init ( void ); void ESP8266_Rst ( void ); bool ESP8266_Cmd ( char * cmd, char * reply1, char * reply2, u32 waittime ); void ESP8266_AT_Test ( void ); bool ESP8266_Net_Mode_Choose ( ENUM_Net_ModeTypeDef enumMode ); bool ESP8266_JoinAP ( char * pSSID, char * pPassWord ); bool ESP8266_BuildAP ( char * pSSID, char * pPassWord, ENUM_AP_PsdMode_TypeDef enunPsdMode ); bool ESP8266_Enable_MultipleId ( FunctionalState enumEnUnvarnishTx ); bool ESP8266_Link_Server ( ENUM_NetPro_TypeDef enumE, char * ip, char * ComNum, ENUM_ID_NO_TypeDef id); bool ESP8266_StartOrShutServer ( FunctionalState enumMode, char * pPortNum, char * pTimeOver ); uint8_t ESP8266_Get_LinkStatus ( void ); uint8_t ESP8266_Get_IdLinkStatus ( void ); uint8_t ESP8266_Inquire_ApIp ( char * pApIp, uint8_t ucArrayLength ); bool ESP8266_UnvarnishSend ( void ); void ESP8266_ExitUnvarnishSend ( void ); bool ESP8266_SendString ( FunctionalState enumEnUnvarnishTx, char * pStr, u32 ulStrLength, ENUM_ID_NO_TypeDef ucId ); char * ESP8266_ReceiveString ( FunctionalState enumEnUnvarnishTx ); /********************************** 用户需要设置的参数**********************************/ #define macUser_ESP8266_ApSsid "www" //要连接的热点的名称 #define macUser_ESP8266_ApPwd "www123456" //要连接的热点的密钥 //#define macUser_ESP8266_TcpServer_IP "192.168.0.11" //要连接的服务器的 IP //#define macUser_ESP8266_TcpServer_Port "8080" //要连接的服务器的端口 /********************************** 外部全局变量 ***************************************/ extern volatile uint8_t ucTcpClosedFlag; /********************************** 测试函数声明 ***************************************/ void ESP8266_StaTcpClient ( void ); #endif /* __ESP8266_H */ esp8266.c文件 #include "esp8266.h" /*****************辰哥单片机设计****************** STM32 * 项目 : ESP8266模块通信实验 * 版本 : V1.0 * 日期 : 2024.9.30 * MCU : STM32F103C8T6 * 接口 : 串口2 * BILIBILI : 辰哥单片机设计 * CSDN : 辰哥单片机设计 * 作者 : 辰哥 **********************BEGIN***********************/ #include "esp8266.h" #include "common.h" #include <stdio.h> #include <string.h> #include <stdbool.h> #include "delay.h" volatile uint8_t ucTcpClosedFlag = 0; char cStr [ 1500 ] = { 0 }; static void ESP8266_GPIO_Config ( void ); static void ESP8266_USART_Config ( void ); static void ESP8266_USART_NVIC_Configuration ( void ); struct STRUCT_USARTx_Fram strEsp8266_Fram_Record = { 0 }; /** * @brief ESP8266 (Sta Tcp Client)透传 * @param 无 * @retval 无 */ void ESP8266_StaTcpClient ( void ) { // uint8_t ucStatus; // char cStr [ 100 ] = { 0 }; printf ( "\r\n正在配置 ESP8266 ......\r\n" ); macESP8266_CH_ENABLE(); ESP8266_AT_Test (); ESP8266_Net_Mode_Choose ( STA ); while ( ! ESP8266_JoinAP ( macUser_ESP8266_ApSsid, macUser_ESP8266_ApPwd ) ); ESP8266_Cmd ( "AT+CIFSR", "OK", 0, 1000 ); ESP8266_Cmd ( "AT+CIPMUX=1", "OK", 0, 1000 ); ESP8266_Cmd ( "AT+CIPSERVER=1,8288", "OK", 0, 1000 ); //ESP8266_Cmd("AT+CIPSTART="TCP",192.168.1.1,8000","OK",0,1000); printf( "\r\n配置 ESP8266 完毕\r\n" ); } /** * @brief ESP8266初始化函数 * @param 无 * @retval 无 */ void ESP8266_Init ( void ) { // ESP8266_GPIO_Config (); ESP8266_USART_Config (); // macESP8266_RST_HIGH_LEVEL(); // macESP8266_CH_DISABLE(); } /** * @brief 初始化ESP8266用到的GPIO引脚 * @param 无 * @retval 无 */ static void ESP8266_GPIO_Config ( void ) { /*定义一个GPIO_InitTypeDef类型的结构体*/ GPIO_InitTypeDef GPIO_InitStructure; /* 配置 CH_PD 引脚*/ macESP8266_CH_PD_APBxClock_FUN ( macESP8266_CH_PD_CLK, ENABLE ); GPIO_InitStructure.GPIO_Pin = macESP8266_CH_PD_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init ( macESP8266_CH_PD_PORT, & GPIO_InitStructure ); /* 配置 RST 引脚*/ macESP8266_RST_APBxClock_FUN ( macESP8266_RST_CLK, ENABLE ); GPIO_InitStructure.GPIO_Pin = macESP8266_RST_PIN; GPIO_Init ( macESP8266_RST_PORT, & GPIO_InitStructure ); } /** * @brief 初始化ESP8266用到的 USART * @param 无 * @retval 无 */ static void ESP8266_USART_Config ( void ) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; /* config USART clock */ macESP8266_USART_APBxClock_FUN ( macESP8266_USART_CLK, ENABLE ); macESP8266_USART_GPIO_APBxClock_FUN ( macESP8266_USART_GPIO_CLK, ENABLE ); /* USART GPIO config */ /* Configure USART Tx as alternate function push-pull */ GPIO_InitStructure.GPIO_Pin = macESP8266_USART_TX_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(macESP8266_USART_TX_PORT, &GPIO_InitStructure); /* Configure USART Rx as input floating */ GPIO_InitStructure.GPIO_Pin = macESP8266_USART_RX_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(macESP8266_USART_RX_PORT, &GPIO_InitStructure); /* USART1 mode config */ USART_InitStructure.USART_BaudRate = macESP8266_USART_BAUD_RATE; 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(macESP8266_USARTx, &USART_InitStructure); /* 中断配置 */ USART_ITConfig ( macESP8266_USARTx, USART_IT_RXNE, ENABLE ); //使能串口接收中断 USART_ITConfig ( macESP8266_USARTx, USART_IT_IDLE, ENABLE ); //使能串口总线空闲中断 ESP8266_USART_NVIC_Configuration (); USART_Cmd(macESP8266_USARTx, ENABLE); } /** * @brief 配置 ESP8266 USART 的 NVIC 中断 * @param 无 * @retval 无 */ static void ESP8266_USART_NVIC_Configuration ( void ) { NVIC_InitTypeDef NVIC_InitStructure; /* Configure the NVIC Preemption Priority Bits */ NVIC_PriorityGroupConfig ( macNVIC_PriorityGroup_x ); /* Enable the USART2 Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = macESP8266_USART_IRQ; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } /* * 函数名:ESP8266_Rst * 描述 :重启WF-ESP8266模块 * 输入 :无 * 返回 : 无 * 调用 :被 ESP8266_AT_Test 调用 */ void ESP8266_Rst ( void ) { #if 0 ESP8266_Cmd ( "AT+RST", "OK", "ready", 2500 ); #else macESP8266_RST_LOW_LEVEL(); delay_ms ( 500 ); macESP8266_RST_HIGH_LEVEL(); #endif } /* * 函数名:ESP8266_Cmd * 描述 :对WF-ESP8266模块发送AT指令 * 输入 :cmd,待发送的指令 * reply1,reply2,期待的响应,为NULL表不需响应,两者为或逻辑关系 * waittime,等待响应的时间 * 返回 : 1,指令发送成功 * 0,指令发送失败 * 调用 :被外部调用 */ bool ESP8266_Cmd ( char * cmd, char * reply1, char * reply2, u32 waittime ) { strEsp8266_Fram_Record .InfBit .FramLength = 0; //从新开始接收新的数据包 macESP8266_Usart ( "%s\r\n", cmd ); if ( ( reply1 == 0 ) && ( reply2 == 0 ) ) //不需要接收数据 return true; delay_ms( waittime ); //延时 strEsp8266_Fram_Record .Data_RX_BUF [ strEsp8266_Fram_Record .InfBit .FramLength ] = '\0'; macPC_Usart ( "%s", strEsp8266_Fram_Record .Data_RX_BUF ); if ( ( reply1 != 0 ) && ( reply2 != 0 ) ) return ( ( bool ) strstr ( strEsp8266_Fram_Record .Data_RX_BUF, reply1 ) || ( bool ) strstr ( strEsp8266_Fram_Record .Data_RX_BUF, reply2 ) ); else if ( reply1 != 0 ) return ( ( bool ) strstr ( strEsp8266_Fram_Record .Data_RX_BUF, reply1 ) ); else return ( ( bool ) strstr ( strEsp8266_Fram_Record .Data_RX_BUF, reply2 ) ); } /* * 函数名:ESP8266_AT_Test * 描述 :对WF-ESP8266模块进行AT测试启动 * 输入 :无 * 返回 : 无 * 调用 :被外部调用 */ void ESP8266_AT_Test ( void ) { char count=0; macESP8266_RST_HIGH_LEVEL(); delay_ms( 1000 ); while ( count < 10 ) { if( ESP8266_Cmd ( "AT", "OK", NULL, 500 ) ) return; ESP8266_Rst(); ++ count; } } /* * 函数名:ESP8266_Net_Mode_Choose * 描述 :选择WF-ESP8266模块的工作模式 * 输入 :enumMode,工作模式 * 返回 : 1,选择成功 * 0,选择失败 * 调用 :被外部调用 */ bool ESP8266_Net_Mode_Choose ( ENUM_Net_ModeTypeDef enumMode ) { switch ( enumMode ) { case STA: return ESP8266_Cmd ( "AT+CWMODE=1", "OK", "no change", 2500 ); case AP: return ESP8266_Cmd ( "AT+CWMODE=2", "OK", "no change", 2500 ); case STA_AP: return ESP8266_Cmd ( "AT+CWMODE=3", "OK", "no change", 2500 ); default: return false; } } /* * 函数名:ESP8266_JoinAP * 描述 :WF-ESP8266模块连接外部WiFi * 输入 :pSSID,WiFi名称字符串 * :pPassWord,WiFi密码字符串 * 返回 : 1,连接成功 * 0,连接失败 * 调用 :被外部调用 */ bool ESP8266_JoinAP ( char * pSSID, char * pPassWord ) { char cCmd [120]; sprintf ( cCmd, "AT+CWJAP=\"%s\",\"%s\"", pSSID, pPassWord ); return ESP8266_Cmd ( cCmd, "OK", NULL, 5000 ); } /* * 函数名:ESP8266_BuildAP * 描述 :WF-ESP8266模块创建WiFi热点 * 输入 :pSSID,WiFi名称字符串 * :pPassWord,WiFi密码字符串 * :enunPsdMode,WiFi加密方式代号字符串 * 返回 : 1,创建成功 * 0,创建失败 * 调用 :被外部调用 */ bool ESP8266_BuildAP ( char * pSSID, char * pPassWord, ENUM_AP_PsdMode_TypeDef enunPsdMode ) { char cCmd [120]; sprintf ( cCmd, "AT+CWSAP=\"%s\",\"%s\",1,%d", pSSID, pPassWord, enunPsdMode ); return ESP8266_Cmd ( cCmd, "OK", 0, 1000 ); } /* * 函数名:ESP8266_Enable_MultipleId * 描述 :WF-ESP8266模块启动多连接 * 输入 :enumEnUnvarnishTx,配置是否多连接 * 返回 : 1,配置成功 * 0,配置失败 * 调用 :被外部调用 */ bool ESP8266_Enable_MultipleId ( FunctionalState enumEnUnvarnishTx ) { return ESP8266_Cmd ( "AT+CIPMUX=%d", "OK", 0, 500 ); } /* * 函数名:ESP8266_Link_Server * 描述 :WF-ESP8266模块连接外部服务器 * 输入 :enumE,网络协议 * :ip,服务器IP字符串 * :ComNum,服务器端口字符串 * :id,模块连接服务器的ID * 返回 : 1,连接成功 * 0,连接失败 * 调用 :被外部调用 */ bool ESP8266_Link_Server ( ENUM_NetPro_TypeDef enumE, char * ip, char * ComNum, ENUM_ID_NO_TypeDef id) { char cStr [100] = { 0 }, cCmd [120]; switch ( enumE ) { case enumTCP: sprintf ( cStr, "\"%s\",\"%s\",%s", "TCP", ip, ComNum ); break; case enumUDP: sprintf ( cStr, "\"%s\",\"%s\",%s", "UDP", ip, ComNum ); break; default: break; } if ( id < 5 ) sprintf ( cCmd, "AT+CIPSTART=%d,%s", id, cStr); else sprintf ( cCmd, "AT+CIPSTART=%s", cStr ); return ESP8266_Cmd ( cCmd, "OK", "ALREAY CONNECT", 4000 ); } /* * 函数名:ESP8266_StartOrShutServer * 描述 :WF-ESP8266模块开启或关闭服务器模式 * 输入 :enumMode,开启/关闭 * :pPortNum,服务器端口号字符串 * :pTimeOver,服务器超时时间字符串,单位:秒 * 返回 : 1,操作成功 * 0,操作失败 * 调用 :被外部调用 */ bool ESP8266_StartOrShutServer ( FunctionalState enumMode, char * pPortNum, char * pTimeOver ) { char cCmd1 [120], cCmd2 [120]; if ( enumMode ) { sprintf ( cCmd1, "AT+CIPSERVER=%d,%s", 1, pPortNum ); sprintf ( cCmd2, "AT+CIPSTO=%s", pTimeOver ); return ( ESP8266_Cmd ( cCmd1, "OK", 0, 500 ) && ESP8266_Cmd ( cCmd2, "OK", 0, 500 ) ); } else { sprintf ( cCmd1, "AT+CIPSERVER=%d,%s", 0, pPortNum ); return ESP8266_Cmd ( cCmd1, "OK", 0, 500 ); } } /* * 函数名:ESP8266_Get_LinkStatus * 描述 :获取 WF-ESP8266 的连接状态,较适合单端口时使用 * 输入 :无 * 返回 : 2,获得ip * 3,建立连接 * 3,失去连接 * 0,获取状态失败 * 调用 :被外部调用 */ uint8_t ESP8266_Get_LinkStatus ( void ) { if ( ESP8266_Cmd ( "AT+CIPSTATUS", "OK", 0, 500 ) ) { if ( strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "STATUS:2\r\n" ) ) return 2; else if ( strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "STATUS:3\r\n" ) ) return 3; else if ( strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "STATUS:4\r\n" ) ) return 4; } return 0; } /* * 函数名:ESP8266_Get_IdLinkStatus * 描述 :获取 WF-ESP8266 的端口(Id)连接状态,较适合多端口时使用 * 输入 :无 * 返回 : 端口(Id)的连接状态,低5位为有效位,分别对应Id5~0,某位若置1表该Id建立了连接,若被清0表该Id未建立连接 * 调用 :被外部调用 */ uint8_t ESP8266_Get_IdLinkStatus ( void ) { uint8_t ucIdLinkStatus = 0x00; if ( ESP8266_Cmd ( "AT+CIPSTATUS", "OK", 0, 500 ) ) { if ( strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "+CIPSTATUS:0," ) ) ucIdLinkStatus |= 0x01; else ucIdLinkStatus &= ~ 0x01; if ( strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "+CIPSTATUS:1," ) ) ucIdLinkStatus |= 0x02; else ucIdLinkStatus &= ~ 0x02; if ( strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "+CIPSTATUS:2," ) ) ucIdLinkStatus |= 0x04; else ucIdLinkStatus &= ~ 0x04; if ( strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "+CIPSTATUS:3," ) ) ucIdLinkStatus |= 0x08; else ucIdLinkStatus &= ~ 0x08; if ( strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "+CIPSTATUS:4," ) ) ucIdLinkStatus |= 0x10; else ucIdLinkStatus &= ~ 0x10; } return ucIdLinkStatus; } /* * 函数名:ESP8266_Inquire_ApIp * 描述 :获取 F-ESP8266 的 AP IP * 输入 :pApIp,存放 AP IP 的数组的首地址 * ucArrayLength,存放 AP IP 的数组的长度 * 返回 : 0,获取失败 * 1,获取成功 * 调用 :被外部调用 */ uint8_t ESP8266_Inquire_ApIp ( char * pApIp, uint8_t ucArrayLength ) { char uc; char * pCh; ESP8266_Cmd ( "AT+CIFSR", "OK", 0, 500 ); pCh = strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "APIP,\"" ); if ( pCh ) pCh += 6; else return 0; for ( uc = 0; uc < ucArrayLength; uc ++ ) { pApIp [ uc ] = * ( pCh + uc); if ( pApIp [ uc ] == '\"' ) { pApIp [ uc ] = '\0'; break; } } return 1; } /* * 函数名:ESP8266_UnvarnishSend * 描述 :配置WF-ESP8266模块进入透传发送 * 输入 :无 * 返回 : 1,配置成功 * 0,配置失败 * 调用 :被外部调用 */ //bool ESP8266_UnvarnishSend ( void ) //{ // ESP8266_Cmd ( "AT+CIPMODE=1", "OK", 0, 500 ); //} /* * 函数名:ESP8266_ExitUnvarnishSend * 描述 :配置WF-ESP8266模块退出透传模式 * 输入 :无 * 返回 : 无 * 调用 :被外部调用 */ void ESP8266_ExitUnvarnishSend ( void ) { delay_ms( 1000 ); macESP8266_Usart ( "+++" ); delay_ms( 500 ); } /* * 函数名:ESP8266_SendString * 描述 :WF-ESP8266模块发送字符串 * 输入 :enumEnUnvarnishTx,声明是否已使能了透传模式 * :pStr,要发送的字符串 * :ulStrLength,要发送的字符串的字节数 * :ucId,哪个ID发送的字符串 * 返回 : 1,发送成功 * 0,发送失败 * 调用 :被外部调用 */ bool ESP8266_SendString ( FunctionalState enumEnUnvarnishTx, char * pStr, u32 ulStrLength, ENUM_ID_NO_TypeDef ucId ) { char cStr [20]; bool bRet = false; if ( enumEnUnvarnishTx ) { macESP8266_Usart ( "%s", pStr ); bRet = true; } else { if ( ucId < 5 ) sprintf ( cStr, "AT+CIPSEND=%d,%d", ucId, ulStrLength + 2 ); else sprintf ( cStr, "AT+CIPSEND=%d", ulStrLength + 2 ); ESP8266_Cmd ( cStr, "> ", 0, 1000 ); bRet = ESP8266_Cmd ( pStr, "SEND OK", 0, 1000 ); } return bRet; } /* * 函数名:ESP8266_ReceiveString * 描述 :WF-ESP8266模块接收字符串 * 输入 :enumEnUnvarnishTx,声明是否已使能了透传模式 * 返回 : 接收到的字符串首地址 * 调用 :被外部调用 */ char * ESP8266_ReceiveString ( FunctionalState enumEnUnvarnishTx ) { char * pRecStr = 0; strEsp8266_Fram_Record .InfBit .FramLength = 0; strEsp8266_Fram_Record .InfBit .FramFinishFlag = 0; while ( ! strEsp8266_Fram_Record .InfBit .FramFinishFlag ); strEsp8266_Fram_Record .Data_RX_BUF [ strEsp8266_Fram_Record .InfBit .FramLength ] = '\0'; if ( enumEnUnvarnishTx ) pRecStr = strEsp8266_Fram_Record .Data_RX_BUF; else { if ( strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "+IPD" ) ) pRecStr = strEsp8266_Fram_Record .Data_RX_BUF; } return pRecStr; } 对以上内容进行总结和解释,重点说明设计是如何实现的,包括:对设计工作的详细表述。要求层次分明、表达确切。

又可乐
  • 粉丝: 1915
上传资源 快速赚钱