STM32F407配置pca9685驅動

2021-08-18 08:08:52 字數 3641 閱讀 1268

pca9685是16路12位pwm訊號發生器,可用於控制舵機、led、電機等裝置,i2c通訊,節省主機資源。在**上隨處可見,arduino用它非常方便,不過stm32要想使用它必須要寫好驅動才行,本文簡述如何配置其驅動以及一些需要注意的地方。

應用與除錯

當然對於老手,看datasheet是最好的選擇pca9685datasheet

對於我這種新手,自然是看高手的文章比較容易上手了~

我在網上看到的對pca9685總結的最好的一篇文章推薦給大家:生命不息折騰不止

pca9685用的是iic通訊,如果有同學對iic不熟悉,要先去了解一下~

網上有不少寫pca9685的文章,寫驅動的也有,不過我試過的大多有錯誤,我詳細地進行了修改,並且除錯成功,走了不少彎路。

標頭檔案的話主要就是暫存器位址和iic通訊的函式宣告,比較簡單。

內部位址(hex)

名稱功能

harry potter

gryffindor

90hermione granger

gryffindor

100draco malfoy

slytherin

9000

mode1

設定暫存器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

照著上面的**寫標頭檔案就好了 - -

#ifndef __pcf8574_h

#define __pcf8574_h

#include "sys.h"

#include "myiic.h"

#define pca9685_adrr 0x80

#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

void pca9685_write(unsigned char reg,unsigned char data);

u8 pca9685_read(unsigned char reg);

void setpwmfreq(u8 freq);

void setpwm(u8 num, u16 on, u16 off);

void down();

void up();

#endif

void pca9685_write(unsigned char reg,unsigned char data)

u8 pca9685_read(unsigned char reg)

設定pwm波的頻率,看下面這個公式即可:

其中osc_clock是時鐘,根據上面的暫存器設定選擇是內部25mhz時鐘還是外部時鐘。

update_rate是頻率,比如週期是20ms,那麼頻率就是50。

注意:實際應用中發現有誤差,需要加入校準,要把udpate_rate乘以0.915。

void setpwmfreq(u8 freq)

setpwm函式,向相應的暫存器(led0_on_l、led0_on_h、led0_off_l、led0_off_h)寫值即可。

其中num為舵機pwm輸出引腳0~15,on是pwm上公升計數值0~4096,off是pwm下降計數值0~4096。

他的pwm發生原理是這樣的:

乙個pwm週期分成4096份,由0開始+1計數,計到on時跳變為高電平,繼續計數到off時跳變為低電平,直到計滿4096重新開始。所以當on不等於0時可作延時,當on等於0時,off/4096的值就是pwm的占空比。

void setpwm(u8 num, u16 on, u16 off) 

為了方便使用,我寫了乙個輸入角度輸出相應pwm值(off值)的函式。

這個要針對舵機進行修改,我用的是樂幻索爾的ldx218雙軸舵機:

週期20ms,所以在設定頻率的時候要設為50;占空比0.5ms~2.5ms分別對應0°~180°,且成線性關係,所以計算公式為:pw

m=4096

×0.5+(

2.5−

0.5)×a

ngle

/180

20 pwm

=4096

×0.5+(

2.5−

0.5)×a

ngle

/180

20

u16 calculate_pwm(u8 angle)
然後就是一些動作組了,這個就隨便寫乙個8個舵機全部置零位和全部置90°:

注意iic通訊間隔的問題,每呼叫一次setpwm()函式就要延遲1ms,否則會出現莫名其妙的bug,這個很重要~

void down

()void up

()

基於stm32f407建立stm32F427工程

分為三個部分 1.啟動檔案 2.fwilib 包含兩個資料夾inc和src。src裡面是stm32資源的c檔案,inc則是32資源的h檔案 3.user這也是我不太理解的部分 ddbugconfig只包含了用於debug的初始化,則是f4的系統檔案。我是在f407的基礎上改的 總的來說 1.改了晶元...

STM32F407上除錯freeRTOS問題

是在正點原子的阿波羅stm32f429開發板上的例子改來的,他們的編譯沒有問題,我編譯時出現如下問題 定位到出錯的地方,是 再追 configmax syscall interrupt priority 的定義是 define configmax syscall interrupt priority...

STM32F407 驅動外部SRAM

需要驅動的sram型號為is61lv25616al,價效比比51216的高很多 配置cubemx 這幾個時序比較關鍵,可以按照手冊來計算,我用下來這幾個數值比較合適。然後就沒有然後了,生成 就可以用了。檢查sram內容是否正確 uint8 t bsp testextsram void 寫sram p...