Saturday, January 29, 2011

PIC16F877A Interrupt Code

During my attempt to program my tachometer, I decided to make things simpler by creating code for an external interrupt, timer 0 interrupt (TMR0), and timer 1 (TMR1) interrupt.  I figured this might be useful to someone in the future, so here it is!

NOTE: I program my code using Sourceboost C complier.

External Interrupt Code on the PIC16F877A
//External Interrupt Test,  
//RoboSlave.Blogspot.com, 1/2011
//Includes
#include <system.h>
//PIC16F877A
#pragma DATA _CONFIG, _PWRTE_OFF & _BODEN_OFF & _WDT_OFF & _LVP_ON & _CPD_OFF & _DEBUG_OFF & _XT_OSC & _CP_OFF
#pragma CLOCK_FREQ 4000000 //Set clock frequency
//Define
#define button1 portb.0
#define led1 portd.0
//Interrupts
void interrupt( void )
{
if( intcon & (1<<INTF) ) //Handle external interrupt
{
clear_bit( intcon, INTF );
led1 = !led1;
}
}
//Main Code
void main( void )
{
trisb = 0x00; //Configure port B
trisd = 0x00; //Configure port D
portb = 0x00; //Initialize port B
portd = 0x00; //Initialize port D
intcon = 0xB0; //Enable interrupts (External, Timer0)
while( 1 ) //Endless loop
{}
}

 Timer0 Interrupt Code on the PIC16F877A
//Timer0 Interrupt Test 
//RoboSlave.Blogspot.com, 1/2011
//Includes
#include <system.h>
//PIC16F877A
#pragma DATA _CONFIG, _PWRTE_OFF & _BODEN_OFF & _WDT_OFF & _LVP_ON & _CPD_OFF & _DEBUG_OFF & _XT_OSC & _CP_OFF
#pragma CLOCK_FREQ 4000000 //Set clock frequency
//Define
#define led1 portd.0
//Interrupts
void interrupt( void )
{
if( intcon & (1<<T0IF) ) //Handle timer0 interrupt
{
clear_bit( intcon, T0IF ); //clear timer 0 interrupt bit
led1 = !led1;
}
}
//Main Code
void main( void )
{
trisd = 0x00; //Configure port D
portd = 0x00; //Initialize port D
intcon = 0xB0; //Enable interrupts (External, Timer0)
//Set Timer0 mode
clear_bit( option_reg, T0CS ); //configure timer0 as a timer
//Set prescaler assignment
clear_bit( option_reg, PSA ); //prescaler is assigned to timer0
//Set prescaler rate
set_bit( option_reg, PS2 ); //prescaler rate 1:128
set_bit( option_reg, PS1 );
set_bit( option_reg, PS0 );
//Set timer0 source edge selection
set_bit( option_reg, T0SE ); //increment on high-to-low transition on RA4/T0CKI pin
while( 1 ) //Endless loop
{}
}

  Timer1 Interrupt Code on the PIC16F877A
//Timer1 Interrupt Test, 
//RoboSlave.Blogspot.com, 1/20111
//Includes
#include <system.h>
//PIC16F877A
#pragma DATA _CONFIG, _PWRTE_OFF & _BODEN_OFF & _WDT_OFF & _LVP_ON & _CPD_OFF & _DEBUG_OFF & _XT_OSC & _CP_OFF
#pragma CLOCK_FREQ 4000000 //Set clock frequency
//Define
#define led1 portd.0
//Interrupts
void interrupt( void )
{
//if( pir1 & (1<<TMR1IF) ) //Handle timer1 interrupt
if (pir1.TMR1IF == 1)
{
clear_bit( pir1, TMR1IF ); //clear timer 1 interrupt bit
led1 = !led1;
}
}
//Main Code
void main( void )
{
trisd = 0x00; //Configure port D
portd = 0x00; //Initialize port D
intcon.GIE = 1;
intcon.PEIE = 1;
pie1.TMR1IE = 1;
t1con= 0b00000001; //set timer1 configs and start
while( 1 ) //Endless loop
{}
}

Wednesday, January 19, 2011

New Tool! - Oscilloscope

I was looking for a function generator to use during my tachometer project debugging.  So I started to bid on a few on ebay.  Wow, ebay is addicting!  Before I realized it, I bought myself an oscilloscope which is just a few years younger than me!  Hitachi Model V-209 Portable Oscilloscope born in 1987, and cost $48.50 + shipping.
My Oscilloscope
Still no function generator... but there is always my next paycheck to look forward too.

Sparkfun Free Day

I wanted to comment on the Sparkfun Free Day on January 13th.  This was the second year I (tried) to participate.  Last year the server did not allow me to even see the pages.  This year it was far better but I still walked away disappointed.

I passed up $30 free dollars (due to my 3+ years as a customer) and attempted to complete the 10 question quiz at a chance to win $100 free dollars.  I did see the first question.... for about 45 minutes... again and again and again.  The server just would not allow me to submit my answer no matter what I did.

Unfortunately, I was being greedy and should have gone for the easy money and walked away.  Instead I got zero.  But I did get this message about a hundred times!
Sparkfun Error Message

Project 4 - Tachometer

Its been over a month since my last post... I did not work much on the others, but I did manage to add another project to my list.

Enter Project 4, the tachometer.  This project was spawned from my father buying a mini milling machine from Grizzly Industrial Inc.  The machine is model G0463 which is a variation of other mini mills on the market.
Grizzly Mini Mill Model G0463
The more expensive mini mill model comes with a number of bells and whistles which may or may not pay for themselves, one of them being an RPM gauge.  After a bit of discussion, I decided to take on the task of making a tachometer to determine the RPM of the spindle.  The range is from 0 to 2000 RPM.  I will probably use a sensor to measure the passing teeth on the drive gear beneath the upper cover... but we'll see how that goes.

Below you can see the current breadboard assembly.  I am using a PIC16F877A for now and will switch to something with less pins when I get the time.  I am also using an old mouse encoder wheel mounted to a motor which I can use to simulate the spindle (bottom right).  The sensor is a simple photogate, which has one LED pointing at a light sensor (all in infrared).
Tachometer Breadboard Set-Up
I bought the following from Sparkfun to display the four digit RPM.
Sparkfun Display Order
I managed to send the numbers via serial communication but was not getting the correct range of RPM... I need to play with the code, the delay_ms(time) function in Sourceboost C may be inaccurate.  I don't have any pictures of that quite yet.

The plan, for now, is to use 1 pin to send the RPM to the display instead of 28 pins.  I did not want the hassle of connecting up each led in each segment and then having to control the mess in the code.  That may happen in a later addition and maybe even if I layout a board for this project.