【雕爷学编程】MicroPython手册之达芬奇 TKM32F499 Hardware I2C bus

发布于:2023-10-25 ⋅ 阅读:(158) ⋅ 点赞:(0)

在这里插入图片描述
MicroPython是为了在嵌入式系统中运行Python 3编程语言而设计的轻量级版本解释器。与常规Python相比,MicroPython解释器体积小(仅100KB左右),通过编译成二进制Executable文件运行,执行效率较高。它使用了轻量级的垃圾回收机制并移除了大部分Python标准库,以适应资源限制的微控制器。

MicroPython主要特点包括:
1、语法和功能与标准Python兼容,易学易用。支持Python大多数核心语法。
2、对硬件直接访问和控制,像Arduino一样控制GPIO、I2C、SPI等。
3、强大的模块系统,提供文件系统、网络、图形界面等功能。
4、支持交叉编译生成高效的原生代码,速度比解释器快10-100倍。
5、代码量少,内存占用小,适合运行在MCU和内存小的开发板上。
6、开源许可,免费使用。Shell交互环境为开发测试提供便利。
7、内置I/O驱动支持大量微控制器平台,如ESP8266、ESP32、STM32、micro:bit、掌控板和PyBoard等。有活跃的社区。

MicroPython的应用场景包括:
1、为嵌入式产品快速构建原型和用户交互。
2、制作一些小型的可 programmable 硬件项目。
3、作为教育工具,帮助初学者学习Python和物联网编程。
4、构建智能设备固件,实现高级控制和云连接。
5、各种微控制器应用如物联网、嵌入式智能、机器人等。

使用MicroPython需要注意:
1、内存和Flash空间有限。
2、解释执行效率不如C语言。
3、部分库函数与标准版有差异。
4、针对平台优化语法,订正与标准Python的差异。
5、合理使用内存资源,避免频繁分配大内存块。
6、利用原生代码提升速度关键部位的性能。
7、适当使用抽象来封装底层硬件操作。

总体来说,MicroPython让Python进入了微控制器领域,是一项重要的创新,既降低了编程门槛,又提供了良好的硬件控制能力。非常适合各类物联网和智能硬件的开发。
在这里插入图片描述
达芬奇 TKM32F499是一款基于ARM Cortex-M4内核的微控制器,以下是其主要的参考技术参数:
1、内核和性能:
内核: ARM Cortex-M4
最高主频: 240 MHz
性能: 225 DMIPS / 608 CoreMark
2、存储器:
Flash存储器: 1 MB
RAM: 192 KB
存储器接口: 支持外部存储器扩展(例如,SD卡,NOR Flash等)
3、外设接口:
通用IO口(GPIO): 支持多达 101 个GPIO引脚,可用于数字输入/输出、中断等。
串行通信接口: 包括多个UART、SPI、I2C接口,用于与外部设备进行通信。
USB接口: 支持USB 2.0 FS(全速)。
定时器: 包括多个定时器/计数器,可用于定时、脉冲宽度调制(PWM)等应用。
ADC和DAC: 内置多个模数转换器(ADC)和数模转换器(DAC),用于模拟信号的采集和输出。
LCD控制器: 支持液晶显示器(LCD)的控制和驱动。
触摸控制器: 支持电容式触摸屏的控制和输入。
SD卡控制器: 支持SD卡的读写操作。
Ethernet控制器: 支持以太网通信。
4、电源管理:
电源供应: 支持广泛的电源电压范围,包括 3.0V 至 3.6V 的工作电压。
低功耗模式: 支持多种低功耗模式,以最小化功耗。
5、安全性:
安全特性: 支持硬件加密和解密、随机数生成器等安全功能,保护系统的数据和通信安全。
6、开发工具支持:
开发环境: 支持常见的开发环境,如Keil MDK、IAR Embedded Workbench等。
调试接口: 支持标准的SWD(Serial Wire Debug)调试接口。

在这里插入图片描述
MicroPython的达芬奇TKM32F499提供了硬件I2C总线功能,下面将以专业的视角为您详细解释其主要特点、应用场景以及需要注意的事项。

主要特点:

硬件实现:达芬奇TKM32F499的硬件I2C总线是通过硬件电路实现的,相比软件I2C总线,硬件I2C具有更高的性能和更稳定的时序控制。它使用专用的I2C控制器和外设接口,能够以较高的速度进行数据传输。

快速传输:硬件I2C总线支持高速数据传输,可以实现较高的通信速率。它的传输速度通常受到主频限制,能够满足对数据传输速度要求较高的应用场景,如传感器数据采集、设备控制等。

硬件协议支持:硬件I2C总线直接支持I2C协议,包括主从模式、多主模式等。它具有硬件级别的协议支持和时序控制,能够更好地满足各种外设的通信需求。

低CPU占用:硬件I2C总线的数据传输由硬件控制器完成,相比软件I2C总线,它不需要CPU的参与,因此可以减轻CPU的负担,提高系统的效率和响应速度。

应用场景:

传感器接口:硬件I2C总线适用于与各种传感器进行通信,如温度传感器、湿度传感器、加速度传感器等。通过硬件I2C总线,可以实现高速、可靠的传感器数据采集。

外设控制:硬件I2C总线广泛应用于与各种外设设备进行控制,如LCD显示屏、触摸屏、LED驱动器等。通过硬件I2C总线的高速传输和硬件协议支持,可以实现与外设的可靠通信和控制。

存储器读写:一些存储器芯片使用I2C总线进行数据读写,如EEPROM、实时时钟(RTC)等。硬件I2C总线可以提供快速、稳定的存储器访问能力,满足对存储器读写速度要求较高的应用场景。

需要注意的事项:

引脚分配:在使用硬件I2C总线时,需要正确配置引脚分配,并避免与其他功能冲突。通常,硬件I2C总线有专用的引脚用于时钟(SCL)和数据(SDA)线。

电气特性:在使用硬件I2C总线时,需要注意外设设备和主控芯片的电气特性匹配,如电压级别、电流驱动能力等。

时序参数:硬件I2C总线的时序参数(如时钟速率、起始条件等)需要根据外设设备的要求进行正确设置。时序设置错误可能导致通信失败或数据错误。

综上所述,MicroPython的达芬奇TKM32F499的硬件I2C总线具有硬件实现、快速传输、硬件协议支持和低CPU占用等特点。它适用于传感器接口、外设控制和存储器读写等应用场景。在使用硬件I2C总线时,需要注意正确的引脚分配、电气特性匹配和时序参数设置,以确保正常的通信和数据传输。

案例1:读取I2C设备数据

from machine import I2C, Pin
import time

# 初始化I2C总线
i2c = I2C(scl=Pin(5), sda=Pin(4))

# 设置I2C设备的地址
device_address = 0x68

# 向I2C设备发送数据
i2c.writeto(device_address, b'\x01')

# 从I2C设备读取数据
data = i2c.readfrom(device_address, 6)

# 打印读取到的数据
print("Data:", data)

要点解读:
导入所需的库和模块,如machine、Pin等。
初始化I2C总线,设置SCL和SDA引脚。
设置要操作的I2C设备的地址。
使用writeto()方法向设备发送数据。
使用readfrom()方法从设备读取数据。
打印读取到的数据。

案例2:控制I2C设

from machine import I2C, Pin
import time

# 初始化I2C总线
i2c = I2C(scl=Pin(5), sda=Pin(4))

# 设置I2C设备的地址
device_address = 0x68

# 向I2C设备发送数据以控制设备
i2c.writeto(device_address, b'\x01\x02\x03')

# 延时一段时间,等待设备响应
time.sleep(1)

# 再次向I2C设备发送数据以获取设备状态
status = i2c.readfrom(device_address, 1)

# 打印设备状态
print("Status:", status)

要点解读:
导入所需的库和模块,如machine、Pin等。
初始化I2C总线,设置SCL和SDA引脚。
设置要操作的I2C设备的地址。
使用writeto()方法向设备发送数据以控制设备。
使用readfrom()方法从设备读取数据以获取设备状态。
打印设备状态。

案例3:读写多个I2C设

from machine import I2C, Pin
import time

# 初始化I2C总线
i2c = I2C(scl=Pin(5), sda=Pin(4))

# 设置要操作的I2C设备的地址列表
device_addresses = [0x68, 0x69, 0x6A]

# 循环遍历设备地址列表,向每个设备发送数据并读取数据
for device_address in device_addresses:
    # 向设备发送数据
    i2c.writeto(device_address, b'\x01\x02\x03')

    # 延时一段时间,等待设备响应
    time.sleep(1)

    # 从设备读取数据
    data = i2c.readfrom(device_address, 6)

    # 打印读取到的数据
    print("Data from device {}: {}".format(device_address, data))

要点解读:
导入所需的库和模块,如machine、Pin等。
初始化I2C总线,设置SCL和SDA引脚。
设置要操作的I2C设备的地址列表。
使用循环遍历设备地址列表,向每个设备发送数据并读取数据。
使用writeto()方法向设备发送数据。
使用readfrom()方法从设备读取数据。
打印读取到的数据。

案例4:通过I2C总线读取设备寄存器

from machine import I2C  
  
# 初始化I2C总线  
i2c = I2C(scl=23, sda=22, freq=400000)  
  
# 设备地址  
DEVICE_ADDRESS = 0x50  
  
# 读取设备寄存器  
def read_device_register(register_address):  
    i2c.writeto_mem(DEVICE_ADDRESS, register_address, bytearray([0]))  # 向设备发送读寄存器命令  
    value = i2c.readfrom_mem(DEVICE_ADDRESS, register_address, 1)  # 从设备读取寄存器值  
    return value[0]  
  
# 读取寄存器0的值  
value = read_device_register(0)  
print(value)

要点解读:
首先,我们初始化了I2C总线,并指定了SCL和SDA引脚的编号以及总线频率。
然后,我们定义了设备的地址,这在I2C通信中是必要的。
接下来,我们定义了一个函数read_device_register(),该函数通过I2C总线向设备发送读寄存器命令,并从设备读取寄存器的值。
最后,我们通过调用read_device_register()函数来读取设备寄存器0的值,并将其打印出来。

案例5:通过I2C总线写入设备寄存器

from machine import I2C  
  
# 初始化I2C总线  
i2c = I2C(scl=23, sda=22, freq=400000)  
  
# 设备地址  
DEVICE_ADDRESS = 0x50  
  
# 写入设备寄存器  
def write_device_register(register_address, value):  
    i2c.writeto_mem(DEVICE_ADDRESS, register_address, bytearray([value]))  # 向设备发送写寄存器命令  
  
# 写入寄存器0的值为123  
write_device_register(0, 123)

要点解读:
同样,我们首先初始化了I2C总线。
然后,我们定义了设备的地址。
接下来,我们定义了一个函数write_device_register(),该函数通过I2C总线向设备发送写寄存器命令,并将值写入设备的寄存器。
最后,我们调用write_device_register()函数将设备寄存器0的值设置为123。

案例6:通过I2C总线读取多个设备寄存器

from machine import I2C  
  
# 初始化I2C总线  
i2c = I2C(scl=23, sda=22, freq=400000)  
  
# 设备地址  
DEVICE_ADDRESS = 0x50  
  
# 读取设备寄存器数组长度  
REGISTER_ARRAY_LENGTH = 10  
  
# 读取设备寄存器数组  
def read_device_register_array(register_address, length):  
    i2c.writeto_mem(DEVICE_ADDRESS, register_address, bytearray([length]))  # 向设备发送读寄存器数组命令和长度  
    data = i2c.readfrom_mem(DEVICE_ADDRESS, register_address + 1, length)  # 从设备读取寄存器数组数据  
    return data  
  
# 读取寄存器010的值  
values = read_device_register_array(0, REGISTER_ARRAY_LENGTH)  
print(values)

要点解读:
同样,我们首先初始化了I2C总线。
然后,我们定义了设备的地址。
接下来,我们定义了一个函数read_device_register_array(),该函数通过I2C总线向设备发送读寄存器数组的命令以及要读取的数组长度,并从设备读取指定长度的寄存器数组数据。
最后,我们调用read_device_register_array()函数来读取设备寄存器0到10的值,并将其打印出来。

案例7:I2C主设备发送数据

from machine import Pin, I2C

# 创建I2C对象
i2c = I2C(0, scl=Pin(5), sda=Pin(4), freq=100000)

# 发送数据
data = b"Hello, I2C!"
i2c.writeto(0x50, data)

要点解读:
使用machine.I2C类创建I2C对象,其中第一个参数指定I2C总线编号,第二个参数scl和sda分别指定I2C时钟和数据引脚,freq参数指定通信频率。
使用i2c.writeto方法将数据发送到指定的I2C从设备地址(这里示例地址为0x50)。

案例8:I2C主设备接收数据

from machine import Pin, I2C

# 创建I2C对象
i2c = I2C(0, scl=Pin(5), sda=Pin(4), freq=100000)

# 接收数据
buffer = bytearray(10)
i2c.readfrom_into(0x50, buffer)
print("Received data: {}".format(buffer))

要点解读:
使用machine.I2C类创建I2C对象,其中第一个参数指定I2C总线编号,第二个参数scl和sda分别指定I2C时钟和数据引脚,freq参数指定通信频率。
使用i2c.readfrom_into方法从指定的I2C从设备地址(这里示例地址为0x50)接收数据,并将数据存储在字节数组中。

案例9:I2C主设备发送和接收数据

from machine import Pin, I2C

# 创建I2C对象
i2c = I2C(0, scl=Pin(5), sda=Pin(4), freq=100000)

# 发送和接收数据
tx_data = b"Hello, I2C!"
rx_data = bytearray(len(tx_data))
i2c.writeto_then_readfrom(0x50, tx_data, rx_data)
print("Received data: {}".format(rx_data))

要点解读:
使用machine.I2C类创建I2C对象,其中第一个参数指定I2C总线编号,第二个参数scl和sda分别指定I2C时钟和数据引脚,freq参数指定通信频率。
使用i2c.writeto_then_readfrom方法同时向指定的I2C从设备地址(这里示例地址为0x50)发送数据并接收数据,将发送的数据存储在一个字节字符串中,接收的数据存储在一个字节数组中。
以上代码示例展示了在达芬奇TKM32F499上使用MicroPython进行硬件I2C总线通信的实际应用。您可以根据需求和实际情况,使用这些示例代码作为起点进行修改和扩展。请注意,具体的I2C总线编号、引脚配置和通信频率可能会因硬件的不同而有所变化,请参考您的硬件文档以及MicroPython的文档以获取更详细的信息。

请注意,以上案例只是为了拓展思路,可能存在错误或不适用的情况。不同的硬件平台、使用场景和MicroPython版本可能会导致不同的使用方法。在实际编程中,您需要根据您的硬件配置和具体需求进行调整,并进行多次实际测试。需要正确连接硬件并了解所使用的传感器和设备的规范和特性非常重要。对于涉及到硬件操作的代码,请确保在使用之前充分了解和确认所使用的引脚和电平等参数的正确性和安全性。

在这里插入图片描述