| scottc 
 
 
 Joined: 16 Aug 2010
 Posts: 95
 
 
 
			    
 
 | 
			
				| Rotary Encoder - QEI Module - PIC18F2331/PIC18F2431 |  
				|  Posted: Sun Feb 20, 2011 11:03 pm |   |  
				| 
 |  
				| Here is a small example of putting the QEI module on the 18F series of parts that contain this hardware to some use. Incremental Rotary
 encoders are very common these days. They are used in many consumer
 items such as radio's, Microwave oven's etc. The 18f series of parts that
 contain the qei module provides the developer with a flexible hardware
 solution so as to decode the rotation of the encoder.
 
 The code uses my own LCD routines. Use the CCS routines instead to
 display the rotation of the encoder on your own LCD display.
 I have commented the code fairly well so it should be a easy read
   
 Thanks Scott
 
  	  | Code: |  	  | // PIC MPU = PIC18F2331, PIC18F2431 With hardware qei module
 // Mechanical Rotary Encoder connected to pins qei-a & qei-b Port A
 // Each Encoder Pin "A,B" is pulled up to vcc with 47k Resistors !
 // The centre pin on the encoder is grounded
 // Encoder is Bourns PEC 11 Incremental Encoder
 // http://www.bourns.com/data/global/pdfs/PEC11.pdf
 
 // CCS compiler ver 4.116
 // Code compile results "Rom = 4% ram = 1%"
 
 #include <MAIN.h>
 #USE delay(clock=10Mhz, crystal)
 
 #USE FAST_IO(A)
 #USE FAST_IO(B)
 #USE FAST_IO(C)
 
 #BYTE port_a = 0xF80
 #BYTE port_b = 0xF81
 #BYTE port_c = 0xF82
 
 #byte POSCNTL     = 0xF66  // Position register low byte CAP2BUFL
 #include <LCD4bit.c>       // 4BIT Lcd Routines non CCS
 
 INT MYVALUE;               // Value Variable to display on LCD
 
 void Write_Display (void)  //Display Handler
 {
 Lcd_Config( LCD_LINE1 );
 printf(Write_LCD, "%u.00 QEI Value " ,MYVALUE);
 }
 
 VOID QEI(VOID)
 {
 MYVALUE=POSCNTL;
 
 if (myvalue>200)
 {
 (myvalue=200) && (POSCNTL=200); //Bound MAX Value & POSCNTL Value
 }
 
 Else
 
 If (myvalue<50)
 {
 (Myvalue=50) && (POSCNTL=50); ////Bound MIN Value & POSCNTL Value
 }
 }
 
 //NOTE the poscntl value will increment/decrement from 0 to 255 as the
 //encoder wheel is turned. To keep the poscntl value at a useable state
 //bound its value so it does not continue to count up or down !
 
 void main(void)
 {
 set_tris_a(0b0011000);        //Port A I/O Config
 set_tris_b(0b00001101);       //Port B I/O Config
 set_tris_c(0b11000000);       //Port C I/O Config
 
 setup_adc_ports(no_analogs);
 LCD_Start();                  //Enable LCD to Start up
 setup_qei(QEI_MODE_X2);       //Configure QEI Module
 POSCNTL=100;                  //Starting value of QEI Encoder/Decoder
 MYVALUE=100;                  //Starting Value of "My value"
 
 //Note if you want to increment my value variable by 2 instead of 1 use
 // setup_qei(QEI_MODE_X4);
 
 while(true)
 {
 Write_Display();
 qei();
 }
 }
 
 | 
 
  	  | Code: |  	  | //include file main.h
 #include <18F2431.h>
 #device adc=16
 #FUSES NOWDT                    //No Watch Dog Timer
 #FUSES WDT128                   //Watch Dog Timer uses 1:128 Postscale
 #FUSES LP                       //Low power osc < 200 khz
 #FUSES NOFCMEN                  //Fail-safe clock monitor disabled
 #FUSES NOIESO                   //Internal External Switch Over mode disabled
 #FUSES NOBROWNOUT               //No brownout reset
 #FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
 
 | 
 |  |