kumarr123
Junior Member level 1
Hi,
I am using PIC16f1526 micro-controller and PCA9685 IC to control servo motor. This below code I am using-
I am using mikroC pro for pic compiler to implement this code.
This code is giving controlled duty cycle like 50%, 25%, etc. But I am not able to set the time period of Pulse 1ms. How to do this?
Currently It's giving first one pulse, And now I am expecting second one pulse
Regards,
Kumar
I am using PIC16f1526 micro-controller and PCA9685 IC to control servo motor. This below code I am using-
I am using mikroC pro for pic compiler to implement this code.
C-like:
#define Write_address 0x80 // I2C address for PCA9865 with no solder bridges
#define Read_address Write_address+1
#define PCA9685_software_reset 0x06
#define Reset 0x01 // Reset the device
#define MODE1 0x00 // 0x00 location for Mode1 register address
#define MODE2 0x01 // 0x01 location for Mode2 reigster address
#define LED0 0x06 // location for start of LED0 registers
#define ALL_CH_ON_L_reg 0xFA
#define ALL_CH_ON_H_reg 0xFB
#define ALL_CH_OFF_L_reg 0xFC
#define ALL_CH_OFF_H_reg 0xFD
#define HEARTBEAT LATC0_bit // green led on ETT board
sbit SCL_i2c at RC3_bit;
sbit SDA_i2c at RC4_bit;
sbit SCL_direction at TRISC3_bit;
sbit SDA_direction at TRISC4_bit;
////////////////////////////////////////////////////////////////////////////////
// Prototype functions - functions at end
void PCA9685_init();
void PCA9685_send(unsigned int value, unsigned char led);
void PCA9685AllLedOff();
unsigned char PCA9685_read_byte(unsigned char chip_register);
void PCA9685_write_byte(unsigned char chip_register, unsigned char value);
void PCA9685_write_word(unsigned char chip_register, unsigned int word_value);
void PCA9685_soft_reset();
////////////////////////////////////////////////////////////////////////////////
void main(){
// block variables
unsigned char n = 0; // LED flash
unsigned int loop = 0; // loop counter
unsigned int pwm = 0;
unsigned int x=0;
OSCCON = 0x7a; //0x7A //122
SCL_i2c = 0;
SDA_i2c = 0;
SCL_direction = 0;
SDA_direction = 0;
ADCON0 = 1;
I2C1_Init(100000);
PCA9685_init();
PCA9685_send((int)4096 * 0.5 ,0); // (int)4096 * 0.5
////////////////////////////////////////////////////////////////////////////////
// Functions
// Init the chip with pwm frequency and MODE2 settings
void PCA9685_init(){
I2C1_start(); // Start
I2C1_Wr(Write_address); // Slave Write_address
I2C1_Wr(MODE1); // Mode 1 ADDRESS
I2C1_Wr(0b00110001); // Sleep and change default PWM frequency 00110001
I2C1_stop(); // Stop
delay_ms(1); // Required 50 us delay
I2C1_start(); // Start
I2C1_Wr(Write_address); // Slave Write_address
I2C1_Wr(0xFE); // PWM frequency PRE_SCALE ADDRESS to set pwm at 100Hz fe
I2C1_Wr(6); // Osc_clk/(4096*update_rate)=25000000/(4096*100)=60=0x3C //06
I2C1_stop(); // Stop
delay_ms(1); // delay at least 500 us
I2C1_start(); // Start
I2C1_Wr(Write_address); // Slave Write_address
I2C1_Wr(MODE1); // Mode 1 register ADDRESS
I2C1_Wr(0b10100001); // Set MODE1 //10100001
I2C1_stop(); // Stop
delay_ms(1); // delay at least 500 us
I2C1_start(); // Start
I2C1_Wr(Write_address); // Slave Address
I2C1_Wr(MODE2); // Mode2 register ADDRESS
I2C1_Wr(0b00000100); // Set MODE2 //00000100
I2C1_stop(); //
}
// Send pulse length[0-4095] to selected LED/SERVO[0-15]
void PCA9685_send(unsigned int value, unsigned char led){
unsigned char pulse_length;// temp variable for PWM
I2C1_start(); // Start
I2C1_Wr(Write_address); // address of selected pca9685
I2C1_Wr(LED0 + 4 * led); // select slected LED ADDRESS
I2C1_Wr(0x00); // LED_ON_L //00
I2C1_Wr(0x00); // LED_ON_H // 00
pulse_length = value; // PWM value lo byte
I2C1_Wr(pulse_length); // LED_OFF_L
pulse_length = value>>8; // pwm 16 bit long, now shift upper 8 to lower 8
I2C1_Wr(pulse_length); // LED_OFF_H
I2C1_stop(); // stop
}
void PCA9685AllLedOff(){
I2C1_start(); // atart
I2C1_Wr(Write_address); // select pca9685
I2C1_Wr(ALL_CH_OFF_L_reg); // All LEDs Off regiter
I2C1_Wr(0b00000000); // low byte
I2C1_Wr(0b00010000); // high byte, bit4 set so full_off see page 21
I2C1_stop(); // Stop
}
// Read a byte and return it's value
unsigned char PCA9685_read_byte(unsigned char chip_register){
unsigned char temp = 0x00;
I2C1_Start();
I2C1_Wr(Write_address);
I2C1_Wr(chip_register);
I2C1_Start();
I2C1_Wr(Read_address);
temp = I2C1_Rd(0);
I2C1_Stop();
return temp;
}
void PCA9685_write_byte(unsigned char chip_register, unsigned char value){
I2C1_Start();
I2C1_Wr(Write_address);
I2C1_Wr(chip_register);
I2C1_Wr(value);
I2C1_Stop();
}
// Write 16bits to chip_register, increments automatically from lo to hi byte
void PCA9685_write_word(unsigned char chip_register, unsigned int word_value){
unsigned char hb = 0x00;
unsigned char lb = 0x00;
lb = (word_value & 0x00FF);
hb = ((word_value & 0xFF00) >> 0x08);
PCA9685_write_byte(chip_register,lb);
PCA9685_write_byte((chip_register+1),hb);
}
// Soft re-set
void PCA9685_soft_reset(){
I2C1_Start();
I2C1_Wr(0x00);
I2C1_Wr(PCA9685_software_reset);
I2C1_Stop();
}
Currently It's giving first one pulse, And now I am expecting second one pulse
Regards,
Kumar