Yes, you get 2k version absolutely free with all the frills like a beautiful simulator / debugger with no other limitation other then 2k code limit. Floating point routines is also available. Consider the pic basic compiler(2k page limit pbc) which is sold at $100. And for just $70 you get a full version BoostC compiler( no limit).
All compilers have instant interrupts its only pic basic compilers that don't have instant interrupts (God knows why)ie. the interrupt latency is much higher than generated by other compilers. more over the pbc commands are non re-enterent, meaning that only after it completes executing the whole command( say pause 1000) will it enter the ISR. Which is very bad & thats why Darrel has created the instant interrupt routines for PBC.
coming to the project..
Both clockwise & anti clockwise the LCD is made to display only positive values. If you wish you can rewrite the code to get -ve value displayed.
Any thing is possible with this compiler.
The 1x code is commented well but not the 4x( i didn't have time).
Ask me if you need the 2x code. I suppose the 4x will give you all the information to build the 2x.
The 1x code is as follows...
Code:
--------------------------------------------------------------------------
// this test builds & works properly.
#include "system.h"
#include "lcd_driver.h"
#include "stdio.h"
// Set clock frequency to 4MHz.
#pragma CLOCK_FREQ 4000000
//set configuration fuse.
#pragma DATA _CONFIG, _XT_OSC & _WDT_OFF & _CP_OFF & _PWRTE_OFF
#define LCD_ARGS 2, /* Interface type: mode 0 = 8bit, 1 = 4bit(low nibble), 2 = 4bit(upper nibble) */ \
0, /* Use busy signal: 1 = use busy, 0 = use time delays */\
PORTC, TRISC, /* Data port and data port tris register */ \
PORTB, TRISB, /* Control port and control port tris register */ \
2, /* Bit number of control port is connected to RS */ \
7, /* Bit number of control port is connected to RW */ \
3 /* Bit number of control port is connected to Enable */
signed long counter;
unsigned long counter1;
unsigned int value1;
bit update_flag;
/*Interrupt service routine (ISR).On ccp capture interrupt, program
will jump to this code location. */
void interrupt( void )
{
update_flag = 1 ;
if(portb.0 == 0) //check the quadrature signal
{
counter ++ ; // increment counter
}
else //else decrement counter.
{
counter -- ;
}
pir1.2 = 0; //clear ccp1if
}
/* function to display counter. */
void display (unsigned int x)
{
unsigned int xn ;
unsigned int xd ;
char buf[ 10 ];
lcd_clear();
lprintf("count=");
sprintf( buf, "%d", x );
lprintf( buf );
}
/* The main code configures the intcon, pie1, t1con & ccpcon1
registers.*/
void main()
{
trisb = 1; //configure portb.0 as input & rest as
portb = 0; //clear port B
trisc = 0b00000100; //RC2/ccp1 pin as input.
// enable interrupts: interrupt control register.
intcon.6=1; //enable peripheral interrupts
intcon.7=1; //enable global interrupt
//peripheral interrupt enable register 1.
pie1.2 = 1; //enable ccp1 interrupt.
/*ccpcon1: capture/compare/pwm control register1.
bit3-0.....ccpxm3:ccpxm0: ccpx mode select bits.
we will use...
0100 = capture mode, every falling edge.
0101 = capture mode, every rising edge.
we can choose any one of the above mode.
but we will use 0101 in our project.
to get less count use 0110( divide by 4).
or 0111 for divide by 16.
*/
/* setup LCD */
lcd_setup();
update_flag = 1; // start counter from 0
ccp1con = 0b00000101; //set capture mode.
counter = 0; //reset counter.
while(1)
{
while (update_flag == 1)
{
if(counter < 0 )
{
counter1 = (-1)* counter;
display(counter1) ;
}
else
{
display(counter) ;
}
update_flag = 0 ;
}
}
}
--------------------------------------------------------------------------
code for the 4x...
Code:
// this test builds & works properly.
#include "system.h"
#include "lcd_driver.h"
#include "stdio.h"
// Set clock frequency to 20MHz.
#pragma CLOCK_FREQ 20000000
//set configuration fuse.
#pragma DATA _CONFIG, _XT_OSC & _WDT_OFF & _CP_OFF & _PWRTE_OFF
#define LCD_ARGS 2, /* Interface type: mode 0 = 8bit, 1 = 4bit(low nibble), 2 = 4bit(upper nibble) */ \
0, /* Use busy signal: 1 = use busy, 0 = use time delays */\
PORTC, TRISC, /* Data port and data port tris register */ \
PORTB, TRISB, /* Control port and control port tris register */ \
2, /* Bit number of control port is connected to RS */ \
7, /* Bit number of control port is connected to RW */ \
3 /* Bit number of control port is connected to Enable */
signed long counter;
unsigned int value1;
bit update_flag;
/*Interrupt service routine (ISR).On ccp capture interrupt, program
will jump to this code location. */
void interrupt( void )
{
update_flag = 1 ;
if(intcon.1) //RB0/int interrupt(rising edge)
{
if(portc.1 == 0)
{
counter ++ ; // increment counter
}
else //else decrement counter.
{
counter -- ;
}
intcon.1 = 0; //clear intf
}
else
if(intcon.2) //tmr0if (falling edge)
{
if(portc.1 == 1)
{
counter ++ ;
}
else
{
counter -- ;
}
tmr0 = 255 ;
intcon.2 = 0;
}
else
if(pir1.0) //tmr1if
{
if(portc.3 == 1)
{
counter ++ ;
}
else
{
counter -- ;
}
t1con.0 = 0 ;
tmr1l = 255 ;
tmr1h = 255 ;
t1con.0 = 1 ;
pir1.0 = 0 ;
}
else
if(pir1.2) //ccp1if
{
if(portc.3 == 0)
{
counter ++ ;
}
else
{
counter -- ;
}
pir1.2 = 0;
}
}
/* function to display counter. */
void display (unsigned long x)
{
char buff [ 10 ] ;
sprintf32(buff,"%d",x);
lcd_clear();
lprintf("count=");
lprintf (buff);
}
/* The main code configures the intcon, pie1, t1con & ccpcon1
registers.*/
void main()
{
trisb = 1; //configure portb.0 as input & rest as
portb = 0; //clear port B
trisc = 0b00000111; //RC2/ccp1, RC0, RC1 as inputs.
//configure option register bits
//portb pull-ups(rbpu)(disable)...bit7
//interrupt on rising edge(RB0/int)(intedg)...bit6
//tmr0 clock source(tocs) is transition on RA4...bit5
//tmr0 source edge select(tose) is high to low transition...bit4
//bit3-bit0...don't care.
option_reg.6 = 0b11111111;
// enable interrupts: interrupt control register.
// intcon.6=1; enable peripheral interrupts
// intcon.7=1; enable global interrupt
// intcon.5=1; enable tmr0 overflow interrupt.
// intcon.4=1; enable inte (RB0/int)
// intcon.1=0; intf ( RB0/int flag)
// intcon = 0b11110000 ;
//i will enable tmr0 & RB0/int along with ccp and tmr1 interrupt.
//timer1 module: configure t1con.
/*TIMER1 INCREMENTS ONLY IN RISING EDGE*/
//bit7-6....00
//bit5-4....00...prescaler 1:1
//bit3......0....t1oscen cleared.(makes RC0 as clk input)
//bit2......0....synchronize external clock input.
//bit1......1....external clock on pin RC0.
//bit0......1....start timer1.
// t1con = 0b00000011;
//we will start all interrupts at one go a bit latter.
//peripheral interrupt enable register 1.
pie1.2 = 1; //enable ccp1 interrupt.
pie1.0 = 1; //enable tmr1 interrupt.
/*ccpcon1: capture/compare/pwm control register1.
bit3-0.....ccpxm3:ccpxm0: ccpx mode select bits.
we will use...
0100 = capture mode, every falling edge.
0101 = capture mode, every rising edge.
we can choose any one of the above mode.
but we will use 0101 in our project.
to get less count use 0110( divide by 4).
or 0111 for divide by 16.
*/
// LCD setup
lcd_setup();
update_flag = 1; // start counter from 0
ccp1con = 0b00000100; //set capture mode in falling edge.
tmr0 = 255; // a pulse will generate an overflow interrupt.
tmr1l = 255;
tmr1h = 255; // a single pulse input will gen an interrupt.
t1con = 0b00000011; // start timer1 as pulse counter.
intcon = 0b11110000 ; //enable RB0/int, tmr0 interrupt
counter = 0; //start measurement.
while(1)
{
while (update_flag == 1)
{
if(counter < 0 )
{
counter = (-1)*counter;
}
update_flag = 0 ;
display(counter) ;
}
}
}
--------------------------------------------------------------------------
Regards
Raghunathan.
Bookmarks