目录
前言:
一、开发环境的快速搭建:
二、基本实验:
1、点亮小灯:
2、流水灯:
3、按键
4.外部中断:
5.定时器:
本人所用为01 studio的pyAi-K210和pyAI-OpenMV4,本人在学习完K210后,学习openMV时发现很多实验K210和openMV可以一起学习,所以写下此篇分享,本人基本都是个人笔记,非常希望有大佬提出错误和改进之处,但大佬轻喷哈!!!
此处官方例程已经很保姆级了,此处就不在多说。
学习前的必要知识点:OpenMV4的引脚应用和一般单片机相同且是固定的,但是pyAI-K210的引脚是自由映射的,有完全的自主性,具体的可以查考:https://wiki.sipeed.com/soft/maixpy/zh/api_reference/Maix/fpioa.html
机型 | pyAI-OpenMV4 | pyAI-K210 |
LED的基本描述 | 一共有四个LED,分别是LED1(红色)、LED2(绿色)、LED3(蓝 色)和 LED4(红外拍照灯) | 一共有三个LED,三色一体 LED。分别是 LED_B(蓝色,IO12)、LED_G(绿色,IO13)、LED_R(红色,IO14) |
构造函数 | pyb.LED(id) | fm.register(pin,function,force=False) GPIO(ID,MODE,PULL,VALUE) |
使用方法 | LED.on() #点亮LED,输出低电平 LED.off() #关闭LED,输出高电平 LED。toggle() #LED亮灭状态翻转,输出电平翻转 |
fm.register(pin,function,force=False) [pin]芯片外部IO [function]芯片功能 [force]=True则强制性注册,清除之前的注册记录; GPIO(ID,MODE,PULL,VALUE) [ID]内部GPIO 编号; [MODE]GPIO 模式; GPIO.IN:输出模式 GPIO.OUT:输入模式 [PULL]上下拉电阻配置 GPIO.PULL_UP:上拉 GPIO.PULL_DOWN:下拉 GPIO.PULL_NONE:无 [value]GPIO初始化电平 1:高电平 0:低电平 *输入模式时候参数为空,表示获取当前 IO 输入电平值。 |
补充模块:
构造函数 | utime() #时间模块,直接导入使用 |
使用方法 | utime.sleep(seconds) #秒级延时,sencnds:延时秒数 utime.sleep_ms(ms) #毫秒级延时,ms:延时毫秒数 utime.sleep_us(us) #微秒级延时,us:延时微秒数 |
以下为官方代码:其中可以对着原理图进行修改,点亮其他颜色的小灯。
# todo OpenMV4
from pyb import LED #从 pyb 导入 LED 模块
import utime #导入延时模块 utime
#关闭全部 LED
LED(2).off()
LED(3).off()
#while True 表示一直循环
while True:
#LED2 亮 1 秒
LED(2).on()
utime.sleep(1)
LED(2).off()
#LED3 亮 1 秒
LED(3).on()
utime.sleep(1)
LED(3).off()
# todo K210
from Maix import GPIO
from fpioa_manager import fm
#将蓝灯引脚 IO12 配置到 GPIO0,K210 引脚支持任意配置
fm.register(12, fm.fpioa.GPIO0,force=True)
LED_B = GPIO(GPIO.GPIO0, GPIO.OUT) #构建 LED 对象
LED_B.value(0) #点亮 LED
所使用的构造函数都不变:
官方代码如下:
# todo OpenMV
from pyb import LED #从 pyb 导入 LED 模块
import utime
#关闭全部 LED
LED(2).off()
LED(3).off()
#while True 表示一直循环
while True:
#LED2 亮 1 秒
LED(2).on()
utime.sleep(1)
LED(2).off()
#LED3 亮 1 秒
LED(3).on()
utime.sleep(1)
LED(3).off()
# todo K210
from Maix import GPIO
from fpioa_manager import fm
import utime
#将将 LED 外部 IO 注册到内部 GPIO,K210 引脚支持任意配置
fm.register(12, fm.fpioa.GPIO0)
fm.register(13, fm.fpioa.GPIO1)
fm.register(14, fm.fpioa.GPIO2)
LED_B = GPIO(GPIO.GPIO0, GPIO.OUT,value=1) #构建 LED 对象
LED_G = GPIO(GPIO.GPIO1, GPIO.OUT,value=1) #构建 LED 对象
LED_R = GPIO(GPIO.GPIO2, GPIO.OUT,value=1) #构建 LED 对象
while True:
#蓝灯亮 1 秒
LED_B.value(0) #点亮 LED
utime.sleep(1)
LED_B.value(1) #关闭 LED
#绿灯亮 1 秒
LED_G.value(0) #点亮 LED
utime.sleep(1)
LED_G.value(1) #关闭 LED
#红灯亮 1 秒
LED_R.value(0) #点亮 LED
utime.sleep(1)
LED_R.value(1) #关闭 LED
按键是最简单也最常见的输入设备,很多产品都离不开按键。------->使用微处理器的GPIO的输入/输出,进而对按键进行操作控制其他元件/代码运行.
机型 | pyAI-OpenMV4 | pyAI-K210 |
基本描述 | GPIO 对象使用非常简单,我们将按键即“P9”引脚配置成输入,实现当检测 到按键被按下时候执行对应代码即可。 | 按键 KEY 的一端连接到 K210 的外部 IO16,另一端连接 到 GND。所以按键在没按下时候输入高电平(1),按下时候输入低电平(0)。 |
构造函数 | pyb.Pin(id,mode,pull_mode) 【id】引脚号,如'P0','P1'; 【mode】输入输出模式选择 Pin.IN:输入模式 Pin.OUT_PP:输出带推挽 【pull_mode】上下拉电阻配置 Pin.PULL_UP:上拉电阻 Pin.PULL_DOWN:下拉电阻 Pin。PULL——NONE:没上下拉电阻 Eg:KEY=Pin('P9',Pin.IN,Pin.PULL_UP) #将按键“P9”配置为输入上拉模式 |
GPIO(ID,MODE,PULL,VALUE) 【ID】内部GPIO编号 【MODE】GPIO模式 GPIO.IN:输入模式 GPIO.OUT:输出模式 【PULL】上下拉电阻 GPIO.PULL_UP:上拉 GPIO.PULL_DOWN:下拉 GPIO.PULL_NONE:无 【value】GPIO初始化电平 1:高电平 0:低电平 |
使用方法 | Pin.high()---->引脚输出高电平 Pin.low()------>引脚输出为低电平 Pin.value()--->获取当前引脚的输入电平,返回0(低电平)或者1(高电平)。仅在引脚配置为输入模式有效。 |
GPIO.value([value]) 【value】GPIO输出电平值 1:高电平 0:低电平 #输入模式时候参数为空,表示获取当前IO输入电平值。 |
官方代码如下:
# todo OpenMV4
'''
导入 Pin 模块
配置按键引脚为输入模式
检测按键是否被按下
若按下则点亮 LED,否则关闭
'''
from pyb import Pin,LED
#将 KEY 按键"P9"配置为输入方式
KEY = Pin('P9', Pin.IN, Pin.PULL_UP)
while True:
if KEY.value()==0: #按键被按下接地
LED(3).on() #点亮 LED(3)蓝灯
else:
LED(3).off() #关闭 LED(3)蓝灯
# todo K210
'''
导入 GPIO 模块
配置按键引脚为输入模式
检测按键是否被按下
若按下则点亮 LED 蓝灯,否则关闭
'''
from Maix import GPIO
from fpioa_manager import fm
#注册 IO,蓝灯-->IO12,KEY-->IO16
fm.register(12, fm.fpioa.GPIO0)
fm.register(16, fm.fpioa.GPIO1)
#初始化 IO
LED_B = GPIO(GPIO.GPIO0, GPIO.OUT)
KEY = GPIO(GPIO.GPIO1, GPIO.IN)
while True:
if KEY.value()==0: #按键被按下接地
LED_B.value(0) #点亮 LED_B,蓝灯
else:
LED_B.value(1) #熄灭 LED
在上一个例程中我们,在普通按键(GPIO)时候,可以实现IO口的输入/出功能,但是代码是一直在运行且检查IO口的变化,这样在实际开发中的开发效率并不高,而在一些特殊情况下,按键使用情况相对较少,就没必要让代码一直检查IO口的输入/出情况了,这样就引入了外部中断。
简而言之,就是按下按键才执行相应代码,其他情况不执行代码。
机型 | pyAI-OpenMV4 | pyAI-K210 |
基本描述 | 利用中断方式来检查按键 KEY 状态,被按键被按下(产生外部中断)后使相应代码运行 | 利用中断方式来检查按键 KEY 状态,按键被按下(产生外部中断)后使代码运行 |
构造函数 | pyb.Extlnt(pin,mode,pull_mode,callback) 外部中断 Extlnt 对象在pyb模块下。 【pin】引脚号,如'P0','P1'; 【mode】中断触发方式 Extlnt.IRQ_RISING:上升沿触发 Extlnt.IRQ_FALLING:下降沿触发 Extlnt.IRQ_RISING_FALLING:上升或下降沿触发 【pull_mode】上下拉电阻配置 Pin.PULL_NONE:无上下拉电阻; Pin.PULL_UP:启用上拉电阻; Pin.PULL_DOWN:启用下拉电阻; 【callback】中断后执行的回调函数。 |
GPIO(ID,MODE,PULL,VALUE) 配置GPIO 对象 【ID】内部 GPIO 编号; 【MODE】GPIO 模式; GPIO.IN:输入模式 GPIO.OUT:输出模式 【PULL】上下拉电阻配置 GPIO.PULL_UP:上拉 GPIO.PULL_DOWN:下拉 GPIO.PULL_NONE:无 【value】GPIO 初始化电平 1:高电平 0:低电平 |
使用方法 | 直接使用:Extlnt(pin,mode,pull_mode,callback) | GPIO.irq(CALLBACK_FUNC,TRIGGER_CONDITION) 配置中断 【CALLBACK_FUNC】中断执行的回调函数; 【TRIGGER_CONDITION】中断触发方式; GPIO.IRQ_RISING:上升沿触发 GPIO.IRQ_FALLING:下降沿沿触发 GPIO.IRQ_BOTH:都触发 GPIO.disirq() 关闭中断 |
其中需要注意的是K210只有高速GPIO才有外部中断,GPIO常量表如下:
普通 GPIO | GPIO0-GPIO7 |
高速 GPIO | GPIOHS0-GPIOHS31 |
官方代码如下:
# todo OpenMV4
'''
导入 ExtInt、Pin、LED 模块
配置中断方式和定义回调函数
当产生外部中断时候自动执行回调函数
'''
from pyb import Pin,ExtInt,LED
callback = lambda e: LED(3).toggle()
#def callback():
# LED(3).toggle()
#下降沿触发,打开上拉电阻
ext = ExtInt(Pin('P9'), ExtInt.IRQ_FALLING, Pin.PULL_UP, callback)
'''
实验结果:
烧录程序,可以看到每次按下按键时候,LED3 蓝灯的亮灭状态翻转。按键可
以使用 pyAI-OpenMV4 顶部的按键或者 pyBase 开发底板上的
'''
# todo K210
'''
导入 GPIO 等相关模块
配置中断方式和定义回调函数
当产生外部中断时候自动执行回调函数
'''
from Maix import GPIO
from fpioa_manager import fm
import utime
#注册 IO,注意高速 GPIO 口才有中断
fm.register(12, fm.fpioa.GPIO0)
fm.register(16, fm.fpioa.GPIOHS0)
#构建 lED 和 KEY 对象
LED_B=GPIO(GPIO.GPIO0,GPIO.OUT,value=1)
KEY=GPIO(GPIO.GPIOHS0, GPIO.IN, GPIO.PULL_UP)
#LED 状态表示
state = 1
#中断回调函数
def fun(KEY):
global state
utime.sleep_ms(10) #消除抖动
if KEY.value()==0: #确认按键被按下
state = not state
LED_B.value(state)
#开启中断,下降沿触发
KEY.irq(fun, GPIO.IRQ_FALLING)
'''
可以看到每次按下按键 KEY 时候,LED_B 蓝灯的亮灭状态翻转。按键可以使
用 pyAI-K210 底部的按键或者 pyBase 开发底板上的 KEY 按键。
'''
这里的定时器就是相当于计时器,就是在达到某个时间后告诉我们需要做什么,也就是运行相应的代码,此处需要与外部中断区分开哦。
机型 | pyAI-OpenMV4 | pyAI-K210 |
构造函数 | pyb.Timer(id,freq,....) 【id】定时器编号,1-14; 【freq】定时器中断频率 |
machine.Timer(id,channel,mode=Timer.MODE_ONE_SHOT,period=1000, unit=Timer.UNIT_MS, callback=None, arg=None, start=True, priority=1, div=0) 【id】定时器编号, [Timer.TIMER0~TIMER2] 定时器 0-2; 【channel】Timer 通道, [Timer.CHANNEL0~Timer.CHANNEL3] 【mode】定时器模式 MODE_ONE_SHOT: 一次性 MODE_PERIODIC: 周期性 MODE_PWM 【period】定时器为周期性模块时每个周期时间值 【unit】周期的单位 Timer.UNIT_S:秒 Timer.UNIT_MS:毫秒 Timer.UNIT_US:微妙 Timer.UNIT_NS:纳秒 【callback】定时器中断执行的回调函数; 注意:回调函数是在中断中调用 的,所以在回调函数中请不要占用太长时间以及做动态内存分配开关中断等 动作。 【arg】回调函数第 2 个参数 【start】是否在构建对象后立即开始定时器, =True: 立即开始; =False: 不立即开始,需要调用 start()来开启。 【priority】硬件中断优先级,在 K210 中,取值范围是[1,7],值越小优先级越高 【div】硬件分频器。 |
使用方法 | Timer.callback(fun) ------>定义执行的回调函数。 Timer.deinit()-------->终止定时器。 |
Timer.callback(fun)---------->定义回调函数。 Timer.period([value])-------->配置周期。 Timer.start()--------->启动定时器。 Timer.stop()--------->停止定时器。 Timer.deinit()-------->注销定时器。 |
官方代码如下:
# todo OpenMV4
'''
导入 LED、Timer 模块
定义回调函数和配置定时器中断方式
当定时器产生中断时候自动执行回调函数
'''
import pyb
tim = pyb.Timer(4,freq=1) # 使用定时器 4 创建定时器对象,频率 1Hz
tim.callback(lambda t:pyb.LED(3).toggle()) #定时器中断回调函数,执行 LED(3)蓝灯状态反转
# todo K210
'''
导入 Timer 等相关模块
定义回调函数和配置定时器中断方式
当定时器产生中断时候自动执行回调函数
'''
from Maix import GPIO
from fpioa_manager import fm
from machine import Timer
#注册 IO 和构建 LED 对象
fm.register(12, fm.fpioa.GPIO0)
LED_B = GPIO(GPIO.GPIO0, GPIO.OUT)
#计数变量
Counter=0
#定时器回调函数
def fun(tim):
global Counter
Counter = Counter + 1
print(Counter)
LED_B.value(Counter%2)#LED 循环亮灭。
#定时器 0 初始化,周期 1 秒
tim = Timer(Timer.TIMER0, Timer.CHANNEL0, mode=Timer.MODE_PERIODIC,
period=1000, callback=fun)
以上是对 pyAI-OpenMV4 与 pyAI-K210 进行摄像头对比学习前的基础,当然两个机器的性能不一样其中的例程和功能有差异,此处不在述说,下一篇将会讲述两个机器的摄像头学习部分。
-------------------------------------------------------我是分割线-----------------------------------------------------------
此处进行说明,当前所有代码均引用官方例程,后续会陆续加入自己碰到的有意思的代码。