|
[DPRG] PIC Dual DC Motor HBridge controller
Subject: [DPRG] PIC Dual DC Motor HBridge controller
From: ellis76016
ellis76016 at tx.rr.com
Date: Sun Jan 14 22:03:16 CST 2007
Vimal,
Yes you can. Attached is a C program that does just that. Warning very non
commented code, sorry.
The main thing you are looking for is:
Set up
// set up PWM
// bank 1 set by compiler
PR2 = 0xFF;
CCPR1L = 0; // bank 0
CCPR2L = 0;
T2CON = 0b.0011.1100;
TMR2IF = 0;
// bank 1
TMR2IE = 1;
// bank 0
PEIE = 1;
GIE = 1;
CCP1CON = 0b.0000.1100;
CCP2CON = 0b.0000.1100;
Changes motor speed, pwm duty cycles, in main loop.
CCPR1L = pwmR; // bank 0
CCPR2L = pwmL;
Hope this helps,
David Ellis
-----Original Message-----
From: dprglist-bounces at dprg.org [mailto:dprglist-bounces at dprg.org] On Behalf
Of Vimal Shankar
Sent: Saturday, January 13, 2007 8:19 PM
To: dprglist at dprg.org
Subject: [DPRG] PIC Dual DC Motor HBridge controller
Guys
Did a lot of homework and got incremental and HBridge
controller working for my DC Geared motor control
system.
Now I am finding reason to focus on the firmware, but
am really confused if I can get the
PIC16F877A/PIC18F4550 to output 2 PWM at SAME
frequency (the freq at which the HBridge is driven)
but at 2 different duty cycles (to control the RPM of
the two motors)...
Is is possible to have two different duty cycles of
the same freq from two different pins of a PIC.
I am obviously asking about hardware PWM as a software
solution would tie up the PIC too much AFAIC...
Do get back.
Vimal
____________________________________________________________________________
________
Never miss an email again!
Yahoo! Toolbar alerts you the instant new Mail arrives.
http://tools.search.yahoo.com/toolbar/features/mail/
_______________________________________________
DPRGlist mailing list
DPRGlist at dprg.org
http://list.dprg.org/mailman/listinfo/dprglist
-------------- next part --------------
/*
PWM06.C 2006-05-15
David Ellis
http://home.comcast.net/~ellis76016/robots/
*/
#include "int16CXX.H"
#define LF 10
#define CR 13
#define SP 32
#define Kprop 256 // 1 * 256
#pragma chip PIC16F877
#pragma resetVector 0x0003
bit pin_b5 @ PORTB.5; //J1 Pin 10 = B5, right motor shaft encoder
bit pin_b6 @ PORTB.6; //J1 Pin 8 = B6, left motor shaft encoder
bit pin_d0 @ PORTD.0; //J1 Pin 40 = D0, CMD I1
bit pin_d1 @ PORTD.1; //J1 Pin 38 = D1, CMD I2
bit pin_d2 @ PORTD.2; //J1 Pin 36 = D2, CMD I3
bit pin_d3 @ PORTD.3; //J1 Pin 34 = D3, CMD I4
bit stateR; // state holder for right motor shaft encoder
bit stateL; // state holder for left motor shaft encoder
uns8 RightCount, LeftCount;
uns8 Ticks;
uns8 LeftInterval, RightInterval;
void putc( char ch );
void simplehex( char val );
interrupt int_server(void) {
int_save_registers // W, STATUS, and PCLATH
// shaft encoder interupt
if (RBIF) {
if (stateR != pin_b5) {
stateR = pin_b5;
RightCount++;
}
if (stateL != pin_b6) {
stateL = pin_b6;
LeftCount++;
}
RBIF = 0;
}
// isr for PWM postscalar interupt
if (TMR2IF) {
// 1 tick = 8 * 19.53 Khz or 409.6us
Ticks++;
if (Ticks == 100) {
LeftInterval = LeftCount;
LeftCount = 0;
RightInterval = RightCount;
RightCount = 0;
Ticks = 0;
}
TMR2IF = 0; /* reset flag */
}
int_restore_registers // W, STATUS, and PCLATH
}
void putc( char ch ) {
// Wait for space in the TX buffer
while ( TXIF == 0 ) ;
TXREG = ch;
}
// transmits char/byte data as two hex characters, 0 = "00", 255 = "FF"
void SimpleHex( char val ) {
char nibble;
char ch;
nibble = val >> 4;
if (nibble < 10)
ch = nibble + '0';
else {
ch = 'a' + nibble;
ch = ch - 10;
}
putc(ch);
nibble = val & 0x0F;
if (nibble < 10)
ch = nibble + '0';
else {
ch = 'a' + nibble;
ch = ch - 10;
}
putc(ch);
}
void main(void) {
PORTB = 0b.0000.0000;
TRISB = 0b.1111.1111;
// J1 Pin 27 = C1/CCP2, PWM to CMD, E1-2
// J1 Pin 29 = C2/CCP1, PWM to CMD, E3-4
PORTC = 0b.0000.0000;
TRISC = 0b.1111.1001;
PORTD = 0b.0000.0000;
TRISD = 0b.1111.0000;
Ticks = 0;
uns8 x , y;
uns8 tempL, tempR;
uns8 pwmL, pwmR;
uns8 setpointL, setpointR;
int16 errorL, errorR;
int16 cvL, cvR;
pwmL = 0;
pwmR = 0;
// set up PWM
// bank 1 set by compiler
PR2 = 0xFF;
CCPR1L = 0; // bank 0
CCPR2L = 0;
T2CON = 0b.0011.1100;
TMR2IF = 0;
// bank 1
TMR2IE = 1;
// bank 0
PEIE = 1;
GIE = 1;
CCP1CON = 0b.0000.1100;
CCP2CON = 0b.0000.1100;
// set Sorbotics Compact Motor Driver CMD directions
pin_d0 = 1;
pin_d1 = 0;
pin_d2 = 0;
pin_d3 = 1;
setpointL = 32;
setpointR = 32;
while ( 1 ) { // loop forever
// print duty cycle, left count, right count
tempL = LeftInterval;
tempR = RightInterval;
SimpleHex (pwmL);
putc(SP);
SimpleHex (tempL);
putc(SP);
SimpleHex (pwmR);
putc(SP);
SimpleHex (tempR);
putc(SP);
putc(CR);
putc(LF);
// set pwm
errorL = (int16)setpointL - (int16)tempL;
errorR = (int16)setpointR - (int16)tempR;
cvL = errorL * Kprop;
cvR = errorR * Kprop;
pwmL = pwmL + cvL.high8;
pwmR = pwmR + cvR.high8;
CCPR1L = pwmR; // bank 0
CCPR2L = pwmL;
/*
delay
y = 0;
while (--y > 0) {
x = 0;
while (--x > 0) {
nop();
}
}
*/
}
}
More information about the DPRG mailing list
|