-
Notifications
You must be signed in to change notification settings - Fork 2
I2C API
Inter-Intergrated Circuit(積體電路之間)又名I2C(I-squared-C), I2C是兩條雙向漏極開路 (Open Drain)分別為串列資料(SDA)與串列時脈(SCL),I2C參考設計使用一個7位元長度為位址空間但保 留了16個位址,所以在一組匯流排最多可以和112個節點通訊。依I2C傳輸速率的不同有不同模式:標準模式 (100 kbit/s)、低速模式(10 kbits/s)、快速模式(400 kbit/s)、高速模式(3.4 Mbit/s)和超高速 模式(5 Mbit/s)
在MT7697的MicroPython可以分硬體I2C與軟體模擬I2C:
- MT7697只有1組硬體I2C,其控制針腳為固定位置分別為Pin8與Pin9,初始傳輸速率為400kbit/s與初始 傳輸TimeOut值為1秒
- 其軟體模擬的I2C作動,所以額外將import Pin,並且指定scl與sda針腳位置。
硬體宣告方式
class machine.I2C(id=-1, *, scl, sda, freq=400000,timeout=1000)
可以使用以下參數建構一個新I2C物件
- id:特別用定義I2C硬體設定值,這系統內部初始值為-1所表示使用者選用軟體模擬實踐I2C作動方式在 大多數情況可以作動,當id為-1並且需要額外import machine.Pin,並且指定SCL與SDA的任何針腳使用。
- scl:串列時脈需指定SCL針腳,MT7697的I2C硬體部份被指定Pin8
- sda:串列資料需指定SDA針腳,MT7697的I2C硬體部份被指定Pin9
- freq:是設置SCL最大頻率的整數
- timeout:設為定為MT7697傳送完後等待回應時間, 其單位為millisecond
Example:
採用I2C硬體方式
from machine import I2C
i2c = I2C(0, freq=400000, timeout=1000)
採用I2C軟體方式
from machine import I2C, Pin
i2c = I2C(scl=Pin(8), sda=Pin(9), freq=400000)
I2C.init(scl, sda, *, freq=400000)
重新設定I2C設定值,如果採用MT7697的硬體I2C,在重新設定I2C的freq需先使用 I2C.deinit 函式, 才可重新設定。
- scl:是用SCL指定針腳
- sda:是用SDA指定針腳
- freq:是設置SCL最大頻率的整數
I2C.deinit()
關閉I2C, 當你需要重新設定MT7697硬體I2C傳送速率時,應先關閉I2C再重新使 I2C.init 函式設定。
I2C.scan()
掃描0x08到0x77之間所有I2C位址,並列表。當在I2C匯流排上發送其位址,設備將SDA拉低則做出回應。
如果你需要更多的操控I2C匯流排操作方式,下列函式將提供給下列方法提實現原始I2C為master使操作,透過
函式組合使用進行任何I2C傳送資料。
這些函式僅在宣告I2C軟體物件可用
I2C.start()
在I2C匯流排上產生一個啟動訊號(SCL為高準位時,SDA轉換為低準位)
I2C.stop()
在I2C匯流排上產生一個結束訊號(SCL為高準位時,SDA轉換為高準位)
I2C.readinto(buf, nack=True)
從I2C匯流排上讀到bytes將存入 buf , 讀取byte數量為 buf 的長度。接收到除最後一個字節以外的 所有字節後,將在總線上發送ACK,如果 nack 為 true ,則將發送 NACK ,否則將發送ACK,在 這種情況下,告知Slave在之後還將要讀取更多字節。
I2C.write(buf)
將buf的byte值傳送I2C匯流排上,檢查每一個byte之後是否回應ACK,如果收到NACK時則停止buf 剩於的bytes傳送,此函式將回應出所接收到ACK次數。
下列函式方法實現master讀/寫slave標準I2C操作。
I2C.readfrom(addr, nbytes, stop=True)
借由指定slave的 addr 讀取 nbytes 。如果 stop 為 True 當傳送資料結束時產生 STOP 狀態,讀取返回 nbytes 的資料
I2C.readfrom_into(addr, buf, stop=True)
借由指定slave的 addr 讀入 buf ,將取得bytes的量將為buf的長度,如果 stop 為 True 當傳送資料結束時產生 STOP 狀態
I2C.writeto(addr, buf, stop=True)
將 buf 的bytes寫入指定 addr 的Slave。如果 buf 每寫入 1 byte 後收到NACK, 則停傳送剩下的bytes。該函式將返回已接收到Slave的ACK的數量。當 stop 設定 true ,即 使接收到NACK,當結束時也會傳輸 Stop 狀態
I2C.writevto(addr, vector, stop=True)
將寫入指定addr的Slave的bytes資料放 vector ,vector 應具有 tuple or list 的物件。 當 addr 發送一次之後依序傳送 vector 資料的每個byte資料給指定 addr 的Slave。當 vetor 的物件bytes長度為0,這樣狀態不會傳送。
如果 vecotr 物件每寫入 1 byte 後收到NACK,則停傳送剩下的bytes。當 stop 設定 true ,即使接收到NACK,當結束時也會傳輸 Stop 狀態, 該函式將返回已接收到Slave的 ACK的數量。
某些I2C元件為記憶元件或是暫存器,可以被讀取與寫入資料。這種情況下,需要有兩種地置分別為I2C address 與記憶體的address。先借由I2C address找到Slave元件,在經由記憶體address,存讀取或寫入資訊。 下列提供函式提供實作功能。
I2C.readfrom_mem(addr, memaddr, nbytes, *, addrsize=8)
從addr指定從Slave取得memaddr指定的內存取器啟始地置讀取nbytes量。addrsize 用於指定位址大單位大小用bits為基本單位,讀取返回的byte單位物件。
I2C.readfrom_mem_into(addr, memaddr, buf, *, addrsize=8)
從addr指定從Slave取得讀取從memaddr指定的內存取器啟始地置寫入buf。addrsize 用於指定位址單位大小用bits為基本單位。
I2C.writeto_mem(addr, memaddr, buf, *, addrsize=8)
將 buf 值從 addr 指定Slave寫入 memaddr 內存取器啟始地址,addrsize 用於 指定位址單位大小用bits為基本單位。
main.py 用於硬體設定
from machine import I2C
import mpu6050
i2c = I2C(0)
accelerometer = mpu6050.accel(i2c)
accelerometer.get_values()
accelerometer.val_test()mpu6050.py
import machine
class accel():
def __init__(self, i2c, addr=0x68):
self.iic = i2c
self.addr = addr
self.iic.writeto(self.addr, bytearray([107, 0]))
def get_raw_values(self):
a = self.iic.readfrom_mem(self.addr, 0x3B, 14)
return a
def get_ints(self):
b = self.get_raw_values()
c = []
for i in b:
c.append(i)
return c
def bytes_toint(self, firstbyte, secondbyte):
if not firstbyte & 0x80:
return firstbyte << 8 | secondbyte
return - (((firstbyte ^ 255) << 8) | (secondbyte ^ 255) + 1)
def get_raw_accel_value(self):
a = self.iic.readfrom_mem(self.addr, 0x3B, 8)
return a
def get_raw_gyro_value(self):
a = self.iic.readfrom_mem(self.addr, 0x43, 6)
return a
def get_values(self):
raw_ints = self.get_raw_accel_value()
vals = {}
vals["AcX"] = self.bytes_toint(raw_ints[0], raw_ints[1])
vals["AcY"] = self.bytes_toint(raw_ints[2], raw_ints[3])
vals["AcZ"] = self.bytes_toint(raw_ints[4], raw_ints[5])
vals["Tmp"] = self.bytes_toint(raw_ints[6], raw_ints[7]) / 340.00 + 36.53
raw_ints = self.get_raw_gyro_value()
vals["GyX"] = self.bytes_toint(raw_ints[0], raw_ints[1])
vals["GyY"] = self.bytes_toint(raw_ints[2], raw_ints[3])
vals["GyZ"] = self.bytes_toint(raw_ints[4], raw_ints[5])
return vals # returned in range of Int16
# -32768 to 32767
def val_test(self): # ONLY FOR TESTING! Also, fast reading sometimes crashes IIC
from utime import sleep
import gc
while 1:
print(self.get_values())
gc.collect()
sleep(0.5)
- Pin (machine module)
- I2C (machine module)
- PWM (machine module)
- WDT (machine module)
- RTC (machine module)
- Timer (machine module)
- ADC (machine module)
- SPI (machine module)
- UART (machine module)
- BLE (Peripheral)
- LinkIt Remote
- cmath (Builtin functions)
- gc (Builtin functions)
- math (Builtin functions)
- sys (Builtin functions)
- uarray (Builtin functions)
- ubinascii (Builtin functions)
- ucollections (Builtin functions)
- uerrno (Builtin functions)
- uhashlib (Builtin functions)
- uheapq (Builtin functions)
- uio (Builtin functions)
- ujson (Builtin functions)
- uos (Builtin functions)
- ure (Builtin functions)
- uselect (Builtin functions)
- usocket (Builtin functions)
- ussl (Builtin functions)
- ustruct (Builtin functions)
- utime (Builtin functions)
- uzlib (Builtin functions)
- []