【嘉楠科技 CanMV K230测评】基础外设学习二——PWM、UART、Thread、WDT、File
[复制链接]
PWM
PWM称为脉冲宽度调制,用于产生一个特定的脉冲信号,当然这个信号的频率(周期)以及占空比都可以进行灵活的设定。PWM被广泛的应用在风扇调速、舵机控制、电机控制等等中。在其他的单片机中,PWM的产生通常都需要搭配定时器进行使用,通过定时器产生一定频率(周期)的中断,并在计数到达一定的数量后,进行电平的反转,从而实现PWM信号的产生。但是在K230中的PWM产生非常的方便,仅需要几个函数就可以实现PWM的快速生成。
PWM也位于machine模块下,因此在使用PWM的时候,要先从machine中进行引用。
通过pwm = machine.PWM(channel, freq, duty, enable=False)进行PWM的函数构建,其中参数channel用于选择PWM的通道,K230提供了6个PWM通道,因此可选的范围为0-5,在这块开发板上,仅有四个通道被引出,可选的范围为0-3。参数freq用于配置PWM的频率,对应的单位为Hz。参数duty用于配置PWM的占空比,取值范围为0-100,默认值为50。enable用于配置PWM输出是否使能,默认为false即不使能状态。
当然PWM的频率和占空比都可以进行单独的配置,通过调用函数pwm.freq([value])和pwm.duty([value])。
在不使用PWM的时候,可以调用pwn.deinit()函数,将PWM功能注销掉。
下面进行PWM代码的演示,产生变换的PWM波形以及控制无源蜂鸣器产生不同声调的声音。
from machine import Pin, PWM
from machine import FPIOA
import time
fpioa = FPIOA()
fpioa.set_function(42,FPIOA.PWM0)
Beep = PWM(0,200, 50, enable=True)
Beep.freq(200)
time.sleep(1)
Beep.freq(400)
time.sleep(1)
Beep.freq(600)
time.sleep(1)
Beep.freq(800)
time.sleep(1)
Beep.freq(1000)
time.sleep(1)
Beep.enable(False)
首先引入了PWM、Pin和FPIOA模块,然后先构建了FPIOA的函数,并将42号引脚配置为PWM0的功能。
然后构建了PWM的函数,命名为Beep,同时进行了初始化配置,配置为通道0,周期为200Hz,占空比为50,并进行使能。
在下面,进行频率的变换,依次变换为200、400、600、800、1000,每次变换完后进行一秒的延时,用于观察。
最终的演示结果如下所示。
Beep
下面进行PWM第二个功能代码的演示,用于控制180°舵机,进行不同角度的变化。
舵机的工作原理:舵机的工作需要一个周期为20ms的脉冲信号,占空比的范围为2.5-12.5,所对应的时间为0.5ms-2.5ms,对应的角度为0-180或者-90~90。
from machine import Pin, PWM
from machine import FPIOA
import time
fpioa = FPIOA()
fpioa.set_function(42,FPIOA.PWM0)
Motor = PWM(0,50, 3, enable=True)
Motor.duty(5)
time.sleep(1)
Motor.duty(7)
time.sleep(1)
Motor.duty(9)
time.sleep(1)
Motor.duty(11)
time.sleep(1)
Motor.duty(4)
time.sleep(1)
Motor.enable(False)
首先引入了PWM、Pin和FPIOA模块,然后先构建了FPIOA的函数,并将42号引脚配置为PWM0的功能。
然后构建了PWM的函数,命名为Motor,同时进行了初始化配置,配置为通道0,周期为50Hz(周期为20ms),占空比为3,并进行使能。
在下面,进行频率的变换,依次变换为5、7、9、11、4,每次变换完后进行一秒的延时,用于观察。
最终的演示结果如下所示。
Servo_Motors
UART
串口是最常用的串行总线,具有全双工、异步的特性。被广泛的应用在无线透传模块以及工控相关的产品上。和其他开发板的通信,往往也是使用串口进行数据的收发。
K230内部有5个UART硬件模块,其中UART0被小核终端占用,UART3被大核终端占用。剩余的UART1、UART2、UART4可以被连接使用,但是在这块开发板上引出了UART1、UART2。
UART也位于machine模块下,因此在使用UART的时候,要先从machine中进行引用。
machine.UART(id, baudrate=115200, bits=UART.EIGHTBITS, parity=UART.PARITY_NONE, stop=UART.STOPBITS_ONE)函数用来构建函数。id为串口号,可以用的范围是UART.UART1和UART.UART2;baudrate为波特率,常用的数值为115200、9600等,使用串口通信时,首先要保证两个设备的串口波特率保持一致。bits为数据位,一般为8位,默认也为8位。parity为校验位,可以选择的有偶校验、奇校验和无校验,默认是无校验;stop为停止位设定,可以选的范围是1、1.5、2,默认为1。
K230使用串口与外面的设备进行通信时,配置完成后要进行数据的收发。
发送数据的函数为UART.write(buf),其中buf为要发送的数据。
接收数据的函数为UART.read(num),其中num为要接收的数据的位数。UART.readline(num)为接收整行的数据,其中num为读取的行数。
在不使用串口后可以使用UART.deinit()函数,将串口注销掉。
下面使用USB转TTL模块,将K230与电脑使用串口进行通信。
硬件接线方式。
软件代码展示。
from machine import UART
from machine import FPIOA
import time
fpioa = FPIOA()
fpioa.set_function(11,FPIOA.UART2_TXD)
fpioa.set_function(12,FPIOA.UART2_RXD)
uart = UART(UART.UART2,115200)
uart.write('Hello EEWORLD')
while True:
text = uart.read(128)
if text != b'':
print(text)
time.sleep(0.1)
首先引入UART和FPIOA的模块。
构建一个FPIOA的函数,并将11和12两个引脚设置为串口2的TXD和RXD工作模式。构建一个UART函数,并将这个串口配置为串口2通道,波特率配置为115200。
使用串口写入函数,发送Hello EEWORLD字符串。
在循环中,接收串口接收的数据到text变量中,判断变量内容,如果不是b'',则打印text内容。产生100ms的延时,避免满跑。
串口收发数据效果展示。在串口调试助手上,选择对应的串口号和波特率以及相应的设置,打开串口后,并运行程序,可以收到由K230发送的字符串。在数据发送编辑栏里发送数据,可以在IDE的串行终端中收到电脑通过串口发送给K230的123字符串。
Thread线程
单片机运行程序的方式是顺序运行,即代码从上至下依次进行程序的运行。但是为了实现程序的更快和更加实时,出现l实时操作系统这一概念,即RTOS。在MicroPython中有一个类似的概念,称之为线程,thread。
在MicroPython中对于线程的描述可以参考官方文档。17.9. _thread — Low-level threading API
使用线程最简单的方式就是通过调用_thread.start_new_thread(function, args[, kwargs])函数,新创建一个线程,便会开始自动运行。其中的参数function代表的是在这个线程中要被调用的函数。这个函数在线程创建函数之前,且其要完成一定的工作。参数args则是传入该函数的一些参数,这个参数的传入方式为元组。
使用多线程打印多条信息。代码演示。
import _thread
import time
def func(name):
while True:
print("hello {}".format(name))
time.sleep(1)
_thread.start_new_thread(func,("1",))
_thread.start_new_thread(func,("2",))
while True:
time.sleep(0.01)
首先引入thread模块。
定义一个要在多线程中运行函数,func,所执行的任务是打印一条信息,传入的参数为name。
在下面开启两个线程,并传入不同的参数。
在循环中写入一小段延时,避免单片机满跑。
下面进行效果延时。可以看到串行终端中不断打印定义的func函数中的数据。
WDT
看门狗是单片机用来防止软件程序跑飞,从而出现问题的一种内部机制。其本质可以看作是一个定时器,当开启看门狗后,定时器开始运行,在定时器到达设定的重启时间之前要进行喂狗(即重置一下定时器),若超过设定的时间没有进行喂狗,就会通过软件复位的方式,将程序进行复位,从而避免了程序跑飞出现的问题。
在K230单片机中也有WDT模块。在使用的时候,需要先引用WDT模块,然后构建一个WDT函数,使用函数wdt = WDT(id, timeout),并在构建函数的时候配置好看门狗的编号以及超时的时间,这里的时间单位是s。喂狗的方式是调用feed函数,wdt.feed()就可以实现喂狗。
下面就用代码演示一下看门狗的配置和喂狗的操作。
from machine import WDT
import time
wdt = WDT(1,3)
for i in range(3):
time.sleep(1)
print(i)
wdt.feed()
while True:
time.sleep(0.01)
首先引入WDT模块。构建一个WDT的函数,并设置超时时间为3s。
执行一个循环函数,循环的次数为3次,在每一次循环的时候进行1s的延时,打印当前的循环次数,并进行一次喂狗。完成3次喂狗后,就会跳出循环,在循环外没有喂狗的操作。因此进入死循环3s后,就会自动复位,此时的开发板就会和电脑断开连接并重新连接。
演示视频如下。
WDT
File
在其他的单片机中我们要是想断电后保存一些数据的话,通常会使用EEPROM或者Flash进行数据的存储。在K230中自带一个文件系统,因此我们直接使用K230的文件系统就可以实现数据的存储和获取。
K230进行文件操作的方式和Python的文件操作方式是一样的。K230的文件路径为/sdcard,所创建的文件,直接存储在这个路径下即可。
代码展示。
f = open('/sdcard/1.txt', 'w')
f.write('EEWORLD')
f.close()
f = open('/sdcard/1.txt', 'r')
text = f.read()
print(text)
f.close()
构建文件函数f,并打开以写的方式,如果没有就会自动新建。使用write函数进行数据的写入。然后关闭文件。
打开文件以读的方式,使用read函数将数据读出并存储在text变量中,打印text,关闭文件。
效果演示。
File
|