Friday, April 15, 2011

How to read a rotary encoder using a PIC 18F45K20 using CCS Compiler

This is  short blog on reading a Rotary Encoder using a PIC microcontroller and CCS compiler

Hardware :

  1. Rotary Encoder
  2. PICkit™ 3 Debug Express PIC18F45K20
  3. USB -TTL board for RS232 connectivity 

Connections:
Rotary encoder  - MCU

  1. Pin A and Pin C of rotary encoder connected to RB4 and RB5 of MCU respectively
  2. Pin B (Common ) of rotary encoder connected to VCC.
  3. Both RB4 and RB 5 pulled to ground using a resistance of 47K

USB-TTL board <-> MCU

  1. RC6 (Tx) of MCU connected to USB-TTL board Recv.
  2. Vss of MCU connected to USB_TTL board Gnd.



Coding Platform:

  1. PICKIT 3 (Programmer/Debugger)
  2. CCS Compiler
  3. MPLAB IDE
  4. Putty/Hyperterminal for results



Code:
 #include <18F45K20.h>   
 #fuses HS,NOWDT,NOPROTECT,NOLVP,BROWNOUT,PUT,NOPBADEN,DEBUG   
 #use delay(internal=4Mhz)  
 #use rs232(baud=9600,xmit=PIN_C6,rcv=PIN_C7)   
 /////////////////////////////Working Vars//////////////////////////////////////   
 int d0=0;int d1=0;int d2=0;int d3=0;int16 a=0;int b=0;   
 int1 preva=0;int1 prevb=0;   
 int16 counter=0;int pata=0b00000000;int patb=0b00000000;   
 int y=0;   
 int1 ina=0;int1 inb=0;   
 int1 temp=0;int dir=0;   
 //INTERRUPT ISR   
 #INT_RB   
 void rb_isr(void)   
 {  ina=input(pin_b4);   
   inb=input(pin_b5);   
   pata=pata<<1;   
   bit_clear(pata,4);   
   if(ina==1)   
   {  bit_set(pata,0);   
   }   
   else   
   {  bit_clear(pata,0);   
   }    
   patb=patb<<1;   
   bit_clear(patb,4);   
   if(inb==1)   
   {  bit_set(patb,0);   
   }   
   else   
   {  bit_clear(patb,0);   
   }   
   if(pata==6&&patb==12)   
   {  counter--;   
 printf("Encoder = %03Ld \n\n\r",counter);   
   }   
   else if(pata==12&&patb==6)   
   {  counter++;   
 printf("Encoder = %03Ld \n\n\r",counter);   
   }   
 }      
 //////////////////////////////////////////////////////////////////////////////////  
 #byte IOCB = 0xF7D   
 #byte ANSEL = 0xF7E   
 #byte ANSELH = 0xF7F   
 void main(void)   
 {   
   setup_adc_ports(NO_ANALOGS);   
    enable_interrupts(INT_RB);   
 setup_comparator(NC_NC_NC_NC);   
 IOCB = 0xF0;   
 ANSEL = 0;   
 ANSELH = 0;   
  EXT_INT_EDGE(L_to_H);  
   enable_interrupts(GLOBAL);   
   printf("\n\n\rRotary Encoder Test\n\n\r");   
   while (true)   
   {   
 //put ur menu code here  
   }   // end of while loop   
 }    // end of main   









Many thanks to http://www.ccsinfo.com/forum/viewtopic.php?t=44491 ; http://www.ccsinfo.com/forum/viewtopic.php?p=127421