Difference between revisions of "PIC32MX: Encoder Motor Control"
From Mech
Jump to navigationJump to searchAndrew Long (talk | contribs) |
Andrew Long (talk | contribs) |
||
Line 9: | Line 9: | ||
===Sample Code=== |
===Sample Code=== |
||
/* |
|||
First include header files with definitions for generic type definitions, compiler, and for specific PIC. Also include the plib header file. |
|||
QuadratureHard.c |
|||
#include "GenericTypeDefs.h" |
|||
The PIC32MX460F512L has 5 available external timer / counter pins denoted TXCK on the pin list, |
|||
#include "Compiler.h" |
|||
where x is from 1 to 5. Unfortunately, the PIC32MX440F512H has only 1 available external counter (T1CK), |
|||
#include "HardwareProfile.h" |
|||
so this PIC cannot be used for quadrature encoder. The NU32 board uses PIC32MX460F512L. |
|||
#include <plib.h> |
|||
This code is based on the QuadratureHard.c for the 8-bit PICS. |
|||
NOTE THAT BECAUSE WE USE THE BOOTLOADER, NO CONFIGURATION IS NECESSARY. THE BOOTLOADER PROJECT ACTUALLY CONTROLS ALL OF OUR CONFIG BITS. |
|||
Quadrature based on Hardware requires two timers to count up-counts and down-counts. |
|||
Define the system frequency |
|||
PWM uses Timer 2 or Timer 3, therefore, we are going to use Timer 4 and Timer 5 for this code. |
|||
#define SYS_FREQ (80000000L) |
|||
Timer 4 is T4CK/RC3 and Timer 5 is SDI1/T5CK/RC4. |
|||
Define global variables for counting |
|||
LS7083 chip decodes quadrature A&B signals into up&down pulses for these two timers |
|||
signed int bigcount = 0; // set encoder value initially to zero, it can go + or - |
|||
The software version doesn't use up timers but this hardware version is arbitrarily fast |
|||
// 32 bit number |
|||
*/ |
|||
short count0, count1; // 16 bit number |
|||
short last0 = 0, last1 = 0; // 16 bit number |
|||
#include "HardwareProfile.h" |
|||
Begin main function |
|||
signed int bigcount = 0; // set encoder value initially to zero, it can go + or - |
|||
int main(void) |
|||
// 32 bit number |
|||
{ |
|||
short count0, count1; // 16 bit number |
|||
short last0 = 0, last1 = 0; // 16 bit number |
|||
Configure the proper PB frequency and the number of wait states |
|||
SYSTEMConfigPerformance(SYS_FREQ); |
|||
int main(void) { |
|||
Initialize Timer1 and Timer2 as external clocks and periods (PR1, PR2) |
|||
// Configure the system performance |
|||
OpenTimer1( T1_ON | T1_PS_1_1 | T1_SOURCE_EXT, 0xFFFF); |
|||
SYSTEMConfigPerformance(SYS_FREQ); |
|||
OpenTimer2( T2_ON | T2_PS_1_1 | T2_SOURCE_EXT, 0xFFFF); |
|||
mInitAllLEDs(); |
|||
main loop |
|||
while (1) |
|||
// Must enable glocal interrupts - in this case, we are using multi-vector mode |
|||
count0 = ReadTimer1(); // in your routine this must be done at least every 32000 |
|||
INTEnableSystemMultiVectoredInt(); |
|||
// encoder counts to avoid rollover ambiguity |
|||
count1 = ReadTimer2(); |
|||
// init Timer4 and Timer5 mode and periods (PR4, PR5) |
|||
OpenTimer4( T4_ON | T4_PS_1_1 | T4_SOURCE_EXT, 0xFFFF); |
|||
bigcount += count0 - last0; // add on the recent up-counts, since the last time |
|||
OpenTimer5( T5_ON | T5_PS_1_1 | T5_SOURCE_EXT, 0xFFFF); |
|||
if (count0 < last0) |
|||
while (1) { |
|||
{ |
|||
count0 = ReadTimer4(); // in your routine this must be done at least every 32000 |
|||
bigcount += 65536; // count0 only increments, so if it got lower |
|||
// encoder counts to avoid rollover ambiguity |
|||
//it must have rolled over |
|||
count1 = ReadTimer5(); |
|||
} |
|||
bigcount += count0 - last0; // add on the recent up-counts, since the last time |
|||
last0 = count0; |
|||
if (count0 < last0) |
|||
bigcount -= count1 - last1; // we're not worrying about rollover of the 32 bit bigcount total |
|||
{ |
|||
bigcount += 65536; // count0 only increments, so if it got lower |
|||
if (count1 < last1) |
|||
//it must have rolled over |
|||
{ |
|||
} |
|||
bigcount -= 65536; |
|||
} |
|||
last0 = count0; |
|||
last1 = count1; |
|||
bigcount -= count1 - last1; // we're not worrying about rollover of the 32 bit bigcount total |
|||
Put Code to Display Here. |
|||
if (count1 < last1) |
|||
I put the above code in the Communicate Via USB Code and added the following lines: |
|||
{ |
|||
bigcount -= 65536; |
|||
sprintf (USB_Out_Buffer, "Encoder Count = %d!\r\n", bigcount); |
|||
} |
|||
if(mUSBUSARTIsTxTrfReady()) |
|||
last1 = count1; |
|||
putrsUSBUSART(USB_Out_Buffer); |
|||
// Put other code here to display (RS232 works nice) |
|||
} |
|||
end the main function |
|||
} |
|||
return 0; |
|||
} |
|||
==Associated Circuitry== |
==Associated Circuitry== |
Revision as of 22:43, 15 April 2010
Available Pins
The PIC32MX460F512L has 5 available external timer / counter pins denoted TXCK on the pin list, where x is from 1 to 5.
Unfortunately, the PIC32MX440F512H has only 1 available external counter (T1CK), so this cannot be used for quadrature encoder using the external counter pins.
Quadrature Encoder Example
This section details how to set up quadrature encoder with the PIC32MX460F512L and the LS7083.
Sample Code
/* QuadratureHard.c The PIC32MX460F512L has 5 available external timer / counter pins denoted TXCK on the pin list, where x is from 1 to 5. Unfortunately, the PIC32MX440F512H has only 1 available external counter (T1CK), so this PIC cannot be used for quadrature encoder. The NU32 board uses PIC32MX460F512L. This code is based on the QuadratureHard.c for the 8-bit PICS. Quadrature based on Hardware requires two timers to count up-counts and down-counts. PWM uses Timer 2 or Timer 3, therefore, we are going to use Timer 4 and Timer 5 for this code. Timer 4 is T4CK/RC3 and Timer 5 is SDI1/T5CK/RC4. LS7083 chip decodes quadrature A&B signals into up&down pulses for these two timers The software version doesn't use up timers but this hardware version is arbitrarily fast */ #include "HardwareProfile.h" signed int bigcount = 0; // set encoder value initially to zero, it can go + or - // 32 bit number short count0, count1; // 16 bit number short last0 = 0, last1 = 0; // 16 bit number int main(void) { // Configure the system performance SYSTEMConfigPerformance(SYS_FREQ); mInitAllLEDs(); // Must enable glocal interrupts - in this case, we are using multi-vector mode INTEnableSystemMultiVectoredInt(); // init Timer4 and Timer5 mode and periods (PR4, PR5) OpenTimer4( T4_ON | T4_PS_1_1 | T4_SOURCE_EXT, 0xFFFF); OpenTimer5( T5_ON | T5_PS_1_1 | T5_SOURCE_EXT, 0xFFFF); while (1) { count0 = ReadTimer4(); // in your routine this must be done at least every 32000 // encoder counts to avoid rollover ambiguity count1 = ReadTimer5(); bigcount += count0 - last0; // add on the recent up-counts, since the last time if (count0 < last0) { bigcount += 65536; // count0 only increments, so if it got lower //it must have rolled over } last0 = count0; bigcount -= count1 - last1; // we're not worrying about rollover of the 32 bit bigcount total if (count1 < last1) { bigcount -= 65536; } last1 = count1; // Put other code here to display (RS232 works nice) } }
Associated Circuitry
This Circuit is based off the HEDS5500 encoder, LS7083 quadrature, and PIC32MX460F512L.