原文地址:http://nicekwell.net/blog/20161213/pca9685-16lu-12wei-pwmxin-hao-fa-sheng-qi.html
16路12位PWM信號發生器,可用於控制舵機、led、電機等設備,i2c通信,節省主機資源。
一、概述和硬件
1、概述
很常見的模塊板子是這個樣子,這個板子也比較便宜,十幾塊錢一個。
i2c通信,只需要幾根i2c線就可以控制16路pwm,週期和佔空比都可控。
可以多個模塊級聯。
可控制16路通道的四種工作模式:關、開、pwm、可變pwm。
精度是12位:
工作頻率 | 時間分辨率 | 通常舵機500~2500us可分成份數 | 通常舵機500~2500us,旋轉角180°的角度分辨率 |
---|---|---|---|
50Hz | 4.88us | 410份 | 0.439° |
60Hz | 4us | 492份 | 0.366° |
驅動方式可以選擇開漏輸出或推輓輸出。
2、硬件
1、電壓
數字電路電壓範圍可接受3.3和5v電平。
此外還有一個v+引腳,這個引腳是給舵機供電用的,可以接稍微高一點的電壓。
2、i2c地址
有6個地址控制腳,通過這些引腳可以控制設備的i2c地址。
7位的I2C地址爲:0x40 + A5:A0,A5到A0如果不做任何處理的話是0,想要把哪一位置1就把那個引腳焊到一起。
另外用i2cdetect檢測出還有一個0x70地址一直存在,這是一個通用地址,可以給所有從機下達指令。
3、使能腳
模塊有一個OE反使能腳,這個引腳低電平使能,不接的話模塊內部默認已經接地使能了,所以正常使用可以不接。
二、寄存器功能
:-:|:-:|:-:
內部地址(hex) | 名稱 | 功能 |
---|---|---|
00 | MODE1 | 設置寄存器1 |
01 | MODE2 | 設置寄存器2 |
02 | SUBADR1 | i2c-bus subaddress1 |
03 | SUBADR2 | i2c-bus subaddress2 |
04 | SUBADR3 | i2c-bus subaddress3 |
05 | ALLCALLADR | |
06 | LED0_ON_L | |
07 | LED0_ON_H | |
08 | LED0_OFF_L | |
09 | LED0_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路通道 |
FA | ALL_LED_ON_L | |
FB | ALL_LED_ON_H | |
FC | ALL_LED_OFF_L | |
FD | ALL_LED_OFF_H | |
FE | PRE_SCALE | 控制週期的寄存器 |
FF | TestMode |
MODE1寄存器
位 | 名稱 | 功能 |
---|---|---|
D7 | RESTART | 寫1復位,寫完後此位自動清除。一定要在SLEEP位寫0後至少500us後才能對此位寫1進行復位。 |
D6 | EXTCLOCK | 0-使用內部時鐘(25MHz)。1-使用外部時鐘引腳的時鐘。修改此位前,一定要先SLEEP,再修改此位(此時SLEEP位仍然寫1),再退出SLEEP。 |
D5 | AI | 0-內部地址讀寫後不自動增加。1-內部地址讀寫後自動增加。一般i2c設備在對從機讀寫後內部地址都會自動增加,這個芯片可以手動設置是否自動增加,我們一般都會設成自動增加。 |
D4 | SLEEP | 0-退出SLEEP模式。1-進入SLEEP模式。注:1、寫0退出sleep模式後,最多等500us後即可產生穩定的時鐘信號。2、寫1進入sleep模式後,時鐘會關閉。此時可以修改時鐘源寄存器EXTCLOCK和週期寄存器PRE_SCALE,修改這兩個寄存器之前必須先進入sleep模式。 |
D3 | SUB1 | |
D2 | SUB2 | |
D1 | SUB3 | |
D0 | ALLCALL | 0-不響應0x70通用i2c地址。1-響應0x70通用i2c地址。這個芯片除了可以通過A5:A0自定義i2c地址外,還有一個通用i2c地址0x70,此寄存器可以控制是否響應這個通用地址。注意啊:這個寄存器的設置好像掉電會保存的! |
各個通道的ON和OFF寄存器
總共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通道輸出低電平。
PRE_SCALE寄存器
這個寄存器是用來設置週期的,具體原理可以不用管,只要記住這個公式: 其中osc_clock是時鐘,根據上面的寄存器設置選擇是內部25MHz時鐘還是外部時鐘; update_rate是頻率,比如週期是20ms,那麼頻率就是50。 注意:實際應用中發現有誤差,需要加入校準,要把udpate_rate乘以0.915。 包括從網上下載的arduino驅動中也加入了此校準。
三、驅動
樹莓派wiringPi平臺
這裏是基於樹莓派wiringPi提供的i2c通信接口基礎上實現的驅動,在其他平臺上的驅動方法類似,只要把這裏的i2c接口換成其他平臺的通信接口即可。
本驅動週期固定爲20ms不可變,如需修改也非常容易。
pca9685_wiringpi.h文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
pca9685_wiringpi.c文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
|
關於驅動在樹莓派上的速度:
樹莓派設置的i2c波特率 | 設置16路通道所用時間 |
---|---|
100000 | |
1000000(1M) | 2067us |
2000000(2M) | 1300us |
四、使用流程
1、確定i2c地址
通過焊接A5~A0確定模塊的i2c地址,如果不做任何焊接,默認地址是0x40。
2、連接數字電路電源。
3、連接兩根i2c線。
4、連接v+引腳,給舵機供電電源。
5、把驅動合入到工程,即可使用。
更多內容,歡迎訪問作者博客:http://nicekwell.net/