早前也用过ESP8266,但是只是把它当成一个模块用,其他MCU才是主角,不过一直知道它本身就可以提供MCU类似的功能,只不过没去深入研究。最近在琢磨着捣鼓点什么东西的时候又想起来了它。本来没它什么事的,我准备直接用MCU+nrf24L01的通信方案,功耗低,速率也不差,除了比wifi模块应用范围窄一点,不方便拓展应用。所以又想着看看ESP8266既当MCU,又当通信模块。
这一琢磨不要紧,就花了我三天时间。这个模块的资料纷繁复杂,但看一个文档又都没把事情说清楚,也没有一个很好的入口。而也怪我直接从买模块配送的资料看起,没有早去乐鑫官网,也没有先搜搜别人的入门帖,导致绕了好大一圈,才知道到底怎么回事,并终于实现了点亮我的LED小灯。。。
首先说说安信可,我们都知道芯片是乐鑫生产的,但是买的模块貌似都提供的安信可的资料,额,因为它把乐鑫的芯片封装成模块(应该也有别的厂商做这种模块封装的事),引出引脚,加上外围电路,以及flash模块,方便大家使用。同时安信可也提供了他们的一些资料,再加上若干年的资料修订升级,又很不巧,我是四五年前买模块顺便下载的资料,导致我这一路历经坎坷。
乐鑫的这个芯片ESP8266EX功能比较强大(32位字长,最高160Mhz,此运行频率是芯片内部设定的,与外部无关),如果配合MCU使用,可以不需要外接flash,直接按照协议受控完成wifi网络任务,而如果单独作为主控设备,则也可以从flash的外部代码启动。
为方便大家扩展使用,原厂给开发了SDK,SDK底层实现了对芯片的具体通信和控制功能,并封装成库供编译时链接,而用户按照SDK编程手册约定,就可以将自己的控制代码编译成.bin二进制文件烧录到flash中,而芯片其实内置了自己的基础作业系统,当启动的时候根据GPIO0,GPIO2,GPIO15的状态判断系统应该处于的工作模式,然后决定是否从flash中的用户程序开始执行。
说道这里,AT系统也是官方实现的SDK库的一部分,相当于把各种接口用AT指令封装成在uart端口上的控制方式,系统的运作方式就是从uart接收指令,然后解析、执行,如此往复。我们其实也可以模拟这样的AT系统来实现自己需要的指令控制方式(AT系统里已经可以实现用户自定义AT指令),比如在user_init()函数里定义上串口中断,中断函数里根据接收到的指令进行判断,并调用系统接口完成执行执行。芯片本身内部的执行逻辑,通信方式是不允许修改的,烧录其实都是对flash的动作。因而烧录失败不过重新烧录一遍就可以。烧录其实也是通过uart总线,和芯片通信写入SPI总线的flash中,这个逻辑是不变的。
要避免各种坑,请移步官网,看官方文档,新版说的很详细明确,不要学我死磕:
https://www.espressif.com/zh-hans/support/download/documents?keys=
下面说说如何实现ESP8266控制LED闪烁这么最简单的功能。
先安装环境。由于我看的资料比较早,还处于用虚拟机的阶段,后来可以直接用Eclipse/Arduino等IDE,先是下载虚拟机,
https://drive.google.com/drive/folders/0B5bwBE9A5dBXaExvdDExVFNrUXM
然后安装虚拟机,配置虚拟机共享文件夹,官方用的virtualBox,比较简单方便,但是我不想再安装了,所以直接用已有的VMware, 这些是虚拟机基本操作,不多说,然后设置的共享文件夹会挂载在 /mnt/hgfs,虚拟机是个linux系统。
然后从如下地址下载SDK:
https://www.espressif.com/zh-hans/support/download/sdks-demos
比如我下的是NONOS SDK,解压后进入目录:
如果不需要可以删掉其中的examples、documents、driver_lib、third_party、tools文件夹,然后新建app文件夹。
官方的编译说明里有说,需要在app路径下放置需要编译的内如,比如examples文件夹内有很多示例,如果要单独编译某个示例,比如IoT_Demo,需要将/examples/IoT_Demo/*拷贝至app/*, 在app目录下编译才行。
我用的模块是ESP-01S,只有GPIO0和GPIO2,示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | #include "ets_sys.h" #include "osapi.h" #include "gpio.h" #include "user_interface.h" LOCAL os_timer_t timer; char ledStatus = 1;
void timer_cb(){ GPIO_OUTPUT_SET(GPIO_ID_PIN(2), ledStatus); ledStatus = ledStatus?0:1; }
void ICACHE_FLASH_ATTR user_rf_pre_init(){ }
uint32 ICACHE_FLASH_ATTR user_rf_cal_sector_set(void){ }
void ICACHE_FLASH_ATTR user_init(void) { PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U,FUNC_GPIO2); os_timer_disarm(&timer); os_timer_setfn(&timer,(os_timer_func_t *)timer_cb,NULL); os_timer_arm(&timer,1000,1); } |
很简单的定时任务,时间到就在回调函数里设置GPIO2的输出,从而控制灯闪烁
其中user_rf_pre_init()函数和user_rf_cal_sector_set函数是手册约定必须加的,但是可以不实现,如果要用到相关的功能,就需要去查手册并写上,后者可以直接从IoT_Demo中拷贝用即可。
就这一个文件就够了,同时保留driver、include文件夹,拷贝到app路径下后就可以编译了。
这里注意下,对于不同大小的flash,要修改ld/eagle.app.v6.ld的一个字段,
编译成功,最后几行会打印出对应bin文件要拷贝到的flash地址。
然后用官方工具下载
这里特别说一下,下载工具里备注的下载地址可能有误,以文档为准:
注意,其中除了flash.bin和irom0text.bin每次都需要下载,blank.bin和esp_init_data_default.bin只需要保证flash里面下载过就行了,对应版本的sdk只需要下载一次,并且要对照着上述地址下载。
再注意,FOTA的下载方式不一样,编译的时候要选择的项目也不一样。
哎,要注意的真多,细碎。
选择好后,点start,然后给模块上电,然后就等着下载吧 !
不过上述从虚拟机拷贝来拷贝去还是太麻烦了,于是也按官方说明弄了个Eclipse版的,本身之前写代码就装有eclipse,这回再装个cygwin,再用官方工具关联一下就行了,
具体安装方法文末参考资料里有。
不过安装完后,如果是最新版本的SDK,要编译的话去掉third_part和driver_lib文件夹,不然会编译不通过:
本来是要写些注意事项,和更多容易混淆的点的,但是无奈太琐碎,大家还是看最新版的官方文档吧,文档看起来慢,但是很全面准确。
最后放张工作照哈:
原博客:
http://www.straka.cn/blog/starting-with-esp8266-light-a-led/
app示例下载(整个打包下载可编译,已删除不必要的文件):
https://github.com/atp798/BlogStraka/tree/master/ESP8266_NONOS_SDK-2.2.1-templates
拓展与参考资料:
官方下载地址:
集成IDE下载地址:
https://pan.baidu.com/s/1c1WRp1A
ESP8266-SDK开发入坑(一)- 各种配置