1.网络系统_设计思路与结构体
本节源码:在GIT仓库中
rtos_doc_source\RTOS培训资料\
01_项目1_基于HAL库实现智能家居\
05_项目1_基于HAL库的智能家居\1_项目源码\
10_19_net_struct
1.1 程序总体框架
1.2 网络系统层次
将网卡设备融入输入子系统中
1.3 怎么得出这些层次?
看视频。
1.4 抽象网卡设备的结构体
typedef struct NetDevice{
char *name; //根据名字来选择不同的网卡
char ip[4];
char mac[6];
int (*Init)(struct NetDevice *ptDev);
int (*Connect)(struct NetDevice *ptdev, char *SSID, char *password);
void (*Disconnect)(struct NetDevice *ptdev);
/*数据传输三要素:source, dest, data*/
/*Type选择TCP传输还是UDP传输*/
int (*Send)(struct NetDevice *ptDev, char *Type, char *pDestIP, int iDestPort, unsigned char *Data, int iLen);
/*接收时,使用iLocalPort来选择监听的端口,使用pSrcIP来保持源头的IP值*/
int (*Recv)(struct NetDevice *ptDev, char *Type, int iLocalPort, cahr *pSrcIP, unsigned char *Data, int iLen, int TimeoutMS);
}NetDevice,*PNetDevice;
2.网络系统_ESP8266模块编程
参考资料:
rtos_doc_source\RTOS培训资料\00_基础资源资料\
1_STM32F103\3_硬件资料\4_ESP8266-01S模块资料\01_技术手册\01_乐鑫(espressif)\
ESP8266 Non-OS AT 指令使用示例_V1.3.pdf
09-7_2-1.AT指令应用示例_UDP 传输_固定远端的 UDP 通信
09-7_2-2.AT指令应用示例_远端可变的 UDP 通信
本节源码:在GIT仓库中
rtos_doc_source\RTOS培训资料\
01_项目1_基于HAL库实现智能家居\
05_项目1_基于HAL库的智能家居\1_项目源码\
10_20_net_esp8266
2.1 AT指令练习
如下图接好ESP8266模块:
练习AT指令:
rtos_doc_source\RTOS培训资料\01_项目1_基于HAL库实现智能家居\
04_AT指令(基于ESP8266)\1_项目源码\
01_STM32F103_ESP8266-01S_Console
1. 配置 WiFi 模式
AT+CWMODE=3 // softAP+station mode
2. 连接路由器
AT+CWJAP="Programmers","100asktech" // SSID and password of router
响应:OK
3. 查询 ESP8266 设备的 IP 地址,查询到的STAIP+CIFSR:STAIP
才是需要的
AT+CIFSR
响应:
+CIFSR:APIP,"192.168.4.1"
+CIFSR:APMAC,"1a:fe:34:a5:8d:c6"
+CIFSR:STAIP,"192.168.3.133"
+CIFSR:STAMAC,"18:fe:34:a5:8d:c6"
OK
4. 单连接
AT+CIPMUX=0
响应:
OK
5. 创建 UDP 传输, 最后一个参数设置为2时表示UDP通信的远端可改变
(这个IP地址为我们所任意设置的PC本地IP,这里任意设置之后,如果需要使用ESP8266向电脑发送数据,那么SSCOM软件中本地IP就需要设置为192.168.101.110,端口为8080)
AT+CIPSTART="UDP","192.168.101.110",8080,1112,2
响应:
CONNNECT
OK
6. 发送数据
AT+CIPSEND=7 // Send 7 bytes
>UDPtest // enter the data, no CR
响应:
Recv 7 bytes
OK
7. 发送数据到其他指定远端。例例如,发数据到 192.168.101.111, 端⼝口 1000
AT+CIPSEND=7,"192.168.101.111",1000 // Send 7 bytes
>UDPtest // enter the data, no CR
响应:
Recv 7 bytes
OK
8. 接收数据。 当 ESP8266 设备接收到服务器器发来的数据,将提示如下信息:
+IPD,n:xxxxxxxxxx // received n bytes, data=xxxxxxxxxxx
9. 断开 UDP 传输
AT+CIPCLOSE
响应:
CLOSED
OK
2.2 ESP8266编程
2.3 网卡管理层编程
3.网络系统_实现AT命令
参考资料:
rtos_doc_source\RTOS培训资料\00_基础资源资料\
1_STM32F103\3_硬件资料\4_ESP8266-01S模块资料\01_技术手册\01_乐鑫(espressif)\
ESP8266 Non-OS AT 指令使用示例_V1.3.pdf
09-7_2-1.AT指令应用示例_UDP 传输_固定远端的 UDP 通信
09-7_2-2.AT指令应用示例_远端可变的 UDP 通信
本节源码:在GIT仓库中
rtos_doc_source\RTOS培训资料\
01_项目1_基于HAL库实现智能家居\
05_项目1_基于HAL库的智能家居\1_项目源码\
10_21_net_at_command
3.1 编写at_command.c
在esp8266.c中,调用了这些函数:
ATInterfaceSelect
ATInterfaceInit
ATCommandSend
ATDataRecv
3.2 实现UART接口设备
所以,对于不同的接口,抽象出一个结构体:
#define ATInterfaceDevice UARTDevice
#define PATInterfaceDevice PUARTDevice
typedef struct UARTDevice {
char *name;
int (*Init)(struct UARTDevice *ptDev);
void (*InvalidRecvBuf)(struct UARTDevice *ptDev);
int (*Write)(struct UARTDevice *ptDev, char *Data, int iLen);
int (*ReadByte)(struct UARTDevice *ptDev, char *Data);
}UARTDevice, *PUARTDevice;
3.3 AT命令返回值判断
以字符形式显示,得到OK换行的编码格式
4.网络系统_串口设备编程
参考资料:
08-6环形缓冲区的概念和实现
rtos_doc_source\RTOS培训资料\
01_项目1_基于HAL库实现智能家居\
05_项目1_基于HAL库的智能家居\1_项目源码\
10_22_net_uart_not_tested\
ModuleDrivers\driver_usart.c
本节源码:在GIT仓库中
rtos_doc_source\RTOS培训资料\
01_项目1_基于HAL库实现智能家居\
05_项目1_基于HAL库的智能家居\1_项目源码\
10_22_net_uart_not_tested
4.1 AT模块框架
在at_command.c里,调用了底层UART硬件的接口函数:
4.2 实现UART接口设备
STM32F103上使用了2个UART:
编程思路:
UART1的代码在ModuleDrivers\driver_usart.c里,
我们可以参考这个文件实现UART3的操作。
4.2.1 初始化
// Core\Src\usart.c
void MX_USART3_UART_Init(void)
{
/* USER CODE BEGIN USART3_Init 0 */
/* USER CODE END USART3_Init 0 */
/* USER CODE BEGIN USART3_Init 1 */
/* USER CODE END USART3_Init 1 */
huart3.Instance = USART3;
huart3.Init.BaudRate = 115200;
huart3.Init.WordLength = UART_WORDLENGTH_8B;
huart3.Init.StopBits = UART_STOPBITS_1;
huart3.Init.Parity = UART_PARITY_NONE;
huart3.Init.Mode = UART_MODE_TX_RX;
huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart3.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart3) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN USART3_Init 2 */
/* USER CODE END USART3_Init 2 */
}
// ModuleDrivers\driver_usart.c
void EnableUART3IRQ(void)
{
HAL_NVIC_SetPriority(USART3_IRQn, 0, 1);
HAL_NVIC_EnableIRQ(USART3_IRQn);
__HAL_UART_ENABLE_IT(&huart3, UART_IT_RXNE);
}
// smartdevice\device\uart\uart_dev.c
/**********************************************************************
* 函数名称: UART3Init
* 功能描述: 初始化UART3
* 输入参数: ptDev-没有使用
* 输出参数: 无
* 返 回 值: 0-成功
* 修改日期 版本号 修改人 修改内容
* -----------------------------------------------
* 2021/10/15 V1.0 韦东山 创建
***********************************************************************/
static int UART3Init(struct UARTDevice *ptDev)
{
/* 在Core\Src\main.c里已经初始化硬件
* 1. MX_USART3_UART_Init
* 2. EnableUART3IRQ
*/
ring_buffer_init(&g_UART3RingBuffer);
return 0;
}
4.2.2 发送数据
使用查询方式发送多个数据,调用流程如下:
UART3Write // smartdevice\device\uart\uart_dev.c
KAL_UART3Write // smartdevice\kal\kal_uart_dev.c
CAL_UART3Write // smartdevice\cal\cal_uart_dev.c
USART3_SendBytes // ModuleDrivers\driver_usart.c
底层函数是USART3_SendBytes,代码如下:
// ModuleDrivers\driver_usart.c
/**********************************************************************
* 函数名称: USART3_SendBytes
* 功能描述: 通过UART3发出多个数据
* 输入参数: buf-数据缓冲区
* 输入参数: len-数据长度
* 输出参数: 无
* 返 回 值: 0-成功
* 修改日期 版本号 修改人 修改内容
* -----------------------------------------------
* 2021/10/15 V1.0 韦东山 创建
***********************************************************************/
void USART3_SendBytes(char *buf, int len)
{
int i;
for (i = 0; i < len; i++)
{
while ((USART3->SR & (1<<7)) == 0);
USART3->DR = buf[i];
}
}
4.2.3 接收数据
流程为:
中断服务程序:把数据放入环形缓冲区
上层代码:从环形缓冲区得到数据
中断服务程序代码:
// ModuleDrivers\driver_usart.c
/**********************************************************************
* 函数名称: USART3_IRQHandler
* 功能描述: UART3中断函数,把接收到的数据放入环形缓冲区
* 输入参数: 无
* 输出参数: 无
* 返 回 值: 无
* 修改日期 版本号 修改人 修改内容
* -----------------------------------------------
* 2021/10/15 V1.0 韦东山 创建
***********************************************************************/
void USART3_IRQHandler(void)
{
static ring_buffer *uart3_ringbuffer = GetUART3RingBuffer();
unsigned char c = 0;
if((USART3->SR &(1<<5)) != 0)
{
c = USART3->DR;
ring_buffer_write(c, uart3_ringbuffer);
}
HAL_UART_IRQHandler(&huart3);
}
上层代码:
// smartdevice\device\uart\uart_dev.c
/**********************************************************************
* 函数名称: UART3ReadByte
* 功能描述: 通过UART3读取1个字节(不等待,无数据就返回-1)
* 输入参数: ptDev-没有使用
* 输出参数: Data-数据缓冲区
* 返 回 值: 0-成功, (-1)-无数据
* 修改日期 版本号 修改人 修改内容
* -----------------------------------------------
* 2021/10/15 V1.0 韦东山 创建
***********************************************************************/
static int UART3ReadByte(struct UARTDevice *ptDev, char *Data)
{
return ring_buffer_read((unsigned char *)Data, &g_UART3RingBuffer)
}
5.网络系统_单元测试
参考资料:
rtos_doc_source\RTOS培训资料\00_基础资源资料\
1_STM32F103\3_硬件资料\4_ESP8266-01S模块资料\01_技术手册\01_乐鑫(espressif)\
ESP8266 Non-OS AT 指令使用示例_V1.3.pdf
09-7_2-1.AT指令应用示例_UDP 传输_固定远端的 UDP 通信
09-7_2-2.AT指令应用示例_远端可变的 UDP 通信
本节源码:在GIT仓库中
rtos_doc_source\RTOS培训资料\
01_项目1_基于HAL库实现智能家居\
05_项目1_基于HAL库的智能家居\1_项目源码\
10_23_net_unittest_err
10_24_net_unittest_ok
5.1 编写测试代码
初始化
连接WIFI
显示自己的IP、端口
创建UDP传输
读取数据、打印出来
5.2 上机测试
向开发板发送数据:
使用sscom5.13.1
使用微信小程序:搜"百问网嵌入式物联网"
使用微信小程序:扫码
6.网络系统_用作输入设备
本节源码:在GIT仓库中
rtos_doc_source\RTOS培训资料\
01_项目1_基于HAL库实现智能家居\
05_项目1_基于HAL库的智能家居\1_项目源码\
10_25_net_input_not_tested
6.1 设计思路
ESP8266通过串口把网络数据发给主控,数据格式为:
+IPD,n:xxxxxxxxxx // received n bytes, data=xxxxxxxxxxx
所以,可以这样做:
在串口接收中断里:记录收到的数据
判断是否有+IPD,前缀
6.2 编写代码
构造一个InputDevice,在它的初始化函数里,提供串口中断的回调函数。
在回调函数里,处理串口数据。
6.3 上机测试
向开发板发送数据:
使用sscom5.13.1
使用微信小程序:搜"百问网嵌入式物联网"
使用微信小程序:扫码
7.网络系统_用作输入设备_单元测试
本节源码:在GIT仓库中
rtos_doc_source\RTOS培训资料\
01_项目1_基于HAL库实现智能家居\
05_项目1_基于HAL库的智能家居\1_项目源码\
10_25_net_input_not_tested
10_26_net_input_unittest_ok
7.1 编写单元测试代码
仍然使用net_test.c
7.2 上机测试
向开发板发送数据:
使用sscom5.13.1
使用微信小程序:搜"百问网嵌入式物联网"
使用微信小程序:扫码