440|1

27

帖子

1

TA的资源

一粒金砂(中级)

楼主
 

【嘉楠科技 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

 

最新回复

学习中的需求资料,谢谢分享,内容真实洋细很好不错。   详情 回复 发表于 2024-10-8 09:21
点赞 关注
 
 

回复
举报

66

帖子

0

TA的资源

禁止发言

沙发
 

学习中的需求资料,谢谢分享,内容真实洋细很好不错。

 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表