2016年10月29日 星期六

DIY - Robot 機器人 - NXP PCA9685 16通道驅動板模塊舵機 PWM 編程(十八)

DIY - Robot 機器人 - NXP PCA9685 16通道驅動板模塊舵機 PWM 編程(十八): 

NXP PCA9685 16通道驅動板模塊的舵機(Servo)編程,由於 NXP PCA9685 內置有 PWMPulse Width Modulation)的功能,祇要控制 PWM 的佔空比(Duty Cycle),便可以控制舵機(Servo)的角度。

NXP PCA9685 16通道驅動板模塊 LCD 顯示
NXP PCA9685 接上電之後的狀態是處於休眠模式(Sleep)之下。SLEEP 模式之下,所有的 PWM 頻道輸出都會被關掉。所以開始在設定好 MODE1 PRE_SCALE 值後,必需離開休眠模式(Sleep)模式, PCA9685 才會有辦法輸出 PWM 訊號,方法是設定 MODE1 暫存器(暫存器位置:0x00)的 SLEEP bit (4 bit)為 1,將 Bit4 改設為 0 的話就醒來。

舵機(Servo)的轉動角度和 PWM 的關係
舵機(Servo)的轉動角度和 PWM 的關係:
-90° = 0.60ms / 20ms = 3% x 4096 = 129 = 0x0081 
-45° = 1.05ms / 20ms = 5.25% x 4096 = 215 = 0x00D7 
   0° = 1.50ms / 20ms = 7.5% x 4096 = 307 = 0x0133 
+45° = 1.95ms / 20ms = 9.75% x 4096 = 400 = 0x0190 
+90° = 2.40ms / 20ms = 12% x 4096 = 492 = 0x01EC

NXP PCA9685 PWM 初始化程式:
// MODE1 Control Byte
   PCA9685_WD_BYTE(PCA9685_ADDR+2);
   PCA9685_WD_BYTE(PCA9685_MODE1);
   PCA9685_WD_BYTE(0xA1);
StopI2C2();

// MODE2 Control Byte
   PCA9685_START_BUS();
   PCA9685_WD_BYTE(PCA9685_ADDR+2);
   PCA9685_WD_BYTE(PCA9685_MODE2);
   PCA9685_WD_BYTE(0b00001101);
StopI2C2();

// Set Up Frequency = 50Hz
PCA9685_WD_PRESCALE(i2c_addr, 0x81);

// Mode1 Bit4=0 PWM will Operate
   PCA9685_WD_BYTE(i2c_addr);
   PCA9685_WD_BYTE(PCA9685_MODE1);
   PCA9685_WD_BYTE(0b00100001);  // 0xA1


NXP PCA9685 PWM 主程式:
while( 1 ) {

// ***** AntiClockwise -90 *****//
   PCA9685_START_BUS();
   PCA9685_WD_BYTE(i2c_addr);
   PCA9685_WD_BYTE(0x06);

   PCA9685_WD_BYTE(0x00);
   PCA9685_WD_BYTE(0x00);
   PCA9685_WD_BYTE(0xEC);
   PCA9685_WD_BYTE(0x01);
   StopI2C2(); 
delayms(2000);

// ***** Stop Servo *****//
   PCA9685_START_BUS();
   PCA9685_WD_BYTE(i2c_addr);
   PCA9685_WD_BYTE(0x06);
   PCA9685_WD_BYTE(0x00);
   PCA9685_WD_BYTE(0x00);
   PCA9685_WD_BYTE(0x00);
   PCA9685_WD_BYTE(0x00);
   StopI2C2(); 
delayms(2000);

// ***** Centre 0 *****//
   PCA9685_START_BUS();
   PCA9685_WD_BYTE(i2c_addr);
   PCA9685_WD_BYTE(0x06);

   PCA9685_WD_BYTE(0x00);
   PCA9685_WD_BYTE(0x00);
   PCA9685_WD_BYTE(0x1C);
   PCA9685_WD_BYTE(0x01); // 0x133 Centre 0
   StopI2C2(); 
   delayms(2000);

// ***** Stop Servo *****//
   PCA9685_START_BUS();
   PCA9685_WD_BYTE(i2c_addr);
   PCA9685_WD_BYTE(0x06);
   PCA9685_WD_BYTE(0x00);
   PCA9685_WD_BYTE(0x00);
   PCA9685_WD_BYTE(0x00);
   PCA9685_WD_BYTE(0x00);
   StopI2C2(); 
   delayms(2000);

// ***** Clockwise +90 *****//
   PCA9685_START_BUS();
   PCA9685_WD_BYTE(i2c_addr);
   PCA9685_WD_BYTE(0x06);

   PCA9685_WD_BYTE(0x00);
   PCA9685_WD_BYTE(0x00);
   PCA9685_WD_BYTE(0x62);
   PCA9685_WD_BYTE(0x00);  // 0x0062 = Clockwise +90
   StopI2C2(); 
   delayms(2000);

// ***** Stop Servo *****//
   PCA9685_START_BUS();
   PCA9685_WD_BYTE(i2c_addr);
   PCA9685_WD_BYTE(0x06);
   PCA9685_WD_BYTE(0x00);
   PCA9685_WD_BYTE(0x00);
   PCA9685_WD_BYTE(0x00);
   PCA9685_WD_BYTE(0x00);
   StopI2C2(); 
   delayms(2000);

}    // End while

NXP PCA9685 16通道驅動板模塊接上舵機(Servo

2016年 10月 29日 天氣報告
氣溫:25.3@ 21:30
相對濕度:百分之 77%
天氣:微雨

2016年10月28日 星期五

DIY - Robot 機器人 - NXP PCA9685 16通道驅動板模塊舵機 PWM 設定(十七)

DIY - Robot 機器人 - NXP PCA9685 16通道驅動板模塊舵機 PWM 設定(十七):

筆者成功驅動了 NXP PCA9685 16通道驅動板模塊的 LED,便可以作舵機 Servo 編程,由於 NXP PCA9685 內置有 PWMPulse Width Modulation)的功能,祇要控制 PWM 的佔空比(Duty Cycle),便可以控制舵機(Servo)的角度。

NXP PCA9685 16通道驅動板模塊舵機 PWM 波形
設置 PWMPulse Width Modulation)的功能:
首先 MODE1 寄存器要設定 EXTCLKbit 6)的時鐘為外置或內置,簡單的設定 0 是使用內置時鐘,頻率為 25MHz。外置時鐘最高為 50MHz

設定 PRE_SCALE0xFEh)寄存器數值,而 PRE_SCALE Default 30,所以沒有更改時,頻率大約是 200Hz50ms),但舵機(Servo)的頻率是 50Hz20ms),所以需要更改 PRE_SCALE 的數值大約是 0x81PRE_SCALE 的數值可用以下公式計算:

NXP PCA9685 PRE_SCALE 的數值公式計算
設定 PRE_SCALE0xFEh寄存器數值後,需要設定 MODE1 寄存器的 SLEEPbit 4)為 0,才可以使用 PWM 功能。

最後要設定 LED 的輸出寄存器,LED 的輸出寄存器由 0x06 ~ 0x69,每個 LED 通道都有獨立的內部寄存器(LEDx_ON_LLEDx_ON_HLEDx_OFF_LLEDx_OFF_H),而將 LED ON LED OFF 的數值設定,便可以令到輸出 PWM 訊號,LEDx_ON_LLEDx_ON_HLEDx_OFF_LLEDx_OFF_的數值可用以下公式計算:

Example 1:LED0 Output (delay time) + (PWM duty cycle) less than 100%
Example 2:LED0 Output (delay time) + (PWM duty cycle) greater than 100%
LED0 PWM 輸出
2016年 10月 28日 天氣報告
氣溫:26.1@ 20:50
相對濕度:百分之 75%
天氣:天色良好

2016年10月27日 星期四

DIY - Robot 機器人 - NXP PCA9685 16通道驅動板模塊 LED 編程(十六)

DIY - Robot 機器人 - NXP PCA9685 16通道驅動板模塊 LED 編程(十六): 

連接好 NXP PCA9685 16通道驅動板模塊接口至 Microchip PIC24FJ64GA008 處理器,便可以開始編程,第一個 NXP PCA9685 的程式是簡單驅動 LED 閃爍,首先是初始化 Microchip PIC24FJ64GA008 處理器的 I2C NXP PCA9685 MODE1 MODE2,然後再將寫入 LED0 的寄存器(LEDx_ON_LLEDx_ON_HLEDx_OFF_LLEDx_OFF_H),LED0 便會閃爍。

NXP PCA9685 16通道驅動板模塊 LCD顯示
NXP PCA9685 初始化程式:
// MODE1 Control Byte
   PCA9685_WD_BYTE(PCA9685_ADDR+2);
   PCA9685_WD_BYTE(PCA9685_MODE1);
   PCA9685_WD_BYTE(0xA1);
StopI2C2();

// MODE2 Control Byte
   PCA9685_START_BUS();
   PCA9685_WD_BYTE(PCA9685_ADDR+2);
   PCA9685_WD_BYTE(PCA9685_MODE2);
   PCA9685_WD_BYTE(0b00001101);
StopI2C2();

Microchip PIC24FJ64GA008 LED0 主程式:
while( 1 ) {

// Test LED0=Flash
// LED0 OFF
   PCA9685_START_BUS();
   PCA9685_WD_BYTE(PCA9685_ADDR+2);
   PCA9685_WD_BYTE(0x06);

// LED0 Off =  0x1000
   PCA9685_WD_BYTE(0x00);
   PCA9685_WD_BYTE(0x00);
   PCA9685_WD_BYTE(0x00);
   PCA9685_WD_BYTE(0x10);
   StopI2C2();
   delayms(1000);

// LED0 ON = 0x1000
   PCA9685_START_BUS();
   PCA9685_WD_BYTE(PCA9685_ADDR+2);
   PCA9685_WD_BYTE(0x06);

   PCA9685_WD_BYTE(0x00);
   PCA9685_WD_BYTE(0x10);
   PCA9685_WD_BYTE(0x00);
   PCA9685_WD_BYTE(0x00);
   StopI2C2();
   delayms(1000);

}    // End while

NXP PCA9685 16通道驅動板模塊接上 LED

2016年 10月 27日 天氣報告
氣溫:25.9@ 20:20
相對濕度:百分之 74%
天氣:天色大致良好

2016年10月26日 星期三

DIY - Robot 機器人 - NXP PCA9685 16通道驅動板模塊 LED 連接(十五)

DIY - Robot 機器人 - NXP PCA9685 16通道驅動板模塊 LED 連接(十五): 

了解 Microchip PIC24FJ64GA008 NXP PCA9685 的晶片內部和連接方法,便可以將兩塊底板連接,最主要是 I2CI²CInter-Integrated Circuit)匯流排的 SDA(串列資料)及 SDL (串列時脈SCL),筆者使用了 2.2kΩ 的電阻將 SDA2 SDL2 電位上拉,電源是由Microchip PIC24FJ64GA008 3.3V 供應。

NXP PCA9685 16通道驅動板模塊電路圖(Schematic
NXP PCA9685 A0 ~ A5 是用作設定 I2C Inter-Integrated Circuit)匯流排地址,用焊錫將 A0 短路連上,就表示一個二進位數字 1,但驅動板模塊地址便變成 0x82Start + 0x01 + Write/ 0x83Start + 0x01 + Read)。LED 會連接到 PCA9685 的輸出,LED 輸出連接 220Ω 的電阻作阻流,直接由 PCA9685 LED 輸出控制。

NXP PCA9685 16通道驅動板模塊
Microchip PIC24FJ64GA008> 和 NXP PCA9685 16通道驅動板模塊連接

2016年10月25日 星期二

DIY - Robot 機器人 - PIC24FJ64GA008 I2C 模組傳輸速率(十四)

DIY - Robot 機器人 - PIC24FJ64GA008 I2C 組傳輸速率(十四): 

Microchip PIC24FJ64GA0008 作為 I2C 主器件工作時,模組必須產生系統 SCLx 時鐘。通常,I2C 系統時鐘指定為100 kHz400 kHz 1 MHz。系統時鐘速率指定為最小 SCLx 低電平時間加最小 SCLx 高電平時間。在大多數情況下,這由 2 TBRG 時間間隔確定。串列傳輸速率發生器的重載值為 I2CxBRG 寄存器值,當串列傳輸速率發生器裝入該值時,發生器倒計數至 0 並停止,直到發生另一次重載。發生器計數在每個指令週期(TCY)遞減兩次。在串列傳輸速率重新啟動時,將自動重載串列傳輸速率發生器。例如,如果發生時鐘同步,串列傳輸速率發生器將在 SCLx 引腳採樣為高電平時重載。

Microchip PIC24FJ64GA0008 波特率發生器框圖
要計算 I2C 串列傳輸速率發生器重載值,可使用以下公式:
注: I2CxBRG 的值不能小於 2
Microchip PIC24FJ64GA0008 波特率發生器公式
I2C 時鐘速率和傳輸速率
Microchip PIC24FJ64GA008 I2C 初始化程式
void MASTER_I2C2_INIT(void) {

    I2C2MSK = 0x20;                  // set this controller's device address

    I2C2CONbits.I2CEN = 1;                // enable I2C module

    I2C2CONbits.I2CSIDL = 0;     // Continue module operation in Idle mode

    I2C2CONbits.IPMIEN = 0;      // IPMI mode disabled

    I2C2CONbits.A10M = 0;         // I2C1ADD is a 7-bit slave address

    I2C2CONbits.DISSLW = 0;    // for 400 kHz up enable slew rate

    I2C2CONbits.SMEN = 1;        // signal conditioning

    I2C2CONbits.GCEN = 0;       // for slave mode only

    I2C2CONbits.STREN = 1;     // Enable software or receive clock stretching,
                            // therefore clock must be release by slave
                            // when done on loading data to sync clock
   
    I2C2BRG = 18;            // 400kHz

    IEC3bits.SI2C2IE = 0;             // enable Slave I2C1 interrupt

    IEC3bits.MI2C2IE = 0;            // enable Master I2C1 interrupt
}


2016年10月24日 星期一

DIY - Robot 機器人 - PIC24FJ64GA008 I2C 模組寄存器介紹(十三)

DIY - Robot 機器人 - PIC24FJ64GA008 I2C 模組寄存器介紹(十三): 

Microchip PIC24FJ64GA008 處理器內置兩個 I2CI2C1 I2C2)的模組,I2CI²CInter-Integrated Circuit)模組是一種串列通訊匯流排,PIC24FJ64GA008 I2C 模組具有 7 個可由用戶訪問的寄存器用於操作。所有寄存器均可通過位元組或字模式訪問。

Microchip PIC24FJ64GA008 I2C 模組的框圖
PIC24FJ64GA008 I2C 模組的 7 個可由用戶訪問的寄存器: 
  1. I2CxCONI2Cx 控制寄存器(Control Register):該寄存器用於控制模組的操作。
  2. I2CXSTATI2CX 狀態寄存器(Status Register):該寄存器包含狀態標誌,指示模組在操作期間的狀態。
  3. I2CxMSKI2Cx 位址遮罩寄存器(Slave Mode Address Mask Register):該寄存器指定I2CxADD 中的哪些位可以忽略,從而提供了多地址支援。
  4. I2CxRCV 接收緩衝寄存器(Receive Buffer Register):這是可從中讀取資料位元組的緩衝寄存器。I2CxRCV 寄存器是唯讀寄存器。I2CxTRN 寄存器是讀/ 寫寄存器。
  5. I2CxTRN 發送寄存器(Transmit Register):這是發送寄存器,在發送操作期間位元組寫入該寄存器。
  6. I2CxADD 位址寄存器Address Register):該寄存器且來裝從器件位址。
  7.  I2CxBRG 串列傳輸速率發生器重載寄存器Baud Rate Generator Reload Register):用來裝I2C 模組串列傳輸速率發生器的串列傳輸速率發生器重載值。

PIC24FJ64GA008 I2CxCONI2Cx 控制寄存器
PIC24FJ64GA008 I2CxCONI2Cx 控制寄存器:
bit
Description
bit 15
I2CENI2Cx 使能位
1 = 使能 I2Cx 模組並將 SDAx SCLx 引腳配置為序列埠引腳
0 = 禁止 I2Cx 模組。所有 I2C 引腳都由埠功能控制。
bit 14
未實現:讀為0
bit 13
I2CSIDL在空閒模式停止位元
1 = 當器件進入空閒模式後,模組停止工作
1 = 在空閒模式下模組繼續工作
bit 12
SCLRELSCLx 釋放控制位(作為 I2C 從器件工作時)
1 = 釋放 SCLx 時鐘
0 = 保持 SCLx 時鐘為低電平(時鐘延長)
如果 STREN = 1
該位元為 R/W (即可由軟體寫入 0 啟動時鐘延長,寫入1 釋放時鐘)。
在從器件開始發送時由硬體清零。
在從器件接收結束時由硬體清零。
如果 STREN = 0
該位元為 R/S (即只能由軟體寫入1 釋放時鐘)。
在從器件開始發送時由硬體清零。
bit 11
IPMIENIPMI 使能位
1 = 使能 IPMI 支援模式;對所有地址做出應答
0 = 禁止 IPMI 模式
bit 10
A10M10 位從器件地址位
1 = I2CxADD 是一個 10 位從器件位址
1 = I2CxADD 是一個 7 位從器件位址
bit 9
DISSLW變化率控制禁止位
1 = 禁止變化率控制
0 = 使能變化率控制
bit 8
SMENSMBus 輸入電平位
1 = 使能符合 SMBus 規範的 I/O 引腳門限值
0 = 禁止 SMBus 輸入門限
bit 7
GCEN廣播呼叫使能位(當作為 I2C 從器件工作時)
1 = 允許在 I2CxRSR 接收到廣播呼叫位址時產生中斷
(已使能模組接收模式)
0 = 禁止廣播呼叫地址
bit 6
STRENSCLx 時鐘延長使能位元(當作為 I2C 從器件工作時)
SCLREL 位一起使用。
1 = 使能軟體或接收時鐘延長
1 = 禁止軟體或接收時鐘延長
bit 5
ACKDT應答資料位元(當作為 I2C 主器件工作時。適用於主器件接收操作。)
當軟體啟動應答序列時將發送的值。
1 = 在應答時發送 NACK
0 = 在應答時發送 ACK
bit 4
ACKEN應答序列使能位
(當作為 I2C 主器件工作時。適用於主器件接收操作。)
1 = SDAx SCLx 引腳啟動應答序列,並發送 ACKDT 資料位元。
在主器件應答序列結束時由硬體清零。
0 = 沒有啟動應答序列
bit 3
RCEN接收使能位(當作為 I2C 主器件工作時)
1 = 使能 I2C 接收模式
在主器件接收到資料位元組的 8 位元後由硬體清零。
0 = 沒有啟動接收序列
bit 2
PEN停止條件使能位(當作為 I2C 主器件工作時)
1 = SDAx SCLx 引腳上產生停止條件
在主器件停止序列結束時由硬體清零。
0 = 沒有啟動停止條件
bit 1
RSEN重複啟動條件使能位(當作為 I2C 主器件工作時)
1 = SDAx SCLx 引腳產生重複啟動條件
在主器件重複啟動序列結束時由硬體清零。
0 = 沒有發起重複啟動條件
bit 0
SEN啟動條件使能位(當作為 I2C 主器件工作時)
1 = SDAx SCLx 引腳上產生啟動條件
在主器件啟動序列結束時由硬體清零。
0 = 沒有發起啟動條件

PIC24FJ64GA008 I2CXSTATI2CX 狀態寄存器
PIC24FJ64GA008 I2CXSTATI2CX 狀態寄存器:
bit
Description
bit 15
ACKSTAT應答狀態位元
1 = 接收到來自從器件的 NACK
0 = 接收到來自從器件的 ACK
在從器件應答結束時由硬體置 1 或清零。
bit 14
TRSTAT發送狀態位元
(當作為 I2C 主器件工作時。適用於主器件發送操作。)
1 = 主器件正在進行發送(8 + ACK
0 = 主器件未進行發送
在主器件發送開始時由硬體置 1
在從器件應答結束時由硬體清零。
bit 13 ~ 11
未實現:讀為 0
bit 10
BCL主器件匯流排衝突檢測位元
1 = 在主器件工作期間檢測到了匯流排衝突
0 = 未發生衝突
在檢測到匯流排衝突時由硬體置 1
bit 9
GCSTAT廣播呼叫狀態位元
1 = 接收到了廣播呼叫位址
0 = 未接收到廣播呼叫位址
當位址與廣播呼叫位址匹配時由硬體置 1
在檢測到停止條件時由硬體清零。
bit 8
ADD1010 位元位址狀態位元
1 = 10 位地址匹配
0 = 10 位地址不匹配
當與 10 位元位址的第二個位元組匹配時由硬體置 1
在檢測到停止條件時由硬體清零。
bit 7
IWCOL寫衝突檢測位
1 = 由於 I2C 匯流排忙,嘗試寫 I2CxTRN 寄存器的操作失敗
0 = 未發生衝突
當在匯流排忙的情況下寫 I2CxTRN 時由硬體置 1 (由軟體清零)。
bit 6
I2COV接收溢出標誌位元
1 = I2CxRCV 寄存器仍然保存原先的位元組時又接收了新位元組
0 = 未發生溢出
嘗試將資料從 I2CxRSR 傳輸到 I2CxRCV 時由硬體置 1 (由軟體清零)。
bit 5
D/A資料/ 位址位元(當作為 I2C 從器件工作時)
1 = 表示上次接收的位元組是資料
0 = 表示上次接收的位元組是器件位址
器件位址匹配時由硬體清零。
通過寫 I2CxTRN 或接收從器件位元組由硬體置 1
bit 4
P停止位
1 = 上一次檢測到了停止位
0 = 上一次沒有檢測到停止位
當檢測到啟動、重複啟動或停止條件時由硬體置 1 或清零。
bit 3
S啟動位
1 = 上一次檢測到了啟動(或重複啟動)位
0 = 上一次未檢測到啟動位
當檢測到啟動、重複啟動或停止條件時由硬體置 1 或清零。
bit 2
R/W/ 寫資訊位元(當作為 I2C 從器件工作時)
1 = 讀——表示從器件輸出資料
0 = 寫——表示從器件接收資料
當接收到 I2C 器件位址位元組後由硬體置1 或清零。
bit 1
RBF接收緩衝器滿狀態位元
1 = 接收完成, I2CxRCV 滿
0 = 接收沒有完成, I2CxRCV
當接收到的位元組寫入 I2CxRCV 後由硬體置1
當軟體讀 I2CxRCV 時由硬體清零。
bit 0
TBF發送緩衝器滿狀態位元
1 = 正在發送, I2CxTRN 滿
0 = 發送完成, I2CxTRN
當軟體寫 I2CxTRN 時由硬體置 1
當資料發送完成時由硬體清零。

PIC24FJ64GA008 I2CxMSKI2Cx 從動模式位址遮罩寄存器
PIC24FJ64GA008 I2CxMSKI2Cx 從動模式位址遮罩寄存器:
bit
Description
bit 15 ~ 10
未實現:讀為 0
bit 9 ~ 0
AMSKx位址位 x 遮罩選擇位
對於 10 位地址:
1 = 對進入報文的地址位 Ax 使能遮罩;在該位置不要求位匹配
0 = 禁止對Ax 位的遮罩;在該位置要求位匹配
對於 7 位地址(僅 I2CxMSK<6:0>):
1 = 對進入報文的地址位 Ax + 1 使能遮罩;在該位置不要求位匹配
0 = 禁止對 Ax + 1 位的遮罩;在該位置要求位匹配

PIC24F I2C 模組相關的寄存器