非常期待的一个环节就是把esp8266用起来,这一节做个简单演示,主要内容是通过串口给esp8266发指令,并将其回显通过串口打印出来。
由于启明开发板在出厂时就给esp8266烧录了固件,这样就可以直接通过esp8266的AT指令集控制这个板载的wifi模块了。
本次演示基于以下内容:
先来看下启明开发板上“USB TO UART”接口的引脚配置
可以看到usb转串口模块中TXD引脚与 UART4 的RXD引脚连接,RXD引脚与 UART4 的TXD引脚连接,接下来回到e2studio中配置stacks
创建完成后,点击新建的stack,在属性窗口会刷新这部分的信息,需要配置的地方有如下几个:
将属性窗口拉到最底下,先分配引脚信息,点击黄色箭头
配置完成保存,切换回stacks界面
其他一般默认即可,除非有别的需求。
到这里usb转串口引脚部分基本配置完成。非常的快速便捷!!
接下来配置esp8266所在串口的输入输出,回到原理图。
结合开发板的平面图
可以看到,开发板默认已经通过跳帽连接了esp8266和开发板的P601和P602两个引脚。
回到e2studio,打开stack界面,新建一个sci stack,用于配置esp8266所连串口。
通道选择9(UART9),配置回调函数名称,随意命令,有辨识度即可
接下来到引脚配置,拉到底部pin部分,点击黄色箭头跳转pin配置界面
到这一步,基本配置好了两个需要用到的串口,还有一点内容就是堆栈部分的配置了,因为要用到printf函数
保存,然后点击右上角的“generate project content”,自动生成相应的配置。依托于这种高效快捷的配置方法,在熟悉硬件原理图和引脚信息之后,配置过程变得非常简单。当然,保持好奇心是我们应该要有的个性,阅读配置完成后的实现细节还是有非常多值得学习的内容。
接下来开始敲代码,习惯将不同部分的内容分文件处理,这样看起来不会太乱,虽然这里只是简单的演示,但我还是这样做了,也是为了后续更高效的管理各个部分的内容。
新建uart4.c,配置中断函数以处理uart4接收和发送数据的内容,可从hal_data.h中看到,
这个函数名就是刚刚在这里填写的名字
void uart4_callback(uart_callback_args_t *p_args)
{
switch (p_args->event)
{
case UART_EVENT_RX_CHAR:
{
R_SCI_UART_Write(&g_wifi_ctrl, (uint8_t *)&(p_args->data), 1);
break;
}
case UART_EVENT_TX_COMPLETE:
{
uSendComplete = true;
break;
}
default:
break;
}
}
uSendComplete
是个全局变量用于记录uart4发送状态
g_wifi_ctrl
这个结构是下一步要配置的esp8266所连串口的名字,也是上一步stack配置中uart9部分配置时定的名字,在生成配置信息时,也是基于这个一般属性的名称生成。
上边中断函数主要内容是:将从uart4接收到的信息转发给uart9,即esp8266在开发板上所连串口uart9;在发送数据完成后,置位uSendComplete
状态
接下来是编写printf重定向的内容
将printf函数重定向到uart4,这样就可以使用printf函数打印过程信息了。
int _write(int fd, char *pBuffer, int size)
{
(void)fd;
R_SCI_UART_Write(&g_uart4_ctrl, (uint8_t *)pBuffer, (uint32_t)size);
while(uSendComplete == false);
uSendComplete = false;
return size;
}
要完全使用printf的重定向,还需要在项目配置中做以下修改
然后是编写uart4的初始化函数
void uart4_init(void)
{
fsp_err_t err;
err = R_SCI_UART_Open(&g_uart4_ctrl, &g_uart4_cfg);
assert(FSP_SUCCESS == err);
}
完整的uart.c文件内容如下:
#include "uart.h"
#include "hal_data.h"
#include "basic.h"
volatile bool uSendComplete = false;
void uart4_callback(uart_callback_args_t *p_args)
{
switch (p_args->event)
{
case UART_EVENT_RX_CHAR:
{
/* 把串口接收到的数据发送回去 */
R_SCI_UART_Write(&g_wifi_ctrl, (uint8_t *)&(p_args->data), 1);
break;
}
case UART_EVENT_TX_COMPLETE:
{
uSendComplete = true;
break;
}
default:
break;
}
}
/* 重定向 printf 输出 */
#if defined __GNUC__ && !defined __clang__
int _write(int fd, char *pBuffer, int size); //防止编译警告
int _write(int fd, char *pBuffer, int size)
{
(void)fd;
R_SCI_UART_Write(&g_uart4_ctrl, (uint8_t *)pBuffer, (uint32_t)size);
while(uSendComplete == false);
uSendComplete = false;
return size;
}
#else
int fputc(int ch, FILE *f)
{
(void)f;
R_SCI_UART_Write(&g_uart4_ctrl, (uint8_t *)&ch, 1);
while(uSendComplete == false);
uSendComplete = false;
return ch;
}
#endif
void uart4_init(void)
{
fsp_err_t err;
err = R_SCI_UART_Open(&g_uart4_ctrl, &g_uart4_cfg);
assert(FSP_SUCCESS == err);
}
uart.h的内容
#ifndef UART_H_
#define UART_H_
void uart4_init(void);
#endif /* UART_H_ */
wifi.c
#include "wifi.h"
#include "hal_data.h"
#include "basic.h"
void wifi_callback(uart_callback_args_t *p_args)
{
switch(p_args->event)
{
case UART_EVENT_RX_CHAR:
R_SCI_UART_Write(&g_uart4_ctrl, (uint8_t *)&(p_args->data), 1);
break;
default:
break;
}
}
void wifi_init(void)
{
fsp_err_t err;
err = R_SCI_UART_Open(&g_wifi_ctrl, &g_wifi_cfg);
assert(FSP_SUCCESS == err);
}
这个wifi_callback
中断函数名字在这里定义
中断函数这部分内容处理很简单,就是将esp8266模块从外部接受到的数据从uart9转发到uart4,
wifi.h
#ifndef WIFI_H_
#define WIFI_H_
void wifi_init(void);
#endif /* WIFI_H_ */
整一个数据流向就是:
发送:电脑 -> usb转串口模块 -> UART4 -> UART9 -> ESP8266
接收:ESP8266 -> UART9 -> UART4 -> usb转串口模块 -> 电脑
打开 hal_entry.c,在hal_entry函数中添加串口初始化代码以及死循环,让串口中断来处理数据流向
void hal_entry(void)
{
uart4_init();
wifi_init();
printf("串口已准备好...\r\n");
while (1){}
#if BSP_TZ_SECURE_BUILD
/* Enter non-secure code */
R_BSP_NonSecureEnter();
#endif
}
并在文件首部添加文件包含
#include "wifi.h"
#include "uart.h"
编译烧录程序后,使用数据线连接开发板USB TO UART 接口和电脑的USB口,发送AT指令和esp8266通信
AT测试指令
重启指令
可以看到板载esp8266模块的flash信息,
**烧录固件的时候需要选择flash size 为32Mbits的固件 **
查询固件版本信息
以上演示只是基本的几个指令,更多AT指令集相关可移步查看ESP8266_AT_Instruction_Set__CN.pages (microduino.cn)
当熟悉使用e2studio IDE配置新项目之后,确实节省了很大一部分配置细节的时间,,有更多的时间去处理上层逻辑的实现,相比起从0开始一步步配置各类外设的初始化过程,这作为入门的过程,着实哇塞。所以啊 ,门槛低了很多。不过进一步熟悉后,总会忍不住想去了解自动化配置的细节,这是一个相当不错的学习过程,这个过程里可以学到库函数编写的风格以及各类清晰优雅的代码实现。由简入繁。
我觉得在这一节演示中我花时间比较多的还是写这篇文章,因为我得好好分享我的感受才对得起这个大大个的主控芯片,它是这么的大。
回到启明开发板,它今夜依旧闪亮,因为还有很多很多可以摸索学习的玩法,我想这缺的不是资料,而是时间。
期待有更多摸鱼的时间可以记录学习的过程,非常不错~
更多回帖