完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
背景介绍: 硬件特点 1、每路 12 位分辨率(4096 级)的 PWM; 2、最多 16 路 PWM 输出,所有路 PWM 频率统一,每路占空比可以独立控制; 3、I2C 通信方式; 4、支持 2.3V~5.5V 电压,逻辑电平 3.3V; 5、复位方式:上电复位、软件复位。 用于舵机控制的 PWM 一、明确控制信号 1、用于舵机控制的 PWM 频率是 50Hz(周期 20000us) 2、对于 12 位分辨率而言,时间控制精度(即:时间分辨率)就是 3、舵机的控制脉宽是0.5ms ~ 2.5ms,时间伸缩范围是 2000us 4、伸缩范围在 4.88us 时间分辨率下可以分成近 410 份。 5、时间伸缩范围 2000us 对应舵机转动范围 0~180 度,因此舵机的角度分辨率约为 0.439 度 二、在 PCA9685 手册里查芯片用法 1、芯片长什么样 2、引脚功能 3、I2C 地址 地址引脚由 A0 ~ A5 组成,因此最多可以有 64 个地址。由于芯片本身保留 All Call 7 位地址 0xE0 以及 Software Reset 7位地址 0x06,所以有 62 个地址可用。 在默认情况下(即:A0 ~ A5 全部接地),其 7 位地址为 0x40。 4、目标寄存器 (1) MODE1 寄存器,地址0x00,可读、可写。 (2) MODE2 寄存器,地址0x01,可读、可写。 (3) 每路 PWM 有 4 个 8 位控制寄存器,地址见 datasheet,可读、可写。 4 个 8 位寄存器在手册上说成:2 路 12 位寄存器。2 个 12 位寄存器分别控制该路输出的高、低电平时间,最大数值是 4095。 根据下面的 Example 1 不难了解到这 2 个 12 位寄存器的意思是:每个周期从第几个 count 开始置 1,则 LEDx_ON 寄存器写几(十六进制形式);每个周期从第几个 count 开始清 0,则 LEDx_OFF 寄存器写几。 下图的 4 个 example 表示了一般情况下 2 个 12 位寄存器设置情况与输出的关系。 下图的 4 个 example 表示了 ON 寄存器值 < OFF 寄存器值情况下的输出。 下图的 4 个 example 表示了 ON 寄存器值 > OFF 寄存器值情况下的输出。 (4) PWM 频率设置寄存器 PRE_SCALE,地址0xFE,可读、可写。 芯片内置 25MHz 的晶振,update_rate 是以 Hz 为单位的频率值。因此,对于 50Hz 的 PWM 来讲此寄存器应设置为 121。 RT-Thread 的 PCA9685 驱动组件 硬件连接如上图,Sugar 使用了最常见的 PCA9658 舵机控制模块,接上逻辑分析仪看数据。 一、第 1 段 展开第一段通信内容,如下图: 上图黄色框中“向 40 号地址写两个 0 ”的意思是:向地址为 40 的设备地址为 0 的寄存器写入数据 0。 相应的,后面蓝色框就解读为:读取地址为 40 的设备地址为 0 的寄存器值,设备反回目标寄存器里的数据值为 0。 下面到代码里去找这段通信的相关内容,如下: 二、第 2 段 根据 PCA9685 的 datasheet 所述,设置 PWM 输出频率的时候要先进入 SLEEP 模式。并且从 SLEEP 模式重启的流程是在 datasheet 里指定的。在 RT-Thread 的 PCA9685 的组件包里,把设置频率相关的一干操作都封装到了一个函数 pca9685_set_pwm_freq() 里面。 三、第 3 段 上面已经把研究方法说透了,这里就不再把逻辑分析仪的图放上来了。通过对代码的分析,Sugar 发现 RT-Thread 这个 PCA9685 的驱动组件包传承了 RT-Thread 本身小而美的特点,按照 PCA9685 的 datasheet 封装函数,这样使得对 PCA9685 的了解容易很多。 以 Arduino “以使用方便”为目的不同,PCA9685 组件包倾向于真正让人弄懂 PCA9685 的用法。在懂了之后,个人就有能力自己“以使用方便”为目的再次做一遍封装。很多玩过 Arduino 的人都觉得做起来真简单,离了 Arduino 的环境真不会。 Arduino 面对的是小白,以方便体验为主,而 RT-Thread 和其一众组件能够让人真正了解深层次的本源,搞懂这些能让人在成为高手的路上走得更轻松。当成为高手之后,再回头看 Arduino 才能体会到 Arduino 封装的真正智慧。 |
|
|
|
只有小组成员才能发言,加入小组>>
3310 浏览 9 评论
2991 浏览 16 评论
3492 浏览 1 评论
9057 浏览 16 评论
4086 浏览 18 评论
1175浏览 3评论
603浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
596浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2333浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1894浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-22 11:43 , Processed in 1.120337 second(s), Total 78, Slave 59 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号