PCA9685芯片的使用
-
PCA9685
芯片介绍这个芯片是通过
I2C
接口控制16路PWM
输出,因此就相当于引脚扩展。但如果只是PWM
扩展的话,那就只能实现输出PWM
方波,即高低电平一直转换,无法实现IO
的单输出低电平或者高电平,但是根据这个芯片的特性,也是可以实现和IO
一样的功能的。下面先介绍一下这个芯片的使用。可以看到使用的是
I2C
的通信引脚,即SDA
和SCL
,另外A0~A5
是六位地址引脚,用于控制芯片在I2C
总线上的地址,这里用不到就不做过多介绍了。LED0~LED15
就是扩展的16位引脚了。关于I2C在下一节进行介绍,关于PCA9685的使用可以先理解为就是通过对芯片内寄存器的读写来实现对芯片的控制的,寄存器存在多个,因此读写操作时需要寄存器的地址。下面介绍一下芯片中寄存器的作用。
-
MODE1寄存器 地址0x00
这个寄存器的作用是对芯片做一些配置用的,这8位各有作用,先放一张图可以参考一下,这里只介绍用到的几位。
这里常用的位是D4、D7,其他位保持默认就好,一般也都是0。D4是在修改时钟相关寄存器时候,需要先写1关闭时钟信号输出,然后等写好时钟相关寄存器之后,再对D4写0开启时钟信号,但是写0之后需要再对D7写1进行复位,D7写1复位后会自动把这位清除成0,因此不用写0。
因此,如果除了D4和D7之外,其他位都是0的话,那么修改一次时钟相关寄存器的操作是这样的:
寄存器:0x00,数据:0x10 修改时钟寄存器 寄存器:0x00,数据:0x00 等待500us 寄存器:0x00,数据:0x80
-
PRE_SCALE寄存器 地址0xFE
这个寄存器是用来修改芯片产生的PWM周期的。下面是这个寄存器中值的计算公式:
prescale_value
就是要写入寄存器的结果round
表示取整,即结果要求证书,向上取整还是向下取整,亦或是四舍五入都可以osc_clock
表示芯片的时钟频率,刚才根据MODE1中的D6位可以看出,我们使用内部时钟的话频率是25MHz,所以这个值为250000004096
这个常数跟PWM的占空比控制有关,一个PWM周期是被分为了4096份,这个是不可修改的,因此是个常数Frequency
表示要修改的PWM周期的频率,例如使用常用的多级的话一个周期是20ms,那这里就是50Hz-1
这就是固定操作了,数据手册中给的要求
我们以控制
MG996R
或者SG90
这种常用的180度舵机为例子,这种舵机需要PWM
周期为20ms
,所以PWM
频率为50Hz
,取证使用向下取整,即C
语言对整数除法的取整方式,这里可以计算得到结果prescale_value=25000000/4096/50-1=121
但是在网上查阅了一下,很多实际使用的时候这个计算出来的周期和实际的周期存在一点误差,因此对这个公式有一个误差修正,具体如下:
可以看到是对频率乘上了
0.98
,这个数字是多次测试测出来的一个经验值,修改后再计算刚才舵机的prescale_value
可以得到prescale_value=25000000/4096/50/0.98-1=123
计算得到
prescale_value
的值后,把这个值写入PRE_SCALE
寄存器即可,需要结合MODE1
寄存器的D4
和D7
位进行操作。 -
LEDx引脚控制相关寄存器
一共有
16
路PWM
引脚,在引脚定义上是LED0~LED15
,每一路控制方法一样,下面就以LED0
为例进行介绍。下面先放一张每个引脚控制对应的寄存器地址图。可以看到
LED0
使用了四个寄存器,地址从0x06
到0x09
。先介绍一下PCA9685
控制PWM
占空比的原理,对每个引脚可以在芯片中设置PWM
高电平的起始和结束位置,之前介绍PRE_SCALE
寄存器时候说过,芯片中对一个PWM
周期是会分成4096
份的,因此这个起始结束位置也是以这个4096
份进行设置的,设置的范围就是0~4095
,因为最大可以是4095
,所以一个开始或者结束需要两字节存储,那一个引脚的开始加结束就需要四字节,所以这里才有四个寄存器,那么对这四个寄存器的使用应该也有了解了,具体的寄存器含义以LED0
为例,如下所示:LED0_ON_L 地址:0x06 起始位置低8位 LED0_ON_H 地址:0x07 起始位置高8位 LED0_OFF_L 地址:0x08 结束位置低8位 LED0_OFF_H 地址:0x09 结束位置高8位
下面还以
MG996R
或者SG90
舵机为例子,假如需要舵机旋转角度为90
度,那么对应的高电平需要的时间是1.5ms
,因为PWM
周期是20ms
,所以可以得到高电平时间在整个PWM
周期中所占比例为,这里20ms
就是对应4096
份,因此高电平时间对应的份数应该是,可以取整得到307
,那么可以让起始位置在0
处,结束位置在307
,所以寄存器的设置如下:LED0_ON_L 地址:0x06 数据:0x00 LED0_ON_H 地址:0x07 数据:0x00 LED0_OFF_L 地址:0x08 数据:0x33 LED0_OFF_H 地址:0x09 数据:0x01
其实在实际使用时候起始位置都可以设置成
0x00
,只需要计算高电平所占份数,得到的结果就可以设置成结束位置,这里LED0_OFF_L
的数据0x33
就是对307
取低八位得到的,LED0_OFF_H
的0x01
同理是307
的高八位。剩下的
15
个引脚控制方法相同,寄存器地址就是在LED0
的四个地址上增加。还有四个特殊的寄存器,是控制所有的16
个引脚,就是0xFA~0xFD
,控制方法和控制一个引脚相同,设置完这四个寄存器后,16
路PWM
输出会变成一样的。
-
-
PCA9685
芯片特殊使用前面了解了
PCA9685
的作用及工作原理,是可以实现PWM
引脚的扩展,但是如果用这个芯片控制之前提到的TB6612FNG
芯片的话,还需要更多的IO
引脚实现高低电平的控制,因此这里介绍一下使用PCA9685
实现IO
的功能。-
实现
IO
扩展-
实现高电平输出
前面根据
PCA9685
的工作原理可以知道,实现PWM
的控制是可以在PCA9685
中设置每路引脚的高电平起始位置,那么如果需要实现一直输出高电平的话,只需要将起始位置设成0
,结束位置设成最大值4095
即可,即整个PWM
周期从开始时候就输出高电平,直到这个周期结束。还以LED0
引脚为例,具体寄存器设置如下:LED0_ON_L 地址:0x06 数据:0x00 LED0_ON_H 地址:0x07 数据:0x00 LED0_OFF_L 地址:0x08 数据:0xff LED0_OFF_H 地址:0x09 数据:0x0f
-
实现低电平输出
与高电平输出同理,只需要将开始和结束位置设成一样即可,在开始输出高电平的时候也是结束的时候,那就一直是低电平了。以
LED0
引脚为例,具体寄存器设置如下:LED0_ON_L 地址:0x06 数据:0x00 LED0_ON_H 地址:0x07 数据:0x00 LED0_OFF_L 地址:0x08 数据:0x00 LED0_OFF_H 地址:0x09 数据:0x00
可以设置成别的值,只要起始和结束中的值一样即可,但一般设置成
0x00
更方便。
-
-