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
|
|
|