早前也用過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開發入坑(一)- 各種配置