PCA9685 16路12位pwm訊號發生器

2021-07-25 08:56:39 字數 4721 閱讀 2330

二、暫存器功能

三、驅動

四、使用流程

16路12位pwm訊號發生器,可用於控制舵機、led、電機等裝置,i2c通訊,節省主機資源。

很常見的模組板子是這個樣子,這個板子也比較便宜,十幾塊錢乙個。

i2c通訊,只需要幾根i2c線就可以控制16路pwm,週期和占空比都可控。

可以多個模組級聯。

可控制16路通道的四種工作模式:關、開、pwm、可變pwm。

精度是12位:

工作頻率

時間解析度

通常舵機500~2500us可分成份數

通常舵機500~2500us,旋轉角180°的角度解析度

50hz

4.88us

410份

0.439°

60hz

4us492份

0.366°

驅動方式可以選擇開漏輸出或推挽輸出。

數位電路電壓範圍可接受3.3和5v電平。

此外還有乙個v+引腳,這個引腳是給舵機供電用的,可以接稍微高一點的電壓。

有6個位址控制腳,通過這些引腳可以控制裝置的i2c位址。

7位的i2c位址為:0x40 + a5:a0,a5到a0如果不做任何處理的話是0,想要把哪一位置1就把那個引腳焊到一起。

另外用i2cdetect檢測出還有乙個0x70位址一直存在,這是乙個通用位址,可以給所有從機下達指令。

模組有乙個oe反使能腳,這個引腳低電平使能,不接的話模組內部預設已經接地使能了,所以正常使用可以不接。

:-:|:-:|:-:

內部位址(hex)

名稱功能

00mode1

設定暫存器1

01mode2

設定暫存器2

02subadr1

i2c-bus subaddress1

03subadr2

i2c-bus subaddress2

04subadr3

i2c-bus subaddress3

05allcalladr

06led0_on_l

07led0_on_h

08led0_off_l

09led0_off_h……

…0x06 + 4*x

ledx_on_l

0x06 + 4*x + 1

ledx_on_h

0x06 + 4*x + 2

ledx_off_l

0x06 + 4*x + 3

ledx_off_h……

… 上面共16路通道

faall_led_on_l

fball_led_on_h

fcall_led_off_l

fdall_led_off_h

fepre_scale

控制週期的暫存器

fftestmode位名稱

功能d7

restart

寫1復位,寫完後此位自動清除。一定要在sleep位寫0後至少500us後才能對此位寫1進行復位。

d6extclock

0-使用內部時鐘(25mhz)。1-使用外部時鐘引腳的時鐘。修改此位前,一定要先sleep,再修改此位(此時sleep位仍然寫1),再退出sleep。

d5ai

0-內部位址讀寫後不自動增加。1-內部位址讀寫後自動增加。一般i2c裝置在對從機讀寫後內部位址都會自動增加,這個晶元可以手動設定是否自動增加,我們一般都會設成自動增加。

d4sleep

0-退出sleep模式。1-進入sleep模式。注:1、寫0退出sleep模式後,最多等500us後即可產生穩定的時鐘訊號。2、寫1進入sleep模式後,時鐘會關閉。此時可以修改時鐘源暫存器extclock和週期暫存器pre_scale,修改這兩個暫存器之前必須先進入sleep模式。

d3sub1

d2sub2

d1sub3

d0allcall

0-不響應0x70通用i2c位址。1-響應0x70通用i2c位址。這個晶元除了可以通過a5:a0自定義i2c位址外,還有乙個通用i2c位址0x70,此暫存器可以控制是否響應這個通用位址。注意啊:這個暫存器的設定好像掉電會儲存的!

總共16個通道,每個通道都有 ledx_on_l、ledx_on_h、ledx_off_l、ledx_off_h 四個暫存器。

系統中有乙個12位的計數ack,ack根據pre_scale暫存器設定的週期進行增加,沒增加一次就會和上述四個暫存器對比:

當發現 ack == ledx_on_h[3:0]:ledx_on_l 時,x通道輸出高電平;

當發現 ack == ledx_off_h[3:0]:ledx_off_l 時,x通道輸出低電平。

這裡是基於樹莓派wiringpi提供的i2c通訊介面基礎上實現的驅動,在其他平台上的驅動方法類似,只要把這裡的i2c介面換成其他平台的通訊介面即可。

本驅動週期固定為20ms不可變,如需修改也非常容易。

pca9685_wiringpi.h檔案:

123

4567

891011

1213

1415

1617

18

/*

這個驅動是在樹莓派的wiringpi基礎上的,基於wiringpi對i2c的介面函式。

此驅動的使用方法是:

1、先用 pca9685_init(從機位址) 初始化,得到乙個裝置描述符(int型),這個裝置描述符代表這個pca9685晶元,因為可能多個pca9685級聯,通過這個裝置描述符來區分它們。

它的2、呼叫 pca9685_setmk

*/#ifndef pca9685_wiringpi_h

#define pca9685_wiringpi_h

#include

int pca9685_init(unsigned char addr); // addr是7位的i2c從機位址,返回的是linux標準的裝置描述符,呼叫它的地方視作pca9685的裝置描述符

//因為可以多個pca9685級聯,通過裝置描述符區別它們

//此驅動僅作為驅動舵機使用,週期固定死位20ms,不允許外部設定

void pca9685_setmk(int fd, int num, int mk); //設定指定通道的脈寬。fd是在pca9685_init時獲得的裝置描述符,num是通道號(從0開始),mk是脈寬單位是us。週期已經固定為20ms了

#endif

pca9685_wiringpi.c檔案:

123

4567

891011

1213

1415

1617

1819

2021

2223

2425

2627

2829

3031

3233

3435

3637

3839

4041

4243

4445

4647

4849

5051

5253

5455

5657

58

#include "pca9685_wiringpi.h"

#define pca9685_subadr1 0x2

#define pca9685_subadr2 0x3

#define pca9685_subadr3 0x4

#define pca9685_mode1 0x0

#define pca9685_prescale 0xfe

#define led0_on_l 0x6

#define led0_on_h 0x7

#define led0_off_l 0x8

#define led0_off_h 0x9

#define allled_on_l 0xfa

#define allled_on_h 0xfb

#define allled_off_l 0xfc

#define allled_off_h 0xfd

int pca9685_init(unsigned char addr) // addr是7位的i2c從機位址,返回的是linux標準的裝置描述符,呼叫它的地方視作pca9685的裝置描述符

//因為可以多個pca9685級聯,通過裝置描述符區別它們

//此驅動僅作為驅動舵機使用,週期固定死位20ms,不允許外部設定

return pca9685;

}void pca9685_setmk(int fd, int num, int mk) //設定指定通道的脈寬。fd是在pca9685_init時獲得的裝置描述符,num是通道號(從0開始),mk是脈寬單位是us。週期已經固定為20ms了

關於驅動在樹莓派上的速度:

樹莓派設定的i2c波特率

設定16路通道所用時間

100000

1000000(1m)

2067us

2000000(2m)

1300us

1、確定i2c位址

通過焊接a5~a0確定模組的i2c位址,如果不做任何焊接,預設位址是0x40。

2、連線數位電路電源。

3、連線兩根i2c線。

4、連線v+引腳,給舵機供電電源。

5、把驅動合入到工程,即可使用。

敏捷開發12路

1。我們最優先要做的是通過盡早的 持續的交付有價值的軟體來使客戶滿意 規劃迭代故事時必須按照優先順序安排,為客戶先提供最有價值的功能。通過頻繁迭代能與客戶形成早期的良好合作,及時反饋提高產品質量。敏捷小組關注完成和交付具有使用者價值的功能,而不是孤立的任務。以前我們都用需求規格說明書或者用例來編寫詳...

12 路徑總和

給定乙個二叉樹和乙個目標和,判斷該樹中是否存在根節點到葉子節點的路徑,這條路徑上所有節點值相加等於目標和。說明 葉子節點是指沒有子節點的節點。示例 給定如下二叉樹,以及目標和 sum 22,5 4 8 11 13 4 7 2 1 返回 true,因為存在目標和為 22 的根節點到葉子節點的路徑 5 ...

配置PCA的一點總結12微控制器

先看 include stc12.h unsigned int last capture data 0 unsigned int new capture data 0 unsigned int g period 0 unsigned int g frequency 0 unsigned char s...