一析珊、基本介紹
請參考下面的GPIO引腳圖以獲取索引gpio映射贝椿。
IO index | ESP8266 pin | IO index | ESP8266 pin |
---|---|---|---|
0[*] | GPIO16 | 7 | GPIO13 |
1 | GPIO5 | 8 | GPIO15 |
2 | GPIO4 | 9 | GPIO 3 |
3 | GPIO0 | 10 | GPIO1 |
4 | GPIO2 | 11 | GPIO9 |
5 | GPIO14 | 12 | GPIO10 |
6 | GPIO12 |
[*] D0(GPIO16)只能用作gpio讀/寫敢会。不支持漏極開路/中斷/ pwm / i2c / ow曾沈。
二、函數介紹
函數 | 功能 |
---|---|
gpio.mode() | 初始化引腳為GPIO模式鸥昏,設置引腳的進/出方向塞俱,以及可選的內部弱上拉電路。 |
gpio.read() | 讀取數字GPIO引腳值吏垮。 |
gpio.serout() | 根據一系列延遲時間(以μs為單位)對輸出進行序列化障涯。 |
gpio.trig() | 建立或清除回調函數以在引腳的中斷上運行罐旗。 |
gpio.write() | 設置數字GPIO引腳值。 |
-
gpio.mode()
初始化引腳為GPIO模式唯蝶,設置引腳的進/出方向九秀,以及可選的內部弱上拉電路。- 句法
gpio.mode(pin, mode [, pullup])
- 參數
- pin 引腳進行配置粘我,IO索引
- mode gpio.OUTPUT鼓蜒, gpio.OPENDRAIN,gpio.INPUT或gpio.INT之一(中斷模式)
- pullup gpio.PULLUP使能弱上拉電阻征字;默認為gpio.FLOAT
- 返回
nil
4.例
gpio.mode(0, gpio.OUTPUT)
- 句法
-
gpio.read()
讀取數字GPIO引腳值都弹。- 句法
gpio.read(pin)
- 參數
pin 引腳讀取,IO索引 - 返回
一個數字匙姜,0=低畅厢,1=高 - 例
-- read value of gpio 0.
gpio.read(0)
- 句法
-
gpio.trig()
建立或清除回調函數以在引腳的中斷上運行。
如果在編譯時未定義GPIO_INTERRUPT_ENABLE氮昧,則此功能不可用框杜。- 句法
gpio.trig(pin, [type [, callback_function]])
- 參數
- pin 1-12,引腳觸發(fā)袖肥,IO索引霸琴。注意,引腳0不支持中斷昭伸。
- type“ up”,“ down”澎迎,“ both”,“ low”夹供,“ high”分別代表上升沿灵份,下降沿,兩個沿哮洽,低電平和高電平觸發(fā)模式填渠。如果類型為“ none”或省略,則刪除回調函數并禁用中斷鸟辅。
- callback_function(level, when, eventcount)觸發(fā)發(fā)生時的回調函數氛什。中斷時指定引腳的電平作為第一個參數傳遞給回調。事件的時間戳作為第二個參數傳遞匪凉。以微秒為單位枪眉,與tmr.now()。此時間戳是在中斷級別獲取的再层,比在回調函數中獲取時間更一致贸铜。此時間戳通常是檢測到的第一個中斷堡纬,但是在過載情況下,可能是后一個蒿秦。eventcount是此回調消除的中斷數烤镐。這對于邊沿觸發(fā)的中斷最有效,并且可以對邊沿進行計數棍鳖。但是炮叶,請注意開關彈跳-單個開關閉合可能會產生多個脈沖。以數字方式生成邊緣時鹊杖,計數效果最佳悴灵。如果省略該函數,則將使用前一個回調函數骂蓖。
- 返回
nil - 例
- 句法
do
-- use pin 1 as the input pulse width counter
local pin, pulse1, du, now, trig = 1, 0, 0, tmr.now, gpio.trig
gpio.mode(pin,gpio.INT)
local function pin1cb(level, pulse2)
print( level, pulse2 - pulse1 )
pulse1 = pulse2
trig(pin, level == gpio.HIGH and "down" or "up")
end
trig(pin, "down", pin1cb)
end
-
gpio.write()
設置數字GPIO引腳值积瞒。- 句法
gpio.write(pin, level)
- 參數
- pin 引腳寫入,IO索引
- level gpio.HIGH 要么 gpio.LOW
- 返回
nil - 例
- 句法
-- set pin index 1 to GPIO mode, and set the pin to high.
pin=1
gpio.mode(pin, gpio.OUTPUT)
gpio.write(pin, gpio.HIGH)
-
gpio,serout()
.serout函數登下,文檔里面寫得又長又臭的茫孔,只看懂一點,估計使用來讓一個Pin翻轉產生序列的被芳,還提到了同步和異步(回調)缰贝。
三、實操
nodeMCU板子上面剛好有個LED畔濒,我們可以拿這個LED來測試剩晴。先來看下板子的電路圖。其中的R10侵状,板子上面沒有焊赞弥。
也就是說LED1和GPIO16連接到一起,低電平就可以點亮趣兄。而GPIO16對應的編號則是0绽左。先用.mode配置GPIO16為輸出模式。使用.write可以設置電平艇潭,設置成gpio.LOW會看到板子上的藍燈亮起了拼窥。使用.read可以得到pin狀態(tài),這里使用print把讀到的值打印出來蹋凝。lua沒有printf函數鲁纠,用起來真費勁。另外仙粱,為了能夠看到燈亮房交,這里用了一下tmr.delay做一下延時。
gpio.mode(0, gpio.OUTPUT)
print(gpio.read(0),"\n")
gpio.write(0, gpio.LOW)
print(gpio.read(0),"\n")
tmr.delay(1000000)
gpio.write(0, gpio.HIGH)
print(gpio.read(0),"\n")
接下來,我們來看看.trig函數是怎么工作的伐割,直接上代碼候味。板子上面的flash按鍵(接在3號IO上)在上電后是可以用來當做普通按鍵使用的刃唤,不一定要外接按鍵。
gpio.mode(0, gpio.OUTPUT)
gpio.mode(3, gpio.INT, gpio.PULLUP)
function ledTrg()
local i = gpio.read(0)
if (i == 0) then
gpio.write(0, gpio.HIGH)
else
gpio.write(0, gpio.LOW)
end
end
gpio.trig(3, "low", ledTrg)
.serout函數可以用來讓IO輸出特定電平白群。直接看一個例子
time = 0
time = tmr.now()
gpio.mode(1, gpio.OUTPUT, PULLUP)
gpio.serout(1,1,{3,7},8)
print(tmr.now() - time)
time = tmr.now()
gpio.serout(1,1,{5000,5000},8, 1)
print(tmr.now() - time)
不過這個例子尚胞,需要示波器來配合,才能看出效果帜慢。
或者把后面的5ms改成500ms笼裳,接上LED。會看到燈閃了幾下粱玲。
四躬柬、綜合例子
結合上一篇的tmr模塊,實現呼吸燈效果抽减。函數ledPWM用來改變LED狀態(tài)允青,同時,修改高低電平的持續(xù)時間卵沉。不過.interval的最小單位是ms颠锉,所以,效果不是特別好史汗。一個周期的時間不要大于50HZ(20ms)琼掠,不然會有明顯的閃爍。changePWM函數用來調節(jié)占空比停撞。最后啟動兩個靜態(tài)定時器瓷蛙。把程序send到nodeMCU里面就可以看到效果了~
ledState = 0
pwm = 1
flag = 0
gpio.mode(0, gpio.OUTPUT)
function ledPWM()
if (ledState == 1) then
ledState = 0
gpio.write(0, gpio.HIGH)
tmr.interval(0, 20 - pwm)
else
ledState = 1
gpio.write(0, gpio.LOW)
tmr.interval(0, pwm)
end
end
function changePWM()
if(flag == 0) then
if(pwm == 12) then
pwm = 11
flag = 1
else
pwm = pwm + 1
end
else
if(pwm == 1) then
pwm = 2
flag = 0
else
pwm = pwm - 1
end
end
end
tmr.alarm(0, 1, tmr.ALARM_AUTO, ledPWM)
tmr.alarm(1, 80, tmr.ALARM_AUTO, changePWM)
一個例子,估計你看著不過癮戈毒。上面使用.trig來做按鍵掃描效果不是特別理想速挑。這里,使用定時器掃描的方式來做按鍵掃描副硅。
gpio.mode(0, gpio.OUTPUT)
gpio.mode(1, gpio.INPUT, gpio.PULLUP)
keyScanTime = tmr.create()
keyCnt = 0
function ledCtrl()
local i = gpio.read(0)
if(i == 0) then
gpio.write(0, gpio.HIGH)
else
gpio.write(0, gpio.LOW)
end
end
function keyScan()
local key = gpio.read(1)
if (key == 0) then
keyCnt = keyCnt + 1
else
if(keyCnt > 10) then
ledCtrl()
keyCnt = 0
end
end
end
tmr.alarm(keyScanTime, 10, tmr.ALARM_AUTO, keyScan)
keyScan函數以10ms的掃描周期掃描按鍵的電平狀態(tài),當按鍵按下足夠長的時間后松手翅萤,則調用ledCtrl函數恐疲。趕緊send to esp后,按一下按鍵看看效果吧,調試過程中套么,不要重復send代碼培己。可以先按ESPlorer上面的Reset按鈕胚泌,重啟模塊省咨。不然可以會導致模塊重啟。猜測是玷室,重復注冊定時器導致的零蓉。使用靜態(tài)定時器笤受,還可以在右邊發(fā)送tmr.stop(定時器序號)來暫停。動態(tài)創(chuàng)建的敌蜂,估計就比較麻煩了箩兽。