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进入了微控制器领域,是一项重要的创新,既降低了编程门槛,又提供了良好的硬件控制能力。非常适合各类物联网和智能硬件的开发。
Teensy 4.1是一款基于ARM Cortex-M7的高性能开发板,具有以下特点:
1、处理器:Teensy 4.1使用了恩智浦的i.MX RT1060处理器,它是一款交叉处理器,具有微控制器的功能,速度与微型计算机相当。它的运行频率高达600 MHz,可提供高达3000 DMIPS的性能,以及浮点运算单元和加密加速器。
2、内存:Teensy 4.1配备了1024 KB的RAM(其中512 KB是紧密耦合的),8 MB的Flash(其中64 KB用于恢复和EEPROM模拟),以及两个位置可以选择添加更多的QSPI内存芯片。
3、I/O引脚:Teensy 4.1共有55个数字输入/输出引脚,其中35个支持PWM输出,18个支持模拟输入。它还提供了8个串口,3个SPI端口,3个I2C端口,2个I2S/TDM数字音频端口,3个CAN总线(其中一个支持CAN FD),以及一个SDIO(4位数据)原生SD卡端口12。
4、以太网:Teensy 4.1包含了一个以太网控制器和一个以太网PHY芯片(DP83825),支持10/100 Mbit的速度。连接以太网电缆只需要一个RJ45磁插孔套件。
5、USB主机:Teensy 4.1提供了一个USB主机端口,支持480 Mbit/sec的速度。它可以连接USB设备,如键盘、鼠标、MIDI设备等。
6、RTC:Teensy 4.1支持实时时钟(RTC),可以通过连接一个3V纽扣电池来保持日期和时间。
7、LED:Teensy 4.1有一个内置的GPIO指示灯LED,连接在引脚13上。
MicroPython是一种在嵌入式系统上运行的解释型编程语言,而Teensy 4.1是一款强大的开发板,支持MicroPython。
主要特点:
引脚多样性:Teensy 4.1开发板配备了丰富的GPIO引脚。这些引脚可以用于输入和输出,支持数字信号和模拟信号,以及各种通信协议(如UART、SPI、I2C等)。这种多样性使得开发者可以根据具体需求连接各种外设和传感器。
灵活的GPIO控制:MicroPython提供了简单而灵活的API,用于控制Teensy 4.1的GPIO引脚。开发者可以轻松地配置引脚的输入/输出模式、读取和写入引脚状态,并实现各种功能,如脉冲宽度调制(PWM)和中断处理。
中断支持:Teensy 4.1的GPIO引脚支持中断功能。开发者可以配置引脚的中断触发条件,并编写中断处理程序,以响应特定事件的发生,如按键按下、传感器触发等。
应用场景:
外设控制:Teensy 4.1的GPIO引脚可用于控制各种外设,如LED、电机、传感器等。通过配置引脚的输入/输出模式和状态,开发者可以实现与外设的交互和控制。
通信协议:Teensy 4.1的GPIO引脚支持多种通信协议,如UART、SPI和I2C。开发者可以使用这些引脚与其他设备进行串行通信、数据传输和设备之间的信息交换。
事件触发和响应:通过配置GPIO引脚的中断触发条件,开发者可以实现基于事件的响应机制。例如,可以使用中断来捕捉按键按下、传感器触发或其他特定事件,并在中断处理程序中执行相应的操作。
需要注意的事项:
引脚功能冲突:在使用Teensy 4.1的GPIO引脚时,需要注意引脚功能之间的冲突。某些引脚可能具有特定的默认功能或与其他模块共享功能。在配置引脚时,要确保避免冲突,合理规划和配置引脚的功能。
引脚电压和电流:在连接外设和传感器时,需要注意引脚的电压和电流要求。确保外设和传感器的工作电压和电流不超过Teensy 4.1引脚的额定值,以防止损坏引脚或设备。
引脚保护:为了保护Teensy 4.1的GPIO引脚,可以采取一些保护措施,如使用限流电阻、电压分压电路或外部保护器件。这有助于防止过电流、过压等情况对引脚和开发板造成损害。
综上所述,MicroPython的Teensy 4.1引脚和GPIO具有多样性、灵活的控制和中断支持等特点,适用于外设控制、通信协议和事件触发响应等应用场景。在使用引脚和GPIO时,需要注意引脚功能冲突、引脚电压和电流要求,以及引脚保护等事项,以确保安全、可靠地使用Teensy 4.1开发板的引脚功能。
案例1:使用GPIO控制LED灯
import machine
import time
# 初始化MCU
dut = machine.Pin(2, machine.Pin.OUT)
# 设置GPIO模式为输出
dut.mode(machine.Pin.OUT)
# 循环控制LED灯的亮灭
while True:
dut.value(1) # 点亮LED灯
time.sleep(1) # 延时1秒
dut.value(0) # 熄灭LED灯
time.sleep(1) # 延时1秒
解读:这个程序首先导入了machine和time模块。然后,我们使用machine.Pin()函数创建一个Pin对象,指定引脚为GPIO2,输出模式为True。接着,我们使用dut.mode()函数将GPIO的模式设置为输出。在主循环中,我们使用dut.value()函数控制LED灯的亮灭状态,并使用time.sleep()函数进行延时。
案例2:使用ADC读取模拟信号值
import machine
# 初始化MCU
dut = machine.Pin(2, machine.Pin.IN)
# 配置ADC
adc = machine.ADC(dut)
adc.atten(machine.ADC.ATTN_11DB)
adc.mode(machine.ADC.MODE_SINGLE)
# 循环读取ADC值
while True:
adc_value = adc.read()
print("ADC value:", adc_value)
time.sleep(1) # 延时1秒
解读:这个程序首先导入了machine模块。然后,我们使用machine.Pin()函数创建一个Pin对象,指定引脚为GPIO2,输入模式为True。接着,我们使用machine.ADC()函数创建一个ADC对象,并将之前创建的Pin对象作为输入引脚。然后,我们使用adc.atten()函数设置ADC的衰减值为11分贝,使用adc.mode()函数设置ADC的模式为单次转换模式。在主循环中,我们使用adc.read()函数读取ADC的值,并将其保存在变量adc_value中。最后,我们使用print()函数输出ADC的值,并使用time.sleep()函数进行延时。
案例3:使用PWM控制电机转速
import machine
from machine import Pin, PWM
# 初始化MCU
motor_pin = Pin(5, Pin.OUT)
pwm = PWM(Pin(6), freq=1000, duty=77)
# 循环控制电机转速
while True:
pwm.duty(77) # 设置占空比为77%
time.sleep(1) # 延时1秒
pwm.duty(100) # 设置占空比为100%
time.sleep(1) # 延时1秒
解读:这个程序首先导入了machine模块和Pin、PWM类。然后,我们使用Pin()函数创建一个Pin对象,指定引脚为GPIO5,输出模式为True。接着,我们使用PWM()函数创建一个PWM对象,指定时钟线为Pin 6,频率为1kHz,初始占空比为50%。在主循环中,我们使用pwm.duty()函数设置PWM的占空比,并使用time.sleep()函数进行延时。
案例4:使用引脚控制LED亮度
import machine
import time
import pwmio
led = machine.Pin(13, machine.Pin.OUT) # 将13号引脚配置为输出模式,连接LED
pwm = pwmio.PWMOut(led, freq=100) # 将13号引脚配置为PWM输出模式,连接LED,设置PWM频率为100Hz
while True:
for duty in range(0, 1024, 64): # 占空比从0变化到1023,每次变化64
pwm.duty_u16(duty) # 设置PWM占空比,控制LED亮度
time.sleep_ms(20) # 延时20毫秒,等待LED亮度变化到位
要点解读:此代码使用引脚控制LED亮度。首先将13号引脚配置为输出模式,然后将其配置为PWM输出模式,并设置PWM频率为100Hz。在无限循环中,使用for循环控制PWM占空比从0变化到1023,每次变化64,从而控制LED亮度变化。使用time.sleep_ms函数延时20毫秒,等待LED亮度变化到位。
案例5:使用引脚读取按键状态
import machine
button = machine.Pin(2, machine.Pin.IN, machine.Pin.PULL_UP) # 将2号引脚配置为输入模式,连接按键,并启用上拉电阻
while True:
if button.value() == 0: # 如果按键被按下
print('Button pressed')
else: # 如果按键未被按下
print('Button not pressed')
time.sleep(1) # 延时1秒,等待下次按键事件
要点解读:此代码使用引脚读取按键状态。首先将2号引脚配置为输入模式,连接按键,并启用上拉电阻。在无限循环中,使用value方法读取按键状态,如果按键被按下则打印出“Button pressed”,否则打印出“Button not pressed”。使用time.sleep函数延时1秒,等待下次按键事件。
案例6:使用GPIO控制RGB LED颜色变化
import machine
import time
import pwmio
red = machine.Pin(4, machine.Pin.OUT) # 将4号引脚配置为输出模式,连接红色LED
green = machine.Pin(5, machine.Pin.OUT) # 将5号引脚配置为输出模式,连接绿色LED
blue = machine.Pin(6, machine.Pin.OUT) # 将6号引脚配置为输出模式,连接蓝色LED
pwm_red = pwmio.PWMOut(red, freq=50) # 将4号引脚配置为PWM输出模式,连接红色LED,设置PWM频率为50Hz
pwm_green = pwmio.PWMOut(green, freq=50) # 将5号引脚配置为PWM输出模式,连接绿色LED,设置PWM频率为50Hz
pwm_blue = pwmio.PWMOut(blue, freq=50) # 将6号引脚配置为PWM输出模式,连接蓝色LED,设置PWM频率为50Hz
while True:
for r in range(256): # 红色LED亮度从0到255变化
pwm_red.duty_u16(r * 100)
pwm_green.duty_u16((255 - r) * 100) # 绿色LED亮度与红色LED亮度互补
pwm_blue.duty_u16(0) # 蓝色LED亮度为0
time.sleep_ms(10) # 延时10毫秒
for g in range(256): # 绿色LED亮度从0到255变化
pwm_red.duty_u16(0) # 红色LED亮度为0
pwm_green.duty_u16(g * 100)
pwm_blue.duty_u16((255 - g) * 100) # 蓝色LED亮度与绿色LED亮度互补
time.sleep_ms(10) # 延时10毫秒
for b in range(256): # 蓝色LED亮度从0到255变化
pwm_red.duty_u16((255 - b) * 100) # 红色LED亮度与蓝色LED亮度互补
pwm_green.duty_u16(0) # 绿色LED亮度为0
pwm_blue.duty_u16(b * 100)
time.sleep_ms(10) # 延时10毫秒
要点解读:此代码使用GPIO控制RGB LED颜色变化。首先将4、5、6号引脚分别配置为输出模式,然后将其分别配置为PWM输出模式,并设置PWM频率为50Hz。在无限循环中,使用三个for循环分别控制红色、绿色、蓝色LED的亮度变化。在每个for循环中,使用duty_u16方法设置PWM占空比,从而控制LED亮度变化。使用time.sleep_ms函数延时10毫秒,等待LED亮度变化到位。在红色LED亮度变化时,绿色LED亮度与红色LED亮度互补,蓝色LED亮度为0;在绿色LED亮度变化时,红色LED亮度为0,蓝色LED亮度与绿色LED亮度互补;在蓝色LED亮度变化时,红色LED亮度与蓝色LED亮度互补,绿色LED亮度为0。这样就实现了RGB LED颜色的循环变化。
案例7:使用Teensy 4.1的内置LED灯实现呼吸灯效果1。这个案例中,我们需要导入machine, math和utime模块,然后创建一个PWM对象,指定连接LED灯的引脚为13。接下来,我们使用一个while循环,不断地计算PWM的占空比,根据数学公式将正弦波的幅度映射为亮度值。然后我们调用duty_u16方法,将占空比输出到LED灯上,并等待一段时间。代码如下:
import machine, math, utime
# 创建PWM对象,连接LED灯的引脚为13
pwm = machine.PWM(machine.Pin(13))
# 设置PWM的频率为1000 Hz
pwm.freq(1000)
while True:
for i in range(256):
# 计算PWM的占空比
duty = int((math.sin(i / 256 * math.pi) + 1) * 32767)
# 将占空比输出到LED灯上
pwm.duty_u16(duty)
# 等待一段时间
utime.sleep_ms(10)
案例8:使用Teensy 4.1的内置温度传感器测量温度,并在OLED屏幕上显示2。这个案例中,我们需要导入machine, utime和ssd1306模块,然后创建一个ADC对象,指定连接温度传感器的引脚为A10。接下来,我们创建一个I2C对象,指定连接OLED屏幕的引脚为SCL和SDA。然后,我们创建一个SSD1306对象,指定屏幕的宽度和高度为128和64。接下来,我们定义一个函数read_temp,它接受一个参数adc,表示ADC对象。在这个函数中,我们读取ADC的值,并根据公式将其转换为摄氏温度。最后,我们使用一个while循环,不断地调用read_temp函数,获取温度值,并在OLED屏幕上显示。代码如下:
import machine, utime, ssd1306
# 创建ADC对象,连接温度传感器的引脚为A10
adc = machine.ADC(machine.Pin(34))
# 创建I2C对象,连接OLED屏幕的引脚为SCL和SDA
i2c = machine.I2C(scl=machine.Pin(19), sda=machine.Pin(18))
# 创建SSD1306对象,指定屏幕的宽度和高度为128和64
oled = ssd1306.SSD1306_I2C(128, 64, i2c)
def read_temp(adc):
# 读取ADC的值
value = adc.read()
# 将ADC的值转换为摄氏温度
temp = (value - 0.7012) / 0.001646
# 返回温度值
return temp
while True:
# 调用read_temp函数,获取温度值
temp = read_temp(adc)
# 清除OLED屏幕
oled.fill(0)
# 在OLED屏幕上显示温度值
oled.text("Temp: {:.1f} C".format(temp), 0, 0)
# 更新OLED屏幕
oled.show()
# 等待一秒
utime.sleep(1)
案例9:使用Teensy 4.1的内置SD卡槽读写文件3。这个案例中,我们需要导入os, sdcard和machine模块,然后创建一个SDCard对象,指定连接SD卡槽的引脚为SCK, MISO, MOSI和CS。接下来,我们使用os模块的mount方法,将SD卡挂载到文件系统中。然后,我们使用open函数,创建一个名为test.txt的文件,并写入一些内容。接下来,我们使用os模块的listdir方法,列出SD卡中的文件。最后,我们使用open函数,打开test.txt文件,并读取其中的内容。代码如下:
import os, sdcard, machine
# 创建SDCard对象,连接SD卡槽的引脚为SCK, MISO, MOSI和CS
sd = sdcard.SDCard(machine.SPI(1), machine.Pin(10))
# 将SD卡挂载到文件系统中
os.mount(sd, "/sd")
# 创建一个名为test.txt的文件,并写入一些内容
with open("/sd/test.txt", "w") as f:
f.write("Hello, Teensy 4.1!")
# 列出SD卡中的文件
print(os.listdir("/sd"))
# 打开test.txt文件,并读取其中的内容
with open("/sd/test.txt", "r") as f:
print(f.read())
请注意,以上案例只是为了拓展思路,可能存在错误或不适用的情况。不同的硬件平台、使用场景和MicroPython版本可能会导致不同的使用方法。在实际编程中,您需要根据您的硬件配置和具体需求进行调整,并进行多次实际测试。确保正确连接硬件并了解所使用的传感器和设备的规范和特性非常重要。