【雕爷学编程】MicroPython手册之 SAMD21 计时器 Timers

在这里插入图片描述
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进入了微控制器领域,是一项重要的创新,既降低了编程门槛,又提供了良好的硬件控制能力。非常适合各类物联网和智能硬件的开发。
在这里插入图片描述
SAMD21是一系列使用32位ARM® Cortex®-M0+处理器的低功耗微控制器,由Microchip Technology公司开发。SAMD21的技术参数如下:

1、处理器:32位ARM® Cortex®-M0+,最高工作频率为48MHz,每兆赫兹可达2.46 Coremark。
2、存储器:闪存容量从32KB到256KB不等,SRAM容量从4KB到32KB不等。
3、电源管理:支持多种低功耗模式,如空闲和待机模式,最低功耗为3.5μA/MHz。
4、外设:拥有丰富的智能和灵活的外设,如直接内存访问控制器(DMAC)、事件系统、定时器/计数器(TC/TCC)、实时时钟(RTC)、看门狗定时器(WDT)、CRC-32生成器、通用串行总线(USB)2.0接口、串行通信接口(SERCOM)、Inter-IC Sound(I2S)接口、模数转换器(ADC/DAC)、模拟比较器(AC)和外设触摸控制器(PTC)。
5、封装:支持多种封装形式,从32引脚到64引脚不等,包括TQFP、QFN、UFBGA和WLCSP。
6、标准:符合AEC-Q100 Grade 1的汽车级标准,工作温度范围为-40°C到+125°C。

在这里插入图片描述
MicroPython的SAMD21计时器(Timers)是指在SAMD21微控制器上使用MicroPython语言进行定时和计时操作的功能模块。

主要特点:

多个计时器通道:SAMD21微控制器通常具有多个计时器通道,每个通道都可以独立配置和控制。这些通道可以同时运行不同的定时和计时任务,提供灵活的时间管理。
精确的时间测量:SAMD21计时器模块提供高精度的时间测量能力,可以实现微秒甚至更小时间单位的计时。这使得开发者可以进行精确的时间测量和控制。
多种计时模式:SAMD21计时器支持多种计时模式,如定时器模式、计数器模式和PWM输出模式等。这使得计时器可以适应不同的应用需求,如定时触发事件、测量时间间隔以及产生PWM信号等。

应用场景:

实时控制系统:SAMD21计时器广泛应用于实时控制系统中,如工业自动化、机器人控制等。通过计时器模块,可以实现精确的定时触发和时间测量,用于控制系统的同步和协调。
通信协议实现:在通信协议的实现中,计时器模块常用于生成精确的时间窗口和时序控制。通过SAMD21计时器的PWM输出模式,可以实现各种通信协议的时序生成和调整。
脉冲测量和频率计数:SAMD21计时器的计数器模式可用于测量脉冲宽度和频率。这在许多应用中很有用,如测量传感器输出的脉冲宽度、计数外部事件的频率等。

扫描二维码关注公众号,回复: 16960077 查看本文章

注意事项:

计时器通道选择:SAMD21微控制器通常具有多个计时器通道,开发者在使用计时器功能时需要选择合适的通道。根据应用需求和资源分配,选择合适的计时器通道进行配置和控制。
中断处理:计时器操作通常涉及中断处理。开发者需要合理处理计时器中断,并确保计时器操作不会受到其他中断的干扰。
定时器溢出:SAMD21计时器在特定计时范围内会发生溢出。开发者在使用定时器模式时,需要注意处理定时器溢出的情况,以确保计时器的准确性和稳定性。

综上所述,MicroPython的SAMD21计时器模块利用SAMD21微控制器丰富的计时器资源和MicroPython语言的支持,提供灵活的定时和计时功能。适用于实时控制系统、通信协议实现以及脉冲测量和频率计数等应用场景。在使用计时器功能时,需要注意计时器通道选择、中断处理以及定时器溢出等问题,以确保计时器的准确性和可靠性。

在这里插入图片描述

在MicroPython中,我们可以使用SAMD21微控制器的计时器功能来实现精确的时间控制。以下是几个实际运用程序参考代码案例:

案例一:使用machine.Pin()设置引脚为输入模式

import machine

pin = machine.Pin(2, machine.Pin.IN)  # 设置引脚2为输入模式

重点解读:这个程序使用machine.Pin()函数创建一个引脚对象,然后通过Pin.IN参数设置引脚为输入模式。在这个例子中,我们将引脚2设置为输入模式,以便读取外部信号。

案例二:使用timer.delay()实现延迟

import time

time.sleep(2)  # 延迟2秒
print("延迟结束")

重点解读:这个程序使用Python内置的time.sleep()函数实现延迟,参数为延迟的秒数。在这个例子中,程序会暂停2秒后再继续执行。

案例三:使用machine.RTC()获取当前时间

import machine

rtc = machine.RTC()
print("当前时间:", rtc.datetime())

重点解读:这个程序使用machine.RTC()函数创建一个实时时钟对象,然后通过datetime()方法获取当前时间并打印出来。

案例四:使用timer.Timer()实现定时器

import machine
from machine import Pin, Timer

def task():
    print("任务执行")

pin = Pin(2, Pin.OUT)  # 设置引脚2为输出模式
timer = Timer(-1)  # 创建一个定时器,初始值为-1,表示立即执行

timer.init(period=1000, mode=Timer.PERIODIC, callback=task)  # 初始化定时器,周期为1000毫秒(1秒),模式为周期性,回调函数为task

重点解读:这个程序使用machine模块中的Pin和Timer类实现定时器功能。首先,我们设置引脚2为输出模式,然后创建一个定时器对象,指定周期为1000毫秒(1秒),并设置回调函数为task。当定时器到达设定的周期时,会自动执行回调函数task。

案例五:使用定时器产生PWM信号

import machine  
import utime  
  
# 初始化定时器  
pwm = machine.PWM(13)  # PWM通道13  
  
# 设置PWM占空比  
pwm.duty(512)  
  
# 启动定时器  
pwm.freq(100)  # PWM频率100Hz  
pwm.start()  
  
# 主循环  
while True:  
    utime.sleep(1)  # 延迟1秒  
    pwm.duty(512)  # 更新PWM占空比

要点解读:
导入machine和utime模块。
使用machine.PWM()初始化PWM模块,并指定PWM通道(在本例中为13)。
使用pwm.duty()设置PWM的占空比,这里设置为512,可以根据需要调整。
使用pwm.freq()设置PWM的频率,这里设置为100Hz。
使用pwm.start()启动PWM输出。
在主循环中,使用utime.sleep()进行延时,这里延时1秒。然后使用pwm.duty()更新PWM的占空比。可以根据需求调整占空比以实现不同的PWM信号输出。

案例六:使用定时器实现滴答时钟

import machine  
import utime  
  
# 时钟显示缓冲区  
clock_buf = bytearray(6)  
  
# 初始化定时器  
timer = machine.Timer(3)  # Timer3  
timer.init(period=1000000, mode=machine.Timer.ONE_SHOT, callback=lambda t: update_clock())  
  
# 定义更新时钟的函数  
def update_clock():  
    hour = (utime.time() // 3600) % 12  
    minute = (utime.time() // 60) % 60  
    second = utime.time() % 60  
    clock_buf[0] = (hour >> 4) & 0x0F  # 存储小时十位  
    clock_buf[1] = hour & 0x0F  # 存储小时个位  
    clock_buf[2] = (minute >> 4) & 0x0F  # 存储分钟十位  
    clock_buf[3] = minute & 0x0F  # 存储分钟个位  
    clock_buf[4] = (second >> 4) & 0x0F  # 存储秒钟十位  
    clock_buf[5] = second & 0x0F  # 存储秒钟个位  
    machine.I2C(scl=machine.Pin(22), sda=machine.Pin(21), freq=400000)  # 初始化I2C总线  
    i2c = machine.I2C()  # 创建I2C对象  
    i2c.writeto_mem(0x4, clock_buf, byteorder='big')  # 向I2C总线写入时钟数据  
    i2c.close()  # 关闭I2C总线  
  
# 主循环  
while True:  
    utime.sleep(1)  # 延迟1秒

要点解读:
导入machine和utime模块。
使用machine.Timer(3)初始化定时器3。
使用timer.init()函数设置定时器的周期为1秒(1000000微秒),模式为一次触发(machine.Timer.ONE_SHOT),并指定回调函数为update_clock()。

案例七:使用Timer模块实现LED闪烁

from machine import Pin, Timer

led = Pin('D13', Pin.OUT) # 创建输出引脚对象,连接到D13
tim = Timer(1) # 创建定时器对象,编号为1
duty = 0 # 初始化占空比为0

def pwm(t): # 定义PWM控制函数
    global duty # 声明全局变量duty
    duty = (duty + 1) % 101 # 更新占空比,范围为0-100
    if duty < 50: # 如果占空比小于50%
        led.on() # 设置引脚为高电平,点亮LED
    else: # 如果占空比大于等于50%
        led.off() # 设置引脚为低电平,熄灭LED

tim.init(freq=100, mode=Timer.PERIODIC, callback=pwm) # 初始化定时器,频率为100Hz,模式为周期性,回调函数为pwm

这个案例使用了Timer模块,它可以创建和控制硬件定时器对象。Timer模块有一个参数,是定时器的编号,SAMD21有4个定时器,编号为0-3。定时器对象有init方法,它可以接受三个参数,freq是定时器的频率,mode是定时器的模式,可以是Timer.ONE_SHOT或Timer.PERIODIC,callback是定时器触发时执行的函数。这个案例实现了一个简单的PWM控制器,它可以改变LED的亮度。PWM是一种调制技术,它通过改变占空比来控制输出电平的平均值。占空比是指输出电平为高的时间占总周期的百分比。这个案例中,定时器每10毫秒触发一次回调函数pwm,回调函数中更新占空比,并根据占空比设置引脚的电平。

案例八:使用Timer模块实现温度测量

from machine import Pin, Timer, ADC
import math

adc = ADC(Pin('A0')) # 创建ADC对象,连接到A0引脚
tim = Timer(2) # 创建定时器对象,编号为2

def measure(t): # 定义温度测量函数
    value = adc.read() # 读取ADC值
    voltage = value * 3.3 / 1024 # 计算输入电压
    resistance = (3.3 - voltage) * 10000 / voltage # 计算热敏电阻阻值
    temp = 1 / (math.log(resistance / 10000) / 3950 + 1 / 298.15) - 273.15 # 计算温度
    print('Temperature: {:.2f} C'.format(temp)) # 打印温度

tim.init(freq=1, mode=Timer.PERIODIC, callback=measure) # 初始化定时器,频率为1Hz,模式为周期性,回调函数为measure

这个案例使用了ADC模块和Timer模块,它们可以创建和控制模拟数字转换器和硬件定时器对象。ADC模块有一个参数,是ADC的引脚标识符。SAMD21有6个ADC通道,分别对应A0-A5引脚。ADC对象有read方法,它可以返回一个0-1023之间的整数值。Timer模块和上一个案例中一样。这个案例实现了一个简单的温度测量器,它可以使用热敏电阻测量环境温度。热敏电阻是一种阻值随温度变化的电阻器,它可以用斯坦哈特方程描述。这个案例中,热敏电阻和一个10k欧姆的电阻器组成一个分压电路,ADC读取分压点的电压,然后根据电压计算热敏电阻的阻值和温度。定时器每秒触发一次回调函数measure,回调函数中读取ADC值并打印温度。

案例九:使用Timer模块实现蜂鸣器播放音乐

from machine import Pin, Timer
import music

buzzer = Pin('D12', Pin.OUT) # 创建输出引脚对象,连接到D12
tim = Timer(3) # 创建定时器对象,编号为3

def play(t): # 定义播放音乐函数
    global index # 声明全局变量index
    if index < len(music.song): # 如果索引小于歌曲长度
        note = music.song[index] # 获取当前音符
        if note > 0: # 如果音符不为0
            tim.init(freq=note, mode=Timer.PERIODIC, callback=lambda t: buzzer.toggle()) # 初始化定时器,频率为音符频率,模式为周期性,回调函数为切换引脚电平
        else: # 如果音符为0
            tim.deinit() # 停止定时器
            buzzer.off() # 设置引脚为低电平
        index += 1 # 索引加一
    else: # 如果索引大于等于歌曲长度
        tim.deinit() # 停止定时器
        buzzer.off() # 设置引脚为低电平

index = 0 # 初始化索引为0
tim.init(freq=1000, mode=Timer.PERIODIC, callback=play) # 初始化定时器,频率为1000Hz,模式为周期性,回调函数为play

这个案例使用了Timer模块和music模块,它们可以创建和控制硬件定时器对象和音乐数据对象。music模块提供了一个song列表,它包含了一首歌曲的音符频率。Timer模块和前面的案例中一样。这个案例实现了一个简单的蜂鸣器播放音乐器,它可以使用PWM信号驱动蜂鸣器发出声音。PWM信号的频率决定了声音的音高,PWM信号的占空比决定了声音的响度。这个案例中,定时器每毫秒触发一次回调函数play,回调函数中根据歌曲列表中的音符设置定时器的频率,并切换引脚的电平。如果音符为0,则表示休止符,停止定时器并设置引脚为低电平。如果索引超过歌曲长度,则表示歌曲结束,停止定时器并设置引脚为低电平。

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

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_41659040/article/details/133433614